diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2010-10-19 21:13:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2010-10-19 21:13:25 +0000 |
| commit | 7a815afd9b5121ee0f65dc1e1de1c0de6de97679 (patch) | |
| tree | f61b968a46c92e81f6de581582cb064bf9dca27d /binutils/objdump.c | |
| parent | 42f6b9ffef1927d55d15075d9e810435c590c404 (diff) | |
Notes
Diffstat (limited to 'binutils/objdump.c')
| -rw-r--r-- | binutils/objdump.c | 502 |
1 files changed, 383 insertions, 119 deletions
diff --git a/binutils/objdump.c b/binutils/objdump.c index f67aacb8881b..6e5eab56da24 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1,6 +1,6 @@ /* objdump.c -- dump information about an object file. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003 + 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /* Objdump overview. @@ -52,6 +52,7 @@ #include "bfdver.h" #include "progress.h" #include "bucomm.h" +#include "dwarf.h" #include "budemang.h" #include "getopt.h" #include "safe-ctype.h" @@ -65,11 +66,6 @@ #define BYTES_IN_WORD 32 #include "aout/aout64.h" -#ifdef NEED_DECLARATION_FPRINTF -/* This is needed by init_disassemble_info(). */ -extern int fprintf (FILE *, const char *, ...); -#endif - /* Exit status. */ static int exit_status = 0; @@ -91,6 +87,7 @@ static int prefix_addresses; /* --prefix-addresses */ static int with_line_numbers; /* -l */ static bfd_boolean with_source_code; /* -S */ static int show_raw_insn; /* --show-raw-insn */ +static int dump_dwarf_section_info; /* --dwarf */ static int dump_stab_section_info; /* --stabs */ static int do_demangle; /* -C, --demangle */ static bfd_boolean disassemble; /* -d */ @@ -102,6 +99,7 @@ static bfd_vma start_address = (bfd_vma) -1; /* --start-address */ static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */ static int dump_debugging; /* --debugging */ static int dump_debugging_tags; /* --debugging-tags */ +static int dump_special_syms = 0; /* --special-syms */ static bfd_vma adjust_section_vma = 0; /* --adjust-vma */ static int file_start_context = 0; /* --file-start-context */ @@ -127,6 +125,7 @@ struct objdump_disasm_info arelent ** dynrelbuf; long dynrelcount; disassembler_ftype disassemble_fn; + arelent * reloc; }; /* Architecture to disassemble for, or default if NULL. */ @@ -153,6 +152,10 @@ static long sorted_symcount = 0; /* The dynamic symbol table. */ static asymbol **dynsyms; +/* The synthetic symbol table. */ +static asymbol *synthsyms; +static long synthcount = 0; + /* Number of symbols in `dynsyms'. */ static long dynsymcount = 0; @@ -181,10 +184,12 @@ usage (FILE *stream, int status) -g, --debugging Display debug information in object file\n\ -e, --debugging-tags Display debug information using ctags style\n\ -G, --stabs Display (in raw form) any STABS info in the file\n\ + -W, --dwarf Display DWARF info in the file\n\ -t, --syms Display the contents of the symbol table(s)\n\ -T, --dynamic-syms Display the contents of the dynamic symbol table\n\ -r, --reloc Display the relocation entries in the file\n\ -R, --dynamic-reloc Display the dynamic relocation entries in the file\n\ + @<file> Read options from <file>\n\ -v, --version Display this program's version number\n\ -i, --info List object formats and architectures supported\n\ -H, --help Display this information\n\ @@ -213,6 +218,7 @@ usage (FILE *stream, int status) --prefix-addresses Print complete address alongside disassembly\n\ --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\ + --special-syms Include special symbols in symbol dumps\n\ \n")); list_supported_targets (program_name, stream); list_supported_architectures (program_name, stream); @@ -264,7 +270,9 @@ static struct option long_options[]= {"section-headers", no_argument, NULL, 'h'}, {"show-raw-insn", no_argument, &show_raw_insn, 1}, {"source", no_argument, NULL, 'S'}, + {"special-syms", no_argument, &dump_special_syms, 1}, {"include", required_argument, NULL, 'I'}, + {"dwarf", no_argument, NULL, 'W'}, {"stabs", no_argument, NULL, 'G'}, {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, @@ -283,12 +291,17 @@ nonfatal (const char *msg) } static void -dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section, +dump_section_header (bfd *abfd, asection *section, void *ignored ATTRIBUTE_UNUSED) { char *comma = ""; unsigned int opb = bfd_octets_per_byte (abfd); + /* Ignore linker created section. See elfNN_ia64_object_p in + bfd/elfxx-ia64.c. */ + if (section->flags & SEC_LINKER_CREATED) + return; + printf ("%3d %-13s %08lx ", section->index, bfd_get_section_name (abfd, section), (unsigned long) bfd_section_size (abfd, section) / opb); @@ -317,16 +330,21 @@ dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section, PF (SEC_NEVER_LOAD, "NEVER_LOAD"); PF (SEC_EXCLUDE, "EXCLUDE"); PF (SEC_SORT_ENTRIES, "SORT_ENTRIES"); - PF (SEC_BLOCK, "BLOCK"); - PF (SEC_CLINK, "CLINK"); + if (bfd_get_arch (abfd) == bfd_arch_tic54x) + { + PF (SEC_TIC54X_BLOCK, "BLOCK"); + PF (SEC_TIC54X_CLINK, "CLINK"); + } PF (SEC_SMALL_DATA, "SMALL_DATA"); - PF (SEC_SHARED, "SHARED"); - PF (SEC_ARCH_BIT_0, "ARCH_BIT_0"); + if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) + PF (SEC_COFF_SHARED, "SHARED"); PF (SEC_THREAD_LOCAL, "THREAD_LOCAL"); + PF (SEC_GROUP, "GROUP"); if ((section->flags & SEC_LINK_ONCE) != 0) { const char *ls; + struct coff_comdat_info *comdat; switch (section->flags & SEC_LINK_DUPLICATES) { @@ -347,9 +365,9 @@ dump_section_header (bfd *abfd ATTRIBUTE_UNUSED, asection *section, } printf ("%s%s", comma, ls); - if (section->comdat != NULL) - printf (" (COMDAT %s %ld)", section->comdat->name, - section->comdat->symbol); + comdat = bfd_coff_get_comdat_section (abfd, section); + if (comdat != NULL) + printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol); comma = ", "; } @@ -450,7 +468,7 @@ remove_useless_symbols (asymbol **symbols, long count) if (sym->name == NULL || sym->name[0] == '\0') continue; - if (sym->flags & (BSF_DEBUGGING)) + if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) continue; if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section)) @@ -840,7 +858,8 @@ objdump_print_addr (bfd_vma vma, bfd_boolean skip_zeroes) { struct objdump_disasm_info *aux; - asymbol *sym; + asymbol *sym = NULL; /* Initialize to avoid compiler warning. */ + bfd_boolean skip_find = FALSE; if (sorted_symcount < 1) { @@ -850,7 +869,23 @@ objdump_print_addr (bfd_vma vma, } aux = (struct objdump_disasm_info *) info->application_data; - sym = find_symbol_for_address (vma, info, NULL); + + if (aux->reloc != NULL + && aux->reloc->sym_ptr_ptr != NULL + && * aux->reloc->sym_ptr_ptr != NULL) + { + sym = * aux->reloc->sym_ptr_ptr; + + /* Adjust the vma to the reloc. */ + vma += bfd_asymbol_value (sym); + + if (bfd_is_und_section (bfd_get_section (sym))) + skip_find = TRUE; + } + + if (!skip_find) + sym = find_symbol_for_address (vma, info, NULL); + objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info, skip_zeroes); } @@ -864,7 +899,7 @@ objdump_print_address (bfd_vma vma, struct disassemble_info *info) objdump_print_addr (vma, info, ! prefix_addresses); } -/* Determine of the given address has a symbol associated with it. */ +/* Determine if the given address has a symbol associated with it. */ static int objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info) @@ -1142,48 +1177,34 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) typedef struct { char *buffer; - size_t size; - char *current; + size_t pos; + size_t alloc; } SFILE; /* sprintf to a "stream". */ -static int +static int ATTRIBUTE_PRINTF_2 objdump_sprintf (SFILE *f, const char *format, ...) { - char *buf; size_t n; va_list args; - va_start (args, format); - - vasprintf (&buf, format, args); - - if (buf == NULL) + while (1) { + size_t space = f->alloc - f->pos; + + va_start (args, format); + n = vsnprintf (f->buffer + f->pos, space, format, args); va_end (args); - fatal (_("Out of virtual memory")); - } - n = strlen (buf); - - while ((size_t) ((f->buffer + f->size) - f->current) < n + 1) - { - size_t curroff; - - curroff = f->current - f->buffer; - f->size *= 2; - f->buffer = xrealloc (f->buffer, f->size); - f->current = f->buffer + curroff; + if (space > n) + break; + + f->alloc = (f->alloc + n) * 2; + f->buffer = xrealloc (f->buffer, f->alloc); } - - memcpy (f->current, buf, n); - f->current += n; - f->current[0] = '\0'; - - free (buf); - - va_end (args); + f->pos += n; + return n; } @@ -1208,9 +1229,7 @@ process_section_p (asection * section) /* The number of zeroes we want to see before we start skipping them. The number is arbitrarily chosen. */ -#ifndef SKIP_ZEROES -#define SKIP_ZEROES (8) -#endif +#define DEFAULT_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 @@ -1219,9 +1238,7 @@ process_section_p (asection * section) attempt to avoid disassembling zeroes inserted by section alignment. */ -#ifndef SKIP_ZEROES_AT_END -#define SKIP_ZEROES_AT_END (3) -#endif +#define DEFAULT_SKIP_ZEROES_AT_END 3 /* Disassemble some data in memory between given values. */ @@ -1242,11 +1259,19 @@ disassemble_bytes (struct disassemble_info * info, bfd_boolean done_dot; int skip_addr_chars; bfd_vma addr_offset; - int opb = info->octets_per_byte; + unsigned int opb = info->octets_per_byte; + unsigned int skip_zeroes = info->skip_zeroes; + unsigned int skip_zeroes_at_end = info->skip_zeroes_at_end; + int octets = opb; + SFILE sfile; aux = (struct objdump_disasm_info *) info->application_data; section = aux->sec; + sfile.alloc = 120; + sfile.buffer = xmalloc (sfile.alloc); + sfile.pos = 0; + if (insns) octets_per_line = 4; else @@ -1282,8 +1307,12 @@ disassemble_bytes (struct disassemble_info * info, while (addr_offset < stop_offset) { bfd_vma z; - int octets = 0; bfd_boolean need_nl = FALSE; + int previous_octets; + + /* Remember the length of the previous instruction. */ + previous_octets = octets; + octets = 0; /* If we see more than SKIP_ZEROES octets of zeroes, we just print `...'. */ @@ -1293,9 +1322,9 @@ disassemble_bytes (struct disassemble_info * info, if (! disassemble_zeroes && (info->insn_info_valid == 0 || info->branch_delay_insns == 0) - && (z - addr_offset * opb >= SKIP_ZEROES + && (z - addr_offset * opb >= skip_zeroes || (z == stop_offset * opb && - z - addr_offset * opb < SKIP_ZEROES_AT_END))) + z - addr_offset * opb < skip_zeroes_at_end))) { printf ("\t...\n"); @@ -1311,17 +1340,13 @@ disassemble_bytes (struct disassemble_info * info, else { char buf[50]; - SFILE sfile; int bpc = 0; int pb = 0; done_dot = FALSE; if (with_line_numbers || with_source_code) - /* The line number tables will refer to unadjusted - section VMAs, so we must undo any VMA modifications - when calling show_line. */ - show_line (aux->abfd, section, addr_offset - adjust_section_vma); + show_line (aux->abfd, section, addr_offset); if (! prefix_addresses) { @@ -1344,25 +1369,44 @@ disassemble_bytes (struct disassemble_info * info, if (insns) { - sfile.size = 120; - sfile.buffer = xmalloc (sfile.size); - sfile.current = sfile.buffer; + sfile.pos = 0; info->fprintf_func = (fprintf_ftype) objdump_sprintf; - info->stream = (FILE *) &sfile; + info->stream = &sfile; info->bytes_per_line = 0; info->bytes_per_chunk = 0; + info->flags = 0; -#ifdef DISASSEMBLER_NEEDS_RELOCS - /* FIXME: This is wrong. It tests the number of octets - in the last instruction, not the current one. */ - if (*relppp < relppend - && (**relppp)->address >= rel_offset + addr_offset - && ((**relppp)->address - < rel_offset + addr_offset + octets / opb)) - info->flags = INSN_HAS_RELOC; - else -#endif - info->flags = 0; + if (info->disassembler_needs_relocs + && *relppp < relppend) + { + bfd_signed_vma distance_to_rel; + + distance_to_rel = (**relppp)->address + - (rel_offset + addr_offset); + + /* Check to see if the current reloc is associated with + the instruction that we are about to disassemble. */ + if (distance_to_rel == 0 + /* FIXME: This is wrong. We are trying to catch + relocs that are addressed part way through the + current instruction, as might happen with a packed + VLIW instruction. Unfortunately we do not know the + length of the current instruction since we have not + disassembled it yet. Instead we take a guess based + upon the length of the previous instruction. The + proper solution is to have a new target-specific + disassembler function which just returns the length + of an instruction at a given address without trying + to display its disassembly. */ + || (distance_to_rel > 0 + && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb))) + { + info->flags = INSN_HAS_RELOC; + aux->reloc = **relppp; + } + else + aux->reloc = NULL; + } octets = (*disassemble_fn) (section->vma + addr_offset, info); info->fprintf_func = (fprintf_ftype) fprintf; @@ -1371,9 +1415,8 @@ disassemble_bytes (struct disassemble_info * info, octets_per_line = info->bytes_per_line; if (octets < 0) { - if (sfile.current != sfile.buffer) + if (sfile.pos) printf ("%s\n", sfile.buffer); - free (sfile.buffer); break; } } @@ -1415,6 +1458,7 @@ disassemble_bytes (struct disassemble_info * info, 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--) @@ -1447,11 +1491,8 @@ disassemble_bytes (struct disassemble_info * info, if (! insns) printf ("%s", buf); - else - { - printf ("%s", sfile.buffer); - free (sfile.buffer); - } + else if (sfile.pos) + printf ("%s", sfile.buffer); if (prefix_addresses ? show_raw_insn > 0 @@ -1518,7 +1559,12 @@ disassemble_bytes (struct disassemble_info * info, objdump_print_value (section->vma - rel_offset + q->address, info, TRUE); - printf (": %s\t", q->howto->name); + if (q->howto == NULL) + printf (": *unknown*\t"); + else if (q->howto->name) + printf (": %s\t", q->howto->name); + else + printf (": %d\t", q->howto->type); if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL) printf ("*unknown*"); @@ -1558,6 +1604,8 @@ disassemble_bytes (struct disassemble_info * info, addr_offset += octets / opb; } + + free (sfile.buffer); } static void @@ -1582,13 +1630,14 @@ disassemble_section (bfd *abfd, asection *section, void *info) code are not normally disassembled. */ if (! disassemble_all && only == NULL - && (section->flags & SEC_CODE) == 0) + && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS)) + != (SEC_CODE | SEC_HAS_CONTENTS))) return; if (! process_section_p (section)) return; - datasize = bfd_get_section_size_before_reloc (section); + datasize = bfd_get_section_size (section); if (datasize == 0) return; @@ -1610,10 +1659,7 @@ disassemble_section (bfd *abfd, asection *section, void *info) rel_offset = 0; if ((section->flags & SEC_RELOC) != 0 -#ifndef DISASSEMBLER_NEEDS_RELOCS - && dump_reloc_info -#endif - ) + && (dump_reloc_info || pinfo->disassembler_needs_relocs)) { long relsize; @@ -1789,6 +1835,7 @@ disassemble_data (bfd *abfd) { struct disassemble_info disasm_info; struct objdump_disasm_info aux; + long i; print_files = NULL; prev_functionname = NULL; @@ -1796,10 +1843,18 @@ disassemble_data (bfd *abfd) /* We make a copy of syms to sort. We don't want to sort syms because that will screw up the relocs. */ - sorted_syms = xmalloc (symcount * sizeof (asymbol *)); - memcpy (sorted_syms, syms, symcount * sizeof (asymbol *)); + sorted_symcount = symcount ? symcount : dynsymcount; + sorted_syms = xmalloc ((sorted_symcount + synthcount) * sizeof (asymbol *)); + memcpy (sorted_syms, symcount ? syms : dynsyms, + sorted_symcount * sizeof (asymbol *)); - sorted_symcount = remove_useless_symbols (sorted_syms, symcount); + sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount); + + for (i = 0; i < synthcount; ++i) + { + sorted_syms[sorted_symcount] = synthsyms + i; + ++sorted_symcount; + } /* Sort the symbols into section and symbol order. */ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); @@ -1811,6 +1866,7 @@ disassemble_data (bfd *abfd) aux.require_sec = FALSE; aux.dynrelbuf = NULL; aux.dynrelcount = 0; + aux.reloc = NULL; disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; @@ -1850,6 +1906,9 @@ disassemble_data (bfd *abfd) disasm_info.mach = bfd_get_mach (abfd); disasm_info.disassembler_options = disassembler_options; disasm_info.octets_per_byte = bfd_octets_per_byte (abfd); + disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; + disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; + disasm_info.disassembler_needs_relocs = FALSE; if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; @@ -1894,6 +1953,163 @@ disassemble_data (bfd *abfd) free (sorted_syms); } +int +load_debug_section (enum dwarf_section_display_enum debug, void *file) +{ + struct dwarf_section *section = &debug_displays [debug].section; + bfd *abfd = file; + asection *sec; + bfd_boolean ret; + + /* If it is already loaded, do nothing. */ + if (section->start != NULL) + return 1; + + /* Locate the debug section. */ + sec = bfd_get_section_by_name (abfd, section->name); + if (sec == NULL) + return 0; + + section->address = bfd_get_section_vma (abfd, sec); + section->size = bfd_get_section_size (sec); + section->start = xmalloc (section->size); + + if (is_relocatable && debug_displays [debug].relocate) + ret = bfd_simple_get_relocated_section_contents (abfd, + sec, + section->start, + syms) != NULL; + else + ret = bfd_get_section_contents (abfd, sec, section->start, 0, + section->size); + + if (!ret) + { + free_debug_section (debug); + printf (_("\nCan't get contents for section '%s'.\n"), + section->name); + } + + return ret; +} + +void +free_debug_section (enum dwarf_section_display_enum debug) +{ + struct dwarf_section *section = &debug_displays [debug].section; + + if (section->start == NULL) + return; + + free ((char *) section->start); + section->start = NULL; + section->address = 0; + section->size = 0; +} + +static void +dump_dwarf_section (bfd *abfd, asection *section, + void *arg ATTRIBUTE_UNUSED) +{ + const char *name = bfd_get_section_name (abfd, section); + const char *match; + enum dwarf_section_display_enum i; + + if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0) + match = ".debug_info"; + else + match = name; + + for (i = 0; i < max; i++) + if (strcmp (debug_displays[i].section.name, match) == 0) + { + if (!debug_displays[i].eh_frame) + { + struct dwarf_section *sec = &debug_displays [i].section; + + if (load_debug_section (i, abfd)) + { + debug_displays[i].display (sec, abfd); + + if (i != info && i != abbrev) + free_debug_section (i); + } + } + break; + } +} + +static const char *mach_o_dwarf_sections [] = { + "LC_SEGMENT.__DWARFA.__debug_abbrev", /* .debug_abbrev */ + "LC_SEGMENT.__DWARFA.__debug_aranges", /* .debug_aranges */ + "LC_SEGMENT.__DWARFA.__debug_frame", /* .debug_frame */ + "LC_SEGMENT.__DWARFA.__debug_info", /* .debug_info */ + "LC_SEGMENT.__DWARFA.__debug_line", /* .debug_line */ + "LC_SEGMENT.__DWARFA.__debug_pubnames", /* .debug_pubnames */ + ".eh_frame", /* .eh_frame */ + "LC_SEGMENT.__DWARFA.__debug_macinfo", /* .debug_macinfo */ + "LC_SEGMENT.__DWARFA.__debug_str", /* .debug_str */ + "LC_SEGMENT.__DWARFA.__debug_loc", /* .debug_loc */ + "LC_SEGMENT.__DWARFA.__debug_pubtypes", /* .debug_pubtypes */ + "LC_SEGMENT.__DWARFA.__debug_ranges", /* .debug_ranges */ + "LC_SEGMENT.__DWARFA.__debug_static_func", /* .debug_static_func */ + "LC_SEGMENT.__DWARFA.__debug_static_vars", /* .debug_static_vars */ + "LC_SEGMENT.__DWARFA.__debug_types", /* .debug_types */ + "LC_SEGMENT.__DWARFA.__debug_weaknames" /* .debug_weaknames */ +}; + +static const char *generic_dwarf_sections [max]; + +static void +check_mach_o_dwarf (bfd *abfd) +{ + static enum bfd_flavour old_flavour = bfd_target_unknown_flavour; + enum bfd_flavour current_flavour = bfd_get_flavour (abfd); + enum dwarf_section_display_enum i; + + if (generic_dwarf_sections [0] == NULL) + for (i = 0; i < max; i++) + generic_dwarf_sections [i] = debug_displays[i].section.name; + + if (old_flavour != current_flavour) + { + if (current_flavour == bfd_target_mach_o_flavour) + for (i = 0; i < max; i++) + debug_displays[i].section.name = mach_o_dwarf_sections [i]; + else if (old_flavour == bfd_target_mach_o_flavour) + for (i = 0; i < max; i++) + debug_displays[i].section.name = generic_dwarf_sections [i]; + + old_flavour = current_flavour; + } +} + +/* Dump the dwarf debugging information. */ + +static void +dump_dwarf (bfd *abfd) +{ + is_relocatable = ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC)) + == HAS_RELOC); + + /* FIXME: bfd_get_arch_size may return -1. We assume that 64bit + targets will return 64. */ + eh_addr_size = bfd_get_arch_size (abfd) == 64 ? 8 : 4; + + if (bfd_big_endian (abfd)) + byte_get = byte_get_big_endian; + else if (bfd_little_endian (abfd)) + byte_get = byte_get_little_endian; + else + abort (); + + check_mach_o_dwarf (abfd); + + bfd_map_over_sections (abfd, dump_dwarf_section, NULL); + + free_debug_memory (); +} + /* Read ABFD's stabs section STABSECT_NAME, and return a pointer to it. Return NULL on failure. */ @@ -2048,7 +2264,8 @@ find_stabs_section (bfd *abfd, asection *section, void *names) if (strtab) { - stabs = read_section_stabs (abfd, section->name, &stab_size); + stabs = (bfd_byte *) read_section_stabs (abfd, section->name, + &stab_size); if (stabs) print_section_stabs (abfd, section->name, &sought->string_offset); } @@ -2275,13 +2492,15 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic) bfd *cur_bfd; if (*current == NULL) - printf (_("no information for the %ld'th symbol"), count); + printf (_("no information for symbol number %ld\n"), count); else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL) - printf (_("could not determine the type of the %ld'th symbol"), + printf (_("could not determine the type of symbol number %ld\n"), count); - else + else if (process_section_p ((* current)->section) + && (dump_special_syms + || !bfd_is_target_special_symbol (cur_bfd, *current))) { const char *name = (*current)->name; @@ -2302,9 +2521,9 @@ dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic) else bfd_print_symbol (cur_bfd, stdout, *current, bfd_print_symbol_all); + printf ("\n"); } - printf ("\n"); current++; } printf ("\n\n"); @@ -2393,23 +2612,20 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) section_name = NULL; } + bfd_printf_vma (abfd, q->address); + if (q->howto == NULL) + printf (" *unknown* "); + else if (q->howto->name) + printf (" %-16s ", q->howto->name); + else + printf (" %-16d ", q->howto->type); if (sym_name) - { - bfd_printf_vma (abfd, q->address); - if (q->howto->name) - printf (" %-16s ", q->howto->name); - else - printf (" %-16d ", q->howto->type); - objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr); - } + objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr); else { if (section_name == NULL) section_name = "*unknown*"; - bfd_printf_vma (abfd, q->address); - printf (" %-16s [%s]", - q->howto->name, - section_name); + printf ("[%s]", section_name); } if (q->addend) @@ -2526,10 +2742,15 @@ add_include_path (const char *path) static void adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED, asection *section, - void *dummy ATTRIBUTE_UNUSED) + void *arg) { - section->vma += adjust_section_vma; - section->lma += adjust_section_vma; + if ((section->flags & SEC_DEBUGGING) == 0) + { + bfd_boolean *has_reloc_p = (bfd_boolean *) arg; + section->vma += adjust_section_vma; + if (*has_reloc_p) + section->lma += adjust_section_vma; + } } /* Dump selected contents of ABFD. */ @@ -2541,7 +2762,10 @@ dump_bfd (bfd *abfd) the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ if (adjust_section_vma != 0) - bfd_map_over_sections (abfd, adjust_addresses, NULL); + { + bfd_boolean has_reloc = (abfd->flags & HAS_RELOC); + bfd_map_over_sections (abfd, adjust_addresses, &has_reloc); + } if (! dump_debugging_tags) printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), @@ -2557,15 +2781,29 @@ dump_bfd (bfd *abfd) if (dump_section_headers) dump_headers (abfd); - if (dump_symtab || dump_reloc_info || disassemble || dump_debugging) + if (dump_symtab + || dump_reloc_info + || disassemble + || dump_debugging + || dump_dwarf_section_info) syms = slurp_symtab (abfd); - if (dump_dynamic_symtab || dump_dynamic_reloc_info) + if (dump_dynamic_symtab || dump_dynamic_reloc_info + || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0)) dynsyms = slurp_dynamic_symtab (abfd); + if (disassemble) + { + synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, + dynsymcount, dynsyms, &synthsyms); + if (synthcount < 0) + synthcount = 0; + } if (dump_symtab) dump_symbols (abfd, FALSE); if (dump_dynamic_symtab) dump_symbols (abfd, TRUE); + if (dump_dwarf_section_info) + dump_dwarf (abfd); if (dump_stab_section_info) dump_stabs (abfd); if (dump_reloc_info && ! disassemble) @@ -2605,6 +2843,16 @@ dump_bfd (bfd *abfd) free (dynsyms); dynsyms = NULL; } + + if (synthsyms) + { + free (synthsyms); + synthsyms = NULL; + } + + symcount = 0; + dynsymcount = 0; + synthcount = 0; } static void @@ -2719,10 +2967,12 @@ main (int argc, char **argv) START_PROGRESS (program_name, 0); + expandargv (&argc, &argv); + bfd_init (); set_default_bfd_target (); - while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSI:j:wE:zgeG", + while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSI:j:wE:zgeGW", long_options, (int *) 0)) != EOF) { @@ -2863,6 +3113,20 @@ main (int argc, char **argv) do_demangle = TRUE; seenflag = TRUE; break; + case 'W': + dump_dwarf_section_info = TRUE; + seenflag = TRUE; + do_debug_info = 1; + do_debug_abbrevs = 1; + do_debug_lines = 1; + do_debug_pubnames = 1; + do_debug_aranges = 1; + do_debug_ranges = 1; + do_debug_frames = 1; + do_debug_macinfo = 1; + do_debug_str = 1; + do_debug_loc = 1; + break; case 'G': dump_stab_section_info = TRUE; seenflag = TRUE; |
