This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] ARM: Add cantunwind when unwind info does not match start of section
- From: Yury Usishchev <y dot usishchev at samsung dot com>
- To: binutils at sourceware dot org
- Date: Wed, 23 Dec 2015 22:47:13 +0300
- Subject: [PATCH] ARM: Add cantunwind when unwind info does not match start of section
- Authentication-results: sourceware.org; auth=none
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