aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2024-04-02 07:18:19 +1030
committerAlan Modra <amodra@gmail.com>2024-04-02 10:32:04 +1030
commitf37f8c46c2e876a524301d6916a04cf7debb6483 (patch)
tree2db867fc4a086aac2d325d3729ed8904168466fd /binutils
parent0ed1e396e4e869970c60d445bf606ed5092f5558 (diff)
downloadgdb-f37f8c46c2e876a524301d6916a04cf7debb6483.zip
gdb-f37f8c46c2e876a524301d6916a04cf7debb6483.tar.gz
gdb-f37f8c46c2e876a524301d6916a04cf7debb6483.tar.bz2
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, post 159daa36fa, 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. Revert 7e538762c2c1. If given a symbol, don't start disassembling until its address is reached. Correct end of function calculation.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/objdump.c61
1 files changed, 27 insertions, 34 deletions
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 8293387..68da543 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -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,
- addr_offset, nextstop_offset,
- rel_offset, &rel_pp, rel_ppend);
-
+ detected_jumps = disassemble_jumps (pinfo, paux->disassemble_fn,
+ addr_offset, nextstop_offset,
+ 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)