From 2468f9c95d416f2880a007190d3bf6c475d279c2 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Tue, 5 May 2009 14:18:30 +0000 Subject: 2009-05-05 Paul Brook bfd/ * bfd-in.h (elf32_arm_fix_exidx_coverage): Add prototype. * bfd-in2.h: Regenerate. * elf32-arm.c (arm_unwind_edit_type, arm_unwind_table_edit): Define. (_arm_elf_section_data): Add text and exidx fields. (add_unwind_table_edit, get_arm_elf_section_data, adjust_exidx_size, insert_cantunwind_after, elf32_arm_fix_exidx_coverage, offset_prel31, copy_exidx_entry): New functions. (elf32_arm_write_section): Fixup .ARM.exidx contents. ld/ * emultempl/armelf.em (compare_output_sec_vma): New function. (gld${EMULATION_NAME}_finish): Add exidx munging code. ld/testsuite/ * ld-arm/arm.ld: Add .ARM.exidx and .ARM.extab. * ld-arm/arm-elf.exp: Add unwind-[1-4]. * ld-arm/unwind-1.d: New test. * ld-arm/unwind-1.s: New test. * ld-arm/unwind-2.d: New test. * ld-arm/unwind-2.s: New test. * ld-arm/unwind-3.d: New test. * ld-arm/unwind-3.s: New test. * ld-arm/unwind-4.d: New test. * ld-arm/unwind-4.s: New test. --- ld/ChangeLog | 5 +++ ld/emultempl/armelf.em | 68 +++++++++++++++++++++++++++++++++++++++++ ld/testsuite/ChangeLog | 13 ++++++++ ld/testsuite/ld-arm/arm-elf.exp | 4 +++ ld/testsuite/ld-arm/arm.ld | 2 ++ ld/testsuite/ld-arm/unwind-1.d | 10 ++++++ ld/testsuite/ld-arm/unwind-1.s | 19 ++++++++++++ ld/testsuite/ld-arm/unwind-2.d | 10 ++++++ ld/testsuite/ld-arm/unwind-2.s | 19 ++++++++++++ ld/testsuite/ld-arm/unwind-3.d | 11 +++++++ ld/testsuite/ld-arm/unwind-3.s | 29 ++++++++++++++++++ ld/testsuite/ld-arm/unwind-4.d | 11 +++++++ ld/testsuite/ld-arm/unwind-4.s | 49 +++++++++++++++++++++++++++++ 13 files changed, 250 insertions(+) create mode 100644 ld/testsuite/ld-arm/unwind-1.d create mode 100644 ld/testsuite/ld-arm/unwind-1.s create mode 100644 ld/testsuite/ld-arm/unwind-2.d create mode 100644 ld/testsuite/ld-arm/unwind-2.s create mode 100644 ld/testsuite/ld-arm/unwind-3.d create mode 100644 ld/testsuite/ld-arm/unwind-3.s create mode 100644 ld/testsuite/ld-arm/unwind-4.d create mode 100644 ld/testsuite/ld-arm/unwind-4.s (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index a13b98534b..2f937b8876 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2009-05-05 Paul Brook + + * emultempl/armelf.em (compare_output_sec_vma): New function. + (gld${EMULATION_NAME}_finish): Add exidx munging code. + 2009-05-05 Anatoly Sokolov * scripttempl/avr.sc (MEMORY): Use DATA_ORIGIN. diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index 2f0c3afd08..2d63a63f10 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -258,10 +258,78 @@ build_section_lists (lang_statement_union_type *statement) } } +static int +compare_output_sec_vma (const void *a, const void *b) +{ + asection *asec = *(asection **) a, *bsec = *(asection **) b; + asection *aout = asec->output_section, *bout = bsec->output_section; + bfd_vma avma, bvma; + + /* If there's no output section for some reason, compare equal. */ + if (!aout || !bout) + return 0; + + avma = aout->vma + asec->output_offset; + bvma = bout->vma + bsec->output_offset; + + if (avma > bvma) + return 1; + else if (avma < bvma) + return -1; + + return 0; +} + static void gld${EMULATION_NAME}_finish (void) { struct bfd_link_hash_entry * h; + unsigned int list_size = 10; + asection **sec_list = xmalloc (list_size * sizeof (asection *)); + unsigned int sec_count = 0; + + if (!link_info.relocatable) + { + /* Build a sorted list of input text sections, then use that to process + the unwind table index. */ + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + bfd *abfd = is->the_bfd; + asection *sec; + + if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) + continue; + + for (sec = abfd->sections; sec != NULL; sec = sec->next) + { + asection *out_sec = sec->output_section; + + if (out_sec + && elf_section_type (sec) == SHT_PROGBITS + && (elf_section_flags (sec) & SHF_EXECINSTR) != 0 + && (sec->flags & SEC_EXCLUDE) == 0 + && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS + && out_sec != bfd_abs_section_ptr) + { + if (sec_count == list_size) + { + list_size *= 2; + sec_list = xrealloc (sec_list, + list_size * sizeof (asection *)); + } + + sec_list[sec_count++] = sec; + } + } + } + + qsort (sec_list, sec_count, sizeof (asection *), &compare_output_sec_vma); + + if (elf32_arm_fix_exidx_coverage (sec_list, sec_count, &link_info)) + need_laying_out = 1; + + free (sec_list); + } /* bfd_elf32_discard_info just plays with debugging sections, ie. doesn't affect any code, so we can delay resizing the diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 63c51ffc89..5631ca2365 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2009-05-05 Paul Brook + + * ld-arm/arm.ld: Add .ARM.exidx and .ARM.extab. + * ld-arm/arm-elf.exp: Add unwind-[1-4]. + * ld-arm/unwind-1.d: New test. + * ld-arm/unwind-1.s: New test. + * ld-arm/unwind-2.d: New test. + * ld-arm/unwind-2.s: New test. + * ld-arm/unwind-3.d: New test. + * ld-arm/unwind-3.s: New test. + * ld-arm/unwind-4.d: New test. + * ld-arm/unwind-4.s: New test. + 2009-05-01 Julian Brown * ld-arm/arm-elf.exp (armeabitests): Add thumb2-bl-blx-interwork test. diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 218bfb5302..054a187026 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -392,3 +392,7 @@ run_dump_test "attr-merge-unknown-1" run_dump_test "attr-merge-unknown-2" run_dump_test "attr-merge-unknown-2r" run_dump_test "attr-merge-unknown-3" +run_dump_test "unwind-1" +run_dump_test "unwind-2" +run_dump_test "unwind-3" +run_dump_test "unwind-4" diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld index cb73fb3b14..8e3fac2846 100644 --- a/ld/testsuite/ld-arm/arm.ld +++ b/ld/testsuite/ld-arm/arm.ld @@ -10,9 +10,11 @@ SECTIONS *(.before) *(.text) *(.after) + *(.ARM.extab*) *(.glue_7) *(.v4_bx) } =0 + .ARM.exidx : { *(.ARM.exidx*) } . = 0x9000; .got : { *(.got) *(.got.plt)} . = 0x12340000; diff --git a/ld/testsuite/ld-arm/unwind-1.d b/ld/testsuite/ld-arm/unwind-1.d new file mode 100644 index 0000000000..add5cb7cca --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-1.d @@ -0,0 +1,10 @@ +#ld: -T arm.ld +#objdump: -s + +.*: file format.* + +#... +Contents of section .ARM.exidx: + 8008 (f8ffff7f b0b0a880 f4ffff7f 01000000|7ffffff8 80a8b0b0 7ffffff4 00000001) .* +Contents of section .far: +#... diff --git a/ld/testsuite/ld-arm/unwind-1.s b/ld/testsuite/ld-arm/unwind-1.s new file mode 100644 index 0000000000..a4eb390178 --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-1.s @@ -0,0 +1,19 @@ + .syntax unified + .text + .global _start + .type _start, %function +_start: + .fnstart + .save {r4, lr} + bx lr + .fnend + + @ Section with no unwinding information. Linker should insert a cantunwind entry. + .section .after, "xa" + .global __aeabi_unwind_cpp_pr0 + .type __aeabi_unwind_cpp_pr0, %function +__aeabi_unwind_cpp_pr0: + bx lr + + .section .far + .word 0 diff --git a/ld/testsuite/ld-arm/unwind-2.d b/ld/testsuite/ld-arm/unwind-2.d new file mode 100644 index 0000000000..a096c9b6a9 --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-2.d @@ -0,0 +1,10 @@ +#ld: -T arm.ld +#objdump: -s + +.*: file format.* + +#... +Contents of section .ARM.exidx: + 8004 (fcffff7f b0b0a880 f8ffff7f 01000000|7ffffffc 80a8b0b0 7ffffff8 00000001) .* +Contents of section .far: +#... diff --git a/ld/testsuite/ld-arm/unwind-2.s b/ld/testsuite/ld-arm/unwind-2.s new file mode 100644 index 0000000000..cd5851caf9 --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-2.s @@ -0,0 +1,19 @@ + .syntax unified + .text + + .global __aeabi_unwind_cpp_pr0 + .type __aeabi_unwind_cpp_pr0, %function +__aeabi_unwind_cpp_pr0: + .global _start + .type _start, %function +_start: + .fnstart + .save {r4, lr} + bx lr + .fnend + + @ last text section has unwind information. Linker should append a + @ terminating cantunwind entry. + + .section .far + .word 0 diff --git a/ld/testsuite/ld-arm/unwind-3.d b/ld/testsuite/ld-arm/unwind-3.d new file mode 100644 index 0000000000..0b8e85e11c --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-3.d @@ -0,0 +1,11 @@ +#ld: -T arm.ld +#objdump: -s + +.*: file format.* + +#... +Contents of section .ARM.exidx: + 800c (f4ffff7f b0b0a880 f0ffff7f 01000000|7ffffff4 80a8b0b0 7ffffff0 00000001) .* + 801c (ecffff7f b0b0a880 e8ffff7f 01000000|7fffffec 80a8b0b0 7fffffe8 00000001) .* +Contents of section .far: +#... diff --git a/ld/testsuite/ld-arm/unwind-3.s b/ld/testsuite/ld-arm/unwind-3.s new file mode 100644 index 0000000000..9cd8514acb --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-3.s @@ -0,0 +1,29 @@ + .syntax unified + .text + @ section without unwind info + .global _start + .type _start, %function +_start: + bl _before + + @ Section that will be placed first + .section .before, "xa" + .type _before, %function +_before: + .fnstart + .save {r4, lr} + bx lr + .fnend + + @ section that will be placed last + .section .after, "xa" + .global __aeabi_unwind_cpp_pr0 + .type __aeabi_unwind_cpp_pr0, %function +__aeabi_unwind_cpp_pr0: + .fnstart + .save {r4, lr} + bx lr + .fnend + + .section .far + .word 0 diff --git a/ld/testsuite/ld-arm/unwind-4.d b/ld/testsuite/ld-arm/unwind-4.d new file mode 100644 index 0000000000..0a4427aafd --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-4.d @@ -0,0 +1,11 @@ +#ld: -T arm.ld +#objdump: -s + +.*: file format.* + +#... +Contents of section .ARM.exidx: + 8020 (e0ffff7f b0b0a880 dcffff7f e8ffff7f|7fffffe0 80a8b0b0 7fffffdc 7fffffe8) .* + 8030 (d8ffff7f b0b0a880 d8ffff7f 01000000|7fffffd8 80a8b0b0 7fffffd8 00000001) .* +Contents of section .far: +#... diff --git a/ld/testsuite/ld-arm/unwind-4.s b/ld/testsuite/ld-arm/unwind-4.s new file mode 100644 index 0000000000..015311bbb0 --- /dev/null +++ b/ld/testsuite/ld-arm/unwind-4.s @@ -0,0 +1,49 @@ + .syntax unified + .text + @ out of line table entry + .global _start + .type _start, %function +_start: + .fnstart + .save {r4, lr} + .vsave {d0} + .vsave {d4} + bl _before + .fnend + + @ entry that can be merged + .fnstart + .save {r4, lr} + bx lr + .fnend + + @ Section that will be placed first + .section .before, "xa" + .type _before, %function +_before: + .fnstart + .save {r4, lr} + bx lr + .fnend + + @ section that will be placed last + .section .after, "xa" + .global __aeabi_unwind_cpp_pr0 + .type __aeabi_unwind_cpp_pr0, %function +__aeabi_unwind_cpp_pr0: + .fnstart + .save {r4, lr} + bx lr + .fnend + @ final function is cantunwind, so output table size is smaller + @ than sum of input sections + .global __aeabi_unwind_cpp_pr1 + .type __aeabi_unwind_cpp_pr1, %function +__aeabi_unwind_cpp_pr1: + .fnstart + .cantunwind + bx lr + .fnend + + .section .far + .word 0 -- cgit v1.2.1