objdump: permit disassembling multiple individual functions

Compilers may split functions, e.g. into a "hot" and "cold" part, or
they may emit special case instantiations (e.g. as a result of IPA). It
can be helpful to be able to disassemble all of the parts or clones in
one go. Permit using "--disassemble=" multiple times.
This commit is contained in:
Jan Beulich
2025-03-07 11:24:19 +01:00
parent 60e254b701
commit cdd8492b05
4 changed files with 63 additions and 14 deletions

View File

@@ -2432,11 +2432,11 @@ with ctags tool.
Display the assembler mnemonics for the machine instructions from the Display the assembler mnemonics for the machine instructions from the
input file. This option only disassembles those sections which are input file. This option only disassembles those sections which are
expected to contain instructions. If the optional @var{symbol} expected to contain instructions. If the optional @var{symbol}
argument is given, then display the assembler mnemonics starting at argument is given (perhaps multiple times), then display the assembler
@var{symbol}. If @var{symbol} is a function name then disassembly mnemonics starting at (all the) @var{symbol}. If @var{symbol} is a
will stop at the end of the function, otherwise it will stop when the function name then disassembly will stop at the end of the function,
next symbol is encountered. If there are no matches for @var{symbol} otherwise it will stop when the next symbol is encountered. If there
then nothing will be displayed. are no matches for any @var{symbol} then nothing will be displayed.
Note if the @option{--dwarf=follow-links} option is enabled Note if the @option{--dwarf=follow-links} option is enabled
then any symbol tables in linked debug info files will be read in and then any symbol tables in linked debug info files will be read in and

View File

@@ -132,7 +132,6 @@ static const char *prefix; /* --prefix */
static int prefix_strip; /* --prefix-strip */ static int prefix_strip; /* --prefix-strip */
static size_t prefix_length; static size_t prefix_length;
static bool unwind_inlines; /* --inlines. */ static bool unwind_inlines; /* --inlines. */
static const char * disasm_sym; /* Disassembly start symbol. */
static const char * source_comment; /* --source_comment. */ static const char * source_comment; /* --source_comment. */
static bool visualize_jumps = false; /* --visualize-jumps. */ static bool visualize_jumps = false; /* --visualize-jumps. */
static bool color_output = false; /* --visualize-jumps=color. */ static bool color_output = false; /* --visualize-jumps=color. */
@@ -141,6 +140,12 @@ static int process_links = false; /* --process-links. */
static int show_all_symbols; /* --show-all-symbols. */ static int show_all_symbols; /* --show-all-symbols. */
static bool decompressed_dumps = false; /* -Z, --decompress. */ static bool decompressed_dumps = false; /* -Z, --decompress. */
static struct symbol_entry
{
const char *name;
struct symbol_entry *next;
} *disasm_sym_list; /* Disassembly start symbol(s). */
static enum color_selection static enum color_selection
{ {
on_if_terminal_output, on_if_terminal_output,
@@ -187,7 +192,7 @@ struct objdump_disasm_info
bool require_sec; bool require_sec;
disassembler_ftype disassemble_fn; disassembler_ftype disassemble_fn;
arelent *reloc; arelent *reloc;
const char *symbol; struct symbol_entry *symbol_list;
}; };
/* Architecture to disassemble for, or default if NULL. */ /* Architecture to disassemble for, or default if NULL. */
@@ -3898,7 +3903,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
the symbol we have just found. Then print the symbol and find the the symbol we have just found. Then print the symbol and find the
next symbol on. Repeat until we have disassembled the entire section next symbol on. Repeat until we have disassembled the entire section
or we have reached the end of the address range we are interested in. */ or we have reached the end of the address range we are interested in. */
do_print = paux->symbol == NULL; do_print = paux->symbol_list == NULL;
loop_until = stop_offset_reached; loop_until = stop_offset_reached;
while (addr_offset < stop_offset) while (addr_offset < stop_offset)
@@ -3938,9 +3943,9 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
pinfo->symtab_pos = -1; pinfo->symtab_pos = -1;
} }
/* If we are only disassembling from a specific symbol, /* If we are only disassembling from specific symbols,
check to see if we should start or stop displaying. */ check to see if we should start or stop displaying. */
if (sym && paux->symbol) if (sym && paux->symbol_list)
{ {
if (do_print) if (do_print)
{ {
@@ -3977,8 +3982,16 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
} }
/* We are not currently printing. Check to see /* We are not currently printing. Check to see
if the current symbol matches the requested symbol. */ if the current symbol matches any of the requested symbols. */
if (streq (name, paux->symbol) for (const struct symbol_entry *ent = paux->symbol_list;
ent;
ent = ent->next)
if (streq (name, ent->name))
{
do_print = true;
break;
}
if (do_print
&& bfd_asymbol_value (sym) <= addr) && bfd_asymbol_value (sym) <= addr)
{ {
do_print = true; do_print = true;
@@ -4175,7 +4188,7 @@ disassemble_data (bfd *abfd)
disasm_info.dynrelbuf = NULL; disasm_info.dynrelbuf = NULL;
disasm_info.dynrelcount = 0; disasm_info.dynrelcount = 0;
aux.reloc = NULL; aux.reloc = NULL;
aux.symbol = disasm_sym; aux.symbol_list = disasm_sym_list;
disasm_info.print_address_func = objdump_print_address; disasm_info.print_address_func = objdump_print_address;
disasm_info.symbol_at_address_func = objdump_symbol_at_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address;
@@ -6229,7 +6242,14 @@ main (int argc, char **argv)
case 'd': case 'd':
disassemble = true; disassemble = true;
seenflag = true; seenflag = true;
disasm_sym = optarg; if (optarg)
{
struct symbol_entry *sym = xmalloc (sizeof (*sym));
sym->name = optarg;
sym->next = disasm_sym_list;
disasm_sym_list = sym;
}
break; break;
case 'z': case 'z':
disassemble_zeroes = true; disassemble_zeroes = true;

View File

@@ -0,0 +1,28 @@
#name: objdump multiple --disassemble=
#source: multi1.s
#source: multi2.s
#ld: -r
#objdump: --disassemble=func --disassemble=func2 -wz
# ECOFF disassembly omits local symbols, for whatever reason.
#xfail: "alpha*-*-*ecoff" "alpha*-*-osf*"
.*: +file format .*
Disassembly of section .*:
0+ <func>:
[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#?[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#?[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
0+[0-1][0-9a-f] <func2>:
[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#...
0+[0-2][0-9a-f] <func2>:
[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#?[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#?[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
0+[0-3][0-9a-f] <func>:
[ ]*[0-9a-f]+: [0-9a-f][0-9a-f].*
#pass

View File

@@ -263,6 +263,7 @@ if { ![istarget "*-*-aix*"]
&& [file normalize "$LD"] == [file normalize "$objdir/../ld/ld-new"]} then { && [file normalize "$LD"] == [file normalize "$objdir/../ld/ld-new"]} then {
run_dump_test multi-1 run_dump_test multi-1
run_dump_test multi-2 run_dump_test multi-2
run_dump_test multi-3
} }
# Test objdump --disassemble=<symbol> # Test objdump --disassemble=<symbol>