From 40a18ebd3ae910042b4d7bf053a41c247db7cbc1 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 1 Oct 2004 12:59:42 +0000 Subject: [PATCH] The patch below adds binutils support for the SHT_ARM_EXIDX, as defined by the ARM EABI. --- bfd/ChangeLog | 7 ++++++ bfd/elf32-arm.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++--- binutils/ChangeLog | 5 ++++ binutils/readelf.c | 16 +++++++++++++ gas/ChangeLog | 7 ++++++ gas/config/tc-arm.c | 14 +++++++++++ gas/config/tc-arm.h | 3 +++ include/elf/ChangeLog | 7 ++++++ include/elf/arm.h | 11 ++++++++- ld/ChangeLog | 4 ++++ ld/emulparams/armelf.sh | 5 ++++ 11 files changed, 139 insertions(+), 4 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cc743c7..4467b65 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2004-10-01 Paul Brook + + * elf32-arm.h (elf32_arm_fake_sections, + is_arm_elf_unwind_section_name, elf32_arm_section_from_shdr): New + functions. + (elf_backend_fake_sections, elf_backend_section_from_shdr): Define. + 2004-10-01 Alan Modra * elf-bfd.h (struct eh_cie_fde): Add need_relative and diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 99ed731..a8aac2b 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -4235,9 +4235,6 @@ elf32_arm_reloc_type_class (const Elf_Internal_Rela *rela) } } -static bfd_boolean elf32_arm_section_flags (flagword *, const Elf_Internal_Shdr *); -static void elf32_arm_final_write_processing (bfd *, bfd_boolean); - /* Set the right machine number for an Arm ELF file. */ static bfd_boolean @@ -4255,6 +4252,65 @@ elf32_arm_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED bfd_arm_update_notes (abfd, ARM_NOTE_SECTION); } +/* Return TRUE if this is an unwinding table entry. */ + +static bfd_boolean +is_arm_elf_unwind_section_name (bfd * abfd ATTRIBUTE_UNUSED, const char * name) +{ + size_t len1, len2; + + len1 = sizeof (ELF_STRING_ARM_unwind) - 1; + len2 = sizeof (ELF_STRING_ARM_unwind_once) - 1; + return (strncmp (name, ELF_STRING_ARM_unwind, len1) == 0 + || strncmp (name, ELF_STRING_ARM_unwind_once, len2) == 0); +} + + +/* Set the type and flags for an ARM section. We do this by + the section name, which is a hack, but ought to work. */ + +static bfd_boolean +elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec) +{ + const char * name; + + name = bfd_get_section_name (abfd, sec); + + if (is_arm_elf_unwind_section_name (abfd, name)) + { + hdr->sh_type = SHT_ARM_EXIDX; + hdr->sh_flags |= SHF_LINK_ORDER; + } + return TRUE; +} + +/* Handle an ARM specific section when reading an object file. + This is called when elf.c finds a section with an unknown type. */ + +static bfd_boolean +elf32_arm_section_from_shdr (bfd *abfd, + Elf_Internal_Shdr * hdr, + const char *name) +{ + /* There ought to be a place to keep ELF backend specific flags, but + at the moment there isn't one. We just keep track of the + sections by their name, instead. Fortunately, the ABI gives + names for all the ARM specific sections, so we will probably get + away with this. */ + switch (hdr->sh_type) + { + case SHT_ARM_EXIDX: + break; + + default: + return FALSE; + } + + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + return FALSE; + + return TRUE; +} /* Called for each symbol. Builds a section map based on mapping symbols. Does not alter any of the symbols. */ @@ -4426,6 +4482,8 @@ elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec, #define elf_backend_reloc_type_class elf32_arm_reloc_type_class #define elf_backend_object_p elf32_arm_object_p #define elf_backend_section_flags elf32_arm_section_flags +#define elf_backend_fake_sections elf32_arm_fake_sections +#define elf_backend_section_from_shdr elf32_arm_section_from_shdr #define elf_backend_final_write_processing elf32_arm_final_write_processing #define elf_backend_copy_indirect_symbol elf32_arm_copy_indirect_symbol diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 71936e2..eea10a2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2004-10-01 Paul Brook + + * readelf.c (get_arm_section_type_name): New function. + (get_section_type_name): Use it. + 2004-09-28 Nick Clifton * nm.c: Reorder functions to eliminate most of the static function diff --git a/binutils/readelf.c b/binutils/readelf.c index d0569c4..b35ddfe 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -2404,6 +2404,19 @@ get_ia64_section_type_name (unsigned int sh_type) } static const char * +get_arm_section_type_name (unsigned int sh_type) +{ + switch (sh_type) + { + case SHT_ARM_EXIDX: + return "ARM_EXIDX"; + default: + break; + } + return NULL; +} + +static const char * get_section_type_name (unsigned int sh_type) { static char buff[32]; @@ -2453,6 +2466,9 @@ get_section_type_name (unsigned int sh_type) case EM_IA_64: result = get_ia64_section_type_name (sh_type); break; + case EM_ARM: + result = get_arm_section_type_name (sh_type); + break; default: result = NULL; break; diff --git a/gas/ChangeLog b/gas/ChangeLog index c328820..3f8fff4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2004-10-01 Paul Brook + + * config/tc-arm.c (arm_elf_section_type): New function. + (arm_elf_change_section): Set section link for exidx sections. + * config/tc-arm.h (arm_elf_section_type): Add prototype. + (md_elf_section_type): Define. + 2004-10-01 Bill Farmer * config/tc-pdp11.c (md_apply_fix3): Change to sign of the SOB diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 752cd3c..9770ccd 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -1338,6 +1338,11 @@ arm_elf_change_section (void) { flagword flags; + /* Link an unlinked unwind index table section to the .text section. */ + if (elf_section_type (now_seg) == SHT_ARM_EXIDX + && elf_linked_to_section (now_seg) == NULL) + elf_linked_to_section (now_seg) = text_section; + if (!SEG_NORMAL (now_seg)) return; @@ -1349,6 +1354,15 @@ arm_elf_change_section (void) mapstate = seg_info (now_seg)->tc_segment_info_data; } + +int +arm_elf_section_type (const char * str, size_t len) +{ + if (len == 5 && strncmp (str, "exidx", 5) == 0) + return SHT_ARM_EXIDX; + + return -1; +} #else #define mapping_state(a) #endif /* OBJ_ELF */ diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index 4e791a0..fb8ca8d 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -167,6 +167,7 @@ struct fix; # define DWARF2_LINE_MIN_INSN_LENGTH 2 # define obj_frob_symbol(sym, punt) armelf_frob_symbol ((sym), & (punt)) # define md_elf_section_change_hook() arm_elf_change_section () +# 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 @@ -209,3 +210,5 @@ extern void cons_fix_new_arm (fragS *, int, int, expressionS *); extern void arm_init_frag (struct frag *); extern void arm_handle_align (struct frag *); extern bfd_boolean arm_fix_adjustable (struct fix *); +extern int arm_elf_section_type (const char *, size_t); + diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 6b0cf0d..300181f 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,10 @@ +2004-10-01 Paul Brook + + * arm.h (SHT_ARM_EXIDX): Define. + (ELF_STRING_ARM_unwind, ELF_STRING_ARM_unwind, + ELF_STRING_ARM_unwind_once, ELF_STRING_ARM_unwind_info_once): + Define. + 2004-08-25 Dmitry Diky * msp430.h: Add new relocs. diff --git a/include/elf/arm.h b/include/elf/arm.h index 05ba346..7b80308 100644 --- a/include/elf/arm.h +++ b/include/elf/arm.h @@ -64,6 +64,9 @@ #define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ #define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ +/* Additional section types. */ +#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */ + /* ARM-specific values for sh_flags. */ #define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */ #define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */ @@ -157,5 +160,11 @@ END_RELOC_NUMBERS (R_ARM_max) /* The name of the note section used to identify arm variants. */ #define ARM_NOTE_SECTION ".note.gnu.arm.ident" - + +/* Special section names. */ +#define ELF_STRING_ARM_unwind ".ARM.exidx" +#define ELF_STRING_ARM_unwind_info ".ARM.extab" +#define ELF_STRING_ARM_unwind_once ".gnu.linkonce.armexidx." +#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab." + #endif /* _ELF_ARM_H */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 4f915c5..68853ce 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2004-10-01 Paul Brook + + * emulparams/armelf.sh: Add unwinding table sections. + 2004-09-30 Filip Navara * emultempl/pe.em (gld_${EMULATION_NAME}_set_symbols): Generate diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh index 35a6d23..195810c 100644 --- a/ld/emulparams/armelf.sh +++ b/ld/emulparams/armelf.sh @@ -10,6 +10,11 @@ OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7)' OTHER_BSS_SYMBOLS='__bss_start__ = .;' OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;' OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }' +OTHER_READONLY_SECTIONS=" + .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) } + __exidx_start = .; + .ARM.exidx ${RELOCATING-0} : { *(.ARM.exidx${RELOCATING+* .gnu.linkonce.armexidx.*}) } + __exidx_end = .;" DATA_START_SYMBOLS='__data_start = . ;'; -- 2.7.4