mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-24 01:33:32 +08:00
* objdump.c (disassemble_bytes): Don't skip zeroes if the
disassembler has told us that we are in a branch delay slot.
This commit is contained in:
parent
39bb58e0ad
commit
b4aabb244e
@ -1,3 +1,8 @@
|
||||
Tue Jan 28 16:47:26 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* objdump.c (disassemble_bytes): Don't skip zeroes if the
|
||||
disassembler has told us that we are in a branch delay slot.
|
||||
|
||||
Mon Jan 20 14:24:04 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* size.c (berkeley_sum): Rewrite. Skip sections which are not
|
||||
|
@ -54,6 +54,7 @@ static int dump_reloc_info; /* -r */
|
||||
static int dump_dynamic_reloc_info; /* -R */
|
||||
static int dump_ar_hdrs; /* -a */
|
||||
static int dump_private_headers; /* -p */
|
||||
static int prefix_addresses; /* --prefix-addresses */
|
||||
static int with_line_numbers; /* -l */
|
||||
static boolean with_source_code; /* -S */
|
||||
static int show_raw_insn; /* --show-raw-insn */
|
||||
@ -124,12 +125,27 @@ display_bfd PARAMS ((bfd *abfd));
|
||||
static void
|
||||
objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
static asymbol *
|
||||
find_symbol_for_address PARAMS ((bfd *, asection *, bfd_vma, boolean, long *));
|
||||
|
||||
static void
|
||||
objdump_print_addr_with_sym PARAMS ((bfd *, asection *, asymbol *, bfd_vma,
|
||||
struct disassemble_info *));
|
||||
|
||||
static void
|
||||
objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
static void
|
||||
show_line PARAMS ((bfd *, asection *, bfd_vma));
|
||||
|
||||
static void
|
||||
disassemble_bytes PARAMS ((struct disassemble_info *, disassembler_ftype,
|
||||
boolean, bfd_byte *, long, long, arelent ***,
|
||||
arelent **));
|
||||
|
||||
static void
|
||||
disassemble_data PARAMS ((bfd *));
|
||||
|
||||
static const char *
|
||||
endian_string PARAMS ((enum bfd_endian));
|
||||
|
||||
@ -149,7 +165,8 @@ Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
|
||||
[--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
|
||||
[--wide] [--version] [--help] [--private-headers]\n\
|
||||
[--start-address=addr] [--stop-address=addr]\n\
|
||||
[--show-raw-insn] [-EB|-EL] [--endian={big|little}] objfile...\n\
|
||||
[--prefix-addresses] [--show-raw-insn]\n\
|
||||
[-EB|-EL] [--endian={big|little}] objfile...\n\
|
||||
at least one option besides -l (--line-numbers) must be given\n");
|
||||
list_supported_targets (program_name, stream);
|
||||
if (status == 0)
|
||||
@ -181,6 +198,7 @@ static struct option long_options[]=
|
||||
{"help", no_argument, NULL, 'H'},
|
||||
{"info", no_argument, NULL, 'i'},
|
||||
{"line-numbers", no_argument, NULL, 'l'},
|
||||
{"prefix-addresses", no_argument, &prefix_addresses, 1},
|
||||
{"reloc", no_argument, NULL, 'r'},
|
||||
{"section", required_argument, NULL, 'j'},
|
||||
{"section-headers", no_argument, NULL, 'h'},
|
||||
@ -437,8 +455,8 @@ compare_symbols (ap, bp)
|
||||
if (! af && bf)
|
||||
return -1;
|
||||
|
||||
/* Try to sort global symbols before local symbols before debugging
|
||||
symbols. */
|
||||
/* Try to sort global symbols before local symbols before function
|
||||
symbols before debugging symbols. */
|
||||
|
||||
aflags = a->flags;
|
||||
bflags = b->flags;
|
||||
@ -450,6 +468,13 @@ compare_symbols (ap, bp)
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
|
||||
{
|
||||
if ((aflags & BSF_FUNCTION) != 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
|
||||
{
|
||||
if ((aflags & BSF_LOCAL) != 0)
|
||||
@ -515,18 +540,24 @@ objdump_print_value (vma, info)
|
||||
sprintf_vma (buf, vma);
|
||||
for (p = buf; *p == '0'; ++p)
|
||||
;
|
||||
if (*p == '\0')
|
||||
--p;
|
||||
(*info->fprintf_func) (info->stream, "%s", p);
|
||||
}
|
||||
|
||||
/* Print VMA symbolically to INFO if possible. */
|
||||
/* Locate a symbol given a bfd, a section, and a VMA. If REQUIRE_SEC
|
||||
is true, then always require the symbol to be in the section. This
|
||||
returns NULL if there is no suitable symbol. If PLACE is not NULL,
|
||||
then *PLACE is set to the index of the symbol in sorted_syms. */
|
||||
|
||||
static void
|
||||
objdump_print_address (vma, info)
|
||||
static asymbol *
|
||||
find_symbol_for_address (abfd, sec, vma, require_sec, place)
|
||||
bfd *abfd;
|
||||
asection *sec;
|
||||
bfd_vma vma;
|
||||
struct disassemble_info *info;
|
||||
boolean require_sec;
|
||||
long *place;
|
||||
{
|
||||
char buf[30];
|
||||
|
||||
/* @@ Would it speed things up to cache the last two symbols returned,
|
||||
and maybe their address ranges? For many processors, only one memory
|
||||
operand can be present at a time, so the 2-entry cache wouldn't be
|
||||
@ -537,11 +568,8 @@ objdump_print_address (vma, info)
|
||||
long max = sorted_symcount;
|
||||
long thisplace;
|
||||
|
||||
sprintf_vma (buf, vma);
|
||||
(*info->fprintf_func) (info->stream, "%s", buf);
|
||||
|
||||
if (sorted_symcount < 1)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* Perform a binary search looking for the closest symbol to the
|
||||
required value. We are searching the range (min, max]. */
|
||||
@ -572,102 +600,150 @@ objdump_print_address (vma, info)
|
||||
== bfd_asymbol_value (sorted_syms[thisplace - 1])))
|
||||
--thisplace;
|
||||
|
||||
{
|
||||
/* If the file is relocateable, and the symbol could be from this
|
||||
section, prefer a symbol from this section over symbols from
|
||||
others, even if the other symbol's value might be closer.
|
||||
/* If the file is relocateable, and the symbol could be from this
|
||||
section, prefer a symbol from this section over symbols from
|
||||
others, even if the other symbol's value might be closer.
|
||||
|
||||
Note that this may be wrong for some symbol references if the
|
||||
sections have overlapping memory ranges, but in that case there's
|
||||
no way to tell what's desired without looking at the relocation
|
||||
table. */
|
||||
struct objdump_disasm_info *aux;
|
||||
long i;
|
||||
Note that this may be wrong for some symbol references if the
|
||||
sections have overlapping memory ranges, but in that case there's
|
||||
no way to tell what's desired without looking at the relocation
|
||||
table. */
|
||||
|
||||
aux = (struct objdump_disasm_info *) info->application_data;
|
||||
if (sorted_syms[thisplace]->section != aux->sec
|
||||
&& (aux->require_sec
|
||||
|| ((aux->abfd->flags & HAS_RELOC) != 0
|
||||
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
|
||||
&& vma < (bfd_get_section_vma (aux->abfd, aux->sec)
|
||||
+ bfd_section_size (aux->abfd, aux->sec)))))
|
||||
{
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (bfd_asymbol_value (sorted_syms[i])
|
||||
!= bfd_asymbol_value (sorted_syms[thisplace]))
|
||||
if (sorted_syms[thisplace]->section != sec
|
||||
&& (require_sec
|
||||
|| ((abfd->flags & HAS_RELOC) != 0
|
||||
&& vma >= bfd_get_section_vma (abfd, sec)
|
||||
&& vma < (bfd_get_section_vma (abfd, sec)
|
||||
+ bfd_section_size (abfd, sec)))))
|
||||
{
|
||||
long i;
|
||||
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (bfd_asymbol_value (sorted_syms[i])
|
||||
!= bfd_asymbol_value (sorted_syms[thisplace]))
|
||||
break;
|
||||
}
|
||||
--i;
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
if (sorted_syms[i]->section == sec
|
||||
&& (i == 0
|
||||
|| sorted_syms[i - 1]->section != sec
|
||||
|| (bfd_asymbol_value (sorted_syms[i])
|
||||
!= bfd_asymbol_value (sorted_syms[i - 1]))))
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
--i;
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
if (sorted_syms[i]->section == aux->sec
|
||||
&& (i == 0
|
||||
|| sorted_syms[i - 1]->section != aux->sec
|
||||
|| (bfd_asymbol_value (sorted_syms[i])
|
||||
!= bfd_asymbol_value (sorted_syms[i - 1]))))
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sorted_syms[thisplace]->section != aux->sec)
|
||||
{
|
||||
/* We didn't find a good symbol with a smaller value.
|
||||
Look for one with a larger value. */
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (sorted_syms[i]->section == aux->sec)
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sorted_syms[thisplace]->section != sec)
|
||||
{
|
||||
/* We didn't find a good symbol with a smaller value.
|
||||
Look for one with a larger value. */
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (sorted_syms[i]->section == sec)
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sorted_syms[thisplace]->section != aux->sec
|
||||
&& (aux->require_sec
|
||||
|| ((aux->abfd->flags & HAS_RELOC) != 0
|
||||
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
|
||||
&& vma < (bfd_get_section_vma (aux->abfd, aux->sec)
|
||||
+ bfd_section_size (aux->abfd, aux->sec)))))
|
||||
{
|
||||
bfd_vma secaddr;
|
||||
|
||||
(*info->fprintf_func) (info->stream, " <%s",
|
||||
bfd_get_section_name (aux->abfd, aux->sec));
|
||||
secaddr = bfd_get_section_vma (aux->abfd, aux->sec);
|
||||
if (vma < secaddr)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "-");
|
||||
objdump_print_value (secaddr - vma, info);
|
||||
}
|
||||
else if (vma > secaddr)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "+");
|
||||
objdump_print_value (vma - secaddr, info);
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*info->fprintf_func) (info->stream, " <%s", sorted_syms[thisplace]->name);
|
||||
if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "-");
|
||||
objdump_print_value (bfd_asymbol_value (sorted_syms[thisplace]) - vma,
|
||||
info);
|
||||
if (sorted_syms[thisplace]->section != sec
|
||||
&& (require_sec
|
||||
|| ((abfd->flags & HAS_RELOC) != 0
|
||||
&& vma >= bfd_get_section_vma (abfd, sec)
|
||||
&& vma < (bfd_get_section_vma (abfd, sec)
|
||||
+ bfd_section_size (abfd, sec)))))
|
||||
{
|
||||
/* There is no suitable symbol. */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
|
||||
|
||||
if (place != NULL)
|
||||
*place = thisplace;
|
||||
|
||||
return sorted_syms[thisplace];
|
||||
}
|
||||
|
||||
/* Print an address to INFO symbolically. */
|
||||
|
||||
static void
|
||||
objdump_print_addr_with_sym (abfd, sec, sym, vma, info)
|
||||
bfd *abfd;
|
||||
asection *sec;
|
||||
asymbol *sym;
|
||||
bfd_vma vma;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
char buf[30];
|
||||
|
||||
sprintf_vma (buf, vma);
|
||||
(*info->fprintf_func) (info->stream, "%s", buf);
|
||||
|
||||
if (sym == NULL)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "+");
|
||||
objdump_print_value (vma - bfd_asymbol_value (sorted_syms[thisplace]),
|
||||
info);
|
||||
bfd_vma secaddr;
|
||||
|
||||
(*info->fprintf_func) (info->stream, " <%s",
|
||||
bfd_get_section_name (abfd, sec));
|
||||
secaddr = bfd_get_section_vma (abfd, sec);
|
||||
if (vma < secaddr)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "-");
|
||||
objdump_print_value (secaddr - vma, info);
|
||||
}
|
||||
else if (vma > secaddr)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "+");
|
||||
objdump_print_value (vma - secaddr, info);
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
else
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, " <%s", sym->name);
|
||||
if (bfd_asymbol_value (sym) > vma)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "-");
|
||||
objdump_print_value (bfd_asymbol_value (sym) - vma, info);
|
||||
}
|
||||
else if (vma > bfd_asymbol_value (sym))
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "+");
|
||||
objdump_print_value (vma - bfd_asymbol_value (sym), info);
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print VMA symbolically to INFO if possible. */
|
||||
|
||||
static void
|
||||
objdump_print_address (vma, info)
|
||||
bfd_vma vma;
|
||||
struct disassemble_info *info;
|
||||
{
|
||||
struct objdump_disasm_info *aux;
|
||||
asymbol *sym;
|
||||
|
||||
if (sorted_symcount < 1)
|
||||
{
|
||||
char buf[30];
|
||||
|
||||
sprintf_vma (buf, vma);
|
||||
(*info->fprintf_func) (info->stream, "%s", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
aux = (struct objdump_disasm_info *) info->application_data;
|
||||
sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
|
||||
(long *) NULL);
|
||||
objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info);
|
||||
}
|
||||
|
||||
/* Hold the last function name and the last line number we displayed
|
||||
@ -910,18 +986,256 @@ objdump_sprintf (va_alist)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The number of zeroes we want to see before we start skipping them.
|
||||
The number is arbitrarily chosen. */
|
||||
|
||||
#define SKIP_ZEROES (8)
|
||||
|
||||
/* The number of zeroes to skip at the end of a section. If the
|
||||
number of zeroes at the end is between SKIP_ZEROES_AT_END and
|
||||
SKIP_ZEROES, they will be disassembled. If there are fewer than
|
||||
SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
|
||||
attempt to avoid disassembling zeroes inserted by section
|
||||
alignment. */
|
||||
|
||||
#define SKIP_ZEROES_AT_END (3)
|
||||
|
||||
/* Disassemble some data in memory between given values. */
|
||||
|
||||
static void
|
||||
disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
|
||||
relppend)
|
||||
struct disassemble_info *info;
|
||||
disassembler_ftype disassemble_fn;
|
||||
boolean insns;
|
||||
bfd_byte *data;
|
||||
long start;
|
||||
long stop;
|
||||
arelent ***relppp;
|
||||
arelent **relppend;
|
||||
{
|
||||
struct objdump_disasm_info *aux;
|
||||
asection *section;
|
||||
int bytes_per_line;
|
||||
boolean done_dot;
|
||||
long i;
|
||||
|
||||
aux = (struct objdump_disasm_info *) info->application_data;
|
||||
section = aux->sec;
|
||||
|
||||
if (insns)
|
||||
bytes_per_line = 4;
|
||||
else
|
||||
bytes_per_line = 16;
|
||||
|
||||
info->insn_info_valid = 0;
|
||||
|
||||
done_dot = false;
|
||||
i = start;
|
||||
while (i < stop)
|
||||
{
|
||||
long z;
|
||||
int bytes;
|
||||
boolean need_nl = false;
|
||||
|
||||
/* If we see more than SKIP_ZEROES bytes of zeroes, we just
|
||||
print `...'. */
|
||||
for (z = i; z < stop; z++)
|
||||
if (data[z] != 0)
|
||||
break;
|
||||
if ((info->insn_info_valid == 0
|
||||
|| info->branch_delay_insns == 0)
|
||||
&& (z - i >= SKIP_ZEROES
|
||||
|| (z == stop && z - i < SKIP_ZEROES_AT_END)))
|
||||
{
|
||||
printf ("\t...\n");
|
||||
|
||||
/* If there are more nonzero bytes to follow, we only skip
|
||||
zeroes in multiples of 4, to try to avoid running over
|
||||
the start of an instruction which happens to start with
|
||||
zero. */
|
||||
if (z != stop)
|
||||
z = i + ((z - i) &~ 3);
|
||||
|
||||
bytes = z - i;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[1000];
|
||||
SFILE sfile;
|
||||
int pb = 0;
|
||||
|
||||
done_dot = false;
|
||||
|
||||
if (with_line_numbers || with_source_code)
|
||||
show_line (aux->abfd, section, i);
|
||||
|
||||
if (! prefix_addresses)
|
||||
printf ("%6lx:\t", (unsigned long) (i - start));
|
||||
else
|
||||
{
|
||||
aux->require_sec = true;
|
||||
objdump_print_address (section->vma + i, info);
|
||||
aux->require_sec = false;
|
||||
putchar (' ');
|
||||
}
|
||||
|
||||
if (insns)
|
||||
{
|
||||
sfile.buffer = sfile.current = buf;
|
||||
info->fprintf_func = (fprintf_ftype) objdump_sprintf;
|
||||
info->stream = (FILE *) &sfile;
|
||||
info->bytes_per_line = 0;
|
||||
bytes = (*disassemble_fn) (section->vma + i, info);
|
||||
info->fprintf_func = (fprintf_ftype) fprintf;
|
||||
info->stream = stdout;
|
||||
if (info->bytes_per_line != 0)
|
||||
bytes_per_line = info->bytes_per_line;
|
||||
if (bytes < 0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
long j;
|
||||
|
||||
bytes = bytes_per_line;
|
||||
if (i + bytes > stop)
|
||||
bytes = stop - i;
|
||||
|
||||
for (j = i; j < i + bytes; ++j)
|
||||
{
|
||||
if (isprint (data[j]))
|
||||
buf[j - i] = data[j];
|
||||
else
|
||||
buf[j - i] = '.';
|
||||
}
|
||||
buf[j - i] = '\0';
|
||||
}
|
||||
|
||||
if (! prefix_addresses || show_raw_insn)
|
||||
{
|
||||
long j;
|
||||
|
||||
/* If ! prefix_addresses and ! wide_output, we print
|
||||
four bytes per line. */
|
||||
pb = bytes;
|
||||
if (pb > bytes_per_line && ! prefix_addresses && ! wide_output)
|
||||
pb = bytes_per_line;
|
||||
|
||||
for (j = i; j < i + pb; ++j)
|
||||
{
|
||||
printf ("%02x", (unsigned) data[j]);
|
||||
putchar (' ');
|
||||
}
|
||||
|
||||
for (; pb < bytes_per_line; ++pb)
|
||||
printf (" ");
|
||||
|
||||
/* Separate raw data from instruction by extra space. */
|
||||
if (insns)
|
||||
putchar ('\t');
|
||||
else
|
||||
printf (" ");
|
||||
}
|
||||
|
||||
printf ("%s", buf);
|
||||
|
||||
if (! prefix_addresses || show_raw_insn)
|
||||
{
|
||||
while (pb < bytes)
|
||||
{
|
||||
long j;
|
||||
|
||||
putchar ('\n');
|
||||
j = i + pb;
|
||||
printf ("%6lx:\t", (unsigned long) (j - start));
|
||||
pb += bytes_per_line;
|
||||
if (pb > bytes)
|
||||
pb = bytes;
|
||||
for (; j < i + pb; ++j)
|
||||
{
|
||||
printf ("%02x", (unsigned) data[j]);
|
||||
putchar (' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!wide_output)
|
||||
putchar ('\n');
|
||||
else
|
||||
need_nl = true;
|
||||
}
|
||||
|
||||
if (dump_reloc_info
|
||||
&& (section->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
while ((*relppp) < relppend
|
||||
&& ((**relppp)->address >= (bfd_vma) i
|
||||
&& (**relppp)->address < (bfd_vma) i + bytes))
|
||||
{
|
||||
arelent *q;
|
||||
const char *sym_name;
|
||||
|
||||
q = **relppp;
|
||||
|
||||
if (wide_output)
|
||||
putchar ('\t');
|
||||
else
|
||||
printf ("\t\t\t");
|
||||
|
||||
objdump_print_value (section->vma + q->address - start, info);
|
||||
|
||||
printf (": %s\t", q->howto->name);
|
||||
|
||||
if (q->sym_ptr_ptr != NULL
|
||||
&& *q->sym_ptr_ptr != NULL)
|
||||
{
|
||||
sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
|
||||
if (sym_name == NULL || *sym_name == '\0')
|
||||
{
|
||||
asection *sym_sec;
|
||||
|
||||
sym_sec = bfd_get_section (*q->sym_ptr_ptr);
|
||||
sym_name = bfd_get_section_name (abfd, sym_sec);
|
||||
if (sym_name == NULL || *sym_name == '\0')
|
||||
sym_name = "*unknown*";
|
||||
}
|
||||
}
|
||||
else
|
||||
sym_name = "*unknown*";
|
||||
|
||||
printf ("%s", sym_name);
|
||||
|
||||
if (q->addend)
|
||||
{
|
||||
printf ("+0x");
|
||||
objdump_print_value (q->addend, info);
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
need_nl = false;
|
||||
++(*relppp);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_nl)
|
||||
printf ("\n");
|
||||
|
||||
i += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disassemble the contents of an object file. */
|
||||
|
||||
static void
|
||||
disassemble_data (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
long i;
|
||||
disassembler_ftype disassemble_fn = 0; /* New style */
|
||||
disassembler_ftype disassemble_fn;
|
||||
struct disassemble_info disasm_info;
|
||||
struct objdump_disasm_info aux;
|
||||
asection *section;
|
||||
boolean done_dot = false;
|
||||
char buf[200];
|
||||
SFILE sfile;
|
||||
|
||||
print_files = NULL;
|
||||
prev_functionname = NULL;
|
||||
@ -1061,118 +1375,76 @@ disassemble_data (abfd)
|
||||
if (stop > disasm_info.buffer_length)
|
||||
stop = disasm_info.buffer_length;
|
||||
}
|
||||
while (i < stop)
|
||||
|
||||
if (prefix_addresses)
|
||||
disassemble_bytes (&disasm_info, disassemble_fn, true, data, i, stop,
|
||||
&relpp, relppend);
|
||||
else
|
||||
{
|
||||
int bytes;
|
||||
boolean need_nl = false;
|
||||
asymbol *sym;
|
||||
long place;
|
||||
|
||||
if (data[i] == 0
|
||||
&& (i + 1 >= stop
|
||||
|| (data[i + 1] == 0
|
||||
&& (i + 2 >= stop
|
||||
|| (data[i + 2] == 0
|
||||
&& (i + 3 >= stop
|
||||
|| data[i + 3] == 0))))))
|
||||
sym = find_symbol_for_address (abfd, section, i, true, &place);
|
||||
++place;
|
||||
while (i < stop)
|
||||
{
|
||||
if (done_dot == false)
|
||||
{
|
||||
printf ("...\n");
|
||||
done_dot = true;
|
||||
}
|
||||
bytes = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
done_dot = false;
|
||||
if (with_line_numbers || with_source_code)
|
||||
show_line (abfd, section, i);
|
||||
aux.require_sec = true;
|
||||
objdump_print_address (section->vma + i, &disasm_info);
|
||||
aux.require_sec = false;
|
||||
putchar (' ');
|
||||
asymbol *nextsym;
|
||||
long nextstop;
|
||||
boolean insns;
|
||||
|
||||
sfile.buffer = sfile.current = buf;
|
||||
disasm_info.fprintf_func = (fprintf_ftype) objdump_sprintf;
|
||||
disasm_info.stream = (FILE *) &sfile;
|
||||
bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
|
||||
disasm_info.fprintf_func = (fprintf_ftype) fprintf;
|
||||
disasm_info.stream = stdout;
|
||||
if (bytes < 0)
|
||||
break;
|
||||
disasm_info.symbol = sym;
|
||||
|
||||
if (show_raw_insn)
|
||||
{
|
||||
long j;
|
||||
for (j = i; j < i + bytes; ++j)
|
||||
{
|
||||
printf ("%02x", (unsigned) data[j]);
|
||||
putchar (' ');
|
||||
}
|
||||
/* Separate raw data from instruction by extra space. */
|
||||
putchar (' ');
|
||||
}
|
||||
printf ("\n");
|
||||
objdump_print_addr_with_sym (abfd, section, sym,
|
||||
section->vma + i,
|
||||
&disasm_info);
|
||||
printf (":\n");
|
||||
|
||||
printf ("%s", sfile.buffer);
|
||||
|
||||
if (!wide_output)
|
||||
putchar ('\n');
|
||||
if (sym == NULL)
|
||||
nextsym = NULL;
|
||||
else
|
||||
need_nl = true;
|
||||
}
|
||||
|
||||
if (dump_reloc_info
|
||||
&& (section->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
while (relpp < relppend
|
||||
&& ((*relpp)->address >= (bfd_vma) i
|
||||
&& (*relpp)->address < (bfd_vma) i + bytes))
|
||||
{
|
||||
arelent *q;
|
||||
const char *sym_name;
|
||||
|
||||
q = *relpp;
|
||||
|
||||
printf ("\t\tRELOC: ");
|
||||
|
||||
printf_vma (section->vma + q->address);
|
||||
|
||||
printf (" %s ", q->howto->name);
|
||||
|
||||
if (q->sym_ptr_ptr != NULL
|
||||
&& *q->sym_ptr_ptr != NULL)
|
||||
{
|
||||
sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
|
||||
if (sym_name == NULL || *sym_name == '\0')
|
||||
{
|
||||
asection *sym_sec;
|
||||
|
||||
sym_sec = bfd_get_section (*q->sym_ptr_ptr);
|
||||
sym_name = bfd_get_section_name (abfd, sym_sec);
|
||||
if (sym_name == NULL || *sym_name == '\0')
|
||||
sym_name = "*unknown*";
|
||||
}
|
||||
}
|
||||
while (place < sorted_symcount
|
||||
&& (sorted_syms[place]->section != section
|
||||
|| (bfd_asymbol_value (sorted_syms[place])
|
||||
<= bfd_asymbol_value (sym))))
|
||||
++place;
|
||||
if (place >= sorted_symcount)
|
||||
nextsym = NULL;
|
||||
else
|
||||
sym_name = "*unknown*";
|
||||
|
||||
printf ("%s", sym_name);
|
||||
|
||||
if (q->addend)
|
||||
{
|
||||
printf ("+0x");
|
||||
printf_vma (q->addend);
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
need_nl = false;
|
||||
++relpp;
|
||||
nextsym = sorted_syms[place];
|
||||
}
|
||||
|
||||
if (nextsym == NULL)
|
||||
nextstop = stop;
|
||||
else
|
||||
{
|
||||
nextstop = bfd_asymbol_value (nextsym) - section->vma;
|
||||
if (nextstop > stop)
|
||||
nextstop = stop;
|
||||
}
|
||||
|
||||
/* If a symbol is explicitly marked as being an object
|
||||
rather than a function, just dump the bytes without
|
||||
disassembling them. */
|
||||
if (disassemble_all
|
||||
|| sym == NULL
|
||||
|| ((sym->flags & BSF_OBJECT) == 0
|
||||
&& (strstr (bfd_asymbol_name (sym), "gnu_compiled")
|
||||
== NULL)
|
||||
&& (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
|
||||
== NULL))
|
||||
|| (sym->flags & BSF_FUNCTION) != 0)
|
||||
insns = true;
|
||||
else
|
||||
insns = false;
|
||||
|
||||
disassemble_bytes (&disasm_info, disassemble_fn, insns, data, i,
|
||||
nextstop, &relpp, relppend);
|
||||
|
||||
i = nextstop;
|
||||
sym = nextsym;
|
||||
}
|
||||
|
||||
if (need_nl)
|
||||
printf ("\n");
|
||||
|
||||
i += bytes;
|
||||
}
|
||||
|
||||
free (data);
|
||||
|
Loading…
Reference in New Issue
Block a user