x86: Don't remove empty GNU_PROPERTY_X86_UINT32_OR_AND properties
[binutils-gdb.git] / binutils / objdump.c
index 40b4acf49fd9531ef1abd1dc9ebb2808ffd2169e..21f128431932b1634c4aa4bafcfdc748e1911525 100644 (file)
@@ -1,5 +1,5 @@
 /* objdump.c -- dump information about an object file.
-   Copyright (C) 1990-2017 Free Software Foundation, Inc.
+   Copyright (C) 1990-2018 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
@@ -118,6 +118,7 @@ static const char *prefix;          /* --prefix */
 static int prefix_strip;               /* --prefix-strip */
 static size_t prefix_length;
 static bfd_boolean unwind_inlines;     /* --inlines.  */
+static const char * disasm_sym;                /* Disassembly start symbol.  */
 
 /* A structure to record the sections mentioned in -j switches.  */
 struct only
@@ -145,6 +146,7 @@ struct objdump_disasm_info
   long               dynrelcount;
   disassembler_ftype disassemble_fn;
   arelent *          reloc;
+  const char *       symbol;
 };
 
 /* Architecture to disassemble for, or default if NULL.  */
@@ -209,6 +211,7 @@ usage (FILE *stream, int status)
   -x, --all-headers        Display the contents of all headers\n\
   -d, --disassemble        Display assembler contents of executable sections\n\
   -D, --disassemble-all    Display assembler contents of all sections\n\
+      --disassemble=<sym>  Display assembler contents from <sym>\n\
   -S, --source             Intermix source code with disassembly\n\
   -s, --full-contents      Display the full contents of all sections requested\n\
   -g, --debugging          Display debug information in object file\n\
@@ -313,7 +316,7 @@ static struct option long_options[]=
   {"debugging", no_argument, NULL, 'g'},
   {"debugging-tags", no_argument, NULL, 'e'},
   {"demangle", optional_argument, NULL, 'C'},
-  {"disassemble", no_argument, NULL, 'd'},
+  {"disassemble", optional_argument, NULL, 'd'},
   {"disassemble-all", no_argument, NULL, 'D'},
   {"disassembler-options", required_argument, NULL, 'M'},
   {"disassemble-zeroes", no_argument, NULL, 'z'},
@@ -664,9 +667,7 @@ slurp_dynamic_symtab (bfd *abfd)
 static bfd_boolean
 is_significant_symbol_name (const char * name)
 {
-  return strcmp (name, ".plt") == 0
-    ||   strcmp (name, ".got") == 0
-    ||   strcmp (name, ".plt.got") == 0;
+  return strncmp (name, ".plt", 4) == 0 || strcmp (name, ".got") == 0;
 }
 
 /* Filter out (in place) symbols that are useless for disassembly.
@@ -937,6 +938,7 @@ find_symbol_for_address (bfd_vma vma,
   asection *sec;
   unsigned int opb;
   bfd_boolean want_section;
+  long rel_count;
 
   if (sorted_symcount < 1)
     return NULL;
@@ -1065,33 +1067,57 @@ find_symbol_for_address (bfd_vma vma,
      and we have dynamic relocations available, then we can produce
      a better result by matching a relocation to the address and
      using the symbol associated with that relocation.  */
+  rel_count = aux->dynrelcount;
   if (!want_section
-      && aux->dynrelbuf != NULL
       && sorted_syms[thisplace]->value != vma
+      && rel_count > 0
+      && aux->dynrelbuf != NULL
+      && aux->dynrelbuf[0]->address <= vma
+      && aux->dynrelbuf[rel_count - 1]->address >= vma
       /* If we have matched a synthetic symbol, then stick with that.  */
       && (sorted_syms[thisplace]->flags & BSF_SYNTHETIC) == 0)
     {
-      long        rel_count;
-      arelent **  rel_pp;
+      arelent **  rel_low;
+      arelent **  rel_high;
 
-      for (rel_count = aux->dynrelcount, rel_pp = aux->dynrelbuf;
-          rel_count--;)
+      rel_low = aux->dynrelbuf;
+      rel_high = rel_low + rel_count - 1;
+      while (rel_low <= rel_high)
        {
-         arelent * rel = rel_pp[rel_count];
+         arelent **rel_mid = &rel_low[(rel_high - rel_low) / 2];
+         arelent * rel = *rel_mid;
 
-         if (rel->address == vma
-             && rel->sym_ptr_ptr != NULL
-             /* Absolute relocations do not provide a more helpful symbolic address.  */
-             && ! bfd_is_abs_section ((* rel->sym_ptr_ptr)->section))
+         if (rel->address == vma)
            {
-             if (place != NULL)
-               * place = thisplace;
-             return * rel->sym_ptr_ptr;
+             /* Absolute relocations do not provide a more helpful
+                symbolic address.  Find a non-absolute relocation
+                with the same address.  */
+             arelent **rel_vma = rel_mid;
+             for (rel_mid--;
+                  rel_mid >= rel_low && rel_mid[0]->address == vma;
+                  rel_mid--)
+               rel_vma = rel_mid;
+
+             for (; rel_vma <= rel_high && rel_vma[0]->address == vma;
+                  rel_vma++)
+               {
+                 rel = *rel_vma;
+                 if (rel->sym_ptr_ptr != NULL
+                     && ! bfd_is_abs_section ((* rel->sym_ptr_ptr)->section))
+                   {
+                     if (place != NULL)
+                       * place = thisplace;
+                     return * rel->sym_ptr_ptr;
+                   }
+               }
+             break;
            }
 
-         /* We are scanning backwards, so if we go below the target address
-            we have failed.  */
-         if (rel_pp[rel_count]->address < vma)
+         if (vma < rel->address)
+           rel_high = rel_mid;
+         else if (vma >= rel_mid[1]->address)
+           rel_low = rel_mid + 1;
+         else
            break;
        }
     }
@@ -2230,6 +2256,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       asymbol *nextsym;
       bfd_vma nextstop_offset;
       bfd_boolean insns;
+      bfd_boolean do_print = TRUE;
 
       addr = section->vma + addr_offset;
       addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust;
@@ -2255,7 +2282,23 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
          pinfo->symtab_pos = -1;
        }
 
-      if (! prefix_addresses)
+      if (sym && paux->symbol)
+       {
+         const char *name = bfd_asymbol_name (sym);
+         char *alloc = NULL;
+
+         if (do_demangle && name[0] != '\0')
+           {
+             /* Demangle the name.  */
+             alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
+             if (alloc != NULL)
+               name = alloc;
+           }
+         do_print = streq (name, paux->symbol);
+         free (alloc);
+       }
+
+      if (! prefix_addresses && do_print)
        {
          pinfo->fprintf_func (pinfo->stream, "\n");
          objdump_print_addr_with_sym (abfd, section, sym, addr,
@@ -2316,9 +2359,14 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       else
        insns = FALSE;
 
-      disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
-                        addr_offset, nextstop_offset,
-                        rel_offset, &rel_pp, rel_ppend);
+      if (do_print)
+       {
+         disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
+                            addr_offset, nextstop_offset,
+                            rel_offset, &rel_pp, rel_ppend);
+         if (paux->symbol)
+           break;
+       }
 
       addr_offset = nextstop_offset;
       sym = nextsym;
@@ -2371,6 +2419,7 @@ disassemble_data (bfd *abfd)
   aux.dynrelbuf = NULL;
   aux.dynrelcount = 0;
   aux.reloc = NULL;
+  aux.symbol = disasm_sym;
 
   disasm_info.print_address_func = objdump_print_address;
   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
@@ -2466,6 +2515,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   struct dwarf_section *section = &debug_displays [debug].section;
   bfd *abfd = (bfd *) file;
   bfd_byte *contents;
+  bfd_size_type amt;
 
   if (section->start != NULL)
     {
@@ -2480,9 +2530,11 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
   section->num_relocs = 0;
   section->address = bfd_get_section_vma (abfd, sec);
   section->size = bfd_get_section_size (sec);
-  section->start = contents = malloc (section->size + 1);
+  amt = section->size + 1;
+  section->start = contents = malloc (amt);
   section->user_data = sec;
-  if (section->start == NULL
+  if (amt == 0
+      || section->start == NULL
       || !bfd_get_full_section_contents (abfd, sec, &contents))
     {
       free_debug_section (debug);
@@ -2729,6 +2781,16 @@ dump_dwarf (bfd *abfd)
       init_dwarf_regnames_s390 ();
       break;
 
+    case bfd_arch_riscv:
+      init_dwarf_regnames_riscv ();
+      break;
+
+    case bfd_arch_s12z:
+      /* S12Z has a 24 bit address space.  But the only known
+        producer of dwarf_info encodes addresses into 32 bits.  */
+      eh_addr_size = 4;
+      break;
+
     default:
       break;
     }
@@ -3427,9 +3489,23 @@ dump_relocs_in_section (bfd *abfd,
     }
 
   if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0
-      && (ufile_ptr) relsize > bfd_get_file_size (abfd))
+      && (/* Check that the size of the relocs is reasonable.  Note that some
+            file formats, eg aout, can have relocs whose internal size is
+            larger than their external size, thus we check the size divided
+            by four against the file size.  See PR 23931 for an example of
+            this.  */
+         ((ufile_ptr) (relsize / 4) > bfd_get_file_size (abfd))
+         /* Also check the section's reloc count since if this is negative
+            (or very large) the computation in bfd_get_reloc_upper_bound
+            may have resulted in returning a small, positive integer.
+            See PR 22508 for a reproducer.
+
+            Note - we check against file size rather than section size as
+            it is possible for there to be more relocs that apply to a
+            section than there are bytes in that section.  */
+         || (section->reloc_count > bfd_get_file_size (abfd))))
     {
-      printf (" (too many: 0x%x)\n", section->reloc_count);
+      printf (" (too many: %#x relocs)\n", section->reloc_count);
       bfd_set_error (bfd_error_file_truncated);
       bfd_fatal (bfd_get_filename (abfd));
     }
@@ -3543,7 +3619,7 @@ dump_bfd (bfd *abfd)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
            abfd->xvec->name);
   if (dump_ar_hdrs)
-    print_arelt_descr (stdout, abfd, TRUE);
+    print_arelt_descr (stdout, abfd, TRUE, FALSE);
   if (dump_file_header)
     dump_bfd_header (abfd);
   if (dump_private_headers)
@@ -3607,8 +3683,8 @@ dump_bfd (bfd *abfd)
              exit_status = 1;
            }
        }
-      /* PR 6483: If there was no STABS or IEEE debug
-        info in the file, try DWARF instead.  */
+      /* PR 6483: If there was no STABS debug info in the file, try
+        DWARF instead.  */
       else if (! dump_dwarf_section_info)
        {
          dwarf_select_sections_all ();
@@ -3797,7 +3873,8 @@ main (int argc, char **argv)
 
   expandargv (&argc, &argv);
 
-  bfd_init ();
+  if (bfd_init () != BFD_INIT_MAGIC)
+    fatal (_("fatal error: libbfd ABI mismatch"));
   set_default_bfd_target ();
 
   while ((c = getopt_long (argc, argv,
@@ -3949,6 +4026,7 @@ main (int argc, char **argv)
        case 'd':
          disassemble = TRUE;
          seenflag = TRUE;
+         disasm_sym = optarg;
          break;
        case 'z':
          disassemble_zeroes = TRUE;