[PATCH] objdump: allow to display instructions only for given label

Masatake YAMATO yamato@redhat.com
Mon Oct 22 19:40:00 GMT 2018


This change introduces "label" option argument to "--disassemble"
option. If the label is given, objdump displays instructions only
for the label. This helps you to read a specified area of a
large library quicly.

Following shows how the change works:

(Show the instructions of getenv in glibc)

    $ binutils/objdump --disassemble=getenv /lib64/libc.so.6

    /lib64/libc.so.6:     file format elf64-x86-64

    Disassembly of section .plt:

    Disassembly of section .text:

    0000000000038c50 <getenv>:
       38c50:	41 57                	push   %r15
       38c52:	41 56                	push   %r14
       38c54:	41 55                	push   %r13
       ...

(Use the label option argument with demangled name)

    $ cat /tmp/foo.cc
    int
    foo(int i)
    {
      return i + 1;
    }

    int
    main(void)
    {
      return foo(3);
    }
    $ gcc -c -g -O0 /tmp/foo.cc
    $ nm --demangle ./foo.o
    000000000000000f T main
    0000000000000000 T foo(int)
    $ ./binutils/objdump --demangle --disassemble='foo(int)' ./foo.o

    ./foo.o:     file format elf64-x86-64

    Disassembly of section .text:

    0000000000000000 <foo(int)>:
       0:	55                   	push   %rbp
       1:	48 89 e5             	mov    %rsp,%rbp
       4:	89 7d fc             	mov    %edi,-0x4(%rbp)
       7:	8b 45 fc             	mov    -0x4(%rbp),%eax
       a:	83 c0 01             	add    $0x1,%eax
       d:	5d                   	pop    %rbp
       e:	c3                   	retq

* objdump.c (long_options): make --disassemble option take
option argument.
(usage): Add description for `label' option argument
for the --disassemble option.
(label): New file private variable.
(struct objdump_disasm_info): New field `label'.
(disassemble_section): Introduce `do_print' local variable
to control whether objdump displays the result of disassembling
for a lable or not.
(main): Set `label' file private variable if the option argument
for the --disassemble option is given.

* doc/binutils.texi (objdump): Add description for the option
argument.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
---
 binutils/ChangeLog         | 17 +++++++++++++++++
 binutils/doc/binutils.texi |  5 +++--
 binutils/objdump.c         | 39 ++++++++++++++++++++++++++++++++------
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index e3bbbc3a84..1ca2fe6918 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,20 @@
+2018-10-23  Masatake YAMATO  <yamato@redhat.com>
+
+	* objdump.c (long_options): make --disassemble option take
+	option argument.
+	(usage): Add description for `label' option argument
+	for the --disassemble option.
+	(label): New file private variable.
+	(struct objdump_disasm_info): New field `label'.
+	(disassemble_section): Introduce `do_print' local variable
+	to control whether objdump displays the result of disassembling
+	for a lable or not.
+	(main): Set `label' file private variable if the option argument
+	for the --disassemble option is given.
+
+	* doc/binutils.texi (objdump): Add description for the option
+	argument.
+
 2018-10-18  Nick Clifton  <nickc@redhat.com>
 
 	* doc/binutils.texi (readelf): Document alternatives to the
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 6edd7b1ae8..66b9a5602b 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2063,7 +2063,7 @@ ld(1), objdump(1), and the Info entries for @file{binutils}.
 objdump [@option{-a}|@option{--archive-headers}]
         [@option{-b} @var{bfdname}|@option{--target=@var{bfdname}}]
         [@option{-C}|@option{--demangle}[=@var{style}] ]
-        [@option{-d}|@option{--disassemble}]
+        [@option{-d}|@option{--disassemble}[=@var{label}]]
         [@option{-D}|@option{--disassemble-all}]
         [@option{-z}|@option{--disassemble-zeroes}]
         [@option{-EB}|@option{-EL}|@option{--endian=}@{big | little @}]
@@ -2193,7 +2193,8 @@ with ctags tool.
 @cindex machine instructions
 Display the assembler mnemonics for the machine instructions from
 @var{objfile}.  This option only disassembles those sections which are
-expected to contain instructions.
+expected to contain instructions. If @var{label} is given, display
+the assembler mnemonics only for @var{label}.
 
 @item -D
 @itemx --disassemble-all
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 9c3bce8b75..56384b3dfa 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -118,6 +118,7 @@ static const char *prefix;		/* --prefix */
 static int prefix_strip;		/* --prefix-strip */
 static size_t prefix_length;
 static bfd_boolean unwind_inlines;	/* --inlines.  */
+static const char *label;
 
 /* A structure to record the sections mentioned in -j switches.  */
 struct only
@@ -145,6 +146,7 @@ struct objdump_disasm_info
   long               dynrelcount;
   disassembler_ftype disassemble_fn;
   arelent *          reloc;
+  const char *       label;
 };
 
 /* Architecture to disassemble for, or default if NULL.  */
@@ -207,7 +209,8 @@ usage (FILE *stream, int status)
   -P, --private=OPT,OPT... Display object format specific contents\n\
   -h, --[section-]headers  Display the contents of the section headers\n\
   -x, --all-headers        Display the contents of all headers\n\
-  -d, --disassemble        Display assembler contents of executable sections\n\
+  -d, --disassemble[=label]\n\
+                           Display assembler contents of executable sections\n\
   -D, --disassemble-all    Display assembler contents of all sections\n\
   -S, --source             Intermix source code with disassembly\n\
   -s, --full-contents      Display the full contents of all sections requested\n\
@@ -313,7 +316,7 @@ static struct option long_options[]=
   {"debugging", no_argument, NULL, 'g'},
   {"debugging-tags", no_argument, NULL, 'e'},
   {"demangle", optional_argument, NULL, 'C'},
-  {"disassemble", no_argument, NULL, 'd'},
+  {"disassemble", optional_argument, NULL, 'd'},
   {"disassemble-all", no_argument, NULL, 'D'},
   {"disassembler-options", required_argument, NULL, 'M'},
   {"disassemble-zeroes", no_argument, NULL, 'z'},
@@ -2253,6 +2256,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       asymbol *nextsym;
       bfd_vma nextstop_offset;
       bfd_boolean insns;
+      bfd_boolean do_print = TRUE;
 
       addr = section->vma + addr_offset;
       addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust;
@@ -2278,7 +2282,23 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 	  pinfo->symtab_pos = -1;
 	}
 
-      if (! prefix_addresses)
+      if (sym && paux->label)
+	{
+	  const char *name = bfd_asymbol_name (sym);
+	  char *alloc = NULL;
+	  if (do_demangle && name[0] != '\0')
+	    {
+	      /* Demangle the name.  */
+	      alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+	      if (alloc != NULL)
+		name = alloc;
+	    }
+	  do_print = streq (name, paux->label);
+	  if (alloc != NULL)
+	    free (alloc);
+	}
+
+      if (! prefix_addresses && do_print)
 	{
 	  pinfo->fprintf_func (pinfo->stream, "\n");
 	  objdump_print_addr_with_sym (abfd, section, sym, addr,
@@ -2339,9 +2359,14 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       else
 	insns = FALSE;
 
-      disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
-			 addr_offset, nextstop_offset,
-			 rel_offset, &rel_pp, rel_ppend);
+      if (do_print)
+	{
+	  disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
+			     addr_offset, nextstop_offset,
+			     rel_offset, &rel_pp, rel_ppend);
+	  if (paux->label)
+	    break;
+	}
 
       addr_offset = nextstop_offset;
       sym = nextsym;
@@ -2394,6 +2419,7 @@ disassemble_data (bfd *abfd)
   aux.dynrelbuf = NULL;
   aux.dynrelcount = 0;
   aux.reloc = NULL;
+  aux.label = label;
 
   disasm_info.print_address_func = objdump_print_address;
   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
@@ -3995,6 +4021,7 @@ main (int argc, char **argv)
 	case 'd':
 	  disassemble = TRUE;
 	  seenflag = TRUE;
+	  label = optarg;
 	  break;
 	case 'z':
 	  disassemble_zeroes = TRUE;
-- 
2.17.2



More information about the Binutils mailing list