This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] Indicate dependency on personality routines for ARM EHABI- take 3
Hi,
This patch fixes output of dependencies on ARM EABI personality routines
for stack unwinding, using R_ARM_NONE relocations. It should output only
one dependency per-section, and should handle .pushsection/.popsection
correctly. These are the previous version of the patch:
http://sourceware.org/ml/binutils/2005-03/msg00126.html
http://sourceware.org/ml/binutils/2005-02/msg00172.html
Tested on arm-none-eabi and i686-pc-linux-gnu with all targets.
OK to apply?
ChangeLog:
* 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.
? bfd/doc/bfd.info
? bfd/doc/bfd.info-1
? gas/doc/as.info
? gas/doc/as.info-1
? gprof/gprof.info
? gprof/gprof.info-1
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.197
diff -c -p -r1.197 tc-arm.c
*** gas/config/tc-arm.c 23 Mar 2005 15:49:02 -0000 1.197
--- gas/config/tc-arm.c 28 Mar 2005 23:31:26 -0000
*************** static struct
*** 83,88 ****
--- 83,93 ----
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
*************** mapping_state (enum mstate state)
*** 1347,1353 ****
abort ();
}
! seg_info (now_seg)->tc_segment_info_data = state;
symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
symbol_table_insert (symbolP);
--- 1352,1358 ----
abort ();
}
! 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);
*************** void
*** 1379,1384 ****
--- 1384,1390 ----
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
*************** arm_elf_change_section (void)
*** 1394,1400 ****
if ((flags & SEC_ALLOC) == 0)
return;
! mapstate = seg_info (now_seg)->tc_segment_info_data;
}
int
--- 1400,1408 ----
if ((flags & SEC_ALLOC) == 0)
return;
! seginfo = seg_info (now_seg);
! mapstate = seginfo->tc_segment_info_data.mapstate;
! marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
}
int
*************** create_unwind_entry (int have_data)
*** 14303,14315 ****
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;
--- 14311,14316 ----
*************** create_unwind_entry (int have_data)
*** 14323,14346 ****
/* Three opcodes bytes are packed into the first word. */
data = 0x80;
n = 3;
! goto emit_reloc;
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:
--- 14324,14336 ----
/* Three opcodes bytes are packed into the first word. */
data = 0x80;
n = 3;
! 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;
break;
default:
*************** s_arm_unwind_fnend (int ignored ATTRIBUT
*** 14449,14454 ****
--- 14439,14461 ----
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);
Index: gas/config/tc-arm.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.h,v
retrieving revision 1.25
diff -c -p -r1.25 tc-arm.h
*** gas/config/tc-arm.h 3 Mar 2005 11:47:49 -0000 1.25
--- gas/config/tc-arm.h 28 Mar 2005 23:31:26 -0000
*************** struct fix;
*** 170,176 ****
# 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
enum mstate
{
--- 170,176 ----
# 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 struct arm_segment_info_type
enum mstate
{
*************** enum mstate
*** 180,185 ****
--- 180,191 ----
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
Index: gas/testsuite/gas/arm/unwind.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/unwind.d,v
retrieving revision 1.5
diff -c -p -r1.5 unwind.d
*** gas/testsuite/gas/arm/unwind.d 4 Mar 2005 15:28:36 -0000 1.5
--- gas/testsuite/gas/arm/unwind.d 28 Mar 2005 23:31:26 -0000
***************
*** 5,20 ****
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
00000008 R_ARM_PREL31 .text.*
0000000c R_ARM_PREL31 .ARM.extab
00000010 R_ARM_PREL31 .text.*
00000014 R_ARM_PREL31 .ARM.extab.*
--- 5,19 ----
RELOCATION RECORDS FOR \[.ARM.extab\]:
OFFSET TYPE VALUE
0000000c R_ARM_PREL31 .text
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.*