mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
Add demangling support to readelf.
PR binutils/26331 * readelf.c (do_demangle): New option flag. (print_symbol): If do_demangle is enabled, demangle the symbol. (enum long_option_values): New enum to hold long option values. (options): Add demangle, no-demangle, recursion-limit and no-recursion-limit options. Alpha sort the table. (usage): Describe the new options. (parse_args): Handle the new options. * NEWS: Mention the new feature. * doc/binutils.texi: Document the new feature. * testsuite/binutils-all/readelf.exp: Test the new feature. * testsuite/binutils-all/mangled.s: New file - assembler source. * testsuite/binutils-all/readelf.demangled: New file - expected output from readelf.
This commit is contained in:
@ -1,3 +1,20 @@
|
|||||||
|
2020-08-12 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR binutils/26331
|
||||||
|
* readelf.c (do_demangle): New option flag.
|
||||||
|
(print_symbol): If do_demangle is enabled, demangle the symbol.
|
||||||
|
(enum long_option_values): New enum to hold long option values.
|
||||||
|
(options): Add demangle, no-demangle, recursion-limit and
|
||||||
|
no-recursion-limit options. Alpha sort the table.
|
||||||
|
(usage): Describe the new options.
|
||||||
|
(parse_args): Handle the new options.
|
||||||
|
* NEWS: Mention the new feature.
|
||||||
|
* doc/binutils.texi: Document the new feature.
|
||||||
|
* testsuite/binutils-all/readelf.exp: Test the new feature.
|
||||||
|
* testsuite/binutils-all/mangled.s: New file - assembler source.
|
||||||
|
* testsuite/binutils-all/readelf.demangled: New file - expected
|
||||||
|
output from readelf.
|
||||||
|
|
||||||
2020-08-12 Nick Clifton <nickc@redhat.com>
|
2020-08-12 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/sr.po: Updated Serbian translation.
|
* po/sr.po: Updated Serbian translation.
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
|
||||||
|
* Readelf now accepts the -C command line option to enable the demangling of
|
||||||
|
symbol names. In addition the --demangle=<style>, --no-demangle,
|
||||||
|
--recurse-limit and --no-recurse-limit options are also now availale.
|
||||||
|
|
||||||
Changes in 2.35:
|
Changes in 2.35:
|
||||||
|
|
||||||
* Changed readelf's display of symbol names when wide mode is not enabled.
|
* Changed readelf's display of symbol names when wide mode is not enabled.
|
||||||
|
@ -4694,6 +4694,8 @@ readelf [@option{-a}|@option{--all}]
|
|||||||
[@option{-e}|@option{--headers}]
|
[@option{-e}|@option{--headers}]
|
||||||
[@option{-s}|@option{--syms}|@option{--symbols}]
|
[@option{-s}|@option{--syms}|@option{--symbols}]
|
||||||
[@option{--dyn-syms}]
|
[@option{--dyn-syms}]
|
||||||
|
[@option{--demangle@var{=style}}|@option{--no-demangle}]
|
||||||
|
[@option{--recurse-limit}|@option{--no-recurse-limit}]
|
||||||
[@option{-n}|@option{--notes}]
|
[@option{-n}|@option{--notes}]
|
||||||
[@option{-r}|@option{--relocs}]
|
[@option{-r}|@option{--relocs}]
|
||||||
[@option{-u}|@option{--unwind}]
|
[@option{-u}|@option{--unwind}]
|
||||||
@ -4809,6 +4811,34 @@ Displays the entries in dynamic symbol table section of the file, if it
|
|||||||
has one. The output format is the same as the format used by the
|
has one. The output format is the same as the format used by the
|
||||||
@option{--syms} option.
|
@option{--syms} option.
|
||||||
|
|
||||||
|
@item -C
|
||||||
|
@itemx --demangle[=@var{style}]
|
||||||
|
@cindex demangling in nm
|
||||||
|
Decode (@dfn{demangle}) low-level symbol names into user-level names.
|
||||||
|
This makes C++ function names readable. Different compilers have
|
||||||
|
different mangling styles. The optional demangling style argument can
|
||||||
|
be used to choose an appropriate demangling style for your
|
||||||
|
compiler. @xref{c++filt}, for more information on demangling.
|
||||||
|
|
||||||
|
@item --no-demangle
|
||||||
|
Do not demangle low-level symbol names. This is the default.
|
||||||
|
|
||||||
|
@item --recurse-limit
|
||||||
|
@itemx --no-recurse-limit
|
||||||
|
@itemx --recursion-limit
|
||||||
|
@itemx --no-recursion-limit
|
||||||
|
Enables or disables a limit on the amount of recursion performed
|
||||||
|
whilst demangling strings. Since the name mangling formats allow for
|
||||||
|
an inifinite level of recursion it is possible to create strings whose
|
||||||
|
decoding will exhaust the amount of stack space available on the host
|
||||||
|
machine, triggering a memory fault. The limit tries to prevent this
|
||||||
|
from happening by restricting recursion to 2048 levels of nesting.
|
||||||
|
|
||||||
|
The default is for this limit to be enabled, but disabling it may be
|
||||||
|
necessary in order to demangle truly complicated names. Note however
|
||||||
|
that if the recursion limit is disabled then stack exhaustion is
|
||||||
|
possible and any bug reports about such an event will be rejected.
|
||||||
|
|
||||||
@item -e
|
@item -e
|
||||||
@itemx --headers
|
@itemx --headers
|
||||||
Display all the headers in the file. Equivalent to @option{-h -l -S}.
|
Display all the headers in the file. Equivalent to @option{-h -l -S}.
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "elfcomm.h"
|
#include "elfcomm.h"
|
||||||
#include "dwarf.h"
|
#include "dwarf.h"
|
||||||
#include "ctf-api.h"
|
#include "ctf-api.h"
|
||||||
|
#include "demangle.h"
|
||||||
|
|
||||||
#include "elf/common.h"
|
#include "elf/common.h"
|
||||||
#include "elf/external.h"
|
#include "elf/external.h"
|
||||||
@ -235,6 +236,8 @@ static bfd_boolean check_all = FALSE;
|
|||||||
static bfd_boolean is_32bit_elf = FALSE;
|
static bfd_boolean is_32bit_elf = FALSE;
|
||||||
static bfd_boolean decompress_dumps = FALSE;
|
static bfd_boolean decompress_dumps = FALSE;
|
||||||
static bfd_boolean do_not_show_symbol_truncation = FALSE;
|
static bfd_boolean do_not_show_symbol_truncation = FALSE;
|
||||||
|
static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
|
||||||
|
static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
|
||||||
|
|
||||||
static char *dump_ctf_parent_name;
|
static char *dump_ctf_parent_name;
|
||||||
static char *dump_ctf_symtab_name;
|
static char *dump_ctf_symtab_name;
|
||||||
@ -552,6 +555,7 @@ print_symbol (signed int width, const char * symbol)
|
|||||||
mbstate_t state;
|
mbstate_t state;
|
||||||
#endif
|
#endif
|
||||||
unsigned int width_remaining;
|
unsigned int width_remaining;
|
||||||
|
const void * alloced_symbol = NULL;
|
||||||
|
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
{
|
{
|
||||||
@ -584,6 +588,14 @@ print_symbol (signed int width, const char * symbol)
|
|||||||
memset (& state, 0, sizeof (state));
|
memset (& state, 0, sizeof (state));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (do_demangle && *symbol)
|
||||||
|
{
|
||||||
|
const char * res = cplus_demangle (symbol, demangle_flags);
|
||||||
|
|
||||||
|
if (res != NULL)
|
||||||
|
alloced_symbol = symbol = res;
|
||||||
|
}
|
||||||
|
|
||||||
while (width_remaining)
|
while (width_remaining)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
@ -643,6 +655,7 @@ print_symbol (signed int width, const char * symbol)
|
|||||||
num_printed = width;
|
num_printed = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free ((void *) alloced_symbol);
|
||||||
return num_printed;
|
return num_printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4471,67 +4484,76 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPTION_DEBUG_DUMP 512
|
enum long_option_values
|
||||||
#define OPTION_DYN_SYMS 513
|
{
|
||||||
#define OPTION_DWARF_DEPTH 514
|
OPTION_DEBUG_DUMP = 512,
|
||||||
#define OPTION_DWARF_START 515
|
OPTION_DYN_SYMS,
|
||||||
#define OPTION_DWARF_CHECK 516
|
OPTION_DWARF_DEPTH,
|
||||||
#define OPTION_CTF_DUMP 517
|
OPTION_DWARF_START,
|
||||||
#define OPTION_CTF_PARENT 518
|
OPTION_DWARF_CHECK,
|
||||||
#define OPTION_CTF_SYMBOLS 519
|
OPTION_CTF_DUMP,
|
||||||
#define OPTION_CTF_STRINGS 520
|
OPTION_CTF_PARENT,
|
||||||
|
OPTION_CTF_SYMBOLS,
|
||||||
|
OPTION_CTF_STRINGS,
|
||||||
|
OPTION_WITH_SYMBOL_VERSIONS,
|
||||||
|
OPTION_RECURSE_LIMIT,
|
||||||
|
OPTION_NO_RECURSE_LIMIT,
|
||||||
|
OPTION_NO_DEMANGLING
|
||||||
|
};
|
||||||
|
|
||||||
static struct option options[] =
|
static struct option options[] =
|
||||||
{
|
{
|
||||||
|
/* Note - This table is alpha-sorted on the 'val'
|
||||||
|
field in order to make adding new options easier. */
|
||||||
|
{"arch-specific", no_argument, 0, 'A'},
|
||||||
{"all", no_argument, 0, 'a'},
|
{"all", no_argument, 0, 'a'},
|
||||||
{"file-header", no_argument, 0, 'h'},
|
{"demangle", optional_argument, 0, 'C'},
|
||||||
{"program-headers", no_argument, 0, 'l'},
|
{"archive-index", no_argument, 0, 'c'},
|
||||||
{"headers", no_argument, 0, 'e'},
|
{"use-dynamic", no_argument, 0, 'D'},
|
||||||
{"histogram", no_argument, 0, 'I'},
|
|
||||||
{"segments", no_argument, 0, 'l'},
|
|
||||||
{"sections", no_argument, 0, 'S'},
|
|
||||||
{"section-headers", no_argument, 0, 'S'},
|
|
||||||
{"section-groups", no_argument, 0, 'g'},
|
|
||||||
{"section-details", no_argument, 0, 't'},
|
|
||||||
{"full-section-name",no_argument, 0, 'N'},
|
|
||||||
{"symbols", no_argument, 0, 's'},
|
|
||||||
{"syms", no_argument, 0, 's'},
|
|
||||||
{"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
|
|
||||||
{"relocs", no_argument, 0, 'r'},
|
|
||||||
{"notes", no_argument, 0, 'n'},
|
|
||||||
{"dynamic", no_argument, 0, 'd'},
|
{"dynamic", no_argument, 0, 'd'},
|
||||||
|
{"headers", no_argument, 0, 'e'},
|
||||||
|
{"section-groups", no_argument, 0, 'g'},
|
||||||
|
{"help", no_argument, 0, 'H'},
|
||||||
|
{"file-header", no_argument, 0, 'h'},
|
||||||
|
{"histogram", no_argument, 0, 'I'},
|
||||||
{"lint", no_argument, 0, 'L'},
|
{"lint", no_argument, 0, 'L'},
|
||||||
{"enable-checks", no_argument, 0, 'L'},
|
{"enable-checks", no_argument, 0, 'L'},
|
||||||
{"arch-specific", no_argument, 0, 'A'},
|
{"program-headers", no_argument, 0, 'l'},
|
||||||
{"version-info", no_argument, 0, 'V'},
|
{"segments", no_argument, 0, 'l'},
|
||||||
{"use-dynamic", no_argument, 0, 'D'},
|
{"full-section-name",no_argument, 0, 'N'},
|
||||||
{"unwind", no_argument, 0, 'u'},
|
{"notes", no_argument, 0, 'n'},
|
||||||
{"archive-index", no_argument, 0, 'c'},
|
|
||||||
{"hex-dump", required_argument, 0, 'x'},
|
|
||||||
{"relocated-dump", required_argument, 0, 'R'},
|
|
||||||
{"string-dump", required_argument, 0, 'p'},
|
{"string-dump", required_argument, 0, 'p'},
|
||||||
|
{"relocated-dump", required_argument, 0, 'R'},
|
||||||
|
{"relocs", no_argument, 0, 'r'},
|
||||||
|
{"section-headers", no_argument, 0, 'S'},
|
||||||
|
{"sections", no_argument, 0, 'S'},
|
||||||
|
{"symbols", no_argument, 0, 's'},
|
||||||
|
{"syms", no_argument, 0, 's'},
|
||||||
|
{"silent-truncation",no_argument, 0, 'T'},
|
||||||
|
{"section-details", no_argument, 0, 't'},
|
||||||
|
{"unwind", no_argument, 0, 'u'},
|
||||||
|
{"version-info", no_argument, 0, 'V'},
|
||||||
|
{"version", no_argument, 0, 'v'},
|
||||||
|
{"wide", no_argument, 0, 'W'},
|
||||||
|
{"hex-dump", required_argument, 0, 'x'},
|
||||||
{"decompress", no_argument, 0, 'z'},
|
{"decompress", no_argument, 0, 'z'},
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
|
||||||
{"instruction-dump", required_argument, 0, 'i'},
|
|
||||||
#endif
|
|
||||||
{"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
|
|
||||||
|
|
||||||
|
{"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
|
||||||
|
{"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
|
||||||
|
{"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
|
||||||
|
{"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
|
||||||
|
{"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
|
||||||
|
{"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
|
||||||
{"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
|
{"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
|
||||||
{"dwarf-start", required_argument, 0, OPTION_DWARF_START},
|
{"dwarf-start", required_argument, 0, OPTION_DWARF_START},
|
||||||
{"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
|
{"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
|
||||||
|
|
||||||
#ifdef ENABLE_LIBCTF
|
#ifdef ENABLE_LIBCTF
|
||||||
{"ctf", required_argument, 0, OPTION_CTF_DUMP},
|
{"ctf", required_argument, 0, OPTION_CTF_DUMP},
|
||||||
|
|
||||||
{"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
|
{"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
|
||||||
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
|
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
|
||||||
{"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
|
{"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{"version", no_argument, 0, 'v'},
|
|
||||||
{"wide", no_argument, 0, 'W'},
|
|
||||||
{"silent-truncation",no_argument, 0, 'T'},
|
|
||||||
{"help", no_argument, 0, 'H'},
|
|
||||||
{0, no_argument, 0, 0}
|
{0, no_argument, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4553,6 +4575,13 @@ usage (FILE * stream)
|
|||||||
-s --syms Display the symbol table\n\
|
-s --syms Display the symbol table\n\
|
||||||
--symbols An alias for --syms\n\
|
--symbols An alias for --syms\n\
|
||||||
--dyn-syms Display the dynamic symbol table\n\
|
--dyn-syms Display the dynamic symbol table\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\
|
||||||
|
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\
|
-n --notes Display the core notes (if present)\n\
|
||||||
-r --relocs Display the relocations (if present)\n\
|
-r --relocs Display the relocations (if present)\n\
|
||||||
-u --unwind Display the unwind info (if present)\n\
|
-u --unwind Display the unwind info (if present)\n\
|
||||||
@ -4693,7 +4722,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
|||||||
usage (stderr);
|
usage (stderr);
|
||||||
|
|
||||||
while ((c = getopt_long
|
while ((c = getopt_long
|
||||||
(argc, argv, "ADHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
|
(argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -4718,6 +4747,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
|||||||
do_arch = TRUE;
|
do_arch = TRUE;
|
||||||
do_notes = TRUE;
|
do_notes = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
do_section_groups = TRUE;
|
do_section_groups = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -4858,6 +4888,32 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
|
|||||||
case 'T':
|
case 'T':
|
||||||
do_not_show_symbol_truncation = TRUE;
|
do_not_show_symbol_truncation = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'C':
|
||||||
|
do_demangle = TRUE;
|
||||||
|
if (optarg != NULL)
|
||||||
|
{
|
||||||
|
enum demangling_styles style;
|
||||||
|
|
||||||
|
style = cplus_demangle_name_to_style (optarg);
|
||||||
|
if (style == unknown_demangling)
|
||||||
|
error (_("unknown demangling style `%s'"), optarg);
|
||||||
|
|
||||||
|
cplus_demangle_set_style (style);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OPTION_NO_DEMANGLING:
|
||||||
|
do_demangle = FALSE;
|
||||||
|
break;
|
||||||
|
case OPTION_RECURSE_LIMIT:
|
||||||
|
demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
|
||||||
|
break;
|
||||||
|
case OPTION_NO_RECURSE_LIMIT:
|
||||||
|
demangle_flags |= DMGL_NO_RECURSE_LIMIT;
|
||||||
|
break;
|
||||||
|
case OPTION_WITH_SYMBOL_VERSIONS:
|
||||||
|
/* Ignored for backward compatibility. */
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* xgettext:c-format */
|
/* xgettext:c-format */
|
||||||
error (_("Invalid option '-%c'\n"), c);
|
error (_("Invalid option '-%c'\n"), c);
|
||||||
|
6
binutils/testsuite/binutils-all/mangled.s
Normal file
6
binutils/testsuite/binutils-all/mangled.s
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.text
|
||||||
|
|
||||||
|
.global _ZN4gold12Output_relocILi9ELb1ELi64ELb0EEC2EPNS_12Sized_relobjILi64ELb0EEEjjPNS_11Output_dataEmbbbb
|
||||||
|
_ZN4gold12Output_relocILi9ELb1ELi64ELb0EEC2EPNS_12Sized_relobjILi64ELb0EEEjjPNS_11Output_dataEmbbbb:
|
||||||
|
.dc.d 0
|
||||||
|
|
5
binutils/testsuite/binutils-all/readelf.demangled
Normal file
5
binutils/testsuite/binutils-all/readelf.demangled
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
Symbol table '.symtab' contains .* entries:
|
||||||
|
#...
|
||||||
|
.*gold::Output_reloc<9, true, 64, false>::Output_reloc\(gold::Sized_relobj<64, false>\*, unsigned int, unsigned int, gold::Output_data\*, unsigned long, bool, bool, bool, bool\)
|
||||||
|
#pass
|
@ -345,12 +345,28 @@ if {![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o]} then {
|
|||||||
readelf_test -r $tempfile readelf.r {}
|
readelf_test -r $tempfile readelf.r {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test demangling symbol names.
|
||||||
|
if {![binutils_assemble $srcdir/$subdir/mangled.s tmpdir/mangled.o]} then {
|
||||||
|
unresolved "readelf -s -C bintest (failed to assemble)"
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if ![is_remote host] {
|
||||||
|
set tempfile tmpdir/mangled.o
|
||||||
|
} else {
|
||||||
|
set tempfile [remote_download host tmpdir/mangled.o]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the test.
|
||||||
|
readelf_test {--syms --demangle --wide} $tempfile readelf.demangled {}
|
||||||
|
}
|
||||||
|
|
||||||
readelf_wi_test
|
readelf_wi_test
|
||||||
readelf_compressed_wa_test
|
readelf_compressed_wa_test
|
||||||
|
|
||||||
readelf_dump_test
|
readelf_dump_test
|
||||||
run_dump_test "pr25543"
|
run_dump_test "pr25543"
|
||||||
|
|
||||||
|
|
||||||
# PR 13482 - Check for off-by-one errors when dumping .note sections.
|
# PR 13482 - Check for off-by-one errors when dumping .note sections.
|
||||||
if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then {
|
if {![binutils_assemble $srcdir/$subdir/version.s tmpdir/version.o]} then {
|
||||||
unresolved "readelf -n version (failed to assemble)"
|
unresolved "readelf -n version (failed to assemble)"
|
||||||
|
Reference in New Issue
Block a user