binutils objcopy test tidy
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 4c00732cd5cc5b3ebd4dcb716a2a80f06c0521b0..ba9cd7c5460a97dbd266ec8058d66ff287fcb346 100644 (file)
@@ -1,5 +1,5 @@
 /* objdump.c -- dump information about an object file.
 /* objdump.c -- dump information about an object file.
-   Copyright (C) 1990-2014 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.
@@ -924,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
@@ -1116,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;
@@ -1175,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;
@@ -1219,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;
 }
 
@@ -1243,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;
@@ -1293,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];
@@ -1316,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++;
@@ -1392,9 +1392,9 @@ 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 || 
+      if (linenumber > 0 && (linenumber != prev_line ||
                              (discriminator != prev_discriminator)))
                              (discriminator != prev_discriminator)))
-        { 
+        {
           if (discriminator > 0)
             printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
                     linenumber, discriminator);
           if (discriminator > 0)
             printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
                     linenumber, discriminator);
@@ -1424,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;
@@ -1476,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;
 }
 
@@ -1536,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)
@@ -1685,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)
@@ -1911,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;
@@ -2035,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;
@@ -2080,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
@@ -2126,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;
     }
@@ -2238,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));
 
@@ -2278,6 +2289,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   if (section->start != NULL)
     return 1;
 
   if (section->start != NULL)
     return 1;
 
+  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->address = bfd_get_section_vma (abfd, sec);
   section->size = bfd_get_section_size (sec);
   section->start = NULL;
@@ -2308,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)
 {
@@ -2400,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);
          }
@@ -2449,6 +2500,10 @@ dump_dwarf (bfd *abfd)
        }
       break;
 
        }
       break;
 
+    case bfd_arch_iamcu:
+      init_dwarf_regnames_iamcu ();
+      break;
+
     case bfd_arch_aarch64:
       init_dwarf_regnames_aarch64();
       break;
     case bfd_arch_aarch64:
       init_dwarf_regnames_aarch64();
       break;
@@ -2616,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,
@@ -2750,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;
@@ -2765,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;
 
@@ -2791,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)"),
@@ -2800,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;
     }
 
@@ -3326,7 +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 (); 
+         dwarf_select_sections_all ();
          dump_dwarf (abfd);
        }
     }
          dump_dwarf (abfd);
        }
     }
@@ -3409,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));
 
@@ -3488,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);
 
This page took 0.030048 seconds and 4 git commands to generate.