X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=79724e0549467c28d3af0511554cce11adcff489;hb=0121f438e83e06efd29e43779edf4a01004a39ff;hp=9d0104d979172b4fba7d041d71f1eb28d5fe237c;hpb=0fa29e2deea19a33fec7f1e5a5cf49b94f93b2f8;p=binutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 9d0104d9791..79724e05494 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -238,6 +238,7 @@ static bool do_not_show_symbol_truncation = false; static bool do_demangle = false; /* Pretty print C++ symbol names. */ static bool process_links = false; static int demangle_flags = DMGL_ANSI | DMGL_PARAMS; +static int sym_base = 0; static char *dump_ctf_parent_name; static char *dump_ctf_symtab_name; @@ -262,12 +263,13 @@ typedef struct filedata FILE * handle; bfd_size_type file_size; Elf_Internal_Ehdr file_header; + unsigned long archive_file_offset; + unsigned long archive_file_size; + /* Everything below this point is cleared out by free_filedata. */ Elf_Internal_Shdr * section_headers; Elf_Internal_Phdr * program_headers; char * string_table; unsigned long string_table_length; - unsigned long archive_file_offset; - unsigned long archive_file_size; unsigned long dynamic_addr; bfd_size_type dynamic_size; size_t dynamic_nent; @@ -292,7 +294,7 @@ typedef struct filedata bfd_vma * gnuchains; bfd_vma * mipsxlat; bfd_vma gnusymidx; - char program_interpreter[PATH_MAX]; + char * program_interpreter; bfd_vma dynamic_info[DT_ENCODING]; bfd_vma dynamic_info_DT_GNU_HASH; bfd_vma dynamic_info_DT_MIPS_XHASH; @@ -312,12 +314,17 @@ typedef struct filedata typedef enum print_mode { HEX, + HEX_5, DEC, DEC_5, UNSIGNED, + UNSIGNED_5, PREFIX_HEX, + PREFIX_HEX_5, FULL_HEX, - LONG_HEX + LONG_HEX, + OCTAL, + OCTAL_5 } print_mode; @@ -351,10 +358,6 @@ static const char * get_symbol_version_string #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define GET_ELF_SYMBOLS(file, section, sym_count) \ - (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \ - : get_64bit_elf_symbols (file, section, sym_count)) - #define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \ (strtab != NULL && offset < strtab_size) #define VALID_DYNAMIC_NAME(filedata, offset) \ @@ -529,18 +532,34 @@ print_vma (bfd_vma vma, print_mode mode) case HEX: return nc + printf ("%" BFD_VMA_FMT "x", vma); + case PREFIX_HEX_5: + nc = printf ("0x"); + /* Fall through. */ + case HEX_5: + return nc + printf ("%05" BFD_VMA_FMT "x", vma); + case DEC: return printf ("%" BFD_VMA_FMT "d", vma); case UNSIGNED: return printf ("%" BFD_VMA_FMT "u", vma); + case UNSIGNED_5: + return printf ("%5" BFD_VMA_FMT "u", vma); + + case OCTAL: + return printf ("%" BFD_VMA_FMT "o", vma); + + case OCTAL_5: + return printf ("%5" BFD_VMA_FMT "o", vma); + default: /* FIXME: Report unrecognised mode ? */ return 0; } } + /* Display a symbol on stdout. Handles the display of control characters and multibye characters (assuming the host environment supports them). @@ -2583,7 +2602,7 @@ get_machine_name (unsigned e_machine) case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit"; case EM_KVX: return "Kalray VLIW core of the MPPA processor family"; case EM_65816: return "WDC 65816/65C816"; - case EM_LOONGARCH: return "Loongson Loongarch"; + case EM_LOONGARCH: return "LoongArch"; case EM_KF32: return "ChipON KungFu32"; /* Large numbers... */ @@ -4523,7 +4542,8 @@ enum long_option_values OPTION_WITH_SYMBOL_VERSIONS, OPTION_RECURSE_LIMIT, OPTION_NO_RECURSE_LIMIT, - OPTION_NO_DEMANGLING + OPTION_NO_DEMANGLING, + OPTION_SYM_BASE }; static struct option options[] = @@ -4580,6 +4600,7 @@ static struct option options[] = {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS}, {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT}, #endif + {"sym-base", optional_argument, 0, OPTION_SYM_BASE}, {0, no_argument, 0, 0} }; @@ -4589,75 +4610,123 @@ usage (FILE * stream) { fprintf (stream, _("Usage: readelf elf-file(s)\n")); fprintf (stream, _(" Display information about the contents of ELF format files\n")); - fprintf (stream, _(" Options are:\n\ - -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\ - -h --file-header Display the ELF file header\n\ - -l --program-headers Display the program headers\n\ - --segments An alias for --program-headers\n\ - -S --section-headers Display the sections' header\n\ - --sections An alias for --section-headers\n\ - -g --section-groups Display the section groups\n\ - -t --section-details Display the section details\n\ - -e --headers Equivalent to: -h -l -S\n\ - -s --syms Display the symbol table\n\ - --symbols An alias for --syms\n\ - --dyn-syms Display the dynamic symbol table\n\ - --lto-syms Display LTO symbol tables\n\ + fprintf (stream, _(" Options are:\n")); + fprintf (stream, _("\ + -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n")); + fprintf (stream, _("\ + -h --file-header Display the ELF file header\n")); + fprintf (stream, _("\ + -l --program-headers Display the program headers\n")); + fprintf (stream, _("\ + --segments An alias for --program-headers\n")); + fprintf (stream, _("\ + -S --section-headers Display the sections' header\n")); + fprintf (stream, _("\ + --sections An alias for --section-headers\n")); + fprintf (stream, _("\ + -g --section-groups Display the section groups\n")); + fprintf (stream, _("\ + -t --section-details Display the section details\n")); + fprintf (stream, _("\ + -e --headers Equivalent to: -h -l -S\n")); + fprintf (stream, _("\ + -s --syms Display the symbol table\n")); + fprintf (stream, _("\ + --symbols An alias for --syms\n")); + fprintf (stream, _("\ + --dyn-syms Display the dynamic symbol table\n")); + fprintf (stream, _("\ + --lto-syms Display LTO symbol tables\n")); + fprintf (stream, _("\ + --sym-base=[0|8|10|16] \n\ + Force base for symbol sizes. The options are \n\ + mixed (the default), octal, decimal, hexadecimal.\n")); + fprintf (stream, _("\ -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\ The STYLE, if specified, can be `auto' (the default),\n\ `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\ - or `gnat'\n\ - --no-demangle Do not demangle low-level symbol names. (This is the default)\n\ - --recurse-limit Enable a demangling recursion limit. (This is the default)\n\ - --no-recurse-limit Disable a demangling recursion limit\n\ - -n --notes Display the core notes (if present)\n\ - -r --relocs Display the relocations (if present)\n\ - -u --unwind Display the unwind info (if present)\n\ - -d --dynamic Display the dynamic section (if present)\n\ - -V --version-info Display the version sections (if present)\n\ - -A --arch-specific Display architecture specific information (if any)\n\ - -c --archive-index Display the symbol/file index in an archive\n\ - -D --use-dynamic Use the dynamic section info when displaying symbols\n\ - -L --lint|--enable-checks Display warning messages for possible problems\n\ + or `gnat'\n")); + fprintf (stream, _("\ + --no-demangle Do not demangle low-level symbol names. (default)\n")); + fprintf (stream, _("\ + --recurse-limit Enable a demangling recursion limit. (default)\n")); + fprintf (stream, _("\ + --no-recurse-limit Disable a demangling recursion limit\n")); + fprintf (stream, _("\ + -n --notes Display the core notes (if present)\n")); + fprintf (stream, _("\ + -r --relocs Display the relocations (if present)\n")); + fprintf (stream, _("\ + -u --unwind Display the unwind info (if present)\n")); + fprintf (stream, _("\ + -d --dynamic Display the dynamic section (if present)\n")); + fprintf (stream, _("\ + -V --version-info Display the version sections (if present)\n")); + fprintf (stream, _("\ + -A --arch-specific Display architecture specific information (if any)\n")); + fprintf (stream, _("\ + -c --archive-index Display the symbol/file index in an archive\n")); + fprintf (stream, _("\ + -D --use-dynamic Use the dynamic section info when displaying symbols\n")); + fprintf (stream, _("\ + -L --lint|--enable-checks\n\ + Display warning messages for possible problems\n")); + fprintf (stream, _("\ -x --hex-dump=\n\ - Dump the contents of section as bytes\n\ + Dump the contents of section as bytes\n")); + fprintf (stream, _("\ -p --string-dump=\n\ - Dump the contents of section as strings\n\ + Dump the contents of section as strings\n")); + fprintf (stream, _("\ -R --relocated-dump=\n\ - Dump the contents of section as relocated bytes\n\ - -z --decompress Decompress section before dumping it\n\ - -w[lLiaprmfFsoORtUuTgAc] or\n\ - --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ - =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\ - =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\ - =addr,=cu_index]\n\ - Display the contents of DWARF debug sections\n\ - -wk,--debug-dump=links Display the contents of sections that link to separate debuginfo files\n\ - -P,--process-links Display the contents of non-debug sections in separate debuginfo files. (Implies -wK)\n")); + Dump the relocated contents of section \n")); + fprintf (stream, _("\ + -z --decompress Decompress section before dumping it\n")); + fprintf (stream, _("\ + -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\ + f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\ + m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\ + s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\ + U/=trace_info]\n\ + Display the contents of DWARF debug sections\n")); + fprintf (stream, _("\ + -wk --debug-dump=links Display the contents of sections that link to separate\n\ + debuginfo files\n")); + fprintf (stream, _("\ + -P --process-links Display the contents of non-debug sections in separate\n\ + debuginfo files. (Implies -wK)\n")); #if DEFAULT_FOR_FOLLOW_LINKS fprintf (stream, _("\ - -wK,--debug-dump=follow-links Follow links to separate debug info files (default)\n\ - -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files\n\ -")); + -wK --debug-dump=follow-links\n\ + Follow links to separate debug info files (default)\n")); + fprintf (stream, _("\ + -wN --debug-dump=no-follow-links\n\ + Do not follow links to separate debug info files\n")); #else fprintf (stream, _("\ - -wK,--debug-dump=follow-links Follow links to separate debug info files\n\ - -wN,--debug-dump=no-follow-links Do not follow links to separate debug info files (default)\n\ -")); + -wK --debug-dump=follow-links\n\ + Follow links to separate debug info files\n")); + fprintf (stream, _("\ + -wN --debug-dump=no-follow-links\n\ + Do not follow links to separate debug info files\n\ + (default)\n")); #endif fprintf (stream, _("\ - --dwarf-depth=N Do not display DIEs at depth N or greater\n\ - --dwarf-start=N Display DIEs starting with N, at the same depth\n\ - or deeper\n")); + --dwarf-depth=N Do not display DIEs at depth N or greater\n")); + fprintf (stream, _("\ + --dwarf-start=N Display DIEs starting at offset N\n")); #ifdef ENABLE_LIBCTF fprintf (stream, _("\ - --ctf= Display CTF info from section \n\ + --ctf= Display CTF info from section \n")); + fprintf (stream, _("\ --ctf-parent=\n\ - Use section as the CTF parent\n\n\ + Use section as the CTF parent\n")); + fprintf (stream, _("\ --ctf-symbols=\n\ - Use section as the CTF external symtab\n\n\ + Use section as the CTF external symtab\n")); + fprintf (stream, _("\ --ctf-strings=\n\ - Use section as the CTF external strtab\n\n")); + Use section as the CTF external strtab\n")); #endif #ifdef SUPPORT_DISASSEMBLY @@ -4666,11 +4735,16 @@ usage (FILE * stream) Disassemble the contents of section \n")); #endif fprintf (stream, _("\ - -I --histogram Display histogram of bucket list lengths\n\ - -W --wide Allow output width to exceed 80 characters\n\ - -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\ - @ Read options from \n\ - -H --help Display this information\n\ + -I --histogram Display histogram of bucket list lengths\n")); + fprintf (stream, _("\ + -W --wide Allow output width to exceed 80 characters\n")); + fprintf (stream, _("\ + -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n")); + fprintf (stream, _("\ + @ Read options from \n")); + fprintf (stream, _("\ + -H --help Display this information\n")); + fprintf (stream, _("\ -v --version Display the version number of readelf\n")); if (REPORT_BUGS_TO[0] && stream == stdout) @@ -4873,7 +4947,10 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv) case OPTION_DEBUG_DUMP: do_dump = true; if (optarg == NULL) - do_debugging = true; + { + do_debugging = true; + dwarf_select_sections_all (); + } else { do_debugging = false; @@ -4962,6 +5039,26 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv) /* Ignored for backward compatibility. */ break; + case OPTION_SYM_BASE: + sym_base = 0; + if (optarg != NULL) + { + sym_base = strtoul (optarg, NULL, 0); + switch (sym_base) + { + case 0: + case 8: + case 10: + case 16: + break; + + default: + sym_base = 0; + break; + } + } + break; + default: /* xgettext:c-format */ error (_("Invalid option '-%c'\n"), c); @@ -5140,8 +5237,6 @@ process_file_header (Filedata * filedata) header->e_shstrndx = filedata->section_headers[0].sh_link; if (header->e_shstrndx >= header->e_shnum) header->e_shstrndx = SHN_UNDEF; - free (filedata->section_headers); - filedata->section_headers = NULL; } return true; @@ -5538,22 +5633,21 @@ the .dynamic section is not the same as the dynamic segment\n")); break; case PT_INTERP: - if (fseek (filedata->handle, - filedata->archive_file_offset + (long) segment->p_offset, - SEEK_SET)) + if (segment->p_offset >= filedata->file_size + || segment->p_filesz > filedata->file_size - segment->p_offset + || segment->p_filesz - 1 >= (size_t) -2 + || fseek (filedata->handle, + filedata->archive_file_offset + (long) segment->p_offset, + SEEK_SET)) error (_("Unable to find program interpreter name\n")); else { - char fmt [32]; - int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1); - - if (ret >= (int) sizeof (fmt) || ret < 0) - error (_("Internal error: failed to create format string to display program interpreter\n")); - - filedata->program_interpreter[0] = 0; - if (fscanf (filedata->handle, fmt, - filedata->program_interpreter) <= 0) - error (_("Unable to read program interpreter name\n")); + size_t len = segment->p_filesz; + free (filedata->program_interpreter); + filedata->program_interpreter = xmalloc (len + 1); + len = fread (filedata->program_interpreter, 1, len, + filedata->handle); + filedata->program_interpreter[len] = 0; if (do_segments) printf (_(" [Requesting program interpreter: %s]\n"), @@ -5657,7 +5751,6 @@ get_32bit_section_headers (Filedata * filedata, bool probe) if (shdrs == NULL) return false; - free (filedata->section_headers); filedata->section_headers = (Elf_Internal_Shdr *) cmalloc (num, sizeof (Elf_Internal_Shdr)); if (filedata->section_headers == NULL) @@ -5724,7 +5817,6 @@ get_64bit_section_headers (Filedata * filedata, bool probe) if (shdrs == NULL) return false; - free (filedata->section_headers); filedata->section_headers = (Elf_Internal_Shdr *) cmalloc (num, sizeof (Elf_Internal_Shdr)); if (filedata->section_headers == NULL) @@ -5759,6 +5851,18 @@ get_64bit_section_headers (Filedata * filedata, bool probe) return true; } +static bool +get_section_headers (Filedata *filedata, bool probe) +{ + if (filedata->section_headers != NULL) + return true; + + if (is_32bit_elf) + return get_32bit_section_headers (filedata, probe); + else + return get_64bit_section_headers (filedata, probe); +} + static Elf_Internal_Sym * get_32bit_elf_symbols (Filedata * filedata, Elf_Internal_Shdr * section, @@ -5995,6 +6099,17 @@ get_64bit_elf_symbols (Filedata * filedata, return isyms; } +static Elf_Internal_Sym * +get_elf_symbols (Filedata *filedata, + Elf_Internal_Shdr *section, + unsigned long *num_syms_return) +{ + if (is_32bit_elf) + return get_32bit_elf_symbols (filedata, section, num_syms_return); + else + return get_64bit_elf_symbols (filedata, section, num_syms_return); +} + static const char * get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags) { @@ -6352,23 +6467,6 @@ process_section_headers (Filedata * filedata) Elf_Internal_Shdr * section; unsigned int i; - free (filedata->section_headers); - filedata->section_headers = NULL; - free (filedata->dynamic_symbols); - filedata->dynamic_symbols = NULL; - filedata->num_dynamic_syms = 0; - free (filedata->dynamic_strings); - filedata->dynamic_strings = NULL; - filedata->dynamic_strings_length = 0; - free (filedata->dynamic_syminfo); - filedata->dynamic_syminfo = NULL; - while (filedata->symtab_shndx_list != NULL) - { - elf_section_list *next = filedata->symtab_shndx_list->next; - free (filedata->symtab_shndx_list); - filedata->symtab_shndx_list = next; - } - if (filedata->file_header.e_shnum == 0) { /* PR binutils/12467. */ @@ -6398,16 +6496,8 @@ process_section_headers (Filedata * filedata) (unsigned long) filedata->file_header.e_shoff); } - if (is_32bit_elf) - { - if (! get_32bit_section_headers (filedata, false)) - return false; - } - else - { - if (! get_64bit_section_headers (filedata, false)) - return false; - } + if (!get_section_headers (filedata, false)) + return false; /* Read in the string table, so that we have names to display. */ if (filedata->file_header.e_shstrndx != SHN_UNDEF @@ -6516,7 +6606,7 @@ process_section_headers (Filedata * filedata) CHECK_ENTSIZE (section, i, Sym); filedata->dynamic_symbols - = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms); + = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms); filedata->dynamic_symtab_section = section; break; @@ -7071,7 +7161,7 @@ get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec, { *strtab = NULL; *strtablen = 0; - *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms); + *symtab = get_elf_symbols (filedata, symsec, nsyms); if (*symtab == NULL) return false; @@ -7214,7 +7304,7 @@ process_section_groups (Filedata * filedata) if (filedata->is_separate) printf (_("Section groups in linked file '%s'\n"), filedata->file_name); - + for (i = 0, section = filedata->section_headers, group = filedata->section_groups; i < filedata->file_header.e_shnum; i++, section++) @@ -7242,7 +7332,7 @@ process_section_groups (Filedata * filedata) { symtab_sec = sec; free (symtab); - symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms); + symtab = get_elf_symbols (filedata, symtab_sec, & num_syms); } if (symtab == NULL) @@ -7665,7 +7755,6 @@ process_relocs (Filedata * filedata) printf (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"), name, rel_offset, rel_size); - dump_relocations (filedata, offset_from_vma (filedata, rel_offset, rel_size), @@ -9785,6 +9874,13 @@ arm_process_unwind (Filedata * filedata) return res; } +static bool +no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED) +{ + printf (_("No processor specific unwind information to decode\n")); + return true; +} + static bool process_unwind (Filedata * filedata) { @@ -9798,6 +9894,8 @@ process_unwind (Filedata * filedata) { EM_IA_64, ia64_process_unwind }, { EM_PARISC, hppa_process_unwind }, { EM_TI_C6000, arm_process_unwind }, + { EM_386, no_processor_specific_unwind }, + { EM_X86_64, no_processor_specific_unwind }, { 0, NULL } }; int i; @@ -10171,6 +10269,18 @@ get_64bit_dynamic_section (Filedata * filedata) return true; } +static bool +get_dynamic_section (Filedata *filedata) +{ + if (filedata->dynamic_section) + return true; + + if (is_32bit_elf) + return get_32bit_dynamic_section (filedata); + else + return get_64bit_dynamic_section (filedata); +} + static void print_dynamic_flags (bfd_vma flags) { @@ -10514,16 +10624,8 @@ process_dynamic_section (Filedata * filedata) return true; } - if (is_32bit_elf) - { - if (! get_32bit_dynamic_section (filedata)) - return false; - } - else - { - if (! get_64bit_dynamic_section (filedata)) - return false; - } + if (!get_dynamic_section (filedata)) + return false; /* Find the appropriate symbol table. */ if (filedata->dynamic_symbols == NULL || do_histogram) @@ -10607,7 +10709,7 @@ the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n")); section.sh_name = filedata->string_table_length; filedata->dynamic_symbols - = GET_ELF_SYMBOLS (filedata, §ion, + = get_elf_symbols (filedata, §ion, &filedata->num_dynamic_syms); if (filedata->dynamic_symbols == NULL || filedata->num_dynamic_syms != num_of_syms) @@ -11094,7 +11196,8 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n")); case DT_NEEDED: printf (_("Shared library: [%s]"), name); - if (streq (name, filedata->program_interpreter)) + if (filedata->program_interpreter + && streq (name, filedata->program_interpreter)) printf (_(" program interpreter")); break; @@ -11353,7 +11456,7 @@ process_version_sections (Filedata * filedata) section->sh_info), printable_section_name (filedata, section), section->sh_info); - + printf (_(" Addr: 0x")); printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link: %u (%s)\n"), @@ -11500,7 +11603,7 @@ process_version_sections (Filedata * filedata) section->sh_info), printable_section_name (filedata, section), section->sh_info); - + printf (_(" Addr: 0x")); printf_vma (section->sh_addr); printf (_(" Offset: %#08lx Link: %u (%s)\n"), @@ -11636,7 +11739,7 @@ process_version_sections (Filedata * filedata) found = true; - symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms); + symbols = get_elf_symbols (filedata, link_section, & num_syms); if (symbols == NULL) break; @@ -12372,6 +12475,28 @@ get_symbol_version_string (Filedata * filedata, return NULL; } +/* Display a symbol size on stdout. Format is based on --sym-base setting. */ + +static unsigned int +print_dynamic_symbol_size (bfd_vma vma, int base) +{ + switch (base) + { + case 8: + return print_vma (vma, OCTAL_5); + + case 10: + return print_vma (vma, UNSIGNED_5); + + case 16: + return print_vma (vma, PREFIX_HEX_5); + + case 0: + default: + return print_vma (vma, DEC_5); + } +} + static void print_dynamic_symbol (Filedata *filedata, unsigned long si, Elf_Internal_Sym *symtab, @@ -12381,12 +12506,14 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si, const char *version_string; enum versioned_symbol_info sym_info; unsigned short vna_other; + bool is_valid; + const char * sstr; Elf_Internal_Sym *psym = symtab + si; printf ("%6ld: ", si); print_vma (psym->st_value, LONG_HEX); putchar (' '); - print_vma (psym->st_size, DEC_5); + print_dynamic_symbol_size (psym->st_size, sym_base); printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info))); printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info))); if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) @@ -12404,8 +12531,20 @@ print_dynamic_symbol (Filedata *filedata, unsigned long si, } printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx)); - bool is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name); - const char * sstr = is_valid ? strtab + psym->st_name : _(""); + if (ELF_ST_TYPE (psym->st_info) == STT_SECTION + && psym->st_shndx < filedata->file_header.e_shnum + && psym->st_name == 0) + { + is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx); + sstr = is_valid ? + SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx) + : _(""); + } + else + { + is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name); + sstr = is_valid ? strtab + psym->st_name : _(""); + } version_string = get_symbol_version_string (filedata, @@ -12526,7 +12665,7 @@ display_lto_symtab (Filedata * filedata, else printf (_("\nLTO Symbol table '%s' is empty!\n"), printable_section_name (filedata, section)); - + return true; } @@ -12802,7 +12941,7 @@ process_symbol_table (Filedata * filedata) else printf (_(" Num: Value Size Type Bind Vis Ndx Name\n")); - symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms); + symtab = get_elf_symbols (filedata, section, & num_syms); if (symtab == NULL) continue; @@ -14168,7 +14307,7 @@ apply_relocations (Filedata * filedata, if (filedata->file_header.e_machine == EM_SH) is_rela = false; - symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms); + symtab = get_elf_symbols (filedata, symsec, & num_syms); for (rp = relocs; rp < relocs + num_relocs; ++rp) { @@ -15522,7 +15661,7 @@ process_section_contents (Filedata * filedata) if (filedata->is_separate && ! process_links) dump &= DEBUG_DUMP; - + #ifdef SUPPORT_DISASSEMBLY if (dump & DISASS_DUMP) { @@ -18585,6 +18724,12 @@ get_note_type (Filedata * filedata, unsigned e_type) return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"); case NT_ARM_HW_WATCH: return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"); + case NT_ARM_SVE: + return _("NT_ARM_SVE (AArch SVE registers)"); + case NT_ARM_PAC_MASK: + return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)"); + case NT_ARM_TAGGED_ADDR_CTRL: + return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)"); case NT_ARC_V2: return _("NT_ARC_V2 (ARC HS accumulator/extra registers)"); case NT_RISCV_CSR: @@ -18605,6 +18750,8 @@ get_note_type (Filedata * filedata, unsigned e_type) return _("NT_SIGINFO (siginfo_t data)"); case NT_FILE: return _("NT_FILE (mapped files)"); + case NT_MEMTAG: + return _("NT_MEMTAG (memory tags)"); default: break; } @@ -19583,15 +19730,11 @@ get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type) /* NetBSD core "procinfo" structure. */ return _("NetBSD procinfo structure"); -#ifdef NT_NETBSDCORE_AUXV case NT_NETBSDCORE_AUXV: return _("NetBSD ELF auxiliary vector data"); -#endif -#ifdef NT_NETBSDCORE_LWPSTATUS case NT_NETBSDCORE_LWPSTATUS: return _("PT_LWPSTATUS (ptrace_lwpstatus structure)"); -#endif default: /* As of Jan 2020 there are no other machine-independent notes @@ -21037,17 +21180,50 @@ get_file_header (Filedata * filedata) filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx); } - if (filedata->file_header.e_shoff) + return true; +} + +static void +free_filedata (Filedata *filedata) +{ + free (filedata->program_interpreter); + free (filedata->program_headers); + free (filedata->section_headers); + free (filedata->string_table); + free (filedata->dump.dump_sects); + free (filedata->dynamic_strings); + free (filedata->dynamic_symbols); + free (filedata->dynamic_syminfo); + free (filedata->dynamic_section); + + while (filedata->symtab_shndx_list != NULL) { - /* There may be some extensions in the first section header. Don't - bomb if we can't read it. */ - if (is_32bit_elf) - get_32bit_section_headers (filedata, true); - else - get_64bit_section_headers (filedata, true); + elf_section_list *next = filedata->symtab_shndx_list->next; + free (filedata->symtab_shndx_list); + filedata->symtab_shndx_list = next; } - return true; + free (filedata->section_headers_groups); + + if (filedata->section_groups) + { + size_t i; + struct group_list * g; + struct group_list * next; + + for (i = 0; i < filedata->group_count; i++) + { + for (g = filedata->section_groups [i].root; g != NULL; g = next) + { + next = g->next; + free (g); + } + } + + free (filedata->section_groups); + } + memset (&filedata->section_headers, 0, + sizeof (Filedata) - offsetof (Filedata, section_headers)); } static void @@ -21064,6 +21240,7 @@ close_file (Filedata * filedata) void close_debug_file (void * data) { + free_filedata ((Filedata *) data); close_file ((Filedata *) data); } @@ -21092,19 +21269,8 @@ open_file (const char * pathname, bool is_separate) if (! get_file_header (filedata)) goto fail; - if (filedata->file_header.e_shoff) - { - bool res; - - /* Read the section headers again, this time for real. */ - if (is_32bit_elf) - res = get_32bit_section_headers (filedata, false); - else - res = get_64bit_section_headers (filedata, false); - - if (!res) - goto fail; - } + if (!get_section_headers (filedata, false)) + goto fail; return filedata; @@ -21180,8 +21346,20 @@ process_object (Filedata * filedata) initialise_dump_sects (filedata); + /* There may be some extensions in the first section header. Don't + bomb if we can't read it. */ + get_section_headers (filedata, true); + if (! process_file_header (filedata)) - return false; + { + res = false; + goto out; + } + + /* Throw away the single section header read above, so that we + re-read the entire set. */ + free (filedata->section_headers); + filedata->section_headers = NULL; if (! process_section_headers (filedata)) { @@ -21277,61 +21455,8 @@ process_object (Filedata * filedata) if (! process_arch_specific (filedata)) res = false; - free (filedata->program_headers); - filedata->program_headers = NULL; - - free (filedata->section_headers); - filedata->section_headers = NULL; - - free (filedata->string_table); - filedata->string_table = NULL; - filedata->string_table_length = 0; - - free (filedata->dump.dump_sects); - filedata->dump.dump_sects = NULL; - filedata->dump.num_dump_sects = 0; - - free (filedata->dynamic_strings); - filedata->dynamic_strings = NULL; - filedata->dynamic_strings_length = 0; - - free (filedata->dynamic_symbols); - filedata->dynamic_symbols = NULL; - filedata->num_dynamic_syms = 0; - - free (filedata->dynamic_syminfo); - filedata->dynamic_syminfo = NULL; - - free (filedata->dynamic_section); - filedata->dynamic_section = NULL; - - while (filedata->symtab_shndx_list != NULL) - { - elf_section_list *next = filedata->symtab_shndx_list->next; - free (filedata->symtab_shndx_list); - filedata->symtab_shndx_list = next; - } - - free (filedata->section_headers_groups); - filedata->section_headers_groups = NULL; - - if (filedata->section_groups) - { - struct group_list * g; - struct group_list * next; - - for (i = 0; i < filedata->group_count; i++) - { - for (g = filedata->section_groups [i].root; g != NULL; g = next) - { - next = g->next; - free (g); - } - } - - free (filedata->section_groups); - filedata->section_groups = NULL; - } + out: + free_filedata (filedata); free_debug_memory ();