gdb/gdbserver/
[binutils-gdb.git] / binutils / objdump.c
index 0334d70dfe177b6d24c9bfecb0adfe46dbe0c946..f94dee968e27ce452351de71cd50d4fbfa081050 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
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -117,13 +117,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 +205,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\
+          =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\
@@ -326,17 +330,78 @@ 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,
@@ -1393,7 +1458,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;
@@ -1440,7 +1504,6 @@ disassemble_bytes (struct disassemble_info * inf,
 
   inf->insn_info_valid = 0;
 
-  done_dot = FALSE;
   addr_offset = start_offset;
   while (addr_offset < stop_offset)
     {
@@ -1452,6 +1515,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++)
@@ -1490,8 +1556,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);
 
@@ -1555,8 +1619,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);
@@ -1782,7 +1844,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;
@@ -2143,14 +2205,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   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);
+  ret = bfd_get_section_contents (abfd, sec, section->start, 0,
+                                 section->size);
 
   if (! ret)
     {
@@ -2172,6 +2228,30 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
       section->size = size;
     }
 
+  if (is_relocatable && debug_displays [debug].relocate)
+    {
+      /* 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 get contents for section '%s'.\n"),
+                 section->name);
+          return 0;
+        }
+    }
+
   return 1;
 }
 
@@ -3193,12 +3273,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;
@@ -3409,6 +3484,8 @@ main (int argc, char **argv)
          display_file (argv[optind++], target);
     }
 
+  free_only_list ();
+
   END_PROGRESS (program_name);
 
   return exit_status;