forked from Imagelibrary/binutils-gdb
objdump --disassemble=sym peculiarities
Given this testcase: .text mov $x1,%eax f1: mov $f1,%eax .type f1,@function .size f1,.-f1 mov $x2,%eax f2: mov $f2,%eax .type f2,@function .size f2,.-f2+0x1000 #bad size objdump --reloc --disassemble=f1 prints 00000000 <f1-0x5>: 0: b8 00 00 00 00 mov $0x0,%eax and objdump --reloc --disassemble=f2 prints 0000000f <f2>: f: b8 0f 00 00 00 mov $0xf,%eax 10: R_386_32 .text It seems for f1 we get the insn before f1 and no reloc whereas, post159daa36fa, f2 is disassembled correctly. Some analysis says that find_symbol_for_address may return a symbol past the current address, and reloc skipping is broken. Fix both of these problems. * objdump.c (disassemble_jumps, disassemble_bytes): Replace relppp with relpp, ie. don't update caller's rel_pp. Adjust calls. (disassemble_section): Skip over relocs inside loop rather than before loop. Revert7e538762c2. If given a symbol, don't start disassembling until its address is reached. Correct end of function calculation.
This commit is contained in:
@@ -2946,7 +2946,7 @@ disassemble_jumps (struct disassemble_info * inf,
|
||||
bfd_vma start_offset,
|
||||
bfd_vma stop_offset,
|
||||
bfd_vma rel_offset,
|
||||
arelent *** relppp,
|
||||
arelent ** relpp,
|
||||
arelent ** relppend)
|
||||
{
|
||||
struct objdump_disasm_info *aux;
|
||||
@@ -2988,11 +2988,11 @@ disassemble_jumps (struct disassemble_info * inf,
|
||||
if (inf->disassembler_needs_relocs
|
||||
&& (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
|
||||
&& (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0
|
||||
&& *relppp < relppend)
|
||||
&& relpp < relppend)
|
||||
{
|
||||
bfd_signed_vma distance_to_rel;
|
||||
|
||||
distance_to_rel = (**relppp)->address - (rel_offset + addr_offset);
|
||||
distance_to_rel = (*relpp)->address - (rel_offset + addr_offset);
|
||||
|
||||
/* Check to see if the current reloc is associated with
|
||||
the instruction that we are about to disassemble. */
|
||||
@@ -3205,7 +3205,7 @@ disassemble_bytes (struct disassemble_info *inf,
|
||||
bfd_vma start_offset,
|
||||
bfd_vma stop_offset,
|
||||
bfd_vma rel_offset,
|
||||
arelent ***relppp,
|
||||
arelent **relpp,
|
||||
arelent **relppend)
|
||||
{
|
||||
struct objdump_disasm_info *aux;
|
||||
@@ -3377,13 +3377,13 @@ disassemble_bytes (struct disassemble_info *inf,
|
||||
if (inf->disassembler_needs_relocs
|
||||
&& (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
|
||||
&& (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0
|
||||
&& *relppp < relppend)
|
||||
&& relpp < relppend)
|
||||
{
|
||||
bfd_signed_vma distance_to_rel;
|
||||
int max_reloc_offset
|
||||
= aux->abfd->arch_info->max_reloc_offset_into_insn;
|
||||
|
||||
distance_to_rel = ((**relppp)->address - rel_offset
|
||||
distance_to_rel = ((*relpp)->address - rel_offset
|
||||
- addr_offset);
|
||||
|
||||
insn_size = 0;
|
||||
@@ -3427,7 +3427,7 @@ disassemble_bytes (struct disassemble_info *inf,
|
||||
&& distance_to_rel < insn_size / (int) opb))
|
||||
{
|
||||
inf->flags |= INSN_HAS_RELOC;
|
||||
aux->reloc = **relppp;
|
||||
aux->reloc = *relpp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3600,14 +3600,14 @@ disassemble_bytes (struct disassemble_info *inf,
|
||||
need_nl = true;
|
||||
}
|
||||
|
||||
while ((*relppp) < relppend
|
||||
&& (**relppp)->address < rel_offset + addr_offset + octets / opb)
|
||||
while (relpp < relppend
|
||||
&& (*relpp)->address < rel_offset + addr_offset + octets / opb)
|
||||
{
|
||||
if (dump_reloc_info || dump_dynamic_reloc_info)
|
||||
{
|
||||
arelent *q;
|
||||
|
||||
q = **relppp;
|
||||
q = *relpp;
|
||||
|
||||
if (wide_output)
|
||||
putchar ('\t');
|
||||
@@ -3665,7 +3665,7 @@ disassemble_bytes (struct disassemble_info *inf,
|
||||
printf ("\n");
|
||||
need_nl = false;
|
||||
}
|
||||
++(*relppp);
|
||||
++relpp;
|
||||
}
|
||||
|
||||
if (need_nl)
|
||||
@@ -3809,12 +3809,6 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
if (sorted_symcount > 1)
|
||||
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
|
||||
|
||||
/* Skip over the relocs belonging to addresses below the
|
||||
start address. */
|
||||
while (rel_pp < rel_ppend
|
||||
&& (*rel_pp)->address < rel_offset + addr_offset)
|
||||
++rel_pp;
|
||||
|
||||
printf (_("\nDisassembly of section %s:\n"), sanitize_string (section->name));
|
||||
|
||||
/* Find the nearest symbol forwards from our current position. */
|
||||
@@ -3846,6 +3840,12 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
bfd_vma nextstop_offset;
|
||||
bool insns;
|
||||
|
||||
/* Skip over the relocs belonging to addresses below the
|
||||
start address. */
|
||||
while (rel_pp < rel_ppend
|
||||
&& (*rel_pp)->address < rel_offset + addr_offset)
|
||||
++rel_pp;
|
||||
|
||||
addr = section->vma + addr_offset;
|
||||
addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust;
|
||||
|
||||
@@ -3912,17 +3912,11 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
|
||||
/* We are not currently printing. Check to see
|
||||
if the current symbol matches the requested symbol. */
|
||||
if (streq (name, paux->symbol))
|
||||
if (streq (name, paux->symbol)
|
||||
&& bfd_asymbol_value (sym) <= addr)
|
||||
{
|
||||
do_print = true;
|
||||
|
||||
/* Skip over the relocs belonging to addresses below the
|
||||
symbol address. */
|
||||
const bfd_vma sym_offset = bfd_asymbol_value (sym) - section->vma;
|
||||
while (rel_pp < rel_ppend &&
|
||||
(*rel_pp)->address - rel_offset < sym_offset)
|
||||
++rel_pp;
|
||||
|
||||
loop_until = next_sym;
|
||||
if (sym->flags & BSF_FUNCTION)
|
||||
{
|
||||
@@ -3932,13 +3926,14 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
{
|
||||
bfd_size_type fsize =
|
||||
((elf_symbol_type *) sym)->internal_elf_sym.st_size;
|
||||
if (addr_offset + fsize > addr_offset
|
||||
&& addr_offset + fsize <= stop_offset)
|
||||
bfd_vma fend =
|
||||
bfd_asymbol_value (sym) - section->vma + fsize;
|
||||
if (fend > addr_offset && fend <= stop_offset)
|
||||
{
|
||||
/* Sym is a function symbol with a valid
|
||||
size associated with it. Disassemble
|
||||
to the end of the function. */
|
||||
stop_offset = addr_offset + fsize;
|
||||
stop_offset = fend;
|
||||
loop_until = stop_offset_reached;
|
||||
}
|
||||
}
|
||||
@@ -4046,11 +4041,9 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
objdump_print_symname (abfd, &di, sym);
|
||||
|
||||
/* Fetch jump information. */
|
||||
detected_jumps = disassemble_jumps
|
||||
(pinfo, paux->disassemble_fn,
|
||||
detected_jumps = disassemble_jumps (pinfo, paux->disassemble_fn,
|
||||
addr_offset, nextstop_offset,
|
||||
rel_offset, &rel_pp, rel_ppend);
|
||||
|
||||
rel_offset, rel_pp, rel_ppend);
|
||||
/* Free symbol name. */
|
||||
free (sf.buffer);
|
||||
}
|
||||
@@ -4058,7 +4051,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
|
||||
/* Add jumps to output. */
|
||||
disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
|
||||
addr_offset, nextstop_offset,
|
||||
rel_offset, &rel_pp, rel_ppend);
|
||||
rel_offset, rel_pp, rel_ppend);
|
||||
|
||||
/* Free jumps. */
|
||||
while (detected_jumps)
|
||||
|
||||
Reference in New Issue
Block a user