* config/tc-mips.c (mips_set_options): Add ase_mt for MT instructions.
[deliverable/binutils-gdb.git] / binutils / objdump.c
index f63e298152b971dfde341b0aa5e1a017764d3b49..14c9cb6888a490873229ec422a19ab01c10bc64b 100644 (file)
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* Objdump overview.
 
@@ -65,7 +65,7 @@
 #define        BYTES_IN_WORD   32
 #include "aout/aout64.h"
 
-#ifdef NEED_DECLARATION_FPRINTF
+#if !HAVE_DECL_FPRINTF
 /* This is needed by init_disassemble_info().  */
 extern int fprintf (FILE *, const char *, ...);
 #endif
@@ -128,6 +128,9 @@ struct objdump_disasm_info
   arelent **         dynrelbuf;
   long               dynrelcount;
   disassembler_ftype disassemble_fn;
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+  arelent *          reloc;
+#endif
 };
 
 /* Architecture to disassemble for, or default if NULL.  */
@@ -296,6 +299,11 @@ dump_section_header (bfd *abfd, asection *section,
   char *comma = "";
   unsigned int opb = bfd_octets_per_byte (abfd);
 
+  /* Ignore linker created section.  See elfNN_ia64_object_p in
+     bfd/elfxx-ia64.c.  */
+  if (section->flags & SEC_LINKER_CREATED)
+    return;
+
   printf ("%3d %-13s %08lx  ", section->index,
          bfd_get_section_name (abfd, section),
          (unsigned long) bfd_section_size (abfd, section) / opb);
@@ -333,6 +341,7 @@ dump_section_header (bfd *abfd, asection *section,
   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
     PF (SEC_COFF_SHARED, "SHARED");
   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
+  PF (SEC_GROUP, "GROUP");
 
   if ((section->flags & SEC_LINK_ONCE) != 0)
     {
@@ -851,7 +860,10 @@ objdump_print_addr (bfd_vma vma,
                    bfd_boolean skip_zeroes)
 {
   struct objdump_disasm_info *aux;
-  asymbol *sym;
+  asymbol *sym = NULL; /* Initialize to avoid compiler warning.  */
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+  bfd_boolean skip_find = FALSE;
+#endif
 
   if (sorted_symcount < 1)
     {
@@ -861,7 +873,25 @@ objdump_print_addr (bfd_vma vma,
     }
 
   aux = (struct objdump_disasm_info *) info->application_data;
-  sym = find_symbol_for_address (vma, info, NULL);
+
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+  if (aux->reloc != NULL
+      && aux->reloc->sym_ptr_ptr != NULL
+      && * aux->reloc->sym_ptr_ptr != NULL)
+    {
+      sym = * aux->reloc->sym_ptr_ptr;
+
+      /* Adjust the vma to the reloc.  */
+      vma += bfd_asymbol_value (sym);
+
+      if (bfd_is_und_section (bfd_get_section (sym)))
+       skip_find = TRUE;
+    }
+
+  if (!skip_find)
+#endif
+    sym = find_symbol_for_address (vma, info, NULL);
+
   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
                               skip_zeroes);
 }
@@ -1159,7 +1189,7 @@ typedef struct
 
 /* sprintf to a "stream".  */
 
-static int
+static int ATTRIBUTE_PRINTF_2
 objdump_sprintf (SFILE *f, const char *format, ...)
 {
   size_t n;
@@ -1238,6 +1268,7 @@ disassemble_bytes (struct disassemble_info * info,
   unsigned int opb = info->octets_per_byte;
   unsigned int skip_zeroes = info->skip_zeroes;
   unsigned int skip_zeroes_at_end = info->skip_zeroes_at_end;
+  int octets = opb;
   SFILE sfile;
 
   aux = (struct objdump_disasm_info *) info->application_data;
@@ -1282,8 +1313,14 @@ disassemble_bytes (struct disassemble_info * info,
   while (addr_offset < stop_offset)
     {
       bfd_vma z;
-      int octets = 0;
       bfd_boolean need_nl = FALSE;
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+      int previous_octets;
+
+      /* Remember the length of the previous instruction.  */
+      previous_octets = octets;
+#endif
+      octets = 0;
 
       /* If we see more than SKIP_ZEROES octets of zeroes, we just
         print `...'.  */
@@ -1317,10 +1354,7 @@ disassemble_bytes (struct disassemble_info * info,
          done_dot = FALSE;
 
          if (with_line_numbers || with_source_code)
-           /* The line number tables will refer to unadjusted
-              section VMAs, so we must undo any VMA modifications
-              when calling show_line.  */
-           show_line (aux->abfd, section, addr_offset - adjust_section_vma);
+           show_line (aux->abfd, section, addr_offset);
 
          if (! prefix_addresses)
            {
@@ -1345,22 +1379,43 @@ disassemble_bytes (struct disassemble_info * info,
            {
              sfile.pos = 0;
              info->fprintf_func = (fprintf_ftype) objdump_sprintf;
-             info->stream = (FILE *) &sfile;
+             info->stream = &sfile;
              info->bytes_per_line = 0;
              info->bytes_per_chunk = 0;
+             info->flags = 0;
 
 #ifdef DISASSEMBLER_NEEDS_RELOCS
-             /* FIXME: This is wrong.  It tests the number of octets
-                in the last instruction, not the current one.  */
-             if (*relppp < relppend
-                 && (**relppp)->address >= rel_offset + addr_offset
-                 && ((**relppp)->address
-                     < rel_offset + addr_offset + octets / opb))
-               info->flags = INSN_HAS_RELOC;
-             else
+             if (*relppp < relppend)
+               {
+                 bfd_signed_vma distance_to_rel;
+
+                 distance_to_rel = (**relppp)->address
+                   - (rel_offset + addr_offset);
+
+                 /* Check to see if the current reloc is associated with
+                    the instruction that we are about to disassemble.  */
+                 if (distance_to_rel == 0
+                     /* FIXME: This is wrong.  We are trying to catch
+                        relocs that are addressed part way through the
+                        current instruction, as might happen with a packed
+                        VLIW instruction.  Unfortunately we do not know the
+                        length of the current instruction since we have not
+                        disassembled it yet.  Instead we take a guess based
+                        upon the length of the previous instruction.  The
+                        proper solution is to have a new target-specific
+                        disassembler function which just returns the length
+                        of an instruction at a given address without trying
+                        to display its disassembly. */
+                     || (distance_to_rel > 0
+                         && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb)))
+                   {
+                     info->flags = INSN_HAS_RELOC;
+                     aux->reloc = **relppp;
+                   }
+                 else
+                   aux->reloc = NULL;
+               }
 #endif
-               info->flags = 0;
-
              octets = (*disassemble_fn) (section->vma + addr_offset, info);
              info->fprintf_func = (fprintf_ftype) fprintf;
              info->stream = stdout;
@@ -1512,7 +1567,12 @@ disassemble_bytes (struct disassemble_info * info,
              objdump_print_value (section->vma - rel_offset + q->address,
                                   info, TRUE);
 
-             printf (": %s\t", q->howto->name);
+             if (q->howto == NULL)
+               printf (": *unknown*\t");
+             else if (q->howto->name)
+               printf (": %s\t", q->howto->name);
+             else
+               printf (": %d\t", q->howto->type);
 
              if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
                printf ("*unknown*");
@@ -1817,6 +1877,9 @@ disassemble_data (bfd *abfd)
   aux.require_sec = FALSE;
   aux.dynrelbuf = NULL;
   aux.dynrelcount = 0;
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+  aux.reloc = NULL;
+#endif
 
   disasm_info.print_address_func = objdump_print_address;
   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
@@ -2290,8 +2353,9 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
        printf (_("could not determine the type of symbol number %ld\n"),
                count);
 
-      else if (dump_special_syms
-              || !bfd_is_target_special_symbol (cur_bfd, *current))
+      else if (process_section_p ((* current)->section)
+              && (dump_special_syms
+                  || !bfd_is_target_special_symbol (cur_bfd, *current)))
        {
          const char *name = (*current)->name;
 
@@ -2314,6 +2378,7 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
                              bfd_print_symbol_all);
          printf ("\n");
        }
+
       current++;
     }
   printf ("\n\n");
@@ -2402,23 +2467,20 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
          section_name = NULL;
        }
 
+      bfd_printf_vma (abfd, q->address);
+      if (q->howto == NULL)
+       printf (" *unknown*         ");
+      else if (q->howto->name)
+       printf (" %-16s  ", q->howto->name);
+      else
+       printf (" %-16d  ", q->howto->type);
       if (sym_name)
-       {
-         bfd_printf_vma (abfd, q->address);
-         if (q->howto->name)
-           printf (" %-16s  ", q->howto->name);
-         else
-           printf (" %-16d  ", q->howto->type);
-         objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
-       }
+       objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
       else
        {
          if (section_name == NULL)
            section_name = "*unknown*";
-         bfd_printf_vma (abfd, q->address);
-         printf (" %-16s  [%s]",
-                 q->howto->name,
-                 section_name);
+         printf ("[%s]", section_name);
        }
 
       if (q->addend)
@@ -2535,10 +2597,15 @@ add_include_path (const char *path)
 static void
 adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
                  asection *section,
-                 void *dummy ATTRIBUTE_UNUSED)
+                 void *arg)
 {
-  section->vma += adjust_section_vma;
-  section->lma += adjust_section_vma;
+  if ((section->flags & SEC_DEBUGGING) == 0)
+    {
+      bfd_boolean *has_reloc_p = (bfd_boolean *) arg;
+      section->vma += adjust_section_vma;
+      if (*has_reloc_p)
+       section->lma += adjust_section_vma;
+    }
 }
 
 /* Dump selected contents of ABFD.  */
@@ -2550,7 +2617,10 @@ dump_bfd (bfd *abfd)
      the BFD information is a hack.  However, we must do it, or
      bfd_find_nearest_line will not do the right thing.  */
   if (adjust_section_vma != 0)
-    bfd_map_over_sections (abfd, adjust_addresses, NULL);
+    {
+      bfd_boolean has_reloc = (abfd->flags & HAS_RELOC);
+      bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
+    }
 
   if (! dump_debugging_tags)
     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
This page took 0.026968 seconds and 4 git commands to generate.