From 579f31ac74d806de9c148fb324a32c488634742a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 11 May 2001 12:36:47 +0000 Subject: [PATCH] * elfxx-ia64.c (is_unwind_section_name): Consider linkonce unwind sections as well. (elfNN_ia64_final_write_processing): Map .gnu.linkonce.ia64unw.FOO to .gnu.linkonce.t.FOO text section. * readelf.c (process_unwind): Print all unwind sections, not just one. * config/tc-ia64.c (special_linkonce_name): New. (make_unw_section): Map .gnu.linkonce.t.FOO text section into .gnu.linkonce.ia64unw{,i}.FOO. (ia64_elf_section_type): Handle .gnu.linkonce.ia64unw{,i}.FOO. (dot_endp): Add comment about it. * elf/ia64.h (ELF_STRING_ia64_unwind_once): Define. (ELF_STRING_ia64_unwind_info_once): Define. * emulparams/elf64_ia64.sh (OTHER_READONLY_SECTIONS): Put .gnu.linkonce.ia64unw{,i} sections into corresponding .IA_64.unwind* output sections. * emulparams/elf64_aix.sh (OTHER_READONLY_SECTIONS): Likewise. --- bfd/ChangeLog | 7 +++ bfd/elfxx-ia64.c | 20 ++++++- binutils/ChangeLog | 5 ++ binutils/readelf.c | 106 ++++++++++++++++++++++++++++-------- gas/ChangeLog | 8 +++ gas/config/tc-ia64.c | 32 +++++++++-- include/ChangeLog | 5 ++ include/elf/ia64.h | 2 + ld/ChangeLog | 7 +++ ld/emulparams/elf64_aix.sh | 2 +- ld/emulparams/elf64_ia64.sh | 2 +- 11 files changed, 164 insertions(+), 32 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c2bb974371e..c97b46aacce 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2001-05-11 Jakub Jelinek + + * elfxx-ia64.c (is_unwind_section_name): Consider linkonce unwind + sections as well. + (elfNN_ia64_final_write_processing): Map .gnu.linkonce.ia64unw.FOO + to .gnu.linkonce.t.FOO text section. + 2001-05-11 Jakub Jelinek * merge.c (struct sec_merge_hash_entry): Add u.entsize and u.suffix diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 8d80e6e27df..f0f64f65441 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -921,12 +921,14 @@ static inline boolean is_unwind_section_name (name) const char *name; { - size_t len1, len2; + size_t len1, len2, len3; len1 = sizeof (ELF_STRING_ia64_unwind) - 1; len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1; - return (strncmp (name, ELF_STRING_ia64_unwind, len1) == 0 - && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0); + len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1; + return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0 + && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0) + || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0); } /* Handle an IA-64 specific section when reading an object file. This @@ -1065,6 +1067,18 @@ elfNN_ia64_final_write_processing (abfd, linker) /* .IA_64.unwindFOO -> FOO */ text_sect = bfd_get_section_by_name (abfd, sname); } + else if (sname + && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1, + strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0) + { + /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */ + size_t len2 = sizeof (".gnu.linkonce.t.") - 1; + char *once_name = alloca (len2 + strlen (sname) - len + 1); + + memcpy (once_name, ".gnu.linkonce.t.", len2); + strcpy (once_name + len2, sname + len); + text_sect = bfd_get_section_by_name (abfd, once_name); + } else /* last resort: fall back on .text */ text_sect = bfd_get_section_by_name (abfd, ".text"); diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f2c82dc08db..311f8335de4 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2001-05-11 Jakub Jelinek + + * readelf.c (process_unwind): Print all unwind sections, not just + one. + 2001-05-07 Thiemo Seufer * readelf.c (process_unwind): Remove const specifier. diff --git a/binutils/readelf.c b/binutils/readelf.c index fa583e441d3..b7aecdebd9a 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -3408,7 +3408,7 @@ process_unwind (file) FILE * file; { Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec; - unsigned long i, addr_size; + unsigned long i, addr_size, unwcount = 0, unwstart = 0; struct unw_aux_info aux; if (!do_unwind) @@ -3437,40 +3437,100 @@ process_unwind (file) aux.strtab, char *, "string table"); } else if (sec->sh_type == SHT_IA_64_UNWIND) - unwsec = sec; - else if (strcmp (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info) == 0) + unwcount++; + } + + if (!unwcount) + printf (_("\nThere are no unwind sections in this file.\n")); + + while (unwcount-- > 0) + { + char *suffix; + size_t len, len2; + + for (i = unwstart, sec = section_headers + unwstart; + i < elf_header.e_shnum; ++i, ++sec) + if (sec->sh_type == SHT_IA_64_UNWIND) + { + unwsec = sec; + break; + } + + unwstart = i + 1; + len = sizeof (ELF_STRING_ia64_unwind_once) - 1; + + if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, + len) == 0) + { + /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */ + len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1; + suffix = SECTION_NAME (unwsec) + len; + for (i = 0, sec = section_headers; i < elf_header.e_shnum; + ++i, ++sec) + if (strncmp (SECTION_NAME (sec), + ELF_STRING_ia64_unwind_info_once, len2) == 0 + && strcmp (SECTION_NAME (sec) + len2, suffix) == 0) + break; + } + else + { + /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO + .IA_64.unwind or BAR -> .IA_64.unwind_info */ + len = sizeof (ELF_STRING_ia64_unwind) - 1; + len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1; + suffix = ""; + if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, + len) == 0) + suffix = SECTION_NAME (unwsec) + len; + for (i = 0, sec = section_headers; i < elf_header.e_shnum; + ++i, ++sec) + if (strncmp (SECTION_NAME (sec), + ELF_STRING_ia64_unwind_info, len2) == 0 + && strcmp (SECTION_NAME (sec) + len2, suffix) == 0) + break; + } + + if (i == elf_header.e_shnum) + { + printf (_("\nCould not find unwind info section for ")); + + if (string_table == NULL) + printf ("%d", unwsec->sh_name); + else + printf ("'%s'", SECTION_NAME (unwsec)); + } + else { aux.info_size = sec->sh_size; aux.info_addr = sec->sh_addr; GET_DATA_ALLOC (sec->sh_offset, aux.info_size, aux.info, char *, "unwind info"); - } - } - if (unwsec) - { - printf (_("\nUnwind section ")); + printf (_("\nUnwind section ")); - if (string_table == NULL) - printf ("%d", unwsec->sh_name); - else - printf ("'%s'", SECTION_NAME (unwsec)); + if (string_table == NULL) + printf ("%d", unwsec->sh_name); + else + printf ("'%s'", SECTION_NAME (unwsec)); - printf (_(" at offset 0x%lx contains %lu entries:\n"), - unwsec->sh_offset, (unsigned long) (unwsec->sh_size / (3 * addr_size))); + printf (_(" at offset 0x%lx contains %lu entries:\n"), + unwsec->sh_offset, + (unsigned long) (unwsec->sh_size / (3 * addr_size))); - (void) slurp_ia64_unwind_table (file, & aux, unwsec); + (void) slurp_ia64_unwind_table (file, & aux, unwsec); - if (aux.table_len > 0) - dump_ia64_unwind (& aux); + if (aux.table_len > 0) + dump_ia64_unwind (& aux); + + if (aux.table) + free ((char *) aux.table); + if (aux.info) + free ((char *) aux.info); + aux.table = NULL; + aux.info = NULL; + } } - else - printf (_("\nThere are no unwind sections in this file.\n")); - if (aux.table) - free ((char *) aux.table); - if (aux.info) - free ((char *) aux.info); if (aux.symtab) free (aux.symtab); if (aux.strtab) diff --git a/gas/ChangeLog b/gas/ChangeLog index 1e6d8c8fd1b..21e5209456a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2001-05-11 Jakub Jelinek + + * config/tc-ia64.c (special_linkonce_name): New. + (make_unw_section): Map .gnu.linkonce.t.FOO text section into + .gnu.linkonce.ia64unw{,i}.FOO. + (ia64_elf_section_type): Handle .gnu.linkonce.ia64unw{,i}.FOO. + (dot_endp): Add comment about it. + 2001-05-11 Nick Clifton * config/tc-arm.c (arm_handle_align): When truncating an aligned diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index be4b7e5bd4d..0a3dcc63e26 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -526,6 +526,11 @@ static char special_section_name[][20] = {".IA_64.unwind"}, {".IA_64.unwind_info"} }; +static char *special_linkonce_name[] = + { + ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi." + }; + /* The best template for a particular sequence of up to three instructions: */ #define N IA64_NUM_TYPES @@ -852,11 +857,20 @@ static int generate_unwind_image PARAMS ((const char *)); #define make_unw_section_name(special, text_name, result) \ { \ char *_prefix = special_section_name[special]; \ - size_t _prefix_len = strlen (_prefix), _text_len = strlen (text_name); \ - char *_result = alloca (_prefix_len + _text_len + 1); \ + char *_suffix = text_name; \ + size_t _prefix_len, _suffix_len; \ + char *_result; \ + if (strncmp (text_name, ".gnu.linkonce.t.", \ + sizeof (".gnu.linkonce.t.") - 1) == 0) \ + { \ + _prefix = special_linkonce_name[special - SPECIAL_SECTION_UNWIND]; \ + _suffix += sizeof (".gnu.linkonce.t.") - 1; \ + } \ + _prefix_len = strlen (_prefix), _suffix_len = strlen (_suffix); \ + _result = alloca (_prefix_len + _suffix_len + 1); \ memcpy(_result, _prefix, _prefix_len); \ - memcpy(_result + _prefix_len, text_name, _text_len); \ - _result[_prefix_len + _text_len] = '\0'; \ + memcpy(_result + _prefix_len, _suffix, _suffix_len); \ + _result[_prefix_len + _suffix_len] = '\0'; \ result = _result; \ } \ while (0) @@ -913,10 +927,18 @@ ia64_elf_section_type (str, len) if (strncmp (str, ELF_STRING_ia64_unwind_info, len) == 0) return SHT_PROGBITS; + len = sizeof (ELF_STRING_ia64_unwind_info_once) - 1; + if (strncmp (str, ELF_STRING_ia64_unwind_info_once, len) == 0) + return SHT_PROGBITS; + len = sizeof (ELF_STRING_ia64_unwind) - 1; if (strncmp (str, ELF_STRING_ia64_unwind, len) == 0) return SHT_IA_64_UNWIND; + len = sizeof (ELF_STRING_ia64_unwind_once) - 1; + if (strncmp (str, ELF_STRING_ia64_unwind_once, len) == 0) + return SHT_IA_64_UNWIND; + return -1; } @@ -3820,6 +3842,8 @@ dot_endp (dummy) .text .IA_64.unwind .text.foo .IA_64.unwind.text.foo .foo .IA_64.unwind.foo + .gnu.linkonce.t.foo + .gnu.linkonce.ia64unw.foo _info .IA_64.unwind_info gas issues error message (ditto) _infoFOO .IA_64.unwind_infoFOO gas issues error message (ditto) diff --git a/include/ChangeLog b/include/ChangeLog index 1cf248342cb..fee7f8901eb 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2001-05-11 Jakub Jelinek + + * elf/ia64.h (ELF_STRING_ia64_unwind_once): Define. + (ELF_STRING_ia64_unwind_info_once): Define. + 2001-05-07 Zack Weinberg * demangle.h: Use PARAMS for all prototypes. diff --git a/include/elf/ia64.h b/include/elf/ia64.h index ecd74b08f66..edfc7c5b532 100644 --- a/include/elf/ia64.h +++ b/include/elf/ia64.h @@ -47,6 +47,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define ELF_STRING_ia64_pltoff ".IA_64.pltoff" #define ELF_STRING_ia64_unwind ".IA_64.unwind" #define ELF_STRING_ia64_unwind_info ".IA_64.unwind_info" +#define ELF_STRING_ia64_unwind_once ".gnu.linkonce.ia64unw." +#define ELF_STRING_ia64_unwind_info_once ".gnu.linkonce.ia64unwi." /* Bits in the sh_flags field of Elf64_Shdr: */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 3cd93912f20..8be1c30dcb5 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2001-05-11 Jakub Jelinek + + * emulparams/elf64_ia64.sh (OTHER_READONLY_SECTIONS): Put + .gnu.linkonce.ia64unw{,i} sections into corresponding .IA_64.unwind* + output sections. + * emulparams/elf64_aix.sh (OTHER_READONLY_SECTIONS): Likewise. + 2001-05-11 Jakub Jelinek * ldlang.c (lang_process): Call bfd_merge_sections. diff --git a/ld/emulparams/elf64_aix.sh b/ld/emulparams/elf64_aix.sh index c0e73a9afd5..057949b602b 100644 --- a/ld/emulparams/elf64_aix.sh +++ b/ld/emulparams/elf64_aix.sh @@ -13,5 +13,5 @@ NOP=0x00300000010070000002000001000400 # a bundle full of nops OTHER_GOT_SYMBOLS='. = ALIGN (8); PROVIDE (__gp = . + 0x200000);' OTHER_GOT_SECTIONS='.IA_64.pltoff : { *(.IA_64.pltoff) }' OTHER_PLT_RELOC_SECTIONS='.rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }' -OTHER_READONLY_SECTIONS='.opd : { *(.opd) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) } .IA_64.unwind : { *(.IA_64.unwind*) }' +OTHER_READONLY_SECTIONS='.opd : { *(.opd) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) *(.gnu.linkonce.ia64unwi.*) } .IA_64.unwind : { *(.IA_64.unwind*) *(.gnu.linkonce.ia64unw.*) }' LIB_PATH=/usr/lib/ia64l64:/usr/lib:/usr/local/lib diff --git a/ld/emulparams/elf64_ia64.sh b/ld/emulparams/elf64_ia64.sh index fff59924cb3..845001bda0b 100644 --- a/ld/emulparams/elf64_ia64.sh +++ b/ld/emulparams/elf64_ia64.sh @@ -12,4 +12,4 @@ GENERATE_SHLIB_SCRIPT=yes NOP=0x00300000010070000002000001000400 # a bundle full of nops OTHER_GOT_SECTIONS='.IA_64.pltoff : { *(.IA_64.pltoff) }' OTHER_PLT_RELOC_SECTIONS='.rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) }' -OTHER_READONLY_SECTIONS='.opd : { *(.opd) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) } .IA_64.unwind : { *(.IA_64.unwind*) }' +OTHER_READONLY_SECTIONS='.opd : { *(.opd) } .IA_64.unwind_info : { *(.IA_64.unwind_info*) *(.gnu.linkonce.ia64unwi.*) } .IA_64.unwind : { *(.IA_64.unwind*) *(.gnu.linkonce.ia64unw.*) }' -- 2.34.1