* 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.
This commit is contained in:
Julian Brown
2005-03-29 16:29:09 +00:00
parent ec72cfe589
commit 84798bd6b6
4 changed files with 52 additions and 25 deletions

View File

@ -1,3 +1,18 @@
2005-03-29 Julian Brown <julian@codesourcery.com>
* 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 <sterling@tensilica.com> 2005-03-28 Sterling Augustine <sterling@tensilica.com>
Bob Wilson <bob.wilson@acm.org> Bob Wilson <bob.wilson@acm.org>

View File

@ -83,6 +83,11 @@ static struct
unsigned sp_restored:1; unsigned sp_restored:1;
} unwind; } 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 */ #endif /* OBJ_ELF */
enum arm_float_abi enum arm_float_abi
@ -1347,7 +1352,7 @@ mapping_state (enum mstate state)
abort (); 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); symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
symbol_table_insert (symbolP); symbol_table_insert (symbolP);
@ -1379,6 +1384,7 @@ void
arm_elf_change_section (void) arm_elf_change_section (void)
{ {
flagword flags; flagword flags;
segment_info_type *seginfo;
/* Link an unlinked unwind index table section to the .text section. */ /* Link an unlinked unwind index table section to the .text section. */
if (elf_section_type (now_seg) == SHT_ARM_EXIDX if (elf_section_type (now_seg) == SHT_ARM_EXIDX
@ -1394,7 +1400,9 @@ arm_elf_change_section (void)
if ((flags & SEC_ALLOC) == 0) if ((flags & SEC_ALLOC) == 0)
return; 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 int
@ -14303,13 +14311,6 @@ create_unwind_entry (int have_data)
fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1, fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
BFD_RELOC_ARM_PREL31); 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; where += 4;
ptr += 4; ptr += 4;
@ -14323,24 +14324,13 @@ create_unwind_entry (int have_data)
/* Three opcodes bytes are packed into the first word. */ /* Three opcodes bytes are packed into the first word. */
data = 0x80; data = 0x80;
n = 3; n = 3;
goto emit_reloc; break;
case 1: case 1:
case 2: case 2:
/* The size and first two opcode bytes go in the first word. */ /* The size and first two opcode bytes go in the first word. */
data = ((0x80 + unwind.personality_index) << 8) | size; data = ((0x80 + unwind.personality_index) << 8) | size;
n = 2; 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; break;
default: default:
@ -14449,6 +14439,23 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
fix_new (frag_now, where, 4, unwind.proc_start, 0, 1, fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
BFD_RELOC_ARM_PREL31); 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) if (val)
/* Inline exception table entry. */ /* Inline exception table entry. */
md_number_to_chars (ptr + 4, val, 4); md_number_to_chars (ptr + 4, val, 4);

View File

@ -170,7 +170,7 @@ struct fix;
# define md_elf_section_type(str, len) arm_elf_section_type (str, len) # define md_elf_section_type(str, len) arm_elf_section_type (str, len)
# define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_" # define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
# define LOCAL_LABEL_PREFIX '.' # define LOCAL_LABEL_PREFIX '.'
# define TC_SEGMENT_INFO_TYPE enum mstate # define TC_SEGMENT_INFO_TYPE struct arm_segment_info_type
enum mstate enum mstate
{ {
@ -180,6 +180,12 @@ enum mstate
MAP_THUMB MAP_THUMB
}; };
struct arm_segment_info_type
{
enum mstate mapstate;
unsigned int marked_pr_dependency;
};
/* We want .cfi_* pseudo-ops for generating unwind info. */ /* We want .cfi_* pseudo-ops for generating unwind info. */
#define TARGET_USE_CFIPOP 1 #define TARGET_USE_CFIPOP 1

View File

@ -5,16 +5,15 @@
RELOCATION RECORDS FOR \[.ARM.extab\]: RELOCATION RECORDS FOR \[.ARM.extab\]:
OFFSET TYPE VALUE OFFSET TYPE VALUE
00000000 R_ARM_NONE __aeabi_unwind_cpp_pr1
0000000c R_ARM_PREL31 .text 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\]: RELOCATION RECORDS FOR \[.ARM.exidx\]:
OFFSET TYPE VALUE OFFSET TYPE VALUE
00000000 R_ARM_PREL31 .text 00000000 R_ARM_PREL31 .text
00000000 R_ARM_NONE __aeabi_unwind_cpp_pr0
00000008 R_ARM_PREL31 .text.* 00000008 R_ARM_PREL31 .text.*
00000008 R_ARM_NONE __aeabi_unwind_cpp_pr1
0000000c R_ARM_PREL31 .ARM.extab 0000000c R_ARM_PREL31 .ARM.extab
00000010 R_ARM_PREL31 .text.* 00000010 R_ARM_PREL31 .text.*
00000014 R_ARM_PREL31 .ARM.extab.* 00000014 R_ARM_PREL31 .ARM.extab.*