This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ARM: Add cantunwind when unwind info does not match start of section


Hi all!

This patch adds to elf32_arm_fix_exidx_coverage one more condition when
cantunwind should be added.
This bug was initially found in rtld
(https://sourceware.org/ml/libc-alpha/2015-12/msg00501.html).
It happens when two sections are merged into one. First section should have
non-cantunwind last unwind entry and in second section first unwind entry
should not match start of section.

In this situation initial sections are correct (if unwinder hits start of
section without unwind info it stops). But merged section has a gap in unwind
info, which can cause problems.

Tested for arm-linux-gnueabi target, verified on ld.so build and on new test.

BR,
Yury Usishchev

Changelogs:
bfd/ChangeLog:

2015-12-23 Yury Usishchev <y.usishchev@samsung.com>

     * bfd/elf32-arm.c (elf32_arm_fix_exidx_coverage): Insert cantunwind when
     address in first unwind entry does not match start of section.

ld/testsuite/ChangeLog:

2015-12-23 Yury Usishchev <y.usishchev@samsung.com>

     * ld-arm/arm-elf.exp: New test.
     * ld-arm/unwind-mix.d: New file.
     * ld-arm/unwind-mix1.s: New file.
     * ld-arm/unwind-mix2.s: New file.

>From aa53442ab297a36e5da9c7e402ecaa894a10424d Mon Sep 17 00:00:00 2001
From: Yury Usishchev <y.usishchev@samsung.com>
Date: Mon, 21 Dec 2015 21:44:22 +0300
Subject: [PATCH] Add cantunwind when unwind info does not match start of
 section

---
 bfd/elf32-arm.c                   | 12 ++++++++++++
 ld/testsuite/ld-arm/arm-elf.exp   |  3 +++
 ld/testsuite/ld-arm/unwind-mix.d  | 20 ++++++++++++++++++++
 ld/testsuite/ld-arm/unwind-mix1.s | 16 ++++++++++++++++
 ld/testsuite/ld-arm/unwind-mix2.s | 15 +++++++++++++++
 5 files changed, 66 insertions(+)
 create mode 100644 ld/testsuite/ld-arm/unwind-mix.d
 create mode 100644 ld/testsuite/ld-arm/unwind-mix1.s
 create mode 100644 ld/testsuite/ld-arm/unwind-mix2.s

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 583db4d..d4cf88c 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -11737,6 +11737,18 @@ elf32_arm_fix_exidx_coverage (asection **text_section_order,
 	/* An error?  */
 	continue;
 
+      if (last_unwind_type > 0)
+	{
+	  unsigned int first_word = bfd_get_32 (ibfd, contents);
+	  /* Add cantunwind if first unwind item does not match section
+	     start.  */
+	  if (first_word != sec->vma)
+	    {
+	      insert_cantunwind_after (last_text_sec, last_exidx_sec);
+	      last_unwind_type = 0;
+	    }
+	}
+
       for (j = 0; j < hdr->sh_size; j += 8)
 	{
 	  unsigned int second_word = bfd_get_32 (ibfd, contents + j + 4);
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index ac2abf1..f518acc 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -945,5 +945,8 @@ set arm_unwind_tests {
     {"unwind-rel" "-r -Tarm.ld" "" "" {unwind-rel1.s unwind-rel2.s unwind-rel3.s}
      {{readelf -ur unwind-rel.d}}
      "unwind-rel"}
+    {"unwind-mix" "-Tarm.ld" "" "" {unwind-mix1.s unwind-mix2.s}
+     {{readelf -u unwind-mix.d}}
+     "unwind-mix"}
 }
 run_ld_link_tests $arm_unwind_tests
diff --git a/ld/testsuite/ld-arm/unwind-mix.d b/ld/testsuite/ld-arm/unwind-mix.d
new file mode 100644
index 0000000..8c157e1
--- /dev/null
+++ b/ld/testsuite/ld-arm/unwind-mix.d
@@ -0,0 +1,20 @@
+
+Unwind table index '\.ARM\.exidx' at offset .* contains 4 entries:
+
+0x8004 <_start>: @0x8010
+  Compact model index: 1
+  0xc9 0x40 pop {D4}
+  0xc9 0x00 pop {D0}
+  0xa8      pop {r4, r14}
+  0xb0      finish
+
+0x8008 <__aeabi_unwind_cpp_pr1>: 0x1 \[cantunwind\]
+
+0x800c <end>: 0x80a8b0b0
+  Compact model index: 0
+  0xa8      pop {r4, r14}
+  0xb0      finish
+  0xb0      finish
+
+0x8010 <end\+0x4>: 0x1 \[cantunwind\]
+
diff --git a/ld/testsuite/ld-arm/unwind-mix1.s b/ld/testsuite/ld-arm/unwind-mix1.s
new file mode 100644
index 0000000..36e5e0a
--- /dev/null
+++ b/ld/testsuite/ld-arm/unwind-mix1.s
@@ -0,0 +1,16 @@
+	.syntax unified
+	.text
+	.global __aeabi_unwind_cpp_pr0
+	.type __aeabi_unwind_cpp_pr0, %function
+__aeabi_unwind_cpp_pr0:
+	bx lr
+
+	.global _start
+	.type _start, %function
+_start:
+	.fnstart
+	.save {r4, lr}
+	.vsave {d0}
+	.vsave {d4}
+	bx lr
+	.fnend
diff --git a/ld/testsuite/ld-arm/unwind-mix2.s b/ld/testsuite/ld-arm/unwind-mix2.s
new file mode 100644
index 0000000..5301edb
--- /dev/null
+++ b/ld/testsuite/ld-arm/unwind-mix2.s
@@ -0,0 +1,15 @@
+	.syntax unified
+	.text
+	.global __aeabi_unwind_cpp_pr1
+	.type __aeabi_unwind_cpp_pr1, %function
+__aeabi_unwind_cpp_pr1:
+	bx lr
+
+	.global end
+	.type end, %function
+end:
+	.fnstart
+	.save {r4, lr}
+	bx lr
+	.fnend
+
-- 
2.6.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]