readelf: move file related static vars to filedata
[deliverable/binutils-gdb.git] / binutils / objdump.c
index a031e9de12291e1d2025f753d92d44aae1e89215..1d9afec992397c4683e56516ce3ef80b91d5360a 100644 (file)
@@ -93,6 +93,7 @@ static int dump_dynamic_reloc_info;   /* -R */
 static int dump_ar_hdrs;               /* -a */
 static int dump_private_headers;       /* -p */
 static char *dump_private_options;     /* -P */
+static int no_addresses;               /* --no-addresses */
 static int prefix_addresses;           /* --prefix-addresses */
 static int with_line_numbers;          /* -l */
 static bfd_boolean with_source_code;   /* -S */
@@ -270,6 +271,7 @@ usage (FILE *stream, int status)
   -z, --disassemble-zeroes       Do not skip blocks of zeroes when disassembling\n\
       --start-address=ADDR       Only process data whose address is >= ADDR\n\
       --stop-address=ADDR        Only process data whose address is < ADDR\n\
+      --no-addresses             Do not print address alongside disassembly\n\
       --prefix-addresses         Print complete address alongside disassembly\n\
       --[no-]show-raw-insn       Display hex alongside symbolic disassembly\n\
       --insn-width=WIDTH         Display WIDTH bytes on a single line for -d\n\
@@ -358,6 +360,7 @@ static struct option long_options[]=
   {"info", no_argument, NULL, 'i'},
   {"line-numbers", no_argument, NULL, 'l'},
   {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
+  {"no-addresses", no_argument, &no_addresses, 1},
   {"prefix-addresses", no_argument, &prefix_addresses, 1},
   {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
   {"recursion-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
@@ -1031,7 +1034,8 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
     }
 
   if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
-    version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
+    version_string = bfd_get_symbol_version_string (abfd, sym, TRUE,
+                                                   &hidden);
 
   if (bfd_is_und_section (bfd_asymbol_section (sym)))
     hidden = TRUE;
@@ -1065,6 +1069,13 @@ sym_ok (bfd_boolean               want_section,
 {
   if (want_section)
     {
+      /* NB: An object file can have different sections with the same
+         section name.  Compare compare section pointers if they have
+        the same owner.  */
+      if (sorted_syms[place]->section->owner == sec->owner
+         && sorted_syms[place]->section != sec)
+       return FALSE;
+
       /* Note - we cannot just compare section pointers because they could
         be different, but the same...  Ie the symbol that we are trying to
         find could have come from a separate debug info file.  Under such
@@ -1295,13 +1306,17 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
                             bfd_vma vma, struct disassemble_info *inf,
                             bfd_boolean skip_zeroes)
 {
-  objdump_print_value (vma, inf, skip_zeroes);
+  if (!no_addresses)
+    {
+      objdump_print_value (vma, inf, skip_zeroes);
+      (*inf->fprintf_func) (inf->stream, " ");
+    }
 
   if (sym == NULL)
     {
       bfd_vma secaddr;
 
-      (*inf->fprintf_func) (inf->stream, " <%s",
+      (*inf->fprintf_func) (inf->stream, "<%s",
                            sanitize_string (bfd_section_name (sec)));
       secaddr = bfd_section_vma (sec);
       if (vma < secaddr)
@@ -1318,7 +1333,7 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
     }
   else
     {
-      (*inf->fprintf_func) (inf->stream, " <");
+      (*inf->fprintf_func) (inf->stream, "<");
 
       objdump_print_symname (abfd, inf, sym);
 
@@ -1368,8 +1383,11 @@ objdump_print_addr (bfd_vma vma,
 
   if (sorted_symcount < 1)
     {
-      (*inf->fprintf_func) (inf->stream, "0x");
-      objdump_print_value (vma, inf, skip_zeroes);
+      if (!no_addresses)
+       {
+         (*inf->fprintf_func) (inf->stream, "0x");
+         objdump_print_value (vma, inf, skip_zeroes);
+       }
 
       if (display_file_offsets)
        inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
@@ -1704,7 +1722,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
 
          /* Skip selected directory levels.  */
          for (s = fname + 1; *s != '\0' && level < prefix_strip; s++)
-           if (IS_DIR_SEPARATOR(*s))
+           if (IS_DIR_SEPARATOR (*s))
              {
                fname = s;
                level++;
@@ -1727,8 +1745,22 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
          && (prev_functionname == NULL
              || strcmp (functionname, prev_functionname) != 0))
        {
-         printf ("%s():\n", sanitize_string (functionname));
+         char *demangle_alloc = NULL;
+         if (do_demangle && functionname[0] != '\0')
+           {
+             /* Demangle the name.  */
+             demangle_alloc = bfd_demangle (abfd, functionname,
+                                                 demangle_flags);
+           }
+
+         /* Demangling adds trailing parens, so don't print those.  */
+         if (demangle_alloc != NULL)
+           printf ("%s:\n", sanitize_string (demangle_alloc));
+         else
+           printf ("%s():\n", sanitize_string (functionname));
+
          prev_line = -1;
+         free (demangle_alloc);
        }
       if (linenumber > 0
          && (linenumber != prev_line
@@ -2087,7 +2119,7 @@ jump_info_merge (struct jump_info **base)
                  a->start.max_count += b->start.max_count;
                  a->start.addresses =
                    xrealloc (a->start.addresses,
-                             a->start.max_count * sizeof(bfd_vma *));
+                             a->start.max_count * sizeof (bfd_vma *));
                }
 
              /* Append start addresses.  */
@@ -2146,24 +2178,34 @@ jump_info_sort (struct jump_info **base)
 /* Visualize all jumps at a given address.  */
 
 static void
-jump_info_visualize_address (const struct jump_info *jumps,
-                            bfd_vma address,
+jump_info_visualize_address (bfd_vma address,
                             int max_level,
                             char *line_buffer,
                             uint8_t *color_buffer)
 {
+  struct jump_info *ji = detected_jumps;
   size_t len = (max_level + 1) * 3;
-  const struct jump_info *ji;
 
   /* Clear line buffer.  */
-  memset(line_buffer, ' ', len);
-  memset(color_buffer, 0, len);
+  memset (line_buffer, ' ', len);
+  memset (color_buffer, 0, len);
 
   /* Iterate over jumps and add their ASCII art.  */
-  for (ji = jumps; ji; ji = ji->next)
+  while (ji)
     {
-      if ((jump_info_min_address (ji) <= address)
-         && (jump_info_max_address (ji) >= address))
+      /* Discard jumps that are never needed again.  */
+      if (jump_info_max_address (ji) < address)
+       {
+         struct jump_info *tmp = ji;
+
+         ji = ji->next;
+         jump_info_unlink (tmp, &detected_jumps);
+         jump_info_free (tmp);
+         continue;
+       }
+
+      /* This jump intersects with the current address.  */
+      if (jump_info_min_address (ji) <= address)
        {
          /* Hash target address to get an even
             distribution between all values.  */
@@ -2246,6 +2288,8 @@ jump_info_visualize_address (const struct jump_info *jumps,
              color_buffer[offset] = color;
            }
        }
+
+      ji = ji->next;
     }
 }
 
@@ -2455,6 +2499,47 @@ null_print (const void * stream ATTRIBUTE_UNUSED, const char * format ATTRIBUTE_
   return 1;
 }
 
+/* Print out jump visualization.  */
+
+static void
+print_jump_visualisation (bfd_vma addr, int max_level, char *line_buffer,
+                         uint8_t *color_buffer)
+{
+  if (!line_buffer)
+    return;
+
+  jump_info_visualize_address (addr, max_level, line_buffer, color_buffer);
+
+  size_t line_buffer_size = strlen (line_buffer);
+  char last_color = 0;
+  size_t i;
+
+  for (i = 0; i <= line_buffer_size; ++i)
+    {
+      if (color_output)
+       {
+         uint8_t color = (i < line_buffer_size) ? color_buffer[i]: 0;
+
+         if (color != last_color)
+           {
+             if (color)
+               if (extended_color_output)
+                 /* Use extended 8bit color, but
+                    do not choose dark colors.  */
+                 printf ("\033[38;5;%dm", 124 + (color % 108));
+               else
+                 /* Use simple terminal colors.  */
+                 printf ("\033[%dm", 31 + (color % 7));
+             else
+               /* Clear color.  */
+               printf ("\033[0m");
+             last_color = color;
+           }
+       }
+      putchar ((i < line_buffer_size) ? line_buffer[i]: ' ');
+    }
+}
+
 /* Disassemble some data in memory between given values.  */
 
 static void
@@ -2498,7 +2583,7 @@ disassemble_bytes (struct disassemble_info * inf,
      zeroes in chunks of 4, ensuring that there is always a leading
      zero remaining.  */
   skip_addr_chars = 0;
-  if (! prefix_addresses)
+  if (!no_addresses && !prefix_addresses)
     {
       char buf[30];
 
@@ -2518,26 +2603,27 @@ disassemble_bytes (struct disassemble_info * inf,
   inf->insn_info_valid = 0;
 
   /* Determine maximum level. */
+  uint8_t *color_buffer = NULL;
+  char *line_buffer = NULL;
   int max_level = -1;
-  struct jump_info *base = detected_jumps ? detected_jumps : NULL;
-  struct jump_info *ji;
 
-  for (ji = base; ji; ji = ji->next)
+  /* Some jumps were detected.  */
+  if (detected_jumps)
     {
-      if (ji->level > max_level)
+      struct jump_info *ji;
+
+      /* Find maximum jump level.  */
+      for (ji = detected_jumps; ji; ji = ji->next)
        {
-         max_level = ji->level;
+         if (ji->level > max_level)
+           max_level = ji->level;
        }
-    }
 
-  /* Allocate line buffer if there are any jumps.  */
-  size_t len = (max_level + 1) * 3 + 1;
-  char *line_buffer = (max_level >= 0) ? xmalloc(len): NULL;
-  uint8_t *color_buffer = (max_level >= 0) ? xmalloc(len): NULL;
-
-  if (line_buffer)
-    {
+      /* Allocate buffers.  */
+      size_t len = (max_level + 1) * 3 + 1;
+      line_buffer = xmalloc (len);
       line_buffer[len - 1] = 0;
+      color_buffer = xmalloc (len);
       color_buffer[len - 1] = 0;
     }
 
@@ -2593,7 +2679,9 @@ disassemble_bytes (struct disassemble_info * inf,
          if (with_line_numbers || with_source_code)
            show_line (aux->abfd, section, addr_offset);
 
-         if (! prefix_addresses)
+         if (no_addresses)
+           printf ("\t");
+         else if (!prefix_addresses)
            {
              char *s;
 
@@ -2612,43 +2700,9 @@ disassemble_bytes (struct disassemble_info * inf,
              putchar (' ');
            }
 
-         /* Visualize jumps. */
-         if (line_buffer)
-           {
-             jump_info_visualize_address (base,
-                                          section->vma + addr_offset,
-                                          max_level,
-                                          line_buffer,
-                                          color_buffer);
-
-             size_t line_buffer_size = strlen (line_buffer);
-             char last_color = 0;
-
-             for (size_t i = 0; i <= line_buffer_size; ++i)
-               {
-                 if (color_output)
-                   {
-                     uint8_t color = (i < line_buffer_size) ? color_buffer[i]: 0;
-
-                     if (color != last_color)
-                       {
-                         if (color)
-                           if (extended_color_output)
-                             /* Use extended 8bit color, but
-                                do not choose dark colors.  */
-                             printf ("\033[38;5;%dm", 124 + (color % 108));
-                           else
-                             /* Use simple terminal colors.  */
-                             printf ("\033[%dm", 31 + (color % 7));
-                         else
-                           /* Clear color.  */
-                           printf ("\033[0m");
-                         last_color = color;
-                       }
-                   }
-                 putchar ((i < line_buffer_size) ? line_buffer[i]: ' ');
-               }
-           }
+         print_jump_visualisation (section->vma + addr_offset,
+                                   max_level, line_buffer,
+                                   color_buffer);
 
          if (insns)
            {
@@ -2833,12 +2887,21 @@ disassemble_bytes (struct disassemble_info * inf,
                  putchar ('\n');
                  j = addr_offset * opb + pb;
 
-                 bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
-                 for (s = buf + skip_addr_chars; *s == '0'; s++)
-                   *s = ' ';
-                 if (*s == '\0')
-                   *--s = '0';
-                 printf ("%s:\t", buf + skip_addr_chars);
+                 if (no_addresses)
+                   printf ("\t");
+                 else
+                   {
+                     bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
+                     for (s = buf + skip_addr_chars; *s == '0'; s++)
+                       *s = ' ';
+                     if (*s == '\0')
+                       *--s = '0';
+                     printf ("%s:\t", buf + skip_addr_chars);
+                   }
+
+                 print_jump_visualisation (section->vma + j / opb,
+                                           max_level, line_buffer,
+                                           color_buffer);
 
                  pb += octets_per_line;
                  if (pb > octets)
@@ -2886,15 +2949,19 @@ disassemble_bytes (struct disassemble_info * inf,
              else
                printf ("\t\t\t");
 
-             objdump_print_value (section->vma - rel_offset + q->address,
-                                  inf, TRUE);
+             if (!no_addresses)
+               {
+                 objdump_print_value (section->vma - rel_offset + q->address,
+                                      inf, TRUE);
+                 printf (": ");
+               }
 
              if (q->howto == NULL)
-               printf ("*unknown*\t");
+               printf ("*unknown*\t");
              else if (q->howto->name)
-               printf ("%s\t", q->howto->name);
+               printf ("%s\t", q->howto->name);
              else
-               printf ("%d\t", q->howto->type);
+               printf ("%d\t", q->howto->type);
 
              if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
                printf ("*unknown*");
@@ -3064,7 +3131,8 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 
   /* Sort the symbols into value and section order.  */
   compare_section = section;
-  qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+  if (sorted_symcount > 1)
+    qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
 
   /* Skip over the relocs belonging to addresses below the
      start address.  */
@@ -3331,10 +3399,13 @@ disassemble_data (bfd *abfd)
   sorted_symcount = symcount ? symcount : dynsymcount;
   sorted_syms = (asymbol **) xmalloc ((sorted_symcount + synthcount)
                                       * sizeof (asymbol *));
-  memcpy (sorted_syms, symcount ? syms : dynsyms,
-         sorted_symcount * sizeof (asymbol *));
+  if (sorted_symcount != 0)
+    {
+      memcpy (sorted_syms, symcount ? syms : dynsyms,
+             sorted_symcount * sizeof (asymbol *));
 
-  sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
+      sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
+    }
 
   for (i = 0; i < synthcount; ++i)
     {
@@ -3933,7 +4004,7 @@ dump_bfd_header (bfd *abfd)
                                   bfd_get_mach (abfd)));
   printf (_("flags 0x%08x:\n"), abfd->flags & ~BFD_FLAGS_FOR_BFD_USE_MASK);
 
-#define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
+#define PF(x, y)    if (abfd->flags & x) {printf ("%s%s", comma, y); comma=", ";}
   PF (HAS_RELOC, "HAS_RELOC");
   PF (EXEC_P, "EXEC_P");
   PF (HAS_LINENO, "HAS_LINENO");
@@ -4477,7 +4548,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
             Undo this transformation, otherwise the output
             will be confusing.  */
          if (abfd->xvec->flavour == bfd_target_elf_flavour
-             && elf_tdata(abfd)->elf_header->e_machine == EM_SPARCV9
+             && elf_tdata (abfd)->elf_header->e_machine == EM_SPARCV9
              && relcount > 1
              && !strcmp (q->howto->name, "R_SPARC_LO10"))
            {
This page took 0.03313 seconds and 4 git commands to generate.