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.
#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
arelent ** dynrelbuf;
long dynrelcount;
disassembler_ftype disassemble_fn;
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+ arelent * reloc;
+#endif
};
/* Architecture to disassemble for, or default if NULL. */
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);
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)
{
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)
{
}
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);
}
/* sprintf to a "stream". */
-static int
+static int ATTRIBUTE_PRINTF_2
objdump_sprintf (SFILE *f, const char *format, ...)
{
size_t n;
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;
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 `...'. */
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)
{
{
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;
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*");
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;
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;
bfd_print_symbol_all);
printf ("\n");
}
+
current++;
}
printf ("\n\n");
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)
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. */
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),