* config/tc-mips.c (mips_set_options): Add ase_mt for MT instructions.
[deliverable/binutils-gdb.git] / binutils / objdump.c
index 7249054214a9e8d5b4e6fc6bdf6c97e841ea8976..14c9cb6888a490873229ec422a19ab01c10bc64b 100644 (file)
@@ -1,6 +1,6 @@
 /* objdump.c -- dump information about an object file.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004
+   2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -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.  */
@@ -290,12 +293,17 @@ nonfatal (const char *msg)
 }
 \f
 static void
-dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
+dump_section_header (bfd *abfd, asection *section,
                     void *ignored ATTRIBUTE_UNUSED)
 {
   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);
@@ -324,12 +332,16 @@ dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section,
   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
   PF (SEC_EXCLUDE, "EXCLUDE");
   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
-  PF (SEC_BLOCK, "BLOCK");
-  PF (SEC_CLINK, "CLINK");
+  if (bfd_get_arch (abfd) == bfd_arch_tic54x)
+    {
+      PF (SEC_TIC54X_BLOCK, "BLOCK");
+      PF (SEC_TIC54X_CLINK, "CLINK");
+    }
   PF (SEC_SMALL_DATA, "SMALL_DATA");
-  PF (SEC_SHARED, "SHARED");
-  PF (SEC_ARCH_BIT_0, "ARCH_BIT_0");
+  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)
     {
@@ -848,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)
     {
@@ -858,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);
 }
@@ -1156,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;
@@ -1235,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;
@@ -1279,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 `...'.  */
@@ -1314,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)
            {
@@ -1342,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;
@@ -1509,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*");
@@ -1814,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;
@@ -2053,7 +2119,8 @@ find_stabs_section (bfd *abfd, asection *section, void *names)
       
       if (strtab)
        {
-         stabs = read_section_stabs (abfd, section->name, &stab_size);
+         stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
+                                                  &stab_size);
          if (stabs)
            print_section_stabs (abfd, section->name, &sought->string_offset);
        }
@@ -2286,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;
 
@@ -2310,6 +2378,7 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
                              bfd_print_symbol_all);
          printf ("\n");
        }
+
       current++;
     }
   printf ("\n\n");
@@ -2398,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)
@@ -2531,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.  */
@@ -2546,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.027088 seconds and 4 git commands to generate.