Automatic date update in version.in
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 174596e252b8aa5610aed01015cc7512d129ca45..59abc1189be5643a44405cc71cabb1397ae9f5d8 100644 (file)
@@ -493,12 +493,7 @@ dump_section_header (bfd *abfd, asection *section,
       PF (SEC_COFF_NOREAD, "NOREAD");
     }
   else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    {
-      /* Note - sections can have both the READONLY and NOREAD attributes
-        set.  In this case the NOREAD takes precedence, but we report both
-        since the user may need to know that both bits are set.  */
-      PF (SEC_ELF_NOREAD, "NOREAD");
-    }
+    PF (SEC_ELF_PURECODE, "PURECODE");
   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
   PF (SEC_GROUP, "GROUP");
   if (bfd_get_arch (abfd) == bfd_arch_mep)
@@ -620,6 +615,18 @@ slurp_dynamic_symtab (bfd *abfd)
   return sy;
 }
 
+/* Some symbol names are significant and should be kept in the
+   table of sorted symbol names, even if they are marked as
+   debugging/section symbols.  */
+
+static bfd_boolean
+is_significant_symbol_name (const char * name)
+{
+  return strcmp (name, ".plt") == 0
+    ||   strcmp (name, ".got") == 0
+    ||   strcmp (name, ".plt.got") == 0;
+}
+
 /* Filter out (in place) symbols that are useless for disassembly.
    COUNT is the number of elements in SYMBOLS.
    Return the number of useful symbols.  */
@@ -635,7 +642,8 @@ remove_useless_symbols (asymbol **symbols, long count)
 
       if (sym->name == NULL || sym->name[0] == '\0')
        continue;
-      if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
+      if ((sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
+         && ! is_significant_symbol_name (sym->name))
        continue;
       if (bfd_is_und_section (sym->section)
          || bfd_is_com_section (sym->section))
@@ -743,6 +751,21 @@ compare_symbols (const void *ap, const void *bp)
        return 1;
     }
 
+  if (bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour
+      && bfd_get_flavour (bfd_asymbol_bfd (b)) == bfd_target_elf_flavour)
+    {
+      bfd_vma asz, bsz;
+
+      asz = 0;
+      if ((a->flags & BSF_SYNTHETIC) == 0)
+       asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
+      bsz = 0;
+      if ((b->flags & BSF_SYNTHETIC) == 0)
+       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 '.'.  */
   if (an[0] == '.' && bn[0] != '.')
@@ -823,7 +846,8 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
        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;
@@ -902,11 +926,14 @@ find_symbol_for_address (bfd_vma vma,
 
   /* The symbol we want is now in min, the low end of the range we
      were searching.  If there are several symbols with the same
-     value, we want the first one.  */
+     value, we want the first (non-section/non-debugging) one.  */
   thisplace = min;
   while (thisplace > 0
         && (bfd_asymbol_value (sorted_syms[thisplace])
-            == bfd_asymbol_value (sorted_syms[thisplace - 1])))
+            == bfd_asymbol_value (sorted_syms[thisplace - 1]))
+        && ((sorted_syms[thisplace - 1]->flags
+             & (BSF_SECTION_SYM | BSF_DEBUGGING)) == 0)
+        )
     --thisplace;
 
   /* Prefer a symbol in the current section if we have multple symbols
@@ -992,6 +1019,41 @@ find_symbol_for_address (bfd_vma vma,
        return NULL;
     }
 
+  /* If we have not found an exact match for the specified address
+     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.  */
+  if (!want_section
+      && aux->dynrelbuf != NULL
+      && sorted_syms[thisplace]->value != 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;
+
+      for (rel_count = aux->dynrelcount, rel_pp = aux->dynrelbuf;
+          rel_count--;)
+       {
+         arelent * rel = rel_pp[rel_count];
+
+         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 (place != NULL)
+               * place = thisplace;
+             return * rel->sym_ptr_ptr;
+           }
+
+         /* We are scanning backwards, so if we go below the target address
+            we have failed.  */
+         if (rel_pp[rel_count]->address < vma)
+           break;
+       }
+    }
+
   if (place != NULL)
     *place = thisplace;
 
@@ -1029,8 +1091,21 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
   else
     {
       (*inf->fprintf_func) (inf->stream, " <");
+
       objdump_print_symname (abfd, inf, sym);
-      if (bfd_asymbol_value (sym) > vma)
+
+      if (bfd_asymbol_value (sym) == vma)
+       ;
+      /* Undefined symbols in an executables and dynamic objects do not have
+        a value associated with them, so it does not make sense to display
+        an offset relative to them.  Normally we would not be provided with
+        this kind of symbol, but the target backend might choose to do so,
+        and the code in find_symbol_for_address might return an as yet
+        unresolved symbol associated with a dynamic reloc.  */
+      else if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC))
+              && bfd_is_und_section (sym->section))
+       ;
+      else if (bfd_asymbol_value (sym) > vma)
        {
          (*inf->fprintf_func) (inf->stream, "-0x");
          objdump_print_value (bfd_asymbol_value (sym) - vma, inf, TRUE);
@@ -1040,6 +1115,7 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
          (*inf->fprintf_func) (inf->stream, "+0x");
          objdump_print_value (vma - bfd_asymbol_value (sym), inf, TRUE);
        }
+
       (*inf->fprintf_func) (inf->stream, ">");
     }
 
@@ -1995,7 +2071,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 
   /* Decide which set of relocs to use.  Load them if necessary.  */
   paux = (struct objdump_disasm_info *) pinfo->application_data;
-  if (paux->dynrelbuf)
+  if (paux->dynrelbuf && dump_dynamic_reloc_info)
     {
       rel_pp = paux->dynrelbuf;
       rel_count = paux->dynrelcount;
@@ -2272,13 +2348,11 @@ disassemble_data (bfd *abfd)
   /* Allow the target to customize the info structure.  */
   disassemble_init_for_target (& disasm_info);
 
-  /* Pre-load the dynamic relocs if we are going
-     to be dumping them along with the disassembly.  */
-  if (dump_dynamic_reloc_info)
+  /* 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)
+      if (relsize < 0 && dump_dynamic_reloc_info)
        bfd_fatal (bfd_get_filename (abfd));
 
       if (relsize > 0)
This page took 0.025079 seconds and 4 git commands to generate.