MIPS: Support `-gnuabi64' target triplet suffix for 64-bit Linux targets
[binutils-gdb.git] / binutils / objdump.c
index 9b27ce73a879edc1eb670d3388a617af4eb3549c..a35982ea9695704e328ab4e89d2866d1279b1d7f 100644 (file)
@@ -1,5 +1,5 @@
 /* objdump.c -- dump information about an object file.
-   Copyright (C) 1990-2022 Free Software Foundation, Inc.
+   Copyright (C) 1990-2023 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -52,7 +52,6 @@
 #include "bfd.h"
 #include "elf-bfd.h"
 #include "coff-bfd.h"
-#include "progress.h"
 #include "bucomm.h"
 #include "elfcomm.h"
 #include "demanguse.h"
@@ -116,7 +115,7 @@ static bool disassemble;            /* -d */
 static bool disassemble_all;           /* -D */
 static int disassemble_zeroes;         /* --disassemble-zeroes */
 static bool formats_info;              /* -i */
-static int wide_output;                        /* -w */
+int wide_output;                       /* -w */
 static int insn_width;                 /* --insn-width */
 static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
 static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
@@ -137,6 +136,7 @@ static bool visualize_jumps = false;        /* --visualize-jumps.  */
 static bool color_output = false;      /* --visualize-jumps=color.  */
 static bool extended_color_output = false; /* --visualize-jumps=extended-color.  */
 static int process_links = false;       /* --process-links.  */
+static int show_all_symbols;            /* --show-all-symbols.  */
 
 static enum color_selection
   {
@@ -399,6 +399,8 @@ usage (FILE *stream, int status)
       fprintf (stream, _("\
       --adjust-vma=OFFSET        Add OFFSET to all displayed section addresses\n"));
       fprintf (stream, _("\
+      --show-all-symbols         When disassembling, display all symbols at a given address\n"));
+      fprintf (stream, _("\
       --special-syms             Include special symbols in symbol dumps\n"));
       fprintf (stream, _("\
       --inlines                  Print all inlines for source line (with -l)\n"));
@@ -537,6 +539,7 @@ static struct option long_options[]=
   {"section", required_argument, NULL, 'j'},
   {"section-headers", no_argument, NULL, 'h'},
   {"sframe", optional_argument, NULL, OPTION_SFRAME},
+  {"show-all-symbols", no_argument, &show_all_symbols, 1},
   {"show-raw-insn", no_argument, &show_raw_insn, 1},
   {"source", no_argument, NULL, 'S'},
   {"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT},
@@ -555,7 +558,7 @@ static struct option long_options[]=
 };
 \f
 static void
-nonfatal (const char *msg)
+my_bfd_nonfatal (const char *msg)
 {
   bfd_nonfatal (msg);
   exit_status = 1;
@@ -990,48 +993,30 @@ dump_headers (bfd *abfd)
 static asymbol **
 slurp_symtab (bfd *abfd)
 {
-  asymbol **sy = NULL;
-  long storage;
-
+  symcount = 0;
   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
-    {
-      symcount = 0;
-      return NULL;
-    }
+    return NULL;
 
-  storage = bfd_get_symtab_upper_bound (abfd);
+  long storage = bfd_get_symtab_upper_bound (abfd);
   if (storage < 0)
     {
-      non_fatal (_("failed to read symbol table from: %s"), bfd_get_filename (abfd));
-      bfd_fatal (_("error message was"));
+      non_fatal (_("failed to read symbol table from: %s"),
+                bfd_get_filename (abfd));
+      my_bfd_nonfatal (_("error message was"));
     }
 
-  if (storage)
-    {
-      off_t filesize = bfd_get_file_size (abfd);
-
-      /* qv PR 24707.  */
-      if (filesize > 0
-         && filesize < storage
-         /* The MMO file format supports its own special compression
-            technique, so its sections can be larger than the file size.  */
-         && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
-       {
-         bfd_nonfatal_message (bfd_get_filename (abfd), abfd, NULL,
-                               _("error: symbol table size (%#lx) "
-                                 "is larger than filesize (%#lx)"),
-                               storage, (long) filesize);
-         exit_status = 1;
-         symcount = 0;
-         return NULL;
-       }
-
-      sy = (asymbol **) xmalloc (storage);
-    }
+  if (storage <= 0)
+    return NULL;
 
+  asymbol **sy = (asymbol **) xmalloc (storage);
   symcount = bfd_canonicalize_symtab (abfd, sy);
   if (symcount < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      free (sy);
+      sy = NULL;
+      symcount = 0;
+    }
   return sy;
 }
 
@@ -1040,29 +1025,32 @@ slurp_symtab (bfd *abfd)
 static asymbol **
 slurp_dynamic_symtab (bfd *abfd)
 {
-  asymbol **sy = NULL;
-  long storage;
-
-  storage = bfd_get_dynamic_symtab_upper_bound (abfd);
+  dynsymcount = 0;
+  long storage = bfd_get_dynamic_symtab_upper_bound (abfd);
   if (storage < 0)
     {
       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
        {
          non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
          exit_status = 1;
-         dynsymcount = 0;
          return NULL;
        }
 
-      bfd_fatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
     }
 
-  if (storage)
-    sy = (asymbol **) xmalloc (storage);
+  if (storage <= 0)
+    return NULL;
 
+  asymbol **sy = (asymbol **) xmalloc (storage);
   dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
   if (dynsymcount < 0)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      free (sy);
+      sy = NULL;
+      dynsymcount = 0;
+    }
   return sy;
 }
 
@@ -1222,20 +1210,17 @@ compare_symbols (const void *ap, const void *bp)
        return 1;
     }
 
-  if (bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour
+  /* Sort larger size ELF symbols before smaller.  See PR20337.  */
+  bfd_vma asz = 0;
+  if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
+      && bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour)
+    asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
+  bfd_vma bsz = 0;
+  if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
       && bfd_get_flavour (bfd_asymbol_bfd (b)) == bfd_target_elf_flavour)
-    {
-      bfd_vma asz, bsz;
-
-      asz = 0;
-      if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
-       asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
-      bsz = 0;
-      if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
-       bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
-      if (asz != bsz)
-       return asz > bsz ? -1 : 1;
-    }
+    bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
+  if (asz != bsz)
+    return asz > bsz ? -1 : 1;
 
   /* Symbols that start with '.' might be section names, so sort them
      after symbols that don't start with '.'.  */
@@ -3709,15 +3694,18 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
    next_sym
   } loop_until;
 
-  /* Sections that do not contain machine
-     code are not normally disassembled.  */
-  if (! disassemble_all
-      && only_list == NULL
-      && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
-         != (SEC_CODE | SEC_HAS_CONTENTS)))
-    return;
+  if (only_list == NULL)
+    {
+      /* Sections that do not contain machine
+        code are not normally disassembled.  */
+      if ((section->flags & SEC_HAS_CONTENTS) == 0)
+       return;
 
-  if (! process_section_p (section))
+      if (! disassemble_all
+         && (section->flags & SEC_CODE) == 0)
+       return;
+    }
+  else if (!process_section_p (section))
     return;
 
   datasize = bfd_section_size (section);
@@ -3769,17 +3757,23 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 
          relsize = bfd_get_reloc_upper_bound (abfd, section);
          if (relsize < 0)
-           bfd_fatal (bfd_get_filename (abfd));
+           my_bfd_nonfatal (bfd_get_filename (abfd));
 
          if (relsize > 0)
            {
-             rel_ppstart = rel_pp = (arelent **) xmalloc (relsize);
+             rel_pp = (arelent **) xmalloc (relsize);
              rel_count = bfd_canonicalize_reloc (abfd, section, rel_pp, syms);
              if (rel_count < 0)
-               bfd_fatal (bfd_get_filename (abfd));
-
-             /* Sort the relocs by address.  */
-             qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs);
+               {
+                 my_bfd_nonfatal (bfd_get_filename (abfd));
+                 free (rel_pp);
+                 rel_pp = NULL;
+                 rel_count = 0;
+               }
+             else if (rel_count > 1)
+               /* Sort the relocs by address.  */
+               qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs);
+             rel_ppstart = rel_pp;
            }
        }
     }
@@ -3909,6 +3903,13 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
                {
                  do_print = true;
 
+                 /* Skip over the relocs belonging to addresses below the
+                    symbol address.  */
+                 const bfd_vma sym_offset = bfd_asymbol_value (sym) - section->vma;
+                 while (rel_pp < rel_ppend &&
+                  (*rel_pp)->address - rel_offset < sym_offset)
+                         ++rel_pp;
+
                  if (sym->flags & BSF_FUNCTION)
                    {
                      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
@@ -3945,6 +3946,24 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
          objdump_print_addr_with_sym (abfd, section, sym, addr,
                                       pinfo, false);
          pinfo->fprintf_func (pinfo->stream, ":\n");
+
+         if (sym != NULL && show_all_symbols)
+           {
+             for (++place; place < sorted_symcount; place++)
+               {
+                 sym = sorted_syms[place];
+                 
+                 if (bfd_asymbol_value (sym) != addr)
+                   break;
+                 if (! pinfo->symbol_is_valid (sym, pinfo))
+                   continue;
+                 if (strcmp (bfd_section_name (sym->section), bfd_section_name (section)) != 0)
+                   break;
+
+                 objdump_print_addr_with_sym (abfd, section, sym, addr, pinfo, false);
+                 pinfo->fprintf_func (pinfo->stream, ":\n");
+               }
+           }      
        }
 
       if (sym != NULL && bfd_asymbol_value (sym) > addr)
@@ -4100,9 +4119,12 @@ disassemble_data (bfd *abfd)
       const bfd_arch_info_type *inf = bfd_scan_arch (machine);
 
       if (inf == NULL)
-       fatal (_("can't use supplied machine %s"), machine);
-
-      abfd->arch_info = inf;
+       {
+         non_fatal (_("can't use supplied machine %s"), machine);
+         exit_status = 1;
+       }
+      else
+       abfd->arch_info = inf;
     }
 
   if (endian != BFD_ENDIAN_UNKNOWN)
@@ -4153,20 +4175,22 @@ disassemble_data (bfd *abfd)
   /* Pre-load the dynamic relocs as we may need them during the disassembly.  */
   long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
 
-  if (relsize < 0 && dump_dynamic_reloc_info)
-    bfd_fatal (bfd_get_filename (abfd));
-
   if (relsize > 0)
     {
       disasm_info.dynrelbuf = (arelent **) xmalloc (relsize);
       disasm_info.dynrelcount
        = bfd_canonicalize_dynamic_reloc (abfd, disasm_info.dynrelbuf, dynsyms);
       if (disasm_info.dynrelcount < 0)
-       bfd_fatal (bfd_get_filename (abfd));
-
-      /* Sort the relocs by address.  */
-      qsort (disasm_info.dynrelbuf, disasm_info.dynrelcount, sizeof (arelent *),
-            compare_relocs);
+       {
+         my_bfd_nonfatal (bfd_get_filename (abfd));
+         free (disasm_info.dynrelbuf);
+         disasm_info.dynrelbuf = NULL;
+         disasm_info.dynrelcount = 0;
+       }
+      else if (disasm_info.dynrelcount > 1)
+       /* Sort the relocs by address.  */
+       qsort (disasm_info.dynrelbuf, disasm_info.dynrelcount,
+              sizeof (arelent *), compare_relocs);
     }
 
   disasm_info.symtab = sorted_syms;
@@ -4206,13 +4230,15 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   section->size = bfd_section_size (sec);
   /* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */
   alloced = amt = section->size + 1;
-  if (alloced != amt || alloced == 0)
+  if (alloced != amt
+      || alloced == 0
+      || (bfd_get_size (abfd) != 0 && alloced >= bfd_get_size (abfd)))
     {
       section->start = NULL;
       free_debug_section (debug);
-      printf (_("\nSection '%s' has an invalid size: %#llx.\n"),
+      printf (_("\nSection '%s' has an invalid size: %#" PRIx64 ".\n"),
              sanitize_string (section->name),
-             (unsigned long long) section->size);
+             section->size);
       return false;
     }
 
@@ -4437,39 +4463,32 @@ dump_dwarf (bfd *abfd, bool is_mainfile)
   bfd_map_over_sections (abfd, dump_dwarf_section, (void *) &is_mainfile);
 }
 \f
-/* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
-   it.  Return NULL on failure.   */
+/* Read ABFD's section SECT_NAME into *CONTENTS, and return a pointer to
+   the section.  Return NULL on failure.   */
 
-static bfd_byte *
-read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr,
-                   bfd_size_type *entsize_ptr)
+static asection *
+read_section (bfd *abfd, const char *sect_name, bfd_byte **contents)
 {
-  asection *stabsect;
-  bfd_byte *contents;
-
-  stabsect = bfd_get_section_by_name (abfd, sect_name);
-  if (stabsect == NULL)
-    {
-      printf (_("No %s section present\n\n"),
-             sanitize_string (sect_name));
-      return false;
-    }
+  asection *sec;
 
-  if (!bfd_malloc_and_get_section (abfd, stabsect, &contents))
+  *contents = NULL;
+  sec = bfd_get_section_by_name (abfd, sect_name);
+  if (sec == NULL)
     {
-      non_fatal (_("reading %s section of %s failed: %s"),
-                sect_name, bfd_get_filename (abfd),
-                bfd_errmsg (bfd_get_error ()));
-      exit_status = 1;
-      free (contents);
+      printf (_("No %s section present\n\n"), sanitize_string (sect_name));
       return NULL;
     }
 
-  *size_ptr = bfd_section_size (stabsect);
-  if (entsize_ptr)
-    *entsize_ptr = stabsect->entsize;
+  if ((bfd_section_flags (sec) & SEC_HAS_CONTENTS) == 0)
+    bfd_set_error (bfd_error_no_contents);
+  else if (bfd_malloc_and_get_section (abfd, sec, contents))
+    return sec;
 
-  return contents;
+  non_fatal (_("reading %s section of %s failed: %s"),
+            sect_name, bfd_get_filename (abfd),
+            bfd_errmsg (bfd_get_error ()));
+  exit_status = 1;
+  return NULL;
 }
 
 /* Stabs entries use a 12 byte format:
@@ -4501,7 +4520,7 @@ print_section_stabs (bfd *abfd,
   bfd_byte *stabp, *stabs_end;
 
   stabp = stabs;
-  stabs_end = stabp + stab_size;
+  stabs_end = PTR_ADD (stabp, stab_size);
 
   printf (_("Contents of %s section:\n\n"), sanitize_string (stabsect_name));
   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
@@ -4510,7 +4529,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.  */
-  for (i = -1; stabp <= stabs_end - STABSIZE; stabp += STABSIZE, i++)
+  for (i = -1; (size_t) (stabs_end - stabp) >= STABSIZE; stabp += STABSIZE, i++)
     {
       const char *name;
       unsigned long strx;
@@ -4589,15 +4608,23 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
       && (section->name[len] == 0
          || (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
     {
+      asection *s;
       if (strtab == NULL)
-       strtab = read_section_stabs (abfd, sought->string_section_name,
-                                    &stabstr_size, NULL);
+       {
+         s = read_section (abfd, sought->string_section_name, &strtab);
+         if (s != NULL)
+           stabstr_size = bfd_section_size (s);
+       }
 
       if (strtab)
        {
-         stabs = read_section_stabs (abfd, section->name, &stab_size, NULL);
-         if (stabs)
-           print_section_stabs (abfd, section->name, &sought->string_offset);
+         s = read_section (abfd, section->name, &stabs);
+         if (s != NULL)
+           {
+             stab_size = bfd_section_size (s);
+             print_section_stabs (abfd, section->name, &sought->string_offset);
+             free (stabs);
+           }
        }
     }
 }
@@ -4767,9 +4794,9 @@ dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
 static void
 dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
 {
+  asection *sec;
   ctf_archive_t *ctfa = NULL;
-  bfd_byte *ctfdata = NULL;
-  bfd_size_type ctfsize;
+  bfd_byte *ctfdata;
   ctf_sect_t ctfsect;
   ctf_dict_t *parent;
   ctf_dict_t *fp;
@@ -4781,25 +4808,34 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
   if (sect_name == NULL)
     sect_name = ".ctf";
 
-  if ((ctfdata = read_section_stabs (abfd, sect_name, &ctfsize, NULL)) == NULL)
-      bfd_fatal (bfd_get_filename (abfd));
+  sec = read_section (abfd, sect_name, &ctfdata);
+  if (sec == NULL)
+    {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      return;
+    }
 
   /* Load the CTF file and dump it.  Preload the parent dict, since it will
      need to be imported into every child in turn. */
 
-  ctfsect = make_ctfsect (sect_name, ctfdata, ctfsize);
+  ctfsect = make_ctfsect (sect_name, ctfdata, bfd_section_size (sec));
   if ((ctfa = ctf_bfdopen_ctfsect (abfd, &ctfsect, &err)) == NULL)
     {
       dump_ctf_errs (NULL);
       non_fatal (_("CTF open failure: %s"), ctf_errmsg (err));
-      bfd_fatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      free (ctfdata);
+      return;
     }
 
   if ((parent = ctf_dict_open (ctfa, parent_name, &err)) == NULL)
     {
       dump_ctf_errs (NULL);
       non_fatal (_("CTF open failure: %s"), ctf_errmsg (err));
-      bfd_fatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      ctf_close (ctfa);
+      free (ctfdata);
+      return;
     }
 
   printf (_("Contents of CTF section %s:\n"), sanitize_string (sect_name));
@@ -4810,7 +4846,7 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
     {
       dump_ctf_errs (NULL);
       non_fatal (_("CTF archive member open failure: %s"), ctf_errmsg (err));
-      bfd_fatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
     }
   ctf_dict_close (parent);
   ctf_close (ctfa);
@@ -4822,64 +4858,45 @@ dump_ctf (bfd *abfd ATTRIBUTE_UNUSED, const char *sect_name ATTRIBUTE_UNUSED,
          const char *parent_name ATTRIBUTE_UNUSED) {}
 #endif
 
-static bfd_byte*
-read_section_sframe (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr,
-                    bfd_vma *sframe_vma)
-{
-  asection *sframe_sect;
-  bfd_byte *contents;
-
-  sframe_sect = bfd_get_section_by_name (abfd, sect_name);
-  if (sframe_sect == NULL)
-    {
-      printf (_("No %s section present\n\n"),
-             sanitize_string (sect_name));
-      return NULL;
-    }
-
-  if (!bfd_malloc_and_get_section (abfd, sframe_sect, &contents))
-    {
-      non_fatal (_("reading %s section of %s failed: %s"),
-                sect_name, bfd_get_filename (abfd),
-                bfd_errmsg (bfd_get_error ()));
-      exit_status = 1;
-      free (contents);
-      return NULL;
-    }
-
-  *size_ptr = bfd_section_size (sframe_sect);
-  *sframe_vma = bfd_section_vma (sframe_sect);
-
-  return contents;
-}
-
 static void
 dump_section_sframe (bfd *abfd ATTRIBUTE_UNUSED,
                     const char * sect_name)
 {
+  asection *sec;
   sframe_decoder_ctx *sfd_ctx = NULL;
   bfd_size_type sf_size;
-  bfd_byte *sframe_data = NULL;
+  bfd_byte *sframe_data;
   bfd_vma sf_vma;
   int err = 0;
 
   if (sect_name == NULL)
     sect_name = ".sframe";
 
-  sframe_data = read_section_sframe (abfd, sect_name, &sf_size, &sf_vma);
-
-  if (sframe_data == NULL)
-    bfd_fatal (bfd_get_filename (abfd));
+  sec = read_section (abfd, sect_name, &sframe_data);
+  if (sec == NULL)
+    {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      return;
+    }
+  sf_size = bfd_section_size (sec);
+  sf_vma = bfd_section_vma (sec);
 
   /* Decode the contents of the section.  */
   sfd_ctx = sframe_decode ((const char*)sframe_data, sf_size, &err);
   if (!sfd_ctx)
-    bfd_fatal (bfd_get_filename (abfd));
+    {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
+      free (sframe_data);
+      return;
+    }
 
   printf (_("Contents of the SFrame section %s:"),
          sanitize_string (sect_name));
   /* Dump the contents as text.  */
   dump_sframe (sfd_ctx, sf_vma);
+
+  sframe_decoder_free (&sfd_ctx);
+  free (sframe_data);
 }
 
 \f
@@ -4961,10 +4978,12 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
   int count;
   int width;
 
-  if (! process_section_p (section))
-    return;
-
-  if ((section->flags & SEC_HAS_CONTENTS) == 0)
+  if (only_list == NULL)
+    {
+      if ((section->flags & SEC_HAS_CONTENTS) == 0)
+       return;
+    }
+  else if (!process_section_p (section))
     return;
 
   if ((datasize = bfd_section_size (section)) == 0)
@@ -5348,7 +5367,7 @@ dump_relocs_in_section (bfd *abfd,
                        asection *section,
                        void *dummy ATTRIBUTE_UNUSED)
 {
-  arelent **relpp = NULL;
+  arelent **relpp;
   long relcount;
   long relsize;
 
@@ -5369,7 +5388,10 @@ dump_relocs_in_section (bfd *abfd,
     }
 
   if (relsize < 0)
-    relcount = relsize;
+    {
+      relpp = NULL;
+      relcount = relsize;
+    }
   else
     {
       relpp = (arelent **) xmalloc (relsize);
@@ -5381,7 +5403,7 @@ dump_relocs_in_section (bfd *abfd,
       printf ("\n");
       non_fatal (_("failed to read relocs in: %s"),
                 sanitize_string (bfd_get_filename (abfd)));
-      bfd_fatal (_("error message was"));
+      my_bfd_nonfatal (_("error message was"));
     }
   else if (relcount == 0)
     printf (" (none)\n\n");
@@ -5408,30 +5430,42 @@ dump_dynamic_relocs (bfd *abfd)
   long relcount;
 
   relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
-  if (relsize < 0)
-    bfd_fatal (bfd_get_filename (abfd));
 
   printf ("DYNAMIC RELOCATION RECORDS");
 
   if (relsize == 0)
-    printf (" (none)\n\n");
+    {
+      printf (" (none)\n\n");
+      return;
+    }
+
+  if (relsize < 0)
+    {
+      relpp = NULL;
+      relcount = relsize;
+    }
   else
     {
       relpp = (arelent **) xmalloc (relsize);
       relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
+    }
 
-      if (relcount < 0)
-       bfd_fatal (bfd_get_filename (abfd));
-      else if (relcount == 0)
-       printf (" (none)\n\n");
-      else
-       {
-         printf ("\n");
-         dump_reloc_set (abfd, NULL, relpp, relcount);
-         printf ("\n\n");
-       }
-      free (relpp);
+  if (relcount < 0)
+    {
+      printf ("\n");
+      non_fatal (_("failed to read relocs in: %s"),
+                sanitize_string (bfd_get_filename (abfd)));
+      my_bfd_nonfatal (_("error message was"));
     }
+  else if (relcount == 0)
+    printf (" (none)\n\n");
+  else
+    {
+      printf ("\n");
+      dump_reloc_set (abfd, NULL, relpp, relcount);
+      printf ("\n\n");
+    }
+  free (relpp);
 }
 
 /* Creates a table of paths, to search for source files.  */
@@ -5664,8 +5698,6 @@ dump_bfd (bfd *abfd, bool is_mainfile)
                         bfd_get_filename (abfd));
              exit_status = 1;
            }
-
-         free (dhandle);
        }
       /* PR 6483: If there was no STABS debug info in the file, try
         DWARF instead.  */
@@ -5715,14 +5747,14 @@ display_object_bfd (bfd *abfd)
 
   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
     {
-      nonfatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
       list_matching_formats (matching);
       return;
     }
 
   if (bfd_get_error () != bfd_error_file_not_recognized)
     {
-      nonfatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
       return;
     }
 
@@ -5732,7 +5764,7 @@ display_object_bfd (bfd *abfd)
       return;
     }
 
-  nonfatal (bfd_get_filename (abfd));
+  my_bfd_nonfatal (bfd_get_filename (abfd));
 
   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
     list_matching_formats (matching);
@@ -5757,7 +5789,8 @@ display_any_bfd (bfd *file, int level)
        {
          /* Prevent corrupted files from spinning us into an
             infinite loop.  100 is an arbitrary heuristic.  */
-         fatal (_("Archive nesting is too deep"));
+         non_fatal (_("Archive nesting is too deep"));
+         exit_status = 1;
          return;
        }
       else
@@ -5772,7 +5805,7 @@ display_any_bfd (bfd *file, int level)
          if (arfile == NULL)
            {
              if (bfd_get_error () != bfd_error_no_more_archived_files)
-               nonfatal (bfd_get_filename (file));
+               my_bfd_nonfatal (bfd_get_filename (file));
              break;
            }
 
@@ -5812,7 +5845,7 @@ display_file (char *filename, char *target, bool last_file)
   file = bfd_openr (filename, target);
   if (file == NULL)
     {
-      nonfatal (filename);
+      my_bfd_nonfatal (filename);
       return;
     }
 
@@ -5851,8 +5884,6 @@ main (int argc, char **argv)
   xmalloc_set_program_name (program_name);
   bfd_set_error_program_name (program_name);
 
-  START_PROGRESS (program_name, 0);
-
   expandargv (&argc, &argv);
 
   if (bfd_init () != BFD_INIT_MAGIC)
@@ -5967,7 +5998,10 @@ main (int argc, char **argv)
              else if (streq (optarg, "off"))
                visualize_jumps = false;
              else
-               nonfatal (_("unrecognized argument to --visualize-option"));
+               {
+                 non_fatal (_("unrecognized argument to --visualize-option"));
+                 usage (stderr, 1);
+               }
            }
          break;
        case OPTION_DISASSEMBLER_COLOR:
@@ -5984,7 +6018,10 @@ main (int argc, char **argv)
                   || streq (optarg, "extended-colour"))
            disassembler_color = extended;
          else
-           nonfatal (_("unrecognized argument to --disassembler-color"));
+           {
+             non_fatal (_("unrecognized argument to --disassembler-color"));
+             usage (stderr, 1);
+           }
          break;
        case 'E':
          if (strcmp (optarg, "B") == 0)
@@ -5993,7 +6030,7 @@ main (int argc, char **argv)
            endian = BFD_ENDIAN_LITTLE;
          else
            {
-             nonfatal (_("unrecognized -E option"));
+             non_fatal (_("unrecognized -E option"));
              usage (stderr, 1);
            }
          break;
@@ -6005,7 +6042,6 @@ main (int argc, char **argv)
          else
            {
              non_fatal (_("unrecognized --endian type `%s'"), optarg);
-             exit_status = 1;
              usage (stderr, 1);
            }
          break;
@@ -6234,7 +6270,5 @@ main (int argc, char **argv)
   free (dump_ctf_parent_name);
   free ((void *) source_comment);
 
-  END_PROGRESS (program_name);
-
   return exit_status;
 }