Adjust the output section size to skip gap fills
[deliverable/binutils-gdb.git] / binutils / objdump.c
index f55b79d645415e466de4c3d7a6b8e4bde285329d..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, 2011,
-   2012 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.
@@ -53,6 +51,7 @@
 #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 "elfcomm.h"
 #include "progress.h"
 #include "bucomm.h"
 #include "elfcomm.h"
@@ -193,6 +192,7 @@ static const struct objdump_private_desc * const objdump_private_vectors[] =
     NULL
   };
 \f
     NULL
   };
 \f
+static void usage (FILE *, int) ATTRIBUTE_NORETURN;
 static void
 usage (FILE *stream, int status)
 {
 static void
 usage (FILE *stream, int status)
 {
@@ -216,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\
-          =gdb_index,=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\
@@ -261,7 +262,9 @@ usage (FILE *stream, int status)
       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\
       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"));
+                             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);
 
       list_supported_targets (program_name, stream);
       list_supported_architectures (program_name, stream);
 
@@ -292,6 +295,7 @@ enum option_values
     OPTION_INSN_WIDTH,
     OPTION_ADJUST_VMA,
     OPTION_DWARF_DEPTH,
     OPTION_INSN_WIDTH,
     OPTION_ADJUST_VMA,
     OPTION_DWARF_DEPTH,
+    OPTION_DWARF_CHECK,
     OPTION_DWARF_START
   };
 
     OPTION_DWARF_START
   };
 
@@ -343,6 +347,7 @@ static struct option long_options[]=
   {"insn-width", required_argument, NULL, OPTION_INSN_WIDTH},
   {"dwarf-depth",      required_argument, 0, OPTION_DWARF_DEPTH},
   {"dwarf-start",      required_argument, 0, OPTION_DWARF_START},
   {"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
@@ -558,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);
 
@@ -788,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);
@@ -800,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);
@@ -901,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
@@ -1082,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
@@ -1092,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;
@@ -1151,38 +1175,38 @@ slurp_file (const char *fn, size_t *size)
 
 /* Precompute array of lines for a mapped file. */
 
 
 /* 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;
@@ -1195,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;
 }
 
@@ -1219,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;
@@ -1230,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.  */
 
@@ -1269,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];
@@ -1292,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++;
@@ -1308,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')
@@ -1366,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
@@ -1391,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;
@@ -1419,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.  */
@@ -1440,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;
 }
 
@@ -1500,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)
@@ -1649,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)
@@ -1836,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");
@@ -1868,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;
@@ -1890,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)
@@ -1940,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;
@@ -1990,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;
@@ -2035,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
@@ -2081,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;
     }
@@ -2104,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.  */
@@ -2192,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));
 
@@ -2232,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)
@@ -2247,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,
@@ -2267,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)
 {
@@ -2307,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;
@@ -2342,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);
          }
@@ -2364,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))
     {
@@ -2373,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;
 
@@ -2382,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;
     }
@@ -2464,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;
@@ -2502,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 (" *");
        }
@@ -2542,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,
@@ -2604,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");
@@ -2629,7 +2757,7 @@ dump_target_specific (bfd *abfd)
     if ((*desc)->filter (abfd))
       break;
 
     if ((*desc)->filter (abfd))
       break;
 
-  if (desc == NULL)
+  if (*desc == NULL)
     {
       non_fatal (_("option -P/--private not supported by this file"));
       return;
     {
       non_fatal (_("option -P/--private not supported by this file"));
       return;
@@ -2677,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;
@@ -2692,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;
 
@@ -2718,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)"),
@@ -2727,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;
     }
 
@@ -2884,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.  */
   {
@@ -2902,12 +3032,14 @@ 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;
       bfd_vma addend2 = 0;
       const char *sym_name;
       const char *section_name;
       bfd_vma addend2 = 0;
@@ -2921,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
@@ -2938,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
-                     && filename_cmp (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)
@@ -3013,8 +3152,15 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
 
       if (q->addend)
        {
 
       if (q->addend)
        {
-         printf ("+0x");
-         bfd_printf_vma (abfd, 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)
        {
        }
       if (addend2)
        {
@@ -3063,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
@@ -3173,8 +3323,6 @@ dump_bfd (bfd *abfd)
     dump_target_specific (abfd);
   if (! dump_debugging_tags && ! suppress_bfd_header)
     putchar ('\n');
     dump_target_specific (abfd);
   if (! dump_debugging_tags && ! suppress_bfd_header)
     putchar ('\n');
-  if (dump_section_headers)
-    dump_headers (abfd);
 
   if (dump_symtab
       || dump_reloc_info
 
   if (dump_symtab
       || dump_reloc_info
@@ -3182,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);
@@ -3230,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);
        }
     }
@@ -3312,6 +3465,13 @@ display_any_bfd (bfd *file, int level)
 
       if (level == 0)
         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));
 
       else
         printf (_("In nested archive %s:\n"), bfd_get_filename (file));
 
@@ -3330,7 +3490,15 @@ display_any_bfd (bfd *file, int level)
          display_any_bfd (arfile, level + 1);
 
          if (last_arfile != NULL)
          display_any_bfd (arfile, level + 1);
 
          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;
        }
 
@@ -3383,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);
 
@@ -3586,6 +3755,9 @@ main (int argc, char **argv)
            suppress_bfd_header = 1;
          }
          break;
            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;
@@ -3610,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.036735 seconds and 4 git commands to generate.