From 047c3dbf5541b14a6fb562c2d847784f4b06de78 Mon Sep 17 00:00:00 2001 From: Nick Lott Date: Wed, 21 Apr 2021 15:33:13 +0100 Subject: [PATCH] Add ability to select numeric base when displaying symbol values in readelf. PR 27672 * readelf.c (sym_base): New variable. (enum print_mode): Add more modes. (print_vma): Add suport for new modes. (options): Add sym-base. (usage): Add sym-base. (parse_args): Add support for --sym-base. (print_dynamic_symbol_size): New function. (print_dynamic_symbol): Use new function. * doc/binutils.texi: Document the new feature. * NEWS: Mention the new feature. --- binutils/ChangeLog | 14 +++++++ binutils/NEWS | 6 +++ binutils/doc/binutils.texi | 13 ++++++ binutils/readelf.c | 86 ++++++++++++++++++++++++++++++++++---- 4 files changed, 110 insertions(+), 9 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 033dd58a0d5..e15d0361236 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +2021-04-21 Nick Lott + + PR 27672 + * readelf.c (sym_base): New variable. + (enum print_mode): Add more modes. + (print_vma): Add suport for new modes. + (options): Add sym-base. + (usage): Add sym-base. + (parse_args): Add support for --sym-base. + (print_dynamic_symbol_size): New function. + (print_dynamic_symbol): Use new function. + * doc/binutils.texi: Document the new feature. + * NEWS: Mention the new feature. + 2021-04-21 Nick Clifton * testsuite/binutils-all/mips/global-local-symtab-sort-n64t.d: diff --git a/binutils/NEWS b/binutils/NEWS index c5b5f4f5952..d21f219251b 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,11 @@ -*- text -*- +* The readelf tool has a new command line option which can be used to specify + how the numeric values of symbols are reported. --sym-base=0|8|10|16 tells + readelf to display the values in base 8, base 10 or base 16. A sym base of 0 + represents the default action of displaying values under 10000 in base 10 and + values above that in base 16. + * Binutils now requires a C99 compiler and library to build. * A new format has been added to the nm program. Specifying diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 292f71110c9..a8157ade3c1 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -4788,6 +4788,7 @@ readelf [@option{-a}|@option{--all}] [@option{-e}|@option{--headers}] [@option{-s}|@option{--syms}|@option{--symbols}] [@option{--dyn-syms}|@option{--lto-syms}] + [@option{--sym-base=[0|8|10|16]}] [@option{--demangle@var{=style}}|@option{--no-demangle}] [@option{--quiet}] [@option{--recurse-limit}|@option{--no-recurse-limit}] @@ -4917,6 +4918,18 @@ has one. The output format is the same as the format used by the @cindex LTO symbol table Displays the contents of any LTO symbol tables in the file. +@item --sym-base=[0|8|10|16] +@cindex symbol table size base +Forces the size field of the symbol table to use the given base. Any +unrecognized options will be treated as @samp{0}. @option{--sym-base=0} +represents the default and legacy behaviour. This will output sizes as decimal +for numbers less than 100000. For sizes 100000 and greater hexadecimal notation +will be used with a 0x prefix. +@option{--sym-base=8} will give the symbol sizes in octal. +@option{--sym-base=10} will always give the symbol sizes in decimal. +@option{--sym-base=16} will always give the symbol sizes in hexadecimal with a +0x prefix. + @item -C @itemx --demangle[=@var{style}] @cindex demangling in nm diff --git a/binutils/readelf.c b/binutils/readelf.c index c8a76de3c37..e63deaf9636 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; @@ -312,12 +313,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; @@ -529,18 +535,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). @@ -4523,7 +4545,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 +4603,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} }; @@ -4603,6 +4627,9 @@ usage (FILE * stream) --symbols An alias for --syms\n\ --dyn-syms Display the dynamic symbol table\n\ --lto-syms Display LTO symbol tables\n\ + --sym-base=[0|8|10|16] \n\ + Force base for symbol sizes. The options are \n\ + mixed (the default), octal, decimal, hexadecimal.\n\ -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\ @@ -4962,6 +4989,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); @@ -7213,7 +7260,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++) @@ -7664,7 +7711,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), @@ -11353,7 +11399,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 +11546,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"), @@ -12372,6 +12418,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, @@ -12388,7 +12456,7 @@ print_dynamic_symbol (Filedata *filedata, unsigned long 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) @@ -12540,7 +12608,7 @@ display_lto_symtab (Filedata * filedata, else printf (_("\nLTO Symbol table '%s' is empty!\n"), printable_section_name (filedata, section)); - + return true; } @@ -15536,7 +15604,7 @@ process_section_contents (Filedata * filedata) if (filedata->is_separate && ! process_links) dump &= DEBUG_DUMP; - + #ifdef SUPPORT_DISASSEMBLY if (dump & DISASS_DUMP) { -- 2.30.2