* NEWS: Add note about --dwarf-depth, --dwarf-start, and
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 79be66501d835bc9116a61116767c4f3ccfd7905..231a66867a70c135823e6fae4ea384497e88f733 100644 (file)
@@ -1,6 +1,6 @@
 /* objdump.c -- dump information about an object file.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -55,6 +55,7 @@
 #include "elf-bfd.h"
 #include "progress.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 #include "getopt.h"
 #include "safe-ctype.h"
@@ -109,6 +110,7 @@ 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 int dump_debugging_tags;                /* --debugging-tags */
+static int suppress_bfd_header;
 static int dump_special_syms = 0;      /* --special-syms */
 static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
 static int file_start_context = 0;      /* --file-start-context */
@@ -117,13 +119,16 @@ static const char *prefix;                /* --prefix */
 static int prefix_strip;               /* --prefix-strip */
 static size_t prefix_length;
 
-/* Pointer to an array of section names provided by
-   one or more "-j secname" command line options.  */
-static char **only;
-/* The total number of slots in the only[] array.  */
-static size_t only_size = 0;
-/* The number of occupied slots in the only[] array.  */
-static size_t only_used = 0;
+/* A structure to record the sections mentioned in -j switches.  */
+struct only
+{
+  const char * name; /* The name of the section.  */
+  bfd_boolean  seen; /* A flag to indicate that the section has been found in one or more input files.  */
+  struct only * next; /* Pointer to the next structure in the list.  */
+};
+/* Pointer to an array of 'only' structures.
+   This pointer is NULL if the -j switch has not been used.  */
+static struct only * only_list = NULL;
 
 /* Variables for handling include file path table.  */
 static const char **include_paths;
@@ -202,7 +207,8 @@ usage (FILE *stream, int status)
   -G, --stabs              Display (in raw form) any STABS info in the file\n\
   -W[lLiaprmfFsoRt] or\n\
   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
-          =frames-interp,=str,=loc,=Ranges,=pubtypes]\n\
+          =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
+          =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
                            Display DWARF info in the file\n\
   -t, --syms               Display the contents of the symbol table(s)\n\
   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
@@ -237,12 +243,15 @@ usage (FILE *stream, int status)
       --stop-address=ADDR        Only process data whose address is <= ADDR\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 signle line for -d\n\
+      --insn-width=WIDTH         Display WIDTH bytes on a single line for -d\n\
       --adjust-vma=OFFSET        Add OFFSET to all displayed section addresses\n\
       --special-syms             Include special symbols in symbol dumps\n\
       --prefix=PREFIX            Add PREFIX to absolute paths for -S\n\
-      --prefix-strip=LEVEL       Strip initial directory names for -S\n\
-\n"));
+      --prefix-strip=LEVEL       Strip initial directory names for -S\n"));
+      fprintf (stream, _("\
+      --dwarf-depth=N        Do not display DIEs at depth N or greater\n\
+      --dwarf-start=N        Display DIEs starting with N, at the same depth\n\
+                             or deeper\n\n"));
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
@@ -263,7 +272,9 @@ enum option_values
     OPTION_PREFIX,
     OPTION_PREFIX_STRIP,
     OPTION_INSN_WIDTH,
-    OPTION_ADJUST_VMA
+    OPTION_ADJUST_VMA,
+    OPTION_DWARF_DEPTH,
+    OPTION_DWARF_START
   };
 
 static struct option long_options[]=
@@ -311,6 +322,8 @@ static struct option long_options[]=
   {"prefix", required_argument, NULL, OPTION_PREFIX},
   {"prefix-strip", required_argument, NULL, OPTION_PREFIX_STRIP},
   {"insn-width", required_argument, NULL, OPTION_INSN_WIDTH},
+  {"dwarf-depth",      required_argument, 0, OPTION_DWARF_DEPTH},
+  {"dwarf-start",      required_argument, 0, OPTION_DWARF_START},
   {0, no_argument, 0, 0}
 };
 \f
@@ -326,17 +339,79 @@ nonfatal (const char *msg)
 static bfd_boolean
 process_section_p (asection * section)
 {
-  size_t i;
+  struct only * only;
 
-  if (only == NULL)
+  if (only_list == NULL)
     return TRUE;
 
-  for (i = 0; i < only_used; i++)
-    if (strcmp (only [i], section->name) == 0)
-      return TRUE;
+  for (only = only_list; only; only = only->next)
+    if (strcmp (only->name, section->name) == 0)
+      {
+       only->seen = TRUE;
+       return TRUE;
+      }
 
   return FALSE;
 }
+
+/* Add an entry to the 'only' list.  */
+
+static void
+add_only (char * name)
+{
+  struct only * only;
+
+  /* First check to make sure that we do not
+     already have an entry for this name.  */
+  for (only = only_list; only; only = only->next)
+    if (strcmp (only->name, name) == 0)
+      return;
+
+  only = xmalloc (sizeof * only);
+  only->name = name;
+  only->seen = FALSE;
+  only->next = only_list;
+  only_list = only;
+}
+
+/* Release the memory used by the 'only' list.
+   PR 11225: Issue a warning message for unseen sections.
+   Only do this if none of the sections were seen.  This is mainly to support
+   tools like the GAS testsuite where an object file is dumped with a list of
+   generic section names known to be present in a range of different file
+   formats.  */
+
+static void
+free_only_list (void)
+{
+  bfd_boolean at_least_one_seen = FALSE;
+  struct only * only;
+  struct only * next;
+
+  if (only_list == NULL)
+    return;
+
+  for (only = only_list; only; only = only->next)
+    if (only->seen)
+      {
+       at_least_one_seen = TRUE;
+       break;
+      }
+
+  for (only = only_list; only; only = next)
+    {
+      if (! at_least_one_seen)
+       {
+         non_fatal (_("section '%s' mentioned in a -j option, "
+                      "but not found in any input file"),
+                    only->name);
+         exit_status = 1;
+       }
+      next = only->next;
+      free (only);
+    }
+}
+
 \f
 static void
 dump_section_header (bfd *abfd, asection *section,
@@ -445,8 +520,6 @@ dump_headers (bfd *abfd)
 
   if (wide_output)
     printf (_("  Flags"));
-  if (abfd->flags & HAS_LOAD_PAGE)
-    printf (_("  Pg"));
   printf ("\n");
 
   bfd_map_over_sections (abfd, dump_section_header, NULL);
@@ -490,6 +563,7 @@ slurp_dynamic_symtab (bfd *abfd)
       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
        {
          non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
+         exit_status = 1;
          dynsymcount = 0;
          return NULL;
        }
@@ -1145,9 +1219,6 @@ update_source_path (const char *filename)
   const char *fname;
   int i;
 
-  if (filename == NULL)
-    return NULL;
-
   p = try_print_file_open (filename, filename);
   if (p != NULL)
     return p;
@@ -1156,21 +1227,7 @@ update_source_path (const char *filename)
     return NULL;
 
   /* Get the name of the file.  */
-  fname = strrchr (filename, '/');
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-  {
-    /* We could have a mixed forward/back slash case.  */
-    char *backslash = strrchr (filename, '\\');
-    if (fname == NULL || (backslash != NULL && backslash > fname))
-      fname = backslash;
-    if (fname == NULL && filename[0] != '\0' && filename[1] == ':')
-      fname = filename + 1;
-  }
-#endif
-  if (fname == NULL)
-    fname = filename;
-  else
-    ++fname;
+  fname = lbasename (filename);
 
   /* If file exists under a new path, we need to add it to the list
      so that show_line knows about it.  */
@@ -1299,7 +1356,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
       unsigned l;
 
       for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
-       if (strcmp ((*pp)->filename, filename) == 0)
+       if (filename_cmp ((*pp)->filename, filename) == 0)
          break;
       p = *pp;
 
@@ -1407,7 +1464,6 @@ disassemble_bytes (struct disassemble_info * inf,
   struct objdump_disasm_info *aux;
   asection *section;
   int octets_per_line;
-  bfd_boolean done_dot;
   int skip_addr_chars;
   bfd_vma addr_offset;
   unsigned int opb = inf->octets_per_byte;
@@ -1454,7 +1510,6 @@ disassemble_bytes (struct disassemble_info * inf,
 
   inf->insn_info_valid = 0;
 
-  done_dot = FALSE;
   addr_offset = start_offset;
   while (addr_offset < stop_offset)
     {
@@ -1466,6 +1521,9 @@ disassemble_bytes (struct disassemble_info * inf,
       previous_octets = octets;
       octets = 0;
 
+      /* Make sure we don't use relocs from previous instructions.  */
+      aux->reloc = NULL;
+
       /* If we see more than SKIP_ZEROES octets of zeroes, we just
         print `...'.  */
       for (z = addr_offset * opb; z < stop_offset * opb; z++)
@@ -1504,8 +1562,6 @@ disassemble_bytes (struct disassemble_info * inf,
          int bpc = 0;
          int pb = 0;
 
-         done_dot = FALSE;
-
          if (with_line_numbers || with_source_code)
            show_line (aux->abfd, section, addr_offset);
 
@@ -1569,8 +1625,6 @@ disassemble_bytes (struct disassemble_info * inf,
                      inf->flags |= INSN_HAS_RELOC;
                      aux->reloc = **relppp;
                    }
-                 else
-                   aux->reloc = NULL;
                }
 
              octets = (*disassemble_fn) (section->vma + addr_offset, inf);
@@ -1578,10 +1632,16 @@ disassemble_bytes (struct disassemble_info * inf,
              inf->stream = stdout;
              if (insn_width == 0 && inf->bytes_per_line != 0)
                octets_per_line = inf->bytes_per_line;
-             if (octets < 0)
+             if (octets < (int) opb)
                {
                  if (sfile.pos)
                    printf ("%s\n", sfile.buffer);
+                 if (octets >= 0)
+                   {
+                     non_fatal (_("disassemble_fn returned length %d"),
+                                octets);
+                     exit_status = 1;
+                   }
                  break;
                }
            }
@@ -1796,7 +1856,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   /* Sections that do not contain machine
      code are not normally disassembled.  */
   if (! disassemble_all
-      && only == NULL
+      && only_list == NULL
       && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
          != (SEC_CODE | SEC_HAS_CONTENTS)))
     return;
@@ -2059,7 +2119,7 @@ disassemble_data (bfd *abfd)
       const bfd_arch_info_type *inf = bfd_scan_arch (machine);
 
       if (inf == NULL)
-       fatal (_("Can't use supplied machine %s"), machine);
+       fatal (_("can't use supplied machine %s"), machine);
 
       abfd->arch_info = inf;
     }
@@ -2078,7 +2138,7 @@ disassemble_data (bfd *abfd)
   aux.disassemble_fn = disassembler (abfd);
   if (!aux.disassemble_fn)
     {
-      non_fatal (_("Can't disassemble for architecture %s\n"),
+      non_fatal (_("can't disassemble for architecture %s\n"),
                 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
       exit_status = 1;
       return;
@@ -2145,26 +2205,15 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   struct dwarf_section *section = &debug_displays [debug].section;
   bfd *abfd = (bfd *) file;
   bfd_boolean ret;
-  int section_is_compressed;
 
   /* If it is already loaded, do nothing.  */
   if (section->start != NULL)
     return 1;
 
-  section_is_compressed = section->name == section->compressed_name;
-
   section->address = 0;
   section->size = bfd_get_section_size (sec);
-  section->start = (unsigned char *) xmalloc (section->size);
-
-  if (is_relocatable && debug_displays [debug].relocate)
-    ret = bfd_simple_get_relocated_section_contents (abfd,
-                                                    sec,
-                                                    section->start,
-                                                    syms) != NULL;
-  else
-    ret = bfd_get_section_contents (abfd, sec, section->start, 0,
-                                   section->size);
+  section->start = NULL;
+  ret = bfd_get_full_section_contents (abfd, sec, &section->start);
 
   if (! ret)
     {
@@ -2174,16 +2223,28 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
       return 0;
     }
 
-  if (section_is_compressed)
+  if (is_relocatable && debug_displays [debug].relocate)
     {
-      bfd_size_type size = section->size;
-      if (! bfd_uncompress_section_contents (&section->start, &size))
+      /* We want to relocate the data we've already read (and
+         decompressed), so we store a pointer to the data in
+         the bfd_section, and tell it that the contents are
+         already in memory.  */
+      sec->contents = section->start;
+      sec->flags |= SEC_IN_MEMORY;
+      sec->size = section->size;
+
+      ret = bfd_simple_get_relocated_section_contents (abfd,
+                                                      sec,
+                                                      section->start,
+                                                      syms) != NULL;
+
+      if (! ret)
         {
           free_debug_section (debug);
-          printf (_("\nCan't uncompress section '%s'.\n"), section->name);
+          printf (_("\nCan't get contents for section '%s'.\n"),
+                 section->name);
           return 0;
         }
-      section->size = size;
     }
 
   return 1;
@@ -2274,9 +2335,7 @@ dump_dwarf (bfd *abfd)
 {
   is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
 
-  /* FIXME: bfd_get_arch_size may return -1.  We assume that 64bit
-     targets will return 64.  */
-  eh_addr_size = bfd_get_arch_size (abfd) == 64 ? 8 : 4;
+  eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
 
   if (bfd_big_endian (abfd))
     byte_get = byte_get_big_endian;
@@ -2285,10 +2344,24 @@ dump_dwarf (bfd *abfd)
   else
     abort ();
 
-  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+  switch (bfd_get_arch (abfd))
     {
-      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-      init_dwarf_regnames (bed->elf_machine_code);
+    case bfd_arch_i386:
+      switch (bfd_get_mach (abfd))
+       {
+       case bfd_mach_x86_64:
+       case bfd_mach_x86_64_intel_syntax:
+         init_dwarf_regnames_x86_64 ();
+         break;
+
+       default:
+         init_dwarf_regnames_i386 ();
+         break;
+       }
+      break;
+
+    default:
+      break;
     }
 
   bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
@@ -2318,11 +2391,11 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
 
   if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
     {
-      non_fatal (_("Reading %s section of %s failed: %s"),
+      non_fatal (_("reading %s section of %s failed: %s"),
                 sect_name, bfd_get_filename (abfd),
                 bfd_errmsg (bfd_get_error ()));
-      free (contents);
       exit_status = 1;
+      free (contents);
       return NULL;
     }
 
@@ -2496,7 +2569,7 @@ dump_bfd_header (bfd *abfd)
   printf (_("architecture: %s, "),
          bfd_printable_arch_mach (bfd_get_arch (abfd),
                                   bfd_get_mach (abfd)));
-  printf (_("flags 0x%08x:\n"), abfd->flags);
+  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=", ";}
   PF (HAS_RELOC, "HAS_RELOC");
@@ -2579,9 +2652,11 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
            (unsigned long) (section->filepos + start_offset));
   printf ("\n");
 
-  data = (bfd_byte *) xmalloc (datasize);
-
-  bfd_get_section_contents (abfd, section, data, 0, datasize);
+  if (!bfd_get_full_section_contents (abfd, section, &data))
+    {
+      non_fatal (_("Reading section failed"));
+      return;
+    }
 
   width = 4;
 
@@ -2762,6 +2837,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
       unsigned int linenumber;
       const char *sym_name;
       const char *section_name;
+      bfd_vma addend2 = 0;
 
       if (start_address != (bfd_vma) -1
          && q->address < start_address)
@@ -2789,7 +2865,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
              && (linenumber != last_line
                  || (filename != NULL
                      && last_filename != NULL
-                     && strcmp (filename, last_filename) != 0)))
+                     && filename_cmp (filename, last_filename) != 0)))
            {
              printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
              last_line = linenumber;
@@ -2817,7 +2893,37 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
       if (q->howto == NULL)
        printf (" *unknown*         ");
       else if (q->howto->name)
-       printf (" %-16s  ", q->howto->name);
+       {
+         const char *name = q->howto->name;
+
+         /* R_SPARC_OLO10 relocations contain two addends.
+            But because 'arelent' lacks enough storage to
+            store them both, the 64-bit ELF Sparc backend
+            records this as two relocations.  One R_SPARC_LO10
+            and one R_SPARC_13, both pointing to the same
+            address.  This is merely so that we have some
+            place to store both addend fields.
+
+            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
+             && relcount > 1
+             && !strcmp (q->howto->name, "R_SPARC_LO10"))
+           {
+             arelent *q2 = *(p + 1);
+             if (q2 != NULL
+                 && q2->howto
+                 && q->address == q2->address
+                 && !strcmp (q2->howto->name, "R_SPARC_13"))
+               {
+                 name = "R_SPARC_OLO10";
+                 addend2 = q2->addend;
+                 p++;
+               }
+           }
+         printf (" %-16s  ", name);
+       }
       else
        printf (" %-16d  ", q->howto->type);
 
@@ -2837,9 +2943,19 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
          printf ("+0x");
          bfd_printf_vma (abfd, q->addend);
        }
+      if (addend2)
+       {
+         printf ("+0x");
+         bfd_printf_vma (abfd, addend2);
+       }
 
       printf ("\n");
     }
+
+  if (last_filename != NULL)
+    free (last_filename);
+  if (last_functionname != NULL)
+    free (last_functionname);
 }
 
 static void
@@ -2971,7 +3087,7 @@ dump_bfd (bfd *abfd)
       bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
     }
 
-  if (! dump_debugging_tags)
+  if (! dump_debugging_tags && ! suppress_bfd_header)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
            abfd->xvec->name);
   if (dump_ar_hdrs)
@@ -2980,7 +3096,7 @@ dump_bfd (bfd *abfd)
     dump_bfd_header (abfd);
   if (dump_private_headers)
     dump_bfd_private_header (abfd);
-  if (! dump_debugging_tags)
+  if (! dump_debugging_tags && ! suppress_bfd_header)
     putchar ('\n');
   if (dump_section_headers)
     dump_headers (abfd);
@@ -3125,6 +3241,10 @@ display_file (char *filename, char *target)
       return;
     }
 
+  /* Decompress sections unless dumping the section contents.  */
+  if (!dump_section_contents)
+    file->flags |= BFD_DECOMPRESS;
+
   /* If the file is an archive, process all of its elements.  */
   if (bfd_check_format (file, bfd_archive))
     {
@@ -3207,12 +3327,7 @@ main (int argc, char **argv)
            disassembler_options = optarg;
          break;
        case 'j':
-         if (only_used == only_size)
-           {
-             only_size += 8;
-             only = (char **) xrealloc (only, only_size * sizeof (char *));
-           }
-         only [only_used++] = optarg;
+         add_only (optarg);
          break;
        case 'F':
          display_file_offsets = TRUE;
@@ -3277,7 +3392,7 @@ main (int argc, char **argv)
            endian = BFD_ENDIAN_LITTLE;
          else
            {
-             non_fatal (_("unrecognized -E option"));
+             nonfatal (_("unrecognized -E option"));
              usage (stderr, 1);
            }
          break;
@@ -3289,6 +3404,7 @@ main (int argc, char **argv)
          else
            {
              non_fatal (_("unrecognized --endian type `%s'"), optarg);
+             exit_status = 1;
              usage (stderr, 1);
            }
          break;
@@ -3368,6 +3484,19 @@ main (int argc, char **argv)
          else
            dwarf_select_sections_all ();
          break;
+       case OPTION_DWARF_DEPTH:
+         {
+           char *cp;
+           dwarf_cutoff_level = strtoul (optarg, & cp, 0);
+         }
+         break;
+       case OPTION_DWARF_START:
+         {
+           char *cp;
+           dwarf_start_die = strtoul (optarg, & cp, 0);
+           suppress_bfd_header = 1;
+         }
+         break;
        case 'G':
          dump_stab_section_info = TRUE;
          seenflag = TRUE;
@@ -3423,6 +3552,8 @@ main (int argc, char **argv)
          display_file (argv[optind++], target);
     }
 
+  free_only_list ();
+
   END_PROGRESS (program_name);
 
   return exit_status;
This page took 0.030914 seconds and 4 git commands to generate.