From 84798bd6b6da79bc96633b981573ededa9727d44 Mon Sep 17 00:00:00 2001 From: Julian Brown Date: Tue, 29 Mar 2005 16:29:09 +0000 Subject: [PATCH] * gas/config/tc-arm.c (marked_pr_dependency): New bitmap, bit N indicates whether personality routine index N has been output for this section. (mapping_state): tc_segment_info_data now struct not enum. (arm_elf_change_section): Likewise, and marked_pr_dependency is now handled on section change. (create_unwind_entry): Previous code to output dependency removed. (s_arm_unwind_fnend): Output dependency if it hasn't been done already for this section. * gas/config/tc-arm.h (TC_SEGMENT_INFO_TYPE): Redefined as struct arm_segment_info_type. (arm_segment_info_type): New struct. * gas/testsuite/gas/arm/unwind.d: Update expected output. --- gas/ChangeLog | 15 +++++++++++ gas/config/tc-arm.c | 49 +++++++++++++++++++--------------- gas/config/tc-arm.h | 8 +++++- gas/testsuite/gas/arm/unwind.d | 5 ++-- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index f45d92539ae..2cc94453e18 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2005-03-29 Julian Brown + + * config/tc-arm.c (marked_pr_dependency): New bitmap, bit N indicates + whether personality routine index N has been output for this section. + (mapping_state): tc_segment_info_data now struct not enum. + (arm_elf_change_section): Likewise, and marked_pr_dependency is now + handled on section change. + (create_unwind_entry): Previous code to output dependency removed. + (s_arm_unwind_fnend): Output dependency if it hasn't been done already + for this section. + * config/tc-arm.h (TC_SEGMENT_INFO_TYPE): Redefined as struct + arm_segment_info_type. + (arm_segment_info_type): New struct. + * testsuite/gas/arm/unwind.d: Update expected output. + 2005-03-28 Sterling Augustine Bob Wilson diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 19faa62e23d..9baf888b68e 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -83,6 +83,11 @@ static struct unsigned sp_restored:1; } unwind; +/* Bit N indicates that an R_ARM_NONE relocation has been output for + __aeabi_unwind_cpp_prN already if set. This enables dependencies to be + emitted only once per section, to save unnecessary bloat. */ +static unsigned int marked_pr_dependency = 0; + #endif /* OBJ_ELF */ enum arm_float_abi @@ -1347,7 +1352,7 @@ mapping_state (enum mstate state) abort (); } - seg_info (now_seg)->tc_segment_info_data = state; + seg_info (now_seg)->tc_segment_info_data.mapstate = state; symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now); symbol_table_insert (symbolP); @@ -1379,6 +1384,7 @@ void arm_elf_change_section (void) { flagword flags; + segment_info_type *seginfo; /* Link an unlinked unwind index table section to the .text section. */ if (elf_section_type (now_seg) == SHT_ARM_EXIDX @@ -1394,7 +1400,9 @@ arm_elf_change_section (void) if ((flags & SEC_ALLOC) == 0) return; - mapstate = seg_info (now_seg)->tc_segment_info_data; + seginfo = seg_info (now_seg); + mapstate = seginfo->tc_segment_info_data.mapstate; + marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency; } int @@ -14303,13 +14311,6 @@ create_unwind_entry (int have_data) fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1, BFD_RELOC_ARM_PREL31); - /* Indicate dependency to linker. */ - { - char *name = "__aeabi_unwind_cpp_pr0"; - symbolS *pr = symbol_find_or_make (name); - fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE); - } - where += 4; ptr += 4; @@ -14323,24 +14324,13 @@ create_unwind_entry (int have_data) /* Three opcodes bytes are packed into the first word. */ data = 0x80; n = 3; - goto emit_reloc; + break; case 1: case 2: /* The size and first two opcode bytes go in the first word. */ data = ((0x80 + unwind.personality_index) << 8) | size; n = 2; - goto emit_reloc; - - emit_reloc: - { - /* Indicate dependency to linker. */ - char *name[] = { "__aeabi_unwind_cpp_pr0", - "__aeabi_unwind_cpp_pr1", - "__aeabi_unwind_cpp_pr2" }; - symbolS *pr = symbol_find_or_make (name[unwind.personality_index]); - fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE); - } break; default: @@ -14449,6 +14439,23 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED) fix_new (frag_now, where, 4, unwind.proc_start, 0, 1, BFD_RELOC_ARM_PREL31); + /* Indicate dependency on EHABI-defined personality routines to the + linker, if it hasn't been done already. */ + if (unwind.personality_index >= 0 && unwind.personality_index < 3) + { + char *name[] = { "__aeabi_unwind_cpp_pr0", + "__aeabi_unwind_cpp_pr1", + "__aeabi_unwind_cpp_pr2" }; + if (!(marked_pr_dependency & (1 << unwind.personality_index))) + { + symbolS *pr = symbol_find_or_make (name[unwind.personality_index]); + fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE); + marked_pr_dependency |= 1 << unwind.personality_index; + seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency + = marked_pr_dependency; + } + } + if (val) /* Inline exception table entry. */ md_number_to_chars (ptr + 4, val, 4); diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index f205dff2522..e3c05b3bad4 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -170,7 +170,7 @@ struct fix; # define md_elf_section_type(str, len) arm_elf_section_type (str, len) # define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" # define LOCAL_LABEL_PREFIX '.' -# define TC_SEGMENT_INFO_TYPE enum mstate +# define TC_SEGMENT_INFO_TYPE struct arm_segment_info_type enum mstate { @@ -180,6 +180,12 @@ enum mstate MAP_THUMB }; +struct arm_segment_info_type +{ + enum mstate mapstate; + unsigned int marked_pr_dependency; +}; + /* We want .cfi_* pseudo-ops for generating unwind info. */ #define TARGET_USE_CFIPOP 1 diff --git a/gas/testsuite/gas/arm/unwind.d b/gas/testsuite/gas/arm/unwind.d index 3ca16260331..982040b7b51 100644 --- a/gas/testsuite/gas/arm/unwind.d +++ b/gas/testsuite/gas/arm/unwind.d @@ -5,16 +5,15 @@ RELOCATION RECORDS FOR \[.ARM.extab\]: OFFSET TYPE VALUE -00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1 0000000c R_ARM_PREL31 .text -0000000c R_ARM_NONE __aeabi_unwind_cpp_pr0 -0000001c R_ARM_NONE __aeabi_unwind_cpp_pr1 RELOCATION RECORDS FOR \[.ARM.exidx\]: OFFSET TYPE VALUE 00000000 R_ARM_PREL31 .text +00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0 00000008 R_ARM_PREL31 .text.* +00000008 R_ARM_NONE __aeabi_unwind_cpp_pr1 0000000c R_ARM_PREL31 .ARM.extab 00000010 R_ARM_PREL31 .text.* 00000014 R_ARM_PREL31 .ARM.extab.* -- 2.30.2