[binutils-gdb] Objdump: Add "-M annotate" option to the AArch64 disassembler.
Nick Clifton via Binutils-cvs <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0166d3cedefcd8f60417427f7b72f46e74a35290 commit 0166d3cedefcd8f60417427f7b72f46e74a35290 Author: Nick Clifton <[email protected]> Date: Fri May 8 11:10:05 2026 +0100 Objdump: Add "-M annotate" option to the AArch64 disassembler. Diff: --- binutils/NEWS | 4 +++ binutils/doc/binutils.texi | 10 +++++- .../testsuite/binutils-all/aarch64/aarch64.exp | 32 +++++++++++++++++ .../testsuite/binutils-all/aarch64/objdumpM1.c | 42 ++++++++++++++++++++++ .../testsuite/binutils-all/aarch64/objdumpM2.c | 5 +++ opcodes/aarch64-dis.c | 39 ++++++++++++++++++-- 6 files changed, 129 insertions(+), 3 deletions(-) diff --git a/binutils/NEWS b/binutils/NEWS index 29821c96d0f..5532670b4a2 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,9 @@ -*- text -*- +* The AArch64 disassembler now accepts a command line option of "-M annotate" + which displays the symbol associated with undefined instructions, should + there be one. + * The x86 and x86_64 disassemblers now accept a command line option of "-M annotate-immediates" which displays the symbol associated with immediate values, should there be one. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 45df92394b6..198ae8244ef 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -2691,7 +2691,15 @@ compilers. For AArch64 targets this switch can be used to set whether instructions are disassembled as the most general instruction using the @option{-M no-aliases} option or whether instruction notes should be generated as comments in the -disasssembly using @option{-M notes}. +disasssembly using @option{-M notes}. In addition the @option{-M +annotate} option can be used to customise the handling of undefined +instructions when disassembling executables and shared libraries. +Normally the disassembler will just show the hexadecimal value of tge +undefined instruction, but if annotation is enabled it will first try +to find a symbol whose value matches the instruction's encoding. If +there is a match then the symbol name will be displayed instead. This +can be useful when disassembling non-code sections which may contain +function and data addresses. For the x86, some of the options duplicate functions of the @option{-m} switch, but allow finer grained control. diff --git a/binutils/testsuite/binutils-all/aarch64/aarch64.exp b/binutils/testsuite/binutils-all/aarch64/aarch64.exp index 05edcf53203..9699df54894 100644 --- a/binutils/testsuite/binutils-all/aarch64/aarch64.exp +++ b/binutils/testsuite/binutils-all/aarch64/aarch64.exp @@ -28,3 +28,35 @@ foreach t $test_list { verbose [file rootname $t] run_dump_test [file rootname $t] } + +# Test objdump -M annotate + +proc test_objdump_M_annotate { } { + global srcdir + global subdir + global OBJDUMP + global OBJDUMPFLAGS + + set test "objdump -M annotate" + + set result [target_compile "$srcdir/$subdir/objdumpM1.c $srcdir/$subdir/objdumpM2.c" tmpdir/objdumpM executable debug] + if { $result != "" } { + unsupported "$test (build): compile result: $result" + return + } + + set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -D -M annotate tmpdir/objdumpM"] + + # Look for something like this in the disassembly: + # 420020: 00400780 .inst 0x00400780 ; [func1] + set want "; \[func1\]" + + if [regexp $want $got] then { + pass $test + # file delete objdumpM + } else { + fail $test + } +} + +test_objdump_M_annotate diff --git a/binutils/testsuite/binutils-all/aarch64/objdumpM1.c b/binutils/testsuite/binutils-all/aarch64/objdumpM1.c new file mode 100644 index 00000000000..1b7c8604f9b --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/objdumpM1.c @@ -0,0 +1,42 @@ +int datum = 22; + +extern int func1 (int); +extern int func2 (int); +extern int func3 (int); +extern int func4 (int); +extern int func5 (int); + +/* Create an array of function pointers in the .data section. */ +struct ptrs +{ + int (* fptr)(int); + int field; +} +fred [5] = +{ + { func1, 1 }, + { func2, 2 }, + { func3, 3 }, + { func4, 4 }, + { func5, 5 } +}; + +int main (int arg) +{ + /* FIXME: We want a way to make sure that undefined instructions that + are inserted via the .inst directive are not annotated. (Since the .inst + directive is used explicitly for instructions and the user does not care + if they happen to match a symbolic value). + + Unfortunately the .inst directive only supports constant expressions so + we cannot use an unresolved symbolic value. Inserting a symbolic value + via one of the data directives does not work since they are labeled as + data (via the MAP_DATA mapping state) and hence they become eligible + for annotation. + + So for now we are stuck. */ + + /* Stop the compiler from optimizing away the function pointer array + by using it in a non-predictable manner. */ + return fred[arg].fptr (fred[arg].field * datum); +} diff --git a/binutils/testsuite/binutils-all/aarch64/objdumpM2.c b/binutils/testsuite/binutils-all/aarch64/objdumpM2.c new file mode 100644 index 00000000000..a4e8dee4365 --- /dev/null +++ b/binutils/testsuite/binutils-all/aarch64/objdumpM2.c @@ -0,0 +1,5 @@ +int func1 (int arg) { return arg * 2; } +int func2 (int arg) { return arg * 3; } +int func3 (int arg) { return arg * 4; } +int func4 (int arg) { return arg * 5; } +int func5 (int arg) { return arg * 6; } diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 8544ce4b6d4..a7a170661b2 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -49,6 +49,7 @@ static enum map_type last_type; static int last_mapping_sym = -1; static bfd_vma last_stop_offset = 0; static bfd_vma last_mapping_addr = 0; +static bool annotate_undefined_insns = false; /* Other options */ static int no_aliases = 0; /* If set disassemble as most general inst. */ @@ -91,6 +92,18 @@ parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED) return; } + if (startswith (option, "annotate")) + { + annotate_undefined_insns = true; + return; + } + + if (startswith (option, "no-annotate")) + { + annotate_undefined_insns = false; + return; + } + #ifdef DEBUG_AARCH64 if (startswith (option, "debug_dump")) { @@ -4260,8 +4273,24 @@ print_insn_aarch64_word (bfd_vma pc, ".inst\t"); (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%08x", word); - (*info->fprintf_styled_func) (info->stream, dis_style_comment_start, - " ; %s", err_msg[ret]); + asymbol * sym = NULL; + /* See if this "instruction" is actually the address of something. */ + if (annotate_undefined_insns + /* Skip values that have been explicitly tagged as code. */ + && last_type == MAP_DATA + /* Skip static object files as symbol values have not be resolved yet. */ + && info->section != NULL + && info->section->owner != NULL + && (info->section->owner->flags & (EXEC_P | DYNAMIC))) + { + sym = info->symbol_at_address_func (word, info); + if (sym != NULL) + info->fprintf_styled_func (info->stream, dis_style_symbol, + " ; [%s]", sym->name); + } + if (sym == NULL) + info->fprintf_styled_func (info->stream, dis_style_comment_start, + " ; %s", err_msg[ret]); break; case ERR_OK: user_friendly_fixup (&inst); @@ -4595,6 +4624,12 @@ with the -M switch (multiple options should be separated by commas):\n")); fprintf (stream, _("\n\ notes Do print instruction notes.\n")); + fprintf (stream, _("\n\ + annotate Display symbol names for undefined instructions.\n")); + + fprintf (stream, _("\n\ + no-annotate Do not display symbol names for undefined instructions.\n")); + #ifdef DEBUG_AARCH64 fprintf (stream, _("\n\ debug_dump Temp switch for debug trace.\n"));