[ARM] Change noread to purecode.
[deliverable/binutils-gdb.git] / binutils / objdump.c
index fdfa60250c2c4ddc035e4003bae9e27202407a01..29d2276f6c27b9a9bfb157c587676872da8d964d 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-2016 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.
@@ -51,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"
@@ -487,9 +488,18 @@ dump_section_header (bfd *abfd, asection *section,
     }
   PF (SEC_SMALL_DATA, "SMALL_DATA");
   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
     }
   PF (SEC_SMALL_DATA, "SMALL_DATA");
   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
-    PF (SEC_COFF_SHARED, "SHARED");
+    {
+      PF (SEC_COFF_SHARED, "SHARED");
+      PF (SEC_COFF_NOREAD, "NOREAD");
+    }
+  else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    PF (SEC_ELF_PURECODE, "PURECODE");
   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
   PF (SEC_GROUP, "GROUP");
   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
   PF (SEC_GROUP, "GROUP");
+  if (bfd_get_arch (abfd) == bfd_arch_mep)
+    {
+      PF (SEC_MEP_VLIW, "VLIW");
+    }
 
   if ((section->flags & SEC_LINK_ONCE) != 0)
     {
 
   if ((section->flags & SEC_LINK_ONCE) != 0)
     {
@@ -808,7 +818,8 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
        name = alloc;
     }
 
        name = alloc;
     }
 
-  version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
+  if ((sym->flags & BSF_SYNTHETIC) == 0)
+    version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
 
   if (bfd_is_und_section (bfd_get_section (sym)))
     hidden = TRUE;
 
   if (bfd_is_und_section (bfd_get_section (sym)))
     hidden = TRUE;
@@ -923,7 +934,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
@@ -1115,11 +1126,12 @@ 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;
   unsigned maxline;
   unsigned last_line;
+  unsigned max_printed;
   int first;
 };
 
   int first;
 };
 
@@ -1174,38 +1186,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;
@@ -1218,11 +1230,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;
 }
 
@@ -1242,9 +1254,10 @@ 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->linemap = index_file (p->map, p->mapsize, &p->maxline);
   p->last_line = 0;
+  p->max_printed = 0;
   p->filename = origname;
   p->modname = modname;
   p->next = print_files;
   p->filename = origname;
   p->modname = modname;
   p->next = print_files;
@@ -1292,13 +1305,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];
@@ -1315,7 +1328,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++;
@@ -1333,6 +1346,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
   unsigned int linenumber;
   unsigned int discriminator;
   bfd_boolean reloc;
   unsigned int linenumber;
   unsigned int discriminator;
   bfd_boolean reloc;
+  char *path = NULL;
 
   if (! with_line_numbers && ! with_source_code)
     return;
 
   if (! with_line_numbers && ! with_source_code)
     return;
@@ -1353,20 +1367,21 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
     {
       char *path_up;
       const char *fname = filename;
     {
       char *path_up;
       const char *fname = filename;
-      char *path = (char *) alloca (prefix_length + PATH_MAX + 1);
+
+      path = xmalloc (prefix_length + PATH_MAX + 1);
 
       if (prefix_length)
        memcpy (path, prefix, prefix_length);
       path_up = path + prefix_length;
 
       /* Build relocated filename, stripping off leading directories
 
       if (prefix_length)
        memcpy (path, prefix, prefix_length);
       path_up = path + prefix_length;
 
       /* Build relocated filename, stripping off leading directories
-        from the initial filename if requested. */
+        from the initial filename if requested.  */
       if (prefix_strip > 0)
        {
          int level = 0;
          const char *s;
 
       if (prefix_strip > 0)
        {
          int level = 0;
          const char *s;
 
-         /* Skip selected directory levels. */
+         /* Skip selected directory levels.  */
          for (s = fname + 1; *s != '\0' && level < prefix_strip; s++)
            if (IS_DIR_SEPARATOR(*s))
              {
          for (s = fname + 1; *s != '\0' && level < prefix_strip; s++)
            if (IS_DIR_SEPARATOR(*s))
              {
@@ -1375,7 +1390,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
              }
        }
 
              }
        }
 
-      /* Update complete filename. */
+      /* Update complete filename.  */
       strncpy (path_up, fname, PATH_MAX);
       path_up[PATH_MAX] = '\0';
 
       strncpy (path_up, fname, PATH_MAX);
       path_up[PATH_MAX] = '\0';
 
@@ -1391,9 +1406,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);
@@ -1423,17 +1438,24 @@ 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;
                l = 1;
-             if (p->last_line >= l && p->last_line <= linenumber)
-               l = p->last_line + 1;
+             if (p->max_printed >= l)
+               {
+                 if (p->max_printed < linenumber)
+                   l = p->max_printed + 1;
+                 else
+                   l = linenumber;
+               }
            }
          dump_lines (p, l, linenumber);
            }
          dump_lines (p, l, linenumber);
+         if (p->max_printed < linenumber)
+           p->max_printed = linenumber;
          p->last_line = linenumber;
          p->first = 0;
        }
          p->last_line = linenumber;
          p->first = 0;
        }
@@ -1454,6 +1476,9 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
 
   if (discriminator != prev_discriminator)
     prev_discriminator = discriminator;
 
   if (discriminator != prev_discriminator)
     prev_discriminator = discriminator;
+
+  if (path)
+    free (path);
 }
 
 /* Pseudo FILE object for strings.  */
 }
 
 /* Pseudo FILE object for strings.  */
@@ -1475,19 +1500,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;
 }
 
@@ -1535,7 +1560,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)
@@ -1684,7 +1709,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)
@@ -1910,7 +1946,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;
@@ -2034,7 +2070,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;
@@ -2079,7 +2115,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
@@ -2125,7 +2161,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;
     }
@@ -2237,7 +2273,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));
 
@@ -2277,9 +2313,12 @@ 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;
+  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)
@@ -2306,11 +2345,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)
 {
@@ -2346,6 +2423,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;
@@ -2381,7 +2475,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);
          }
@@ -2430,10 +2524,18 @@ 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;
 
+    case bfd_arch_s390:
+      init_dwarf_regnames_s390 ();
+      break;
+
     default:
       break;
     }
     default:
       break;
     }
@@ -2597,7 +2699,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,
@@ -2731,9 +2833,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;
@@ -2746,7 +2848,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;
 
@@ -2772,7 +2874,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)"),
@@ -2781,7 +2883,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;
     }
 
@@ -3307,7 +3410,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);
        }
     }
@@ -3390,6 +3493,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));
 
@@ -3408,7 +3518,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;
        }
 
@@ -3461,6 +3579,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.030298 seconds and 4 git commands to generate.