binutils objcopy test tidy
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 5f996e682d4236120e7ca954e472a70baf604e89..ba9cd7c5460a97dbd266ec8058d66ff287fcb346 100644 (file)
@@ -1,7 +1,5 @@
 /* objdump.c -- dump information about an object file.
 /* 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, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
 
    This file is part of GNU Binutils.
 
    relocations, debugging directives and more.
 
    The flow of execution is as follows:
    relocations, debugging directives and more.
 
    The flow of execution is as follows:
+
    1. Command line arguments are checked for control switches and the
       information to be displayed is selected.
    1. Command line arguments are checked for control switches and the
       information to be displayed is selected.
-      
+
    2. Any remaining arguments are assumed to be object files, and they are
       processed in order by display_bfd().  If the file is an archive each
       of its elements is processed in turn.
    2. Any remaining arguments are assumed to be object files, and they are
       processed in order by display_bfd().  If the file is an archive each
       of its elements is processed in turn.
-      
+
    3. The file's target architecture and binary file format are determined
       by bfd_check_format().  If they are recognised, then dump_bfd() is
       called.
    3. The file's target architecture and binary file format are determined
       by bfd_check_format().  If they are recognised, then dump_bfd() is
       called.
 #include "sysdep.h"
 #include "bfd.h"
 #include "elf-bfd.h"
 #include "sysdep.h"
 #include "bfd.h"
 #include "elf-bfd.h"
+#include "coff-bfd.h"
 #include "progress.h"
 #include "bucomm.h"
 #include "progress.h"
 #include "bucomm.h"
+#include "elfcomm.h"
 #include "dwarf.h"
 #include "getopt.h"
 #include "safe-ctype.h"
 #include "dwarf.h"
 #include "getopt.h"
 #include "safe-ctype.h"
 #include "filenames.h"
 #include "debug.h"
 #include "budbg.h"
 #include "filenames.h"
 #include "debug.h"
 #include "budbg.h"
+#include "objdump.h"
 
 #ifdef HAVE_MMAP
 #include <sys/mman.h>
 #endif
 
 
 #ifdef HAVE_MMAP
 #include <sys/mman.h>
 #endif
 
-#include <sys/stat.h>
-
 /* Internal headers for the ELF .stab-dump code - sorry.  */
 #define        BYTES_IN_WORD   32
 #include "aout/aout64.h"
 /* Internal headers for the ELF .stab-dump code - sorry.  */
 #define        BYTES_IN_WORD   32
 #include "aout/aout64.h"
@@ -92,6 +91,7 @@ static int dump_reloc_info;           /* -r */
 static int dump_dynamic_reloc_info;    /* -R */
 static int dump_ar_hdrs;               /* -a */
 static int dump_private_headers;       /* -p */
 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 prefix_addresses;           /* --prefix-addresses */
 static int with_line_numbers;          /* -l */
 static bfd_boolean with_source_code;   /* -S */
 static int prefix_addresses;           /* --prefix-addresses */
 static int with_line_numbers;          /* -l */
 static bfd_boolean with_source_code;   /* -S */
@@ -109,6 +109,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 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 */
 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 */
@@ -183,7 +184,15 @@ static char *strtab;
 static bfd_size_type stabstr_size;
 
 static bfd_boolean is_relocatable = FALSE;
 static bfd_size_type stabstr_size;
 
 static bfd_boolean is_relocatable = FALSE;
+
+/* Handlers for -P/--private.  */
+static const struct objdump_private_desc * const objdump_private_vectors[] =
+  {
+    OBJDUMP_PRIVATE_VECTORS
+    NULL
+  };
 \f
 \f
+static void usage (FILE *, int) ATTRIBUTE_NORETURN;
 static void
 usage (FILE *stream, int status)
 {
 static void
 usage (FILE *stream, int status)
 {
@@ -194,6 +203,7 @@ usage (FILE *stream, int status)
   -a, --archive-headers    Display archive header information\n\
   -f, --file-headers       Display the contents of the overall file header\n\
   -p, --private-headers    Display object format specific file header contents\n\
   -a, --archive-headers    Display archive header information\n\
   -f, --file-headers       Display the contents of the overall file header\n\
   -p, --private-headers    Display object format specific file header contents\n\
+  -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\
   -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\
@@ -206,7 +216,8 @@ usage (FILE *stream, int status)
   -W[lLiaprmfFsoRt] or\n\
   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
           =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
   -W[lLiaprmfFsoRt] or\n\
   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
           =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
-          =trace_info,=trace_abbrev,=trace_aranges]\n\
+          =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
+          =addr,=cu_index]\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\
                            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\
@@ -219,6 +230,8 @@ usage (FILE *stream, int status)
 "));
   if (status != 2)
     {
 "));
   if (status != 2)
     {
+      const struct objdump_private_desc * const *desc;
+
       fprintf (stream, _("\n The following switches are optional:\n"));
       fprintf (stream, _("\
   -b, --target=BFDNAME           Specify the target object format as BFDNAME\n\
       fprintf (stream, _("\n The following switches are optional:\n"));
       fprintf (stream, _("\
   -b, --target=BFDNAME           Specify the target object format as BFDNAME\n\
@@ -241,16 +254,29 @@ 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\
       --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\
       --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\
+      --dwarf-check          Make additional dwarf internal consistency checks.\
+      \n\n"));
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
       disassembler_usage (stream);
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
       disassembler_usage (stream);
+
+      if (objdump_private_vectors[0] != NULL)
+        {
+          fprintf (stream,
+                   _("\nOptions supported for -P/--private switch:\n"));
+          for (desc = objdump_private_vectors; *desc != NULL; desc++)
+            (*desc)->help (stream);
+        }
     }
   if (REPORT_BUGS_TO[0] && status == 0)
     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
     }
   if (REPORT_BUGS_TO[0] && status == 0)
     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
@@ -267,7 +293,10 @@ enum option_values
     OPTION_PREFIX,
     OPTION_PREFIX_STRIP,
     OPTION_INSN_WIDTH,
     OPTION_PREFIX,
     OPTION_PREFIX_STRIP,
     OPTION_INSN_WIDTH,
-    OPTION_ADJUST_VMA
+    OPTION_ADJUST_VMA,
+    OPTION_DWARF_DEPTH,
+    OPTION_DWARF_CHECK,
+    OPTION_DWARF_START
   };
 
 static struct option long_options[]=
   };
 
 static struct option long_options[]=
@@ -275,6 +304,7 @@ 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'},
   {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
   {"all-headers", no_argument, NULL, 'x'},
   {"private-headers", no_argument, NULL, 'p'},
+  {"private", required_argument, NULL, 'P'},
   {"architecture", required_argument, NULL, 'm'},
   {"archive-headers", no_argument, NULL, 'a'},
   {"debugging", no_argument, NULL, 'g'},
   {"architecture", required_argument, NULL, 'm'},
   {"archive-headers", no_argument, NULL, 'a'},
   {"debugging", no_argument, NULL, 'g'},
@@ -315,6 +345,9 @@ 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},
   {"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},
+  {"dwarf-check",      no_argument, 0, OPTION_DWARF_CHECK},
   {0, no_argument, 0, 0}
 };
 \f
   {0, no_argument, 0, 0}
 };
 \f
@@ -511,8 +544,6 @@ dump_headers (bfd *abfd)
 
   if (wide_output)
     printf (_("  Flags"));
 
   if (wide_output)
     printf (_("  Flags"));
-  if (abfd->flags & HAS_LOAD_PAGE)
-    printf (_("  Pg"));
   printf ("\n");
 
   bfd_map_over_sections (abfd, dump_section_header, NULL);
   printf ("\n");
 
   bfd_map_over_sections (abfd, dump_section_header, NULL);
@@ -532,7 +563,10 @@ slurp_symtab (bfd *abfd)
 
   storage = bfd_get_symtab_upper_bound (abfd);
   if (storage < 0)
 
   storage = bfd_get_symtab_upper_bound (abfd);
   if (storage < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      non_fatal (_("failed to read symbol table from: %s"), bfd_get_filename (abfd));
+      bfd_fatal (_("error message was"));
+    }
   if (storage)
     sy = (asymbol **) xmalloc (storage);
 
   if (storage)
     sy = (asymbol **) xmalloc (storage);
 
@@ -762,7 +796,8 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
                       asymbol *sym)
 {
   char *alloc;
                       asymbol *sym)
 {
   char *alloc;
-  const char *name;
+  const char *name, *version_string = NULL;
+  bfd_boolean hidden = FALSE;
 
   alloc = NULL;
   name = bfd_asymbol_name (sym);
 
   alloc = NULL;
   name = bfd_asymbol_name (sym);
@@ -774,10 +809,24 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
        name = alloc;
     }
 
        name = alloc;
     }
 
+  version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
+
+  if (bfd_is_und_section (bfd_get_section (sym)))
+    hidden = TRUE;
+
   if (inf != NULL)
   if (inf != NULL)
-    (*inf->fprintf_func) (inf->stream, "%s", name);
+    {
+      (*inf->fprintf_func) (inf->stream, "%s", name);
+      if (version_string && *version_string != '\0')
+       (*inf->fprintf_func) (inf->stream, hidden ? "@%s" : "@@%s",
+                             version_string);
+    }
   else
   else
-    printf ("%s", name);
+    {
+      printf ("%s", name);
+      if (version_string && *version_string != '\0')
+       printf (hidden ? "@%s" : "@@%s", version_string);
+    }
 
   if (alloc != NULL)
     free (alloc);
 
   if (alloc != NULL)
     free (alloc);
@@ -875,7 +924,7 @@ find_symbol_for_address (bfd_vma vma,
      sections have overlapping memory ranges, but in that case there's
      no way to tell what's desired without looking at the relocation
      table.
      sections have overlapping memory ranges, but in that case there's
      no way to tell what's desired without looking at the relocation
      table.
-     
+
      Also give the target a chance to reject symbols.  */
   want_section = (aux->require_sec
                  || ((abfd->flags & HAS_RELOC) != 0
      Also give the target a chance to reject symbols.  */
   want_section = (aux->require_sec
                  || ((abfd->flags & HAS_RELOC) != 0
@@ -1056,6 +1105,7 @@ objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * inf)
 
 static char *prev_functionname;
 static unsigned int prev_line;
 
 static char *prev_functionname;
 static unsigned int prev_line;
+static unsigned int prev_discriminator;
 
 /* We keep a list of all files that we have seen when doing a
    disassembly with source, so that we know how much of the file to
 
 /* We keep a list of all files that we have seen when doing a
    disassembly with source, so that we know how much of the file to
@@ -1066,9 +1116,9 @@ struct print_file_list
   struct print_file_list *next;
   const char *filename;
   const char *modname;
   struct print_file_list *next;
   const char *filename;
   const char *modname;
-  const char *map; 
+  const char *map;
   size_t mapsize;
   size_t mapsize;
-  const char **linemap; 
+  const char **linemap;
   unsigned maxline;
   unsigned last_line;
   int first;
   unsigned maxline;
   unsigned last_line;
   int first;
@@ -1097,63 +1147,66 @@ slurp_file (const char *fn, size_t *size)
   if (fd < 0)
     return NULL;
   if (fstat (fd, &st) < 0)
   if (fd < 0)
     return NULL;
   if (fstat (fd, &st) < 0)
-    return NULL;
+    {
+      close (fd);
+      return NULL;
+    }
   *size = st.st_size;
 #ifdef HAVE_MMAP
   msize = (*size + ps - 1) & ~(ps - 1);
   map = mmap (NULL, msize, PROT_READ, MAP_SHARED, fd, 0);
   *size = st.st_size;
 #ifdef HAVE_MMAP
   msize = (*size + ps - 1) & ~(ps - 1);
   map = mmap (NULL, msize, PROT_READ, MAP_SHARED, fd, 0);
-  if (map != (char *)-1L)
+  if (map != (char *) -1L)
     {
     {
-      close(fd);
-      return map; 
+      close (fd);
+      return map;
     }
 #endif
   map = (const char *) malloc (*size);
     }
 #endif
   map = (const char *) malloc (*size);
-  if (!map || (size_t) read (fd, (char *)map, *size) != *size) 
-    { 
-      free ((void *)map);
+  if (!map || (size_t) read (fd, (char *) map, *size) != *size)
+    {
+      free ((void *) map);
       map = NULL;
     }
   close (fd);
       map = NULL;
     }
   close (fd);
-  return map; 
+  return map;
 }
 
 #define line_map_decrease 5
 
 /* Precompute array of lines for a mapped file. */
 
 }
 
 #define line_map_decrease 5
 
 /* Precompute array of lines for a mapped file. */
 
-static const char ** 
-index_file (const char *map, size_t size, unsigned int *maxline) 
+static const char **
+index_file (const char *map, size_t size, unsigned int *maxline)
 {
   const char *p, *lstart, *end;
   int chars_per_line = 45; /* First iteration will use 40.  */
   unsigned int lineno;
 {
   const char *p, *lstart, *end;
   int chars_per_line = 45; /* First iteration will use 40.  */
   unsigned int lineno;
-  const char **linemap = NULL; 
+  const char **linemap = NULL;
   unsigned long line_map_size = 0;
   unsigned long line_map_size = 0;
+
   lineno = 0;
   lstart = map;
   end = map + size;
 
   lineno = 0;
   lstart = map;
   end = map + size;
 
-  for (p = map; p < end; p++) 
-    { 
-      if (*p == '\n') 
-       { 
-         if (p + 1 < end && p[1] == '\r') 
-           p++;  
-       } 
-      else if (*p == '\r') 
-       { 
+  for (p = map; p < end; p++)
+    {
+      if (*p == '\n')
+       {
+         if (p + 1 < end && p[1] == '\r')
+           p++;
+       }
+      else if (*p == '\r')
+       {
          if (p + 1 < end && p[1] == '\n')
            p++;
        }
       else
        continue;
          if (p + 1 < end && p[1] == '\n')
            p++;
        }
       else
        continue;
-      
+
       /* End of line found.  */
 
       /* End of line found.  */
 
-      if (linemap == NULL || line_map_size < lineno + 1) 
-       { 
+      if (linemap == NULL || line_map_size < lineno + 1)
+       {
          unsigned long newsize;
 
          chars_per_line -= line_map_decrease;
          unsigned long newsize;
 
          chars_per_line -= line_map_decrease;
@@ -1166,11 +1219,11 @@ index_file (const char *map, size_t size, unsigned int *maxline)
          linemap = (const char **) xrealloc (linemap, newsize);
        }
 
          linemap = (const char **) xrealloc (linemap, newsize);
        }
 
-      linemap[lineno++] = lstart; 
-      lstart = p + 1; 
+      linemap[lineno++] = lstart;
+      lstart = p + 1;
     }
     }
-  
-  *maxline = lineno; 
+
+  *maxline = lineno;
   return linemap;
 }
 
   return linemap;
 }
 
@@ -1190,7 +1243,7 @@ try_print_file_open (const char *origname, const char *modname)
       free (p);
       return NULL;
     }
       free (p);
       return NULL;
     }
-  
+
   p->linemap = index_file (p->map, p->mapsize, &p->maxline);
   p->last_line = 0;
   p->filename = origname;
   p->linemap = index_file (p->map, p->mapsize, &p->maxline);
   p->last_line = 0;
   p->filename = origname;
@@ -1201,7 +1254,7 @@ try_print_file_open (const char *origname, const char *modname)
   return p;
 }
 
   return p;
 }
 
-/* If the the source file, as described in the symtab, is not found
+/* If the source file, as described in the symtab, is not found
    try to locate it in one of the paths specified with -I
    If found, add location to print_files linked list.  */
 
    try to locate it in one of the paths specified with -I
    If found, add location to print_files linked list.  */
 
@@ -1240,13 +1293,13 @@ update_source_path (const char *filename)
 
 /* Print a source file line.  */
 
 
 /* Print a source file line.  */
 
-static void 
+static void
 print_line (struct print_file_list *p, unsigned int linenum)
 {
   const char *l;
   size_t len;
 print_line (struct print_file_list *p, unsigned int linenum)
 {
   const char *l;
   size_t len;
-  --linenum; 
+
+  --linenum;
   if (linenum >= p->maxline)
     return;
   l = p->linemap [linenum];
   if (linenum >= p->maxline)
     return;
   l = p->linemap [linenum];
@@ -1263,7 +1316,7 @@ dump_lines (struct print_file_list *p, unsigned int start, unsigned int end)
 {
   if (p->map == NULL)
     return;
 {
   if (p->map == NULL)
     return;
-  while (start <= end) 
+  while (start <= end)
     {
       print_line (p, start);
       start++;
     {
       print_line (p, start);
       start++;
@@ -1279,13 +1332,15 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
   const char *filename;
   const char *functionname;
   unsigned int linenumber;
   const char *filename;
   const char *functionname;
   unsigned int linenumber;
+  unsigned int discriminator;
   bfd_boolean reloc;
 
   if (! with_line_numbers && ! with_source_code)
     return;
 
   bfd_boolean reloc;
 
   if (! with_line_numbers && ! with_source_code)
     return;
 
-  if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
-                              &functionname, &linenumber))
+  if (! bfd_find_nearest_line_discriminator (abfd, section, syms, addr_offset,
+                                             &filename, &functionname,
+                                             &linenumber, &discriminator))
     return;
 
   if (filename != NULL && *filename == '\0')
     return;
 
   if (filename != NULL && *filename == '\0')
@@ -1337,8 +1392,15 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
          && (prev_functionname == NULL
              || strcmp (functionname, prev_functionname) != 0))
        printf ("%s():\n", functionname);
          && (prev_functionname == NULL
              || strcmp (functionname, prev_functionname) != 0))
        printf ("%s():\n", functionname);
-      if (linenumber > 0 && linenumber != prev_line)
-       printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
+      if (linenumber > 0 && (linenumber != prev_line ||
+                             (discriminator != prev_discriminator)))
+        {
+          if (discriminator > 0)
+            printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
+                    linenumber, discriminator);
+          else
+            printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
+        }
     }
 
   if (with_source_code
     }
 
   if (with_source_code
@@ -1349,7 +1411,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
       unsigned l;
 
       for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
       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;
 
          break;
       p = *pp;
 
@@ -1362,12 +1424,12 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
 
       if (p != NULL && linenumber != p->last_line)
        {
 
       if (p != NULL && linenumber != p->last_line)
        {
-         if (file_start_context && p->first) 
+         if (file_start_context && p->first)
            l = 1;
            l = 1;
-         else 
+         else
            {
              l = linenumber - SHOW_PRECEDING_CONTEXT_LINES;
            {
              l = linenumber - SHOW_PRECEDING_CONTEXT_LINES;
-             if (l >= linenumber) 
+             if (l >= linenumber)
                l = 1;
              if (p->last_line >= l && p->last_line <= linenumber)
                l = p->last_line + 1;
                l = 1;
              if (p->last_line >= l && p->last_line <= linenumber)
                l = p->last_line + 1;
@@ -1390,6 +1452,9 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
 
   if (linenumber > 0 && linenumber != prev_line)
     prev_line = linenumber;
 
   if (linenumber > 0 && linenumber != prev_line)
     prev_line = linenumber;
+
+  if (discriminator != prev_discriminator)
+    prev_discriminator = discriminator;
 }
 
 /* Pseudo FILE object for strings.  */
 }
 
 /* Pseudo FILE object for strings.  */
@@ -1411,19 +1476,19 @@ objdump_sprintf (SFILE *f, const char *format, ...)
   while (1)
     {
       size_t space = f->alloc - f->pos;
   while (1)
     {
       size_t space = f->alloc - f->pos;
-  
+
       va_start (args, format);
       n = vsnprintf (f->buffer + f->pos, space, format, args);
       va_end (args);
 
       if (space > n)
        break;
       va_start (args, format);
       n = vsnprintf (f->buffer + f->pos, space, format, args);
       va_end (args);
 
       if (space > n)
        break;
-      
+
       f->alloc = (f->alloc + n) * 2;
       f->buffer = (char *) xrealloc (f->buffer, f->alloc);
     }
   f->pos += n;
       f->alloc = (f->alloc + n) * 2;
       f->buffer = (char *) xrealloc (f->buffer, f->alloc);
     }
   f->pos += n;
-  
+
   return n;
 }
 
   return n;
 }
 
@@ -1471,7 +1536,7 @@ disassemble_bytes (struct disassemble_info * inf,
   sfile.alloc = 120;
   sfile.buffer = (char *) xmalloc (sfile.alloc);
   sfile.pos = 0;
   sfile.alloc = 120;
   sfile.buffer = (char *) xmalloc (sfile.alloc);
   sfile.pos = 0;
-  
+
   if (insn_width)
     octets_per_line = insn_width;
   else if (insns)
   if (insn_width)
     octets_per_line = insn_width;
   else if (insns)
@@ -1620,7 +1685,18 @@ disassemble_bytes (struct disassemble_info * inf,
                    }
                }
 
                    }
                }
 
+             if (! disassemble_all
+                 && (section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
+                 == (SEC_CODE | SEC_HAS_CONTENTS))
+               /* Set a stop_vma so that the disassembler will not read
+                  beyond the next symbol.  We assume that symbols appear on
+                  the boundaries between instructions.  We only do this when
+                  disassembling code of course, and when -D is in effect.  */
+               inf->stop_vma = section->vma + stop_offset;
+
              octets = (*disassemble_fn) (section->vma + addr_offset, inf);
              octets = (*disassemble_fn) (section->vma + addr_offset, inf);
+
+             inf->stop_vma = 0;
              inf->fprintf_func = (fprintf_ftype) fprintf;
              inf->stream = stdout;
              if (insn_width == 0 && inf->bytes_per_line != 0)
              inf->fprintf_func = (fprintf_ftype) fprintf;
              inf->stream = stdout;
              if (insn_width == 0 && inf->bytes_per_line != 0)
@@ -1807,8 +1883,15 @@ disassemble_bytes (struct disassemble_info * inf,
 
              if (q->addend)
                {
 
              if (q->addend)
                {
-                 printf ("+0x");
-                 objdump_print_value (q->addend, inf, TRUE);
+                 bfd_signed_vma addend = q->addend;
+                 if (addend < 0)
+                   {
+                     printf ("-0x");
+                     addend = -addend;
+                   }
+                 else
+                   printf ("+0x");
+                 objdump_print_value (addend, inf, TRUE);
                }
 
              printf ("\n");
                }
 
              printf ("\n");
@@ -1839,7 +1922,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   arelent **                   rel_pp = NULL;
   arelent **                   rel_ppstart = NULL;
   arelent **                   rel_ppend;
   arelent **                   rel_pp = NULL;
   arelent **                   rel_ppstart = NULL;
   arelent **                   rel_ppend;
-  unsigned long                stop_offset;
+  bfd_vma                      stop_offset;
   asymbol *                    sym = NULL;
   long                         place = 0;
   long                         rel_count;
   asymbol *                    sym = NULL;
   long                         place = 0;
   long                         rel_count;
@@ -1861,6 +1944,27 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   if (datasize == 0)
     return;
 
   if (datasize == 0)
     return;
 
+  if (start_address == (bfd_vma) -1
+      || start_address < section->vma)
+    addr_offset = 0;
+  else
+    addr_offset = start_address - section->vma;
+
+  if (stop_address == (bfd_vma) -1)
+    stop_offset = datasize / opb;
+  else
+    {
+      if (stop_address < section->vma)
+       stop_offset = 0;
+      else
+       stop_offset = stop_address - section->vma;
+      if (stop_offset > datasize / opb)
+       stop_offset = datasize / opb;
+    }
+
+  if (addr_offset >= stop_offset)
+    return;
+
   /* Decide which set of relocs to use.  Load them if necessary.  */
   paux = (struct objdump_disasm_info *) pinfo->application_data;
   if (paux->dynrelbuf)
   /* Decide which set of relocs to use.  Load them if necessary.  */
   paux = (struct objdump_disasm_info *) pinfo->application_data;
   if (paux->dynrelbuf)
@@ -1911,32 +2015,13 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   pinfo->buffer_length = datasize;
   pinfo->section = section;
 
   pinfo->buffer_length = datasize;
   pinfo->section = section;
 
-  if (start_address == (bfd_vma) -1
-      || start_address < pinfo->buffer_vma)
-    addr_offset = 0;
-  else
-    addr_offset = start_address - pinfo->buffer_vma;
-
-  if (stop_address == (bfd_vma) -1)
-    stop_offset = datasize / opb;
-  else
-    {
-      if (stop_address < pinfo->buffer_vma)
-       stop_offset = 0;
-      else
-       stop_offset = stop_address - pinfo->buffer_vma;
-      if (stop_offset > pinfo->buffer_length / opb)
-       stop_offset = pinfo->buffer_length / opb;
-    }
-
   /* Skip over the relocs belonging to addresses below the
      start address.  */
   while (rel_pp < rel_ppend
         && (*rel_pp)->address < rel_offset + addr_offset)
     ++rel_pp;
 
   /* Skip over the relocs belonging to addresses below the
      start address.  */
   while (rel_pp < rel_ppend
         && (*rel_pp)->address < rel_offset + addr_offset)
     ++rel_pp;
 
-  if (addr_offset < stop_offset)
-    printf (_("\nDisassembly of section %s:\n"), section->name);
+  printf (_("\nDisassembly of section %s:\n"), section->name);
 
   /* Find the nearest symbol forwards from our current position.  */
   paux->require_sec = TRUE;
 
   /* Find the nearest symbol forwards from our current position.  */
   paux->require_sec = TRUE;
@@ -1961,7 +2046,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
     {
       bfd_vma addr;
       asymbol *nextsym;
     {
       bfd_vma addr;
       asymbol *nextsym;
-      unsigned long nextstop_offset;
+      bfd_vma nextstop_offset;
       bfd_boolean insns;
 
       addr = section->vma + addr_offset;
       bfd_boolean insns;
 
       addr = section->vma + addr_offset;
@@ -2006,7 +2091,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   ((SYM)->section == section \
    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
    && pinfo->symbol_is_valid (SYM, pinfo))
   ((SYM)->section == section \
    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
    && pinfo->symbol_is_valid (SYM, pinfo))
-           
+
          /* Search forward for the next appropriate symbol in
             SECTION.  Note that all the symbols are sorted
             together into one big array, and that some sections
          /* Search forward for the next appropriate symbol in
             SECTION.  Note that all the symbols are sorted
             together into one big array, and that some sections
@@ -2052,7 +2137,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
                         addr_offset, nextstop_offset,
                         rel_offset, &rel_pp, rel_ppend);
       disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
                         addr_offset, nextstop_offset,
                         rel_offset, &rel_pp, rel_ppend);
-      
+
       addr_offset = nextstop_offset;
       sym = nextsym;
     }
       addr_offset = nextstop_offset;
       sym = nextsym;
     }
@@ -2075,6 +2160,7 @@ disassemble_data (bfd *abfd)
   print_files = NULL;
   prev_functionname = NULL;
   prev_line = -1;
   print_files = NULL;
   prev_functionname = NULL;
   prev_line = -1;
+  prev_discriminator = 0;
 
   /* We make a copy of syms to sort.  We don't want to sort syms
      because that will screw up the relocs.  */
 
   /* We make a copy of syms to sort.  We don't want to sort syms
      because that will screw up the relocs.  */
@@ -2163,7 +2249,7 @@ disassemble_data (bfd *abfd)
   if (dump_dynamic_reloc_info)
     {
       long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
   if (dump_dynamic_reloc_info)
     {
       long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
-  
+
       if (relsize < 0)
        bfd_fatal (bfd_get_filename (abfd));
 
       if (relsize < 0)
        bfd_fatal (bfd_get_filename (abfd));
 
@@ -2203,9 +2289,12 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   if (section->start != NULL)
     return 1;
 
   if (section->start != NULL)
     return 1;
 
-  section->address = 0;
+  section->reloc_info = NULL;
+  section->num_relocs = 0;
+  section->address = bfd_get_section_vma (abfd, sec);
   section->size = bfd_get_section_size (sec);
   section->start = NULL;
   section->size = bfd_get_section_size (sec);
   section->start = NULL;
+  section->user_data = sec;
   ret = bfd_get_full_section_contents (abfd, sec, &section->start);
 
   if (! ret)
   ret = bfd_get_full_section_contents (abfd, sec, &section->start);
 
   if (! ret)
@@ -2218,13 +2307,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
 
   if (is_relocatable && debug_displays [debug].relocate)
     {
 
   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;
+      bfd_cache_section_contents (sec, section->start);
 
       ret = bfd_simple_get_relocated_section_contents (abfd,
                                                       sec,
 
       ret = bfd_simple_get_relocated_section_contents (abfd,
                                                       sec,
@@ -2238,11 +2321,49 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
                  section->name);
           return 0;
         }
                  section->name);
           return 0;
         }
+
+      long reloc_size;
+
+      reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
+      if (reloc_size > 0)
+       {
+         unsigned long reloc_count;
+         arelent **relocs;
+
+         relocs = (arelent **) xmalloc (reloc_size);
+
+         reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, NULL);
+         if (reloc_count == 0)
+           free (relocs);
+         else
+           {
+             section->reloc_info = relocs;
+             section->num_relocs = reloc_count;
+           }
+       }
     }
 
   return 1;
 }
 
     }
 
   return 1;
 }
 
+bfd_boolean
+reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
+{
+  arelent ** relocs;
+  arelent * rp;
+
+  if (dsec == NULL || dsec->reloc_info == NULL)
+    return FALSE;
+
+  relocs = (arelent **) dsec->reloc_info;
+
+  for (; (rp = * relocs) != NULL; ++ relocs)
+    if (rp->address == offset)
+      return TRUE;
+
+  return FALSE;
+}
+
 int
 load_debug_section (enum dwarf_section_display_enum debug, void *file)
 {
 int
 load_debug_section (enum dwarf_section_display_enum debug, void *file)
 {
@@ -2278,6 +2399,23 @@ free_debug_section (enum dwarf_section_display_enum debug)
   if (section->start == NULL)
     return;
 
   if (section->start == NULL)
     return;
 
+  /* PR 17512: file: 0f67f69d.  */
+  if (section->user_data != NULL)
+    {
+      asection * sec = (asection *) section->user_data;
+
+      /* If we are freeing contents that are also pointed to by the BFD
+        library's section structure then make sure to update those pointers
+        too.  Otherwise, the next time we try to load data for this section
+        we can end up using a stale pointer.  */
+      if (section->start == sec->contents)
+       {
+         sec->contents = NULL;
+         sec->flags &= ~ SEC_IN_MEMORY;
+         sec->compress_status = COMPRESS_SECTION_NONE;
+       }
+    }
+
   free ((char *) section->start);
   section->start = NULL;
   section->address = 0;
   free ((char *) section->start);
   section->start = NULL;
   section->address = 0;
@@ -2313,7 +2451,7 @@ dump_dwarf_section (bfd *abfd, asection *section,
                                          section, abfd))
          {
            debug_displays [i].display (sec, abfd);
                                          section, abfd))
          {
            debug_displays [i].display (sec, abfd);
-           
+
            if (i != info && i != abbrev)
              free_debug_section ((enum dwarf_section_display_enum) i);
          }
            if (i != info && i != abbrev)
              free_debug_section ((enum dwarf_section_display_enum) i);
          }
@@ -2335,7 +2473,12 @@ dump_dwarf (bfd *abfd)
   else if (bfd_little_endian (abfd))
     byte_get = byte_get_little_endian;
   else
   else if (bfd_little_endian (abfd))
     byte_get = byte_get_little_endian;
   else
-    abort ();
+    /* PR 17512: file: objdump-s-endless-loop.tekhex.  */
+    {
+      warn (_("File %s does not contain any dwarf debug information\n"),
+           bfd_get_filename (abfd));
+      return;
+    }
 
   switch (bfd_get_arch (abfd))
     {
 
   switch (bfd_get_arch (abfd))
     {
@@ -2344,6 +2487,10 @@ dump_dwarf (bfd *abfd)
        {
        case bfd_mach_x86_64:
        case bfd_mach_x86_64_intel_syntax:
        {
        case bfd_mach_x86_64:
        case bfd_mach_x86_64_intel_syntax:
+       case bfd_mach_x86_64_nacl:
+       case bfd_mach_x64_32:
+       case bfd_mach_x64_32_intel_syntax:
+       case bfd_mach_x64_32_nacl:
          init_dwarf_regnames_x86_64 ();
          break;
 
          init_dwarf_regnames_x86_64 ();
          break;
 
@@ -2353,6 +2500,14 @@ dump_dwarf (bfd *abfd)
        }
       break;
 
        }
       break;
 
+    case bfd_arch_iamcu:
+      init_dwarf_regnames_iamcu ();
+      break;
+
+    case bfd_arch_aarch64:
+      init_dwarf_regnames_aarch64();
+      break;
+
     default:
       break;
     }
     default:
       break;
     }
@@ -2435,7 +2590,7 @@ print_section_stabs (bfd *abfd,
 
      We start the index at -1 because there is a dummy symbol on
      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
 
      We start the index at -1 because there is a dummy symbol on
      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
-  for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
+  for (i = -1; stabp <= stabs_end - STABSIZE; stabp += STABSIZE, i++)
     {
       const char *name;
       unsigned long strx;
     {
       const char *name;
       unsigned long strx;
@@ -2473,10 +2628,13 @@ print_section_stabs (bfd *abfd,
        }
       else
        {
        }
       else
        {
+         bfd_size_type amt = strx + file_string_table_offset;
+
          /* Using the (possibly updated) string table offset, print the
             string (if any) associated with this symbol.  */
          /* Using the (possibly updated) string table offset, print the
             string (if any) associated with this symbol.  */
-         if ((strx + file_string_table_offset) < stabstr_size)
-           printf (" %s", &strtab[strx + file_string_table_offset]);
+         if (amt < stabstr_size)
+           /* PR 17512: file: 079-79389-0.001:0.1.  */
+           printf (" %.*s", (int)(stabstr_size - amt), strtab + amt);
          else
            printf (" *");
        }
          else
            printf (" *");
        }
@@ -2513,7 +2671,7 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
       if (strtab == NULL)
        strtab = read_section_stabs (abfd, sought->string_section_name,
                                     &stabstr_size);
       if (strtab == NULL)
        strtab = read_section_stabs (abfd, sought->string_section_name,
                                     &stabstr_size);
-      
+
       if (strtab)
        {
          stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
       if (strtab)
        {
          stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
@@ -2562,7 +2720,7 @@ dump_bfd_header (bfd *abfd)
   printf (_("architecture: %s, "),
          bfd_printable_arch_mach (bfd_get_arch (abfd),
                                   bfd_get_mach (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");
 
 #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
   PF (HAS_RELOC, "HAS_RELOC");
@@ -2575,7 +2733,6 @@ dump_bfd_header (bfd *abfd)
   PF (WP_TEXT, "WP_TEXT");
   PF (D_PAGED, "D_PAGED");
   PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
   PF (WP_TEXT, "WP_TEXT");
   PF (D_PAGED, "D_PAGED");
   PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
-  PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE");
   printf (_("\nstart address 0x"));
   bfd_printf_vma (abfd, abfd->start_address);
   printf ("\n");
   printf (_("\nstart address 0x"));
   bfd_printf_vma (abfd, abfd->start_address);
   printf ("\n");
@@ -2588,6 +2745,57 @@ dump_bfd_private_header (bfd *abfd)
   bfd_print_private_bfd_data (abfd, stdout);
 }
 
   bfd_print_private_bfd_data (abfd, stdout);
 }
 
+static void
+dump_target_specific (bfd *abfd)
+{
+  const struct objdump_private_desc * const *desc;
+  struct objdump_private_option *opt;
+  char *e, *b;
+
+  /* Find the desc.  */
+  for (desc = objdump_private_vectors; *desc != NULL; desc++)
+    if ((*desc)->filter (abfd))
+      break;
+
+  if (*desc == NULL)
+    {
+      non_fatal (_("option -P/--private not supported by this file"));
+      return;
+    }
+
+  /* Clear all options.  */
+  for (opt = (*desc)->options; opt->name; opt++)
+    opt->selected = FALSE;
+
+  /* Decode options.  */
+  b = dump_private_options;
+  do
+    {
+      e = strchr (b, ',');
+
+      if (e)
+        *e = 0;
+
+      for (opt = (*desc)->options; opt->name; opt++)
+        if (strcmp (opt->name, b) == 0)
+          {
+            opt->selected = TRUE;
+            break;
+          }
+      if (opt->name == NULL)
+        non_fatal (_("target specific dump '%s' not supported"), b);
+
+      if (e)
+        {
+          *e = ',';
+          b = e + 1;
+        }
+    }
+  while (e != NULL);
+
+  /* Dump.  */
+  (*desc)->dump (abfd);
+}
 \f
 /* Display a section in hexadecimal format with associated characters.
    Each line prefixed by the zero padded address.  */
 \f
 /* Display a section in hexadecimal format with associated characters.
    Each line prefixed by the zero padded address.  */
@@ -2597,9 +2805,9 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
 {
   bfd_byte *data = 0;
   bfd_size_type datasize;
 {
   bfd_byte *data = 0;
   bfd_size_type datasize;
-  bfd_size_type addr_offset;
-  bfd_size_type start_offset;
-  bfd_size_type stop_offset;
+  bfd_vma addr_offset;
+  bfd_vma start_offset;
+  bfd_vma stop_offset;
   unsigned int opb = bfd_octets_per_byte (abfd);
   /* Bytes per line.  */
   const int onaline = 16;
   unsigned int opb = bfd_octets_per_byte (abfd);
   /* Bytes per line.  */
   const int onaline = 16;
@@ -2612,7 +2820,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
 
   if (! process_section_p (section))
     return;
 
   if (! process_section_p (section))
     return;
-  
+
   if ((datasize = bfd_section_size (abfd, section)) == 0)
     return;
 
   if ((datasize = bfd_section_size (abfd, section)) == 0)
     return;
 
@@ -2638,7 +2846,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
 
   if (start_offset >= stop_offset)
     return;
 
   if (start_offset >= stop_offset)
     return;
-  
+
   printf (_("Contents of section %s:"), section->name);
   if (display_file_offsets)
     printf (_("  (Starting at file offset: 0x%lx)"),
   printf (_("Contents of section %s:"), section->name);
   if (display_file_offsets)
     printf (_("  (Starting at file offset: 0x%lx)"),
@@ -2647,7 +2855,8 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
 
   if (!bfd_get_full_section_contents (abfd, section, &data))
     {
 
   if (!bfd_get_full_section_contents (abfd, section, &data))
     {
-      non_fatal (_("Reading section failed"));
+      non_fatal (_("Reading section %s failed because: %s"),
+                section->name, bfd_errmsg (bfd_get_error ()));
       return;
     }
 
       return;
     }
 
@@ -2804,6 +3013,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
   arelent **p;
   char *last_filename, *last_functionname;
   unsigned int last_line;
   arelent **p;
   char *last_filename, *last_functionname;
   unsigned int last_line;
+  unsigned int last_discriminator;
 
   /* Get column headers lined up reasonably.  */
   {
 
   /* Get column headers lined up reasonably.  */
   {
@@ -2822,14 +3032,17 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
   last_filename = NULL;
   last_functionname = NULL;
   last_line = 0;
   last_filename = NULL;
   last_functionname = NULL;
   last_line = 0;
+  last_discriminator = 0;
 
   for (p = relpp; relcount && *p != NULL; p++, relcount--)
     {
       arelent *q = *p;
       const char *filename, *functionname;
       unsigned int linenumber;
 
   for (p = relpp; relcount && *p != NULL; p++, relcount--)
     {
       arelent *q = *p;
       const char *filename, *functionname;
       unsigned int linenumber;
+      unsigned int discriminator;
       const char *sym_name;
       const char *section_name;
       const char *sym_name;
       const char *section_name;
+      bfd_vma addend2 = 0;
 
       if (start_address != (bfd_vma) -1
          && q->address < start_address)
 
       if (start_address != (bfd_vma) -1
          && q->address < start_address)
@@ -2840,8 +3053,9 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
 
       if (with_line_numbers
          && sec != NULL
 
       if (with_line_numbers
          && sec != NULL
-         && bfd_find_nearest_line (abfd, sec, syms, q->address,
-                                   &filename, &functionname, &linenumber))
+         && bfd_find_nearest_line_discriminator (abfd, sec, syms, q->address,
+                                                  &filename, &functionname,
+                                                  &linenumber, &discriminator))
        {
          if (functionname != NULL
              && (last_functionname == NULL
        {
          if (functionname != NULL
              && (last_functionname == NULL
@@ -2857,10 +3071,16 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
              && (linenumber != last_line
                  || (filename != NULL
                      && last_filename != NULL
              && (linenumber != last_line
                  || (filename != NULL
                      && last_filename != NULL
-                     && strcmp (filename, last_filename) != 0)))
+                     && filename_cmp (filename, last_filename) != 0)
+                  || (discriminator != last_discriminator)))
            {
            {
-             printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
+              if (discriminator > 0)
+                printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
+              else
+                printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
+                        linenumber, discriminator);
              last_line = linenumber;
              last_line = linenumber;
+             last_discriminator = discriminator;
              if (last_filename != NULL)
                free (last_filename);
              if (filename == NULL)
              if (last_filename != NULL)
                free (last_filename);
              if (filename == NULL)
@@ -2885,7 +3105,37 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
       if (q->howto == NULL)
        printf (" *unknown*         ");
       else if (q->howto->name)
       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);
 
       else
        printf (" %-16d  ", q->howto->type);
 
@@ -2901,13 +3151,30 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
        }
 
       if (q->addend)
        }
 
       if (q->addend)
+       {
+         bfd_signed_vma addend = q->addend;
+         if (addend < 0)
+           {
+             printf ("-0x");
+             addend = -addend;
+           }
+         else
+           printf ("+0x");
+         bfd_printf_vma (abfd, addend);
+       }
+      if (addend2)
        {
          printf ("+0x");
        {
          printf ("+0x");
-         bfd_printf_vma (abfd, q->addend);
+         bfd_printf_vma (abfd, addend2);
        }
 
       printf ("\n");
     }
        }
 
       printf ("\n");
     }
+
+  if (last_filename != NULL)
+    free (last_filename);
+  if (last_functionname != NULL)
+    free (last_functionname);
 }
 
 static void
 }
 
 static void
@@ -2942,7 +3209,11 @@ dump_relocs_in_section (bfd *abfd,
   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
 
   if (relcount < 0)
   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
 
   if (relcount < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      printf ("\n");
+      non_fatal (_("failed to read relocs in: %s"), bfd_get_filename (abfd));
+      bfd_fatal (_("error message was"));
+    }
   else if (relcount == 0)
     printf (" (none)\n\n");
   else
   else if (relcount == 0)
     printf (" (none)\n\n");
   else
@@ -3039,7 +3310,7 @@ dump_bfd (bfd *abfd)
       bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
     }
 
       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)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
            abfd->xvec->name);
   if (dump_ar_hdrs)
@@ -3048,10 +3319,10 @@ dump_bfd (bfd *abfd)
     dump_bfd_header (abfd);
   if (dump_private_headers)
     dump_bfd_private_header (abfd);
     dump_bfd_header (abfd);
   if (dump_private_headers)
     dump_bfd_private_header (abfd);
-  if (! dump_debugging_tags)
+  if (dump_private_options != NULL)
+    dump_target_specific (abfd);
+  if (! dump_debugging_tags && ! suppress_bfd_header)
     putchar ('\n');
     putchar ('\n');
-  if (dump_section_headers)
-    dump_headers (abfd);
 
   if (dump_symtab
       || dump_reloc_info
 
   if (dump_symtab
       || dump_reloc_info
@@ -3059,6 +3330,10 @@ dump_bfd (bfd *abfd)
       || dump_debugging
       || dump_dwarf_section_info)
     syms = slurp_symtab (abfd);
       || dump_debugging
       || dump_dwarf_section_info)
     syms = slurp_symtab (abfd);
+
+  if (dump_section_headers)
+    dump_headers (abfd);
+
   if (dump_dynamic_symtab || dump_dynamic_reloc_info
       || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
     dynsyms = slurp_dynamic_symtab (abfd);
   if (dump_dynamic_symtab || dump_dynamic_reloc_info
       || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
     dynsyms = slurp_dynamic_symtab (abfd);
@@ -3107,6 +3382,7 @@ dump_bfd (bfd *abfd)
         info in the file, try DWARF instead.  */
       else if (! dump_dwarf_section_info)
        {
         info in the file, try DWARF instead.  */
       else if (! dump_dwarf_section_info)
        {
+         dwarf_select_sections_all ();
          dump_dwarf (abfd);
        }
     }
          dump_dwarf (abfd);
        }
     }
@@ -3135,7 +3411,7 @@ dump_bfd (bfd *abfd)
 }
 
 static void
 }
 
 static void
-display_bfd (bfd *abfd)
+display_object_bfd (bfd *abfd)
 {
   char **matching;
 
 {
   char **matching;
 
@@ -3175,24 +3451,8 @@ display_bfd (bfd *abfd)
 }
 
 static void
 }
 
 static void
-display_file (char *filename, char *target)
+display_any_bfd (bfd *file, int level)
 {
 {
-  bfd *file;
-  bfd *arfile = NULL;
-
-  if (get_file_size (filename) < 1)
-    {
-      exit_status = 1;
-      return;
-    }
-
-  file = bfd_openr (filename, target);
-  if (file == NULL)
-    {
-      nonfatal (filename);
-      return;
-    }
-
   /* Decompress sections unless dumping the section contents.  */
   if (!dump_section_contents)
     file->flags |= BFD_DECOMPRESS;
   /* Decompress sections unless dumping the section contents.  */
   if (!dump_section_contents)
     file->flags |= BFD_DECOMPRESS;
@@ -3200,9 +3460,21 @@ display_file (char *filename, char *target)
   /* If the file is an archive, process all of its elements.  */
   if (bfd_check_format (file, bfd_archive))
     {
   /* If the file is an archive, process all of its elements.  */
   if (bfd_check_format (file, bfd_archive))
     {
+      bfd *arfile = NULL;
       bfd *last_arfile = NULL;
 
       bfd *last_arfile = NULL;
 
-      printf (_("In archive %s:\n"), bfd_get_filename (file));
+      if (level == 0)
+        printf (_("In archive %s:\n"), bfd_get_filename (file));
+      else if (level > 100)
+       {
+         /* Prevent corrupted files from spinning us into an
+            infinite loop.  100 is an arbitrary heuristic.  */
+         fatal (_("Archive nesting is too deep"));
+         return;
+       }
+      else
+        printf (_("In nested archive %s:\n"), bfd_get_filename (file));
+
       for (;;)
        {
          bfd_set_error (bfd_error_no_error);
       for (;;)
        {
          bfd_set_error (bfd_error_no_error);
@@ -3215,10 +3487,18 @@ display_file (char *filename, char *target)
              break;
            }
 
              break;
            }
 
-         display_bfd (arfile);
+         display_any_bfd (arfile, level + 1);
 
          if (last_arfile != NULL)
 
          if (last_arfile != NULL)
-           bfd_close (last_arfile);
+           {
+             bfd_close (last_arfile);
+             /* PR 17512: file: ac585d01.  */
+             if (arfile == last_arfile)
+               {
+                 last_arfile = NULL;
+                 break;
+               }
+           }
          last_arfile = arfile;
        }
 
          last_arfile = arfile;
        }
 
@@ -3226,7 +3506,28 @@ display_file (char *filename, char *target)
        bfd_close (last_arfile);
     }
   else
        bfd_close (last_arfile);
     }
   else
-    display_bfd (file);
+    display_object_bfd (file);
+}
+
+static void
+display_file (char *filename, char *target)
+{
+  bfd *file;
+
+  if (get_file_size (filename) < 1)
+    {
+      exit_status = 1;
+      return;
+    }
+
+  file = bfd_openr (filename, target);
+  if (file == NULL)
+    {
+      nonfatal (filename);
+      return;
+    }
+
+  display_any_bfd (file, 0);
 
   bfd_close (file);
 }
 
   bfd_close (file);
 }
@@ -3250,6 +3551,7 @@ main (int argc, char **argv)
 
   program_name = *argv;
   xmalloc_set_program_name (program_name);
 
   program_name = *argv;
   xmalloc_set_program_name (program_name);
+  bfd_set_error_program_name (program_name);
 
   START_PROGRESS (program_name, 0);
 
 
   START_PROGRESS (program_name, 0);
 
@@ -3259,7 +3561,7 @@ main (int argc, char **argv)
   set_default_bfd_target ();
 
   while ((c = getopt_long (argc, argv,
   set_default_bfd_target ();
 
   while ((c = getopt_long (argc, argv,
-                          "pib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::",
+                          "pP:ib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::",
                           long_options, (int *) 0))
         != EOF)
     {
                           long_options, (int *) 0))
         != EOF)
     {
@@ -3376,6 +3678,10 @@ main (int argc, char **argv)
          dump_private_headers = TRUE;
          seenflag = TRUE;
          break;
          dump_private_headers = TRUE;
          seenflag = TRUE;
          break;
+       case 'P':
+         dump_private_options = optarg;
+         seenflag = TRUE;
+         break;
        case 'x':
          dump_private_headers = TRUE;
          dump_symtab = TRUE;
        case 'x':
          dump_private_headers = TRUE;
          dump_symtab = TRUE;
@@ -3436,6 +3742,22 @@ main (int argc, char **argv)
          else
            dwarf_select_sections_all ();
          break;
          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 OPTION_DWARF_CHECK:
+         dwarf_check = TRUE;
+         break;
        case 'G':
          dump_stab_section_info = TRUE;
          seenflag = TRUE;
        case 'G':
          dump_stab_section_info = TRUE;
          seenflag = TRUE;
@@ -3460,15 +3782,15 @@ main (int argc, char **argv)
          dump_section_headers = TRUE;
          seenflag = TRUE;
          break;
          dump_section_headers = TRUE;
          seenflag = TRUE;
          break;
-       case 'H':
-         usage (stdout, 0);
-         seenflag = TRUE;
        case 'v':
        case 'V':
          show_version = TRUE;
          seenflag = TRUE;
          break;
 
        case 'v':
        case 'V':
          show_version = TRUE;
          seenflag = TRUE;
          break;
 
+       case 'H':
+         usage (stdout, 0);
+         /* No need to set seenflag or to break - usage() does not return.  */
        default:
          usage (stderr, 1);
        }
        default:
          usage (stderr, 1);
        }
This page took 0.040552 seconds and 4 git commands to generate.