[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"));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.