* frags.c (frag_var): fr_pcrel_adjust renamed to
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 5eca0fc0519b2899591dc92b475e4cf022b9f3f2..e6c4c76a2ffda3f9bfbe6e99dfe1fb8ff170f8ef 100644 (file)
@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <ctype.h>
 #include "dis-asm.h"
 #include "libiberty.h"
+#include "demangle.h"
 #include "debug.h"
 #include "budbg.h"
 
@@ -59,6 +60,7 @@ static int with_line_numbers;         /* -l */
 static boolean with_source_code;       /* -S */
 static int show_raw_insn;              /* --show-raw-insn */
 static int dump_stab_section_info;     /* --stabs */
+static int do_demangle;                        /* -C, --demangle */
 static boolean disassemble;            /* -d */
 static boolean disassemble_all;                /* -D */
 static int disassemble_zeroes;         /* --disassemble-zeroes */
@@ -68,6 +70,7 @@ static int wide_output;                       /* -w */
 static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
 static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
 static int dump_debugging;             /* --debugging */
+static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
 
 /* Extra info to pass to the disassembler address printing function.  */
 struct objdump_disasm_info {
@@ -126,6 +129,9 @@ display_bfd PARAMS ((bfd *abfd));
 static void
 objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *, boolean));
 
+static void
+objdump_print_symname PARAMS ((bfd *, struct disassemble_info *, asymbol *));
+
 static asymbol *
 find_symbol_for_address PARAMS ((bfd *, asection *, bfd_vma, boolean, long *));
 
@@ -159,7 +165,7 @@ usage (stream, status)
      int status;
 {
   fprintf (stream, "\
-Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
+Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
        [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
        [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\
        [--section-headers] [--headers]\n\
@@ -170,8 +176,8 @@ Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
        [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
        [--wide] [--version] [--help] [--private-headers]\n\
        [--start-address=addr] [--stop-address=addr]\n\
-       [--prefix-addresses] [--show-raw-insn]\n\
-       [-EB|-EL] [--endian={big|little}] objfile...\n\
+       [--prefix-addresses] [--[no-]show-raw-insn] [--demangle]\n\
+       [--adjust-vma=offset] [-EB|-EL] [--endian={big|little}] objfile...\n\
 at least one option besides -l (--line-numbers) must be given\n");
   list_supported_targets (program_name, stream);
   if (status == 0)
@@ -184,14 +190,17 @@ at least one option besides -l (--line-numbers) must be given\n");
 #define OPTION_ENDIAN (150)
 #define OPTION_START_ADDRESS (OPTION_ENDIAN + 1)
 #define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1)
+#define OPTION_ADJUST_VMA (OPTION_STOP_ADDRESS + 1)
 
 static struct option long_options[]=
 {
+  {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
   {"all-headers", no_argument, NULL, 'x'},
   {"private-headers", no_argument, NULL, 'p'},
   {"architecture", required_argument, NULL, 'm'},
   {"archive-headers", no_argument, NULL, 'a'},
   {"debugging", no_argument, &dump_debugging, 1},
+  {"demangle", no_argument, &do_demangle, 1},
   {"disassemble", no_argument, NULL, 'd'},
   {"disassemble-all", no_argument, NULL, 'D'},
   {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1},
@@ -204,6 +213,7 @@ static struct option long_options[]=
   {"help", no_argument, NULL, 'H'},
   {"info", no_argument, NULL, 'i'},
   {"line-numbers", no_argument, NULL, 'l'},
+  {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
   {"prefix-addresses", no_argument, &prefix_addresses, 1},
   {"reloc", no_argument, NULL, 'r'},
   {"section", required_argument, NULL, 'j'},
@@ -557,6 +567,44 @@ objdump_print_value (vma, info, skip_zeroes)
   (*info->fprintf_func) (info->stream, "%s", p);
 }
 
+/* Print the name of a symbol.  */
+
+static void
+objdump_print_symname (abfd, info, sym)
+     bfd *abfd;
+     struct disassemble_info *info;
+     asymbol *sym;
+{
+  char *alloc;
+  const char *name;
+  const char *print;
+
+  alloc = NULL;
+  name = bfd_asymbol_name (sym);
+  if (! do_demangle || name[0] == '\0')
+    print = name;
+  else
+    {
+      /* Demangle the name.  */
+      if (bfd_get_symbol_leading_char (abfd) == name[0])
+       ++name;
+
+      alloc = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+      if (alloc == NULL)
+       print = name;
+      else
+       print = alloc;
+    }
+
+  if (info != NULL)
+    (*info->fprintf_func) (info->stream, "%s", print);
+  else
+    printf ("%s", print);
+
+  if (alloc != NULL)
+    free (alloc);
+}
+
 /* Locate a symbol given a bfd, a section, and a VMA.  If REQUIRE_SEC
    is true, then always require the symbol to be in the section.  This
    returns NULL if there is no suitable symbol.  If PLACE is not NULL,
@@ -716,7 +764,8 @@ objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
     }
   else
     {
-      (*info->fprintf_func) (info->stream, " <%s", sym->name);
+      (*info->fprintf_func) (info->stream, " <");
+      objdump_print_symname (abfd, info, sym);
       if (bfd_asymbol_value (sym) > vma)
        {
          (*info->fprintf_func) (info->stream, "-");
@@ -1166,7 +1215,9 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
              buf[j - i] = '\0';
            }
 
-         if (! prefix_addresses || show_raw_insn)
+         if (prefix_addresses
+             ? show_raw_insn > 0
+             : show_raw_insn >= 0)
            {
              long j;
 
@@ -1216,7 +1267,9 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
 
          printf ("%s", buf);
 
-         if (! prefix_addresses || show_raw_insn)
+         if (prefix_addresses
+             ? show_raw_insn > 0
+             : show_raw_insn >= 0)
            {
              while (pb < bytes)
                {
@@ -1270,7 +1323,6 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
                     && (**relppp)->address < (bfd_vma) i + bytes))
            {
              arelent *q;
-             const char *sym_name;
 
              q = **relppp;
 
@@ -1283,24 +1335,26 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
 
              printf (": %s\t", q->howto->name);
 
-             if (q->sym_ptr_ptr != NULL
-                 && *q->sym_ptr_ptr != NULL)
+             if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
+               printf ("*unknown*");
+             else
                {
+                 const char *sym_name;
+
                  sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
-                 if (sym_name == NULL || *sym_name == '\0')
+                 if (sym_name != NULL && *sym_name != '\0')
+                   objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
+                 else
                    {
                      asection *sym_sec;
 
                      sym_sec = bfd_get_section (*q->sym_ptr_ptr);
-                     sym_name = bfd_get_section_name (abfd, sym_sec);
+                     sym_name = bfd_get_section_name (aux->abfd, sym_sec);
                      if (sym_name == NULL || *sym_name == '\0')
                        sym_name = "*unknown*";
+                     printf ("%s", sym_name);
                    }
                }
-             else
-               sym_name = "*unknown*";
-
-             printf ("%s", sym_name);
 
              if (q->addend)
                {
@@ -1481,7 +1535,8 @@ disassemble_data (abfd)
          asymbol *sym;
          long place;
 
-         sym = find_symbol_for_address (abfd, section, i, true, &place);
+         sym = find_symbol_for_address (abfd, section, section->vma + i,
+                                        true, &place);
          ++place;
          while (i < stop)
            {
@@ -1489,7 +1544,10 @@ disassemble_data (abfd)
              long nextstop;
              boolean insns;
 
-             disasm_info.symbol = sym;
+             if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + i)
+               disasm_info.symbol = sym;
+             else
+               disasm_info.symbol = NULL;
 
              printf ("\n");
              objdump_print_addr_with_sym (abfd, section, sym,
@@ -1498,7 +1556,9 @@ disassemble_data (abfd)
                                           false);
              printf (":\n");
 
-             if (sym == NULL)
+             if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i)
+               nextsym = sym;
+             else if (sym == NULL)
                nextsym = NULL;
              else
                {
@@ -1513,7 +1573,13 @@ disassemble_data (abfd)
                    nextsym = sorted_syms[place];
                }
 
-             if (nextsym == NULL)
+             if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i)
+               {
+                 nextstop = bfd_asymbol_value (sym) - section->vma;
+                 if (nextstop > stop)
+                   nextstop = stop;
+               }
+             else if (nextsym == NULL)
                nextstop = stop;
              else
                {
@@ -1527,6 +1593,7 @@ disassemble_data (abfd)
                  disassembling them.  */
              if (disassemble_all
                  || sym == NULL
+                 || bfd_asymbol_value (sym) > section->vma + i
                  || ((sym->flags & BSF_OBJECT) == 0
                      && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
                          == NULL)
@@ -1812,6 +1879,20 @@ display_bfd (abfd)
       return;
     }
 
+  /* If we are adjusting section VMA's, change them all now.  Changing
+     the BFD information is a hack.  However, we must do it, or
+     bfd_find_nearest_line will not do the right thing.  */
+  if (adjust_section_vma != 0)
+    {
+      asection *s;
+
+      for (s = abfd->sections; s != NULL; s = s->next)
+       {
+         s->vma += adjust_section_vma;
+         s->lma += adjust_section_vma;
+       }
+    }
+
   printf ("\n%s:     file format %s\n", bfd_get_filename (abfd),
          abfd->xvec->name);
   if (dump_ar_hdrs)
@@ -2028,12 +2109,40 @@ dump_symbols (abfd, dynamic)
     {
       if (*current)
        {
-         bfd *cur_bfd = bfd_asymbol_bfd(*current);
-         if (cur_bfd)
+         bfd *cur_bfd = bfd_asymbol_bfd (*current);
+
+         if (cur_bfd != NULL)
            {
-             bfd_print_symbol (cur_bfd,
-                               stdout,
-                               *current, bfd_print_symbol_all);
+             const char *name;
+             char *alloc;
+
+             name = bfd_asymbol_name (*current);
+             alloc = NULL;
+             if (do_demangle && name != NULL && *name != '\0')
+               {
+                 const char *n;
+
+                 /* If we want to demangle the name, we demangle it
+                     here, and temporarily clobber it while calling
+                     bfd_print_symbol.  FIXME: This is a gross hack.  */
+
+                 n = name;
+                 if (bfd_get_symbol_leading_char (cur_bfd) == *n)
+                   ++n;
+                 alloc = cplus_demangle (n, DMGL_ANSI | DMGL_PARAMS);
+                 if (alloc != NULL)
+                   (*current)->name = alloc;
+                 else
+                   (*current)->name = n;
+               }
+
+             bfd_print_symbol (cur_bfd, stdout, *current,
+                               bfd_print_symbol_all);
+
+             (*current)->name = name;
+             if (alloc != NULL)
+               free (alloc);
+
              printf ("\n");
            }
        }
@@ -2225,9 +2334,9 @@ dump_reloc_set (abfd, sec, relpp, relcount)
       if (sym_name)
        {
          printf_vma (q->address);
-         printf (" %-16s  %s",
-                 q->howto->name,
-                 sym_name);
+         printf (" %-16s  ", q->howto->name);
+         objdump_print_symname (abfd, (struct disassemble_info *) NULL,
+                                *q->sym_ptr_ptr);
        }
       else
        {
@@ -2436,8 +2545,9 @@ main (argc, argv)
   START_PROGRESS (program_name, 0);
 
   bfd_init ();
+  set_default_bfd_target ();
 
-  while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:wE:",
+  while ((c = getopt_long (argc, argv, "pib:m:VCdDlfahrRtTxsSj:wE:",
                           long_options, (int *) 0))
         != EOF)
     {
@@ -2482,6 +2592,9 @@ main (argc, argv)
        case 'T':
          dump_dynamic_symtab = 1;
          break;
+       case 'C':
+         do_demangle = 1;
+         break;
        case 'd':
          disassemble = true;
          break;
@@ -2515,6 +2628,9 @@ main (argc, argv)
        case 'w':
          wide_output = 1;
          break;
+       case OPTION_ADJUST_VMA:
+         adjust_section_vma = parse_vma (optarg, "--adjust-vma");
+         break;
        case OPTION_START_ADDRESS:
          start_address = parse_vma (optarg, "--start-address");
          break;
This page took 0.027777 seconds and 4 git commands to generate.