From 579f31ac74d806de9c148fb324a32c488634742a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 11 May 2001 12:36:47 +0000 Subject: * 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. --- binutils/ChangeLog | 5 +++ binutils/readelf.c | 106 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 23 deletions(-) (limited to 'binutils') diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f2c82dc..311f833 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 fa583e4..b7aecde 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) -- cgit v1.1