MIPS: Support `-gnuabi64' target triplet suffix for 64-bit Linux targets
[binutils-gdb.git] / binutils / objdump.c
index 9dd1ebd4da0a332ec5d3649aac56111df9ad6010..a35982ea9695704e328ab4e89d2866d1279b1d7f 100644 (file)
@@ -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 */
@@ -559,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;
@@ -1003,16 +1002,21 @@ slurp_symtab (bfd *abfd)
     {
       non_fatal (_("failed to read symbol table from: %s"),
                 bfd_get_filename (abfd));
-      bfd_fatal (_("error message was"));
+      my_bfd_nonfatal (_("error message was"));
     }
 
-  if (storage == 0)
+  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;
 }
 
@@ -1032,16 +1036,21 @@ slurp_dynamic_symtab (bfd *abfd)
          return NULL;
        }
 
-      bfd_fatal (bfd_get_filename (abfd));
+      my_bfd_nonfatal (bfd_get_filename (abfd));
     }
 
-  if (storage == 0)
+  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;
 }
 
@@ -3748,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;
            }
        }
     }
@@ -4104,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)
@@ -4157,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;
@@ -4443,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:
@@ -4507,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");
@@ -4516,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;
@@ -4595,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);
+           }
        }
     }
 }
@@ -4773,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;
@@ -4787,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));
@@ -4816,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);
@@ -4828,61 +4858,36 @@ 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)
     {
+      my_bfd_nonfatal (bfd_get_filename (abfd));
       free (sframe_data);
-      bfd_fatal (bfd_get_filename (abfd));
+      return;
     }
 
   printf (_("Contents of the SFrame section %s:"),
@@ -4890,8 +4895,8 @@ dump_section_sframe (bfd *abfd ATTRIBUTE_UNUSED,
   /* Dump the contents as text.  */
   dump_sframe (sfd_ctx, sf_vma);
 
-  free (sframe_data);
   sframe_decoder_free (&sfd_ctx);
+  free (sframe_data);
 }
 
 \f
@@ -5362,7 +5367,7 @@ dump_relocs_in_section (bfd *abfd,
                        asection *section,
                        void *dummy ATTRIBUTE_UNUSED)
 {
-  arelent **relpp = NULL;
+  arelent **relpp;
   long relcount;
   long relsize;
 
@@ -5383,7 +5388,10 @@ dump_relocs_in_section (bfd *abfd,
     }
 
   if (relsize < 0)
-    relcount = relsize;
+    {
+      relpp = NULL;
+      relcount = relsize;
+    }
   else
     {
       relpp = (arelent **) xmalloc (relsize);
@@ -5395,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");
@@ -5422,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.  */
@@ -5678,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.  */
@@ -5729,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;
     }
 
@@ -5746,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);
@@ -5771,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
@@ -5786,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;
            }
 
@@ -5826,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;
     }
 
@@ -5865,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)
@@ -5981,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:
@@ -5998,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)
@@ -6007,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;
@@ -6019,7 +6042,6 @@ main (int argc, char **argv)
          else
            {
              non_fatal (_("unrecognized --endian type `%s'"), optarg);
-             exit_status = 1;
              usage (stderr, 1);
            }
          break;
@@ -6248,7 +6270,5 @@ main (int argc, char **argv)
   free (dump_ctf_parent_name);
   free ((void *) source_comment);
 
-  END_PROGRESS (program_name);
-
   return exit_status;
 }