diff options
-rw-r--r-- | binutils/ChangeLog | 9 | ||||
-rw-r--r-- | binutils/objdump.c | 186 |
2 files changed, 86 insertions, 109 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6b1ed66..07fc09d 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,12 @@ +2003-07-30 Alan Modra <amodra@bigpond.net.au> + + * objdump.c: Remove unnecessary prototypes. + (disassemble_bytes): Add rel_offset parameter. Simplify reloc skipping + code, and print relocs when dump_dynamic_reloc_info. + (disassemble_data): Read and handle dynamic relocs. Correct reloc + skip code. Formatting. + (dump_bfd): Don't dump dynamic relocs when disassembling. + 2003-07-29 Ben Elliston <bje@wasabisystems.com> * MAINTAINERS: Remove self as M88k maintainer. Future M88k diff --git a/binutils/objdump.c b/binutils/objdump.c index 8629beb..998a413 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -38,8 +38,7 @@ #ifdef NEED_DECLARATION_FPRINTF /* This is needed by INIT_DISASSEMBLE_INFO. */ -extern int fprintf - (FILE *, const char *, ...); +extern int fprintf (FILE *, const char *, ...); #endif /* Exit status. */ @@ -119,76 +118,14 @@ static bfd_size_type stab_size; static char *strtab; static bfd_size_type stabstr_size; -/* Static declarations. */ - -static void usage - (FILE *, int); -static void nonfatal - (const char *); -static void display_file - (char *, char *); -static void dump_section_header - (bfd *, asection *, void *); -static void dump_headers - (bfd *); -static void dump_data - (bfd *); -static void dump_relocs - (bfd *); -static void dump_dynamic_relocs - (bfd *); -static void dump_reloc_set - (bfd *, asection *, arelent **, long); -static void dump_symbols - (bfd *, bfd_boolean); -static void dump_bfd_header - (bfd *); -static void dump_bfd_private_header - (bfd *); -static void dump_bfd - (bfd *); -static void display_bfd - (bfd *); -static void objdump_print_value - (bfd_vma, struct disassemble_info *, bfd_boolean); -static void objdump_print_symname - (bfd *, struct disassemble_info *, asymbol *); -static asymbol *find_symbol_for_address - (bfd *, asection *, bfd_vma, bfd_boolean, long *); -static void objdump_print_addr_with_sym - (bfd *, asection *, asymbol *, bfd_vma, - struct disassemble_info *, bfd_boolean); -static void objdump_print_addr - (bfd_vma, struct disassemble_info *, bfd_boolean); -static void objdump_print_address - (bfd_vma, struct disassemble_info *); -static int objdump_symbol_at_address - (bfd_vma, struct disassemble_info *); -static void show_line - (bfd *, asection *, bfd_vma); -static void disassemble_bytes - (struct disassemble_info *, disassembler_ftype, bfd_boolean, - bfd_byte *, bfd_vma, bfd_vma, arelent ***, arelent **); -static void disassemble_data - (bfd *); -static asymbol ** slurp_symtab - (bfd *); -static asymbol ** slurp_dynamic_symtab - (bfd *); -static long remove_useless_symbols - (asymbol **, long); -static int compare_symbols - (const void *, const void *); -static int compare_relocs - (const void *, const void *); -static void dump_stabs - (bfd *); -static bfd_boolean read_section_stabs - (bfd *, const char *, const char *); -static void print_section_stabs - (bfd *, const char *, const char *); -static void dump_section_stabs - (bfd *, char *, char *); +/* Forward declarations. */ + +static void dump_data (bfd *); +static void dump_relocs (bfd *); +static void dump_dynamic_relocs (bfd *); +static void dump_reloc_set (bfd *, asection *, arelent **, long); +static void dump_symbols (bfd *, bfd_boolean); +static void dump_section_stabs (bfd *, char *, char *); static void usage (FILE *stream, int status) @@ -1161,6 +1098,7 @@ disassemble_bytes (struct disassemble_info * info, bfd_byte * data, bfd_vma start_offset, bfd_vma stop_offset, + bfd_vma rel_offset, arelent *** relppp, arelent ** relppend) { @@ -1284,8 +1222,9 @@ disassemble_bytes (struct disassemble_info * info, /* FIXME: This is wrong. It tests the number of octets in the last instruction, not the current one. */ if (*relppp < relppend - && (**relppp)->address >= addr_offset - && (**relppp)->address <= addr_offset + octets / opb) + && (**relppp)->address >= rel_offset + addr_offset + && ((**relppp)->address + < rel_offset + addr_offset + octets / opb)) info->flags = INSN_HAS_RELOC; else #endif @@ -1428,20 +1367,10 @@ disassemble_bytes (struct disassemble_info * info, need_nl = TRUE; } - if ((section->flags & SEC_RELOC) != 0 -#ifndef DISASSEMBLER_NEEDS_RELOCS - && dump_reloc_info -#endif - ) + while ((*relppp) < relppend + && (**relppp)->address < rel_offset + addr_offset + octets / opb) { - while ((*relppp) < relppend - && ((**relppp)->address >= (bfd_vma) addr_offset - && (**relppp)->address < (bfd_vma) addr_offset + octets / opb)) -#ifdef DISASSEMBLER_NEEDS_RELOCS - if (! dump_reloc_info) - ++(*relppp); - else -#endif + if (dump_reloc_info || dump_dynamic_reloc_info) { arelent *q; @@ -1485,8 +1414,8 @@ disassemble_bytes (struct disassemble_info * info, printf ("\n"); need_nl = FALSE; - ++(*relppp); } + ++(*relppp); } if (need_nl) @@ -1507,6 +1436,9 @@ disassemble_data (bfd *abfd) struct objdump_disasm_info aux; asection *section; unsigned int opb; + arelent **dynrelbuf = NULL; + long relcount = 0; + bfd_vma rel_offset; print_files = NULL; prev_functionname = NULL; @@ -1576,6 +1508,25 @@ disassemble_data (bfd *abfd) instead. */ disasm_info.endian = BFD_ENDIAN_UNKNOWN; + if (dump_dynamic_reloc_info) + { + long relsize = bfd_get_dynamic_reloc_upper_bound (abfd); + + if (relsize < 0) + bfd_fatal (bfd_get_filename (abfd)); + + if (relsize > 0) + { + dynrelbuf = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf, dynsyms); + if (relcount < 0) + bfd_fatal (bfd_get_filename (abfd)); + + /* Sort the relocs by address. */ + qsort (dynrelbuf, relcount, sizeof (arelent *), compare_relocs); + } + } + for (section = abfd->sections; section != (asection *) NULL; section = section->next) @@ -1589,8 +1540,8 @@ disassemble_data (bfd *abfd) asymbol *sym = NULL; long place = 0; - /* Sections that do not contain machine - code are not normally disassembled. */ + /* Sections that do not contain machine code are not normally + disassembled. */ if (! disassemble_all && only == NULL && (section->flags & SEC_CODE) == 0) @@ -1608,11 +1559,13 @@ disassemble_data (bfd *abfd) continue; } + if (dynrelbuf == NULL) + relcount = 0; if ((section->flags & SEC_RELOC) != 0 #ifndef DISASSEMBLER_NEEDS_RELOCS && dump_reloc_info #endif - ) + && dynrelbuf == NULL) { long relsize; @@ -1622,8 +1575,6 @@ disassemble_data (bfd *abfd) if (relsize > 0) { - long relcount; - relbuf = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms); if (relcount < 0) @@ -1631,16 +1582,6 @@ disassemble_data (bfd *abfd) /* Sort the relocs by address. */ qsort (relbuf, relcount, sizeof (arelent *), compare_relocs); - - relpp = relbuf; - relppend = relpp + relcount; - - /* Skip over the relocs belonging to addresses below the - start address. */ - if (start_address != (bfd_vma) -1) - while (relpp < relppend - && (*relpp)->address < start_address) - ++relpp; } } @@ -1666,6 +1607,27 @@ disassemble_data (bfd *abfd) else addr_offset = start_address - disasm_info.buffer_vma; + if (dynrelbuf) + { + relpp = dynrelbuf; + /* Dynamic reloc addresses are absolute, non-dynamic are + section relative. REL_OFFSET specifies the reloc address + corresponnding to the start of this section. */ + rel_offset = disasm_info.buffer_vma; + } + else + { + relpp = relbuf; + rel_offset = 0; + } + relppend = relpp + relcount; + + /* Skip over the relocs belonging to addresses below the + start address. */ + while (relpp < relppend + && (*relpp)->address < rel_offset + addr_offset) + ++relpp; + if (stop_address == (bfd_vma) -1) stop_offset = datasize / opb; else @@ -1687,14 +1649,15 @@ disassemble_data (bfd *abfd) unsigned long nextstop_offset; bfd_boolean insns; - if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + addr_offset) + if (sym != NULL + && bfd_asymbol_value (sym) <= section->vma + addr_offset) { int x; for (x = place; (x < sorted_symcount - && bfd_asymbol_value (sorted_syms[x]) - <= section->vma + addr_offset); + && (bfd_asymbol_value (sorted_syms[x]) + <= section->vma + addr_offset)); ++x) continue; @@ -1736,7 +1699,8 @@ disassemble_data (bfd *abfd) nextsym = sorted_syms[place]; } - if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) + if (sym != NULL + && bfd_asymbol_value (sym) > section->vma + addr_offset) { nextstop_offset = bfd_asymbol_value (sym) - section->vma; if (nextstop_offset > stop_offset) @@ -1768,7 +1732,8 @@ disassemble_data (bfd *abfd) insns = FALSE; disassemble_bytes (&disasm_info, disassemble_fn, insns, data, - addr_offset, nextstop_offset, &relpp, relppend); + addr_offset, nextstop_offset, + rel_offset, &relpp, relppend); addr_offset = nextstop_offset; sym = nextsym; @@ -1779,6 +1744,9 @@ disassemble_data (bfd *abfd) if (relbuf != NULL) free (relbuf); } + + if (dynrelbuf != NULL) + free (dynrelbuf); free (sorted_syms); } @@ -2052,7 +2020,7 @@ dump_bfd (bfd *abfd) dump_stabs (abfd); if (dump_reloc_info && ! disassemble) dump_relocs (abfd); - if (dump_dynamic_reloc_info) + if (dump_dynamic_reloc_info && ! disassemble) dump_dynamic_relocs (abfd); if (dump_section_contents) dump_data (abfd); |