* syslex.l: Adjust top-of-file comment: this file is part of GNU
[deliverable/binutils-gdb.git] / binutils / objdump.c
index f63e298152b971dfde341b0aa5e1a017764d3b49..52cd3d005cc051ffd1e2a53156dcea60f1955a56 100644 (file)
@@ -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);
 }
@@ -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 `...'.  */
@@ -1345,22 +1382,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;
@@ -1817,6 +1875,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 +2351,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 +2376,7 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
                              bfd_print_symbol_all);
          printf ("\n");
        }
+
       current++;
     }
   printf ("\n\n");
This page took 0.026554 seconds and 4 git commands to generate.