@R devel snapshot
This commit is contained in:
parent
0e9acdc7ec
commit
179513c0a0
|
@ -76,12 +76,15 @@ static int dump_debugging; /* --debugging */
|
|||
static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
|
||||
static int file_start_context = 0; /* --file-start-context */
|
||||
|
||||
static int flag_re_source = 0; /* -X, --re-source */
|
||||
|
||||
/* Extra info to pass to the disassembler address printing function. */
|
||||
struct objdump_disasm_info
|
||||
{
|
||||
bfd *abfd;
|
||||
asection *sec;
|
||||
bfd_boolean require_sec;
|
||||
bfd_boolean rts;
|
||||
};
|
||||
|
||||
/* Architecture to disassemble for, or default if NULL. */
|
||||
|
@ -164,7 +167,7 @@ static int objdump_symbol_at_address
|
|||
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
static void show_line
|
||||
PARAMS ((bfd *, asection *, bfd_vma));
|
||||
static void disassemble_bytes
|
||||
static bfd_vma disassemble_bytes
|
||||
PARAMS ((struct disassemble_info *, disassembler_ftype, bfd_boolean,
|
||||
bfd_byte *, bfd_vma, bfd_vma, arelent ***, arelent **));
|
||||
static void disassemble_data
|
||||
|
@ -233,6 +236,7 @@ usage (stream, status)
|
|||
`lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
|
||||
or `gnat'\n\
|
||||
-w, --wide Format output for more than 80 columns\n\
|
||||
-X, --re-source Generate asm style output\n\
|
||||
-z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\
|
||||
--start-address=ADDR Only process data whose address is >= ADDR\n\
|
||||
--stop-address=ADDR Only process data whose address is <= ADDR\n\
|
||||
|
@ -283,6 +287,7 @@ static struct option long_options[]=
|
|||
{"no-show-raw-insn", no_argument, &show_raw_insn, -1},
|
||||
{"prefix-addresses", no_argument, &prefix_addresses, 1},
|
||||
{"reloc", no_argument, NULL, 'r'},
|
||||
{"re-source", no_argument, NULL, 'X'},
|
||||
{"section", required_argument, NULL, 'j'},
|
||||
{"section-headers", no_argument, NULL, 'h'},
|
||||
{"show-raw-insn", no_argument, &show_raw_insn, 1},
|
||||
|
@ -816,6 +821,7 @@ objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
|
|||
struct disassemble_info *info;
|
||||
bfd_boolean skip_zeroes;
|
||||
{
|
||||
if (!flag_re_source)
|
||||
objdump_print_value (vma, info, skip_zeroes);
|
||||
|
||||
if (sym == NULL)
|
||||
|
@ -839,6 +845,7 @@ objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!flag_re_source)
|
||||
(*info->fprintf_func) (info->stream, " <");
|
||||
objdump_print_symname (abfd, info, sym);
|
||||
if (bfd_asymbol_value (sym) > vma)
|
||||
|
@ -851,7 +858,8 @@ objdump_print_addr_with_sym (abfd, sec, sym, vma, info, skip_zeroes)
|
|||
(*info->fprintf_func) (info->stream, "+0x");
|
||||
objdump_print_value (vma - bfd_asymbol_value (sym), info, TRUE);
|
||||
}
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
if (!flag_re_source)
|
||||
(*info->fprintf_func) (info->stream, ">");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,6 +921,65 @@ objdump_symbol_at_address (vma, info)
|
|||
return (sym != NULL && (bfd_asymbol_value (sym) == vma));
|
||||
}
|
||||
|
||||
|
||||
/* This function is used to print to the bit-bucket. */
|
||||
static int
|
||||
#ifdef __STDC__
|
||||
dummy_printer(FILE *file ATTRIBUTE_UNUSED,
|
||||
const char *format ATTRIBUTE_UNUSED, ...)
|
||||
#else
|
||||
dummy_printer(file)
|
||||
FILE *file ATTRIBUTE_UNUSED;
|
||||
#endif
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Add a synthetic symbol to the sorted symbols.
|
||||
* Derived from the current symbol.
|
||||
*/
|
||||
static asymbol * current_symbol;
|
||||
static unsigned dummy_symbol_counter;
|
||||
bfd_boolean mark_local;
|
||||
bfd_boolean mark_skip;
|
||||
static void
|
||||
objdump_add_synthetic_symbol(bfd_vma vma, struct disassemble_info *info)
|
||||
{
|
||||
static char buf[512];
|
||||
asymbol *new_symbol;
|
||||
long place = 0;
|
||||
|
||||
if (mark_skip)
|
||||
{
|
||||
mark_skip = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
struct objdump_disasm_info *aux =
|
||||
(struct objdump_disasm_info *) info->application_data;
|
||||
|
||||
new_symbol = find_symbol_for_address(aux->sec->owner, aux->sec, vma,
|
||||
TRUE, &place);
|
||||
if (new_symbol && new_symbol->section == info->section && new_symbol->value == vma)
|
||||
return;
|
||||
|
||||
|
||||
++sorted_symcount;
|
||||
sorted_syms = (asymbol **)xrealloc(sorted_syms, sorted_symcount * sizeof(asymbol *));
|
||||
sorted_syms[sorted_symcount - 1] = new_symbol = (asymbol *)xmalloc(sizeof(asymbol));
|
||||
*new_symbol = *current_symbol;
|
||||
new_symbol->section = aux->sec;
|
||||
new_symbol->value = vma;
|
||||
sprintf(buf, ".%s_%d", current_symbol->name, ++dummy_symbol_counter);
|
||||
new_symbol->name = xstrdup(buf);
|
||||
if (mark_local)
|
||||
{
|
||||
new_symbol->flags |= BSF_LOCAL;
|
||||
mark_local = 0;
|
||||
}
|
||||
/* Sort the symbols into section and symbol order. */
|
||||
qsort(sorted_syms, sorted_symcount, sizeof(asymbol *), compare_symbols);
|
||||
}
|
||||
|
||||
/* Hold the last function name and the last line number we displayed
|
||||
in a disassembly. */
|
||||
|
||||
|
@ -1185,7 +1252,7 @@ objdump_sprintf VPARAMS ((SFILE *f, const char *format, ...))
|
|||
|
||||
/* Disassemble some data in memory between given values. */
|
||||
|
||||
static void
|
||||
static bfd_vma
|
||||
disassemble_bytes (info, disassemble_fn, insns, data,
|
||||
start_offset, stop_offset, relppp,
|
||||
relppend)
|
||||
|
@ -1219,7 +1286,7 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
zeroes in chunks of 4, ensuring that there is always a leading
|
||||
zero remaining. */
|
||||
skip_addr_chars = 0;
|
||||
if (! prefix_addresses)
|
||||
if (! prefix_addresses && !flag_re_source)
|
||||
{
|
||||
char buf[30];
|
||||
char *s;
|
||||
|
@ -1287,14 +1354,17 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
|
||||
if (! prefix_addresses)
|
||||
{
|
||||
char *s;
|
||||
if (!flag_re_source)
|
||||
{
|
||||
char *s;
|
||||
|
||||
bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
|
||||
for (s = buf + skip_addr_chars; *s == '0'; s++)
|
||||
*s = ' ';
|
||||
if (*s == '\0')
|
||||
*--s = '0';
|
||||
printf ("%s:\t", buf + skip_addr_chars);
|
||||
bfd_sprintf_vma(aux->abfd, buf, section->vma + addr_offset);
|
||||
for (s = buf + skip_addr_chars; *s == '0'; s++)
|
||||
*s = ' ';
|
||||
if (*s == '\0')
|
||||
*--s = '0';
|
||||
printf("%s:\t", buf + skip_addr_chars);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1306,10 +1376,12 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
|
||||
if (insns)
|
||||
{
|
||||
fprintf_ftype saved_fprintf_func = info->fprintf_func;
|
||||
sfile.size = 120;
|
||||
sfile.buffer = xmalloc (sfile.size);
|
||||
sfile.current = sfile.buffer;
|
||||
info->fprintf_func = (fprintf_ftype) objdump_sprintf;
|
||||
|
||||
info->fprintf_func = (fprintf_ftype) objdump_sprintf;
|
||||
info->stream = (FILE *) &sfile;
|
||||
info->bytes_per_line = 0;
|
||||
info->bytes_per_chunk = 0;
|
||||
|
@ -1346,8 +1418,10 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
info->flags = 0;
|
||||
|
||||
octets = (*disassemble_fn) (section->vma + addr_offset, info);
|
||||
info->fprintf_func = (fprintf_ftype) fprintf;
|
||||
|
||||
info->fprintf_func = saved_fprintf_func;
|
||||
info->stream = stdout;
|
||||
|
||||
if (info->bytes_per_line != 0)
|
||||
octets_per_line = info->bytes_per_line;
|
||||
if (octets < 0)
|
||||
|
@ -1393,33 +1467,38 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
else
|
||||
bpc = 1;
|
||||
|
||||
for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
|
||||
{
|
||||
int k;
|
||||
if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
|
||||
{
|
||||
for (k = bpc - 1; k >= 0; k--)
|
||||
printf ("%02x", (unsigned) data[j + k]);
|
||||
putchar (' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
for (k = 0; k < bpc; k++)
|
||||
printf ("%02x", (unsigned) data[j + k]);
|
||||
putchar (' ');
|
||||
}
|
||||
}
|
||||
if (!flag_re_source)
|
||||
{
|
||||
for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
|
||||
{
|
||||
int k;
|
||||
if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
|
||||
{
|
||||
for (k = bpc - 1; k >= 0; k--)
|
||||
printf("%02x", (unsigned)data[j + k]);
|
||||
putchar(' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
for (k = 0; k < bpc; k++)
|
||||
printf("%02x", (unsigned)data[j + k]);
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
|
||||
for (; pb < octets_per_line; pb += bpc)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < bpc; k++)
|
||||
printf (" ");
|
||||
putchar (' ');
|
||||
}
|
||||
for (; pb < octets_per_line; pb += bpc)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < bpc; k++)
|
||||
printf(" ");
|
||||
putchar(' ');
|
||||
}
|
||||
}
|
||||
/* Separate raw data from instruction by extra space. */
|
||||
if (insns < 0)
|
||||
{
|
||||
} else
|
||||
if (insns)
|
||||
putchar ('\t');
|
||||
else
|
||||
|
@ -1429,14 +1508,15 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
if (! insns)
|
||||
printf ("%s", buf);
|
||||
else
|
||||
if (insns > 0)
|
||||
{
|
||||
printf ("%s", sfile.buffer);
|
||||
free (sfile.buffer);
|
||||
}
|
||||
|
||||
if (prefix_addresses
|
||||
if (!flag_re_source && (prefix_addresses
|
||||
? show_raw_insn > 0
|
||||
: show_raw_insn >= 0)
|
||||
: show_raw_insn >= 0))
|
||||
{
|
||||
while (pb < octets)
|
||||
{
|
||||
|
@ -1477,15 +1557,19 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
}
|
||||
|
||||
if (!wide_output)
|
||||
putchar ('\n');
|
||||
{
|
||||
if (insns >= 0)
|
||||
putchar('\n');
|
||||
}
|
||||
else
|
||||
need_nl = TRUE;
|
||||
}
|
||||
|
||||
if ((section->flags & SEC_RELOC) != 0
|
||||
#ifndef DISASSEMBLER_NEEDS_RELOCS
|
||||
&& dump_reloc_info
|
||||
&& dump_reloc_info
|
||||
#endif
|
||||
&& !flag_re_source
|
||||
)
|
||||
{
|
||||
while ((*relppp) < relppend
|
||||
|
@ -1547,7 +1631,15 @@ disassemble_bytes (info, disassemble_fn, insns, data,
|
|||
printf ("\n");
|
||||
|
||||
addr_offset += octets / opb;
|
||||
|
||||
if (((struct objdump_disasm_info *) info->application_data)->rts)
|
||||
{
|
||||
((struct objdump_disasm_info *) info->application_data)->rts = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return addr_offset;
|
||||
}
|
||||
|
||||
/* Disassemble the contents of an object file. */
|
||||
|
@ -1582,6 +1674,7 @@ disassemble_data (abfd)
|
|||
disasm_info.application_data = (PTR) &aux;
|
||||
aux.abfd = abfd;
|
||||
aux.require_sec = FALSE;
|
||||
aux.rts = FALSE;
|
||||
disasm_info.print_address_func = objdump_print_address;
|
||||
disasm_info.symbol_at_address_func = objdump_symbol_at_address;
|
||||
|
||||
|
@ -1687,8 +1780,10 @@ disassemble_data (abfd)
|
|||
++relpp;
|
||||
}
|
||||
}
|
||||
|
||||
printf (_("Disassembly of section %s:\n"), section->name);
|
||||
if (flag_re_source)
|
||||
printf(_("\tsection %s:\n"), section->name);
|
||||
else
|
||||
printf (_("Disassembly of section %s:\n"), section->name);
|
||||
|
||||
datasize = bfd_get_section_size_before_reloc (section);
|
||||
if (datasize == 0)
|
||||
|
@ -1722,6 +1817,40 @@ disassemble_data (abfd)
|
|||
stop_offset = disasm_info.buffer_length / opb;
|
||||
}
|
||||
|
||||
if (flag_re_source && (section->flags & BSF_KEEP))
|
||||
{
|
||||
arelent **myrelpp = relpp;
|
||||
disasm_info.fprintf_func = (fprintf_ftype)dummy_printer;
|
||||
disasm_info.print_address_func = &objdump_add_synthetic_symbol;
|
||||
|
||||
for (unsigned long pos = addr_offset, end = addr_offset; pos < stop_offset;)
|
||||
{
|
||||
current_symbol = find_symbol_for_address(abfd, section, section->vma + pos,
|
||||
TRUE, &place);
|
||||
|
||||
while (place < sorted_symcount) {
|
||||
asymbol * s = sorted_syms[place];
|
||||
if (s->section == section && s->value > pos && s->name[0] != '.')
|
||||
{
|
||||
end = s->value;
|
||||
break;
|
||||
}
|
||||
++place;
|
||||
}
|
||||
if (place == sorted_symcount)
|
||||
pos = stop_offset;
|
||||
|
||||
dummy_symbol_counter = 0;
|
||||
disassemble_bytes(&disasm_info, disassemble_fn, -1, data,
|
||||
pos, end, &myrelpp, relppend);
|
||||
|
||||
pos = end;
|
||||
}
|
||||
disasm_info.print_address_func = objdump_print_address;
|
||||
disasm_info.fprintf_func = (fprintf_ftype)fprintf;
|
||||
}
|
||||
|
||||
|
||||
sym = find_symbol_for_address (abfd, section, section->vma + addr_offset,
|
||||
TRUE, &place);
|
||||
|
||||
|
@ -1797,21 +1926,30 @@ disassemble_data (abfd)
|
|||
rather than a function, just dump the bytes without
|
||||
disassembling them. */
|
||||
if (disassemble_all
|
||||
|| sym == NULL
|
||||
|| bfd_asymbol_value (sym) > section->vma + addr_offset
|
||||
|| ((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)
|
||||
|| sym == NULL
|
||||
|| bfd_asymbol_value(sym) > section->vma + addr_offset
|
||||
|| ((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)
|
||||
#ifdef TARGET_AMIGA
|
||||
insns = (section->flags & BSF_KEEP) != 0 && (sym->flags & BSF_LOCAL) == 0;
|
||||
#else
|
||||
insns = TRUE;
|
||||
#endif
|
||||
else
|
||||
insns = FALSE;
|
||||
|
||||
disassemble_bytes (&disasm_info, disassemble_fn, insns, data,
|
||||
addr_offset = disassemble_bytes (&disasm_info, disassemble_fn, insns, data,
|
||||
addr_offset, nextstop_offset, &relpp, relppend);
|
||||
|
||||
if (addr_offset < nextstop_offset)
|
||||
disassemble_bytes(&disasm_info, disassemble_fn, 0, data,
|
||||
addr_offset, nextstop_offset, &relpp, relppend);
|
||||
|
||||
|
||||
addr_offset = nextstop_offset;
|
||||
sym = nextsym;
|
||||
}
|
||||
|
@ -2647,7 +2785,7 @@ main (argc, argv)
|
|||
bfd_init ();
|
||||
set_default_bfd_target ();
|
||||
|
||||
while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zgG",
|
||||
while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zgGX",
|
||||
long_options, (int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
|
@ -2655,6 +2793,9 @@ main (argc, argv)
|
|||
{
|
||||
case 0:
|
||||
break; /* We've been given a long option. */
|
||||
case 'X':
|
||||
flag_re_source = 1;
|
||||
break;
|
||||
case 'm':
|
||||
machine = optarg;
|
||||
break;
|
||||
|
|
|
@ -31,8 +31,12 @@ struct objdump_disasm_info
|
|||
bfd *abfd;
|
||||
asection *sec;
|
||||
bfd_boolean require_sec;
|
||||
bfd_boolean rts;
|
||||
};
|
||||
|
||||
extern bfd_boolean mark_local;
|
||||
extern bfd_boolean mark_skip;
|
||||
|
||||
/* Support display of symbols in baserel offsets. */
|
||||
static void
|
||||
parse_disassembler_options (char *);
|
||||
|
@ -461,6 +465,8 @@ print_insn_m68k (memaddr, info)
|
|||
|
||||
d = best->args;
|
||||
|
||||
((struct objdump_disasm_info *) info->application_data)->rts = 0 == strncmp("rts", best->name, 3);
|
||||
|
||||
(*info->fprintf_func) (info->stream, "%s", best->name);
|
||||
|
||||
if (*d)
|
||||
|
@ -698,7 +704,7 @@ print_insn_arg (d, buffer, p0, addr, info)
|
|||
val = NEXTLONG (p1);
|
||||
else
|
||||
return -2;
|
||||
(*info->fprintf_func) (info->stream, "#%d", val);
|
||||
(*info->fprintf_func) (info->stream, "#%d", val);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
|
@ -836,6 +842,7 @@ print_insn_arg (d, buffer, p0, addr, info)
|
|||
(struct objdump_disasm_info *) info->application_data;
|
||||
asection * text = aux->sec;
|
||||
aux->sec = bfd_get_section (*info->relp->sym_ptr_ptr);
|
||||
mark_local = TRUE;
|
||||
(*info->print_address_func) (uval, info);
|
||||
|
||||
/* restore section to .text */
|
||||
|
@ -851,6 +858,7 @@ print_insn_arg (d, buffer, p0, addr, info)
|
|||
case 2:
|
||||
val = NEXTWORD (p);
|
||||
(*info->fprintf_func) (info->stream, "%%pc@(");
|
||||
mark_local = TRUE;
|
||||
(*info->print_address_func) (addr + val, info);
|
||||
(*info->fprintf_func) (info->stream, ")");
|
||||
break;
|
||||
|
@ -899,8 +907,27 @@ print_insn_arg (d, buffer, p0, addr, info)
|
|||
}
|
||||
if (flt_p) /* Print a float? */
|
||||
(*info->fprintf_func) (info->stream, "#%g", flval);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "#%d", val);
|
||||
else
|
||||
{
|
||||
if (info->relp &&
|
||||
info->relp->address <= addr + (p - p0)
|
||||
&& info->relp->sym_ptr_ptr && *info->relp->sym_ptr_ptr)
|
||||
{
|
||||
/* Swap section with the correct one. */
|
||||
struct objdump_disasm_info *aux =
|
||||
(struct objdump_disasm_info *) info->application_data;
|
||||
asection * text = aux->sec;
|
||||
aux->sec = bfd_get_section(*info->relp->sym_ptr_ptr);
|
||||
(*info->fprintf_func) (info->stream, "#");
|
||||
mark_local = 1;
|
||||
(*info->print_address_func) (val, info);
|
||||
|
||||
/* restore section to .text */
|
||||
aux->sec = text;
|
||||
}
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "#%d", val);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1352,6 +1379,7 @@ print_base (regno, disp, info)
|
|||
if (regno == -1)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "%%pc@(");
|
||||
mark_local = TRUE;
|
||||
(*info->print_address_func) (disp, info);
|
||||
}
|
||||
else
|
||||
|
@ -1381,6 +1409,8 @@ print_base (regno, disp, info)
|
|||
*/
|
||||
if (disp & 0x80000000)
|
||||
offset = 0x7ffe;
|
||||
|
||||
mark_skip = TRUE;
|
||||
(*info->print_address_func) (disp + offset, info);
|
||||
|
||||
/* restore section to .text */
|
||||
|
|
Loading…
Reference in New Issue