X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fobjdump.c;h=52cd3d005cc051ffd1e2a53156dcea60f1955a56;hb=943ea8a2b0cce77e272b34dd88b901b2b9b0e0a0;hp=1e9d97058ba6c8401ed124d5d10781e59717e8fd;hpb=6f10430691d62918f763003227676dc348351eec;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/objdump.c b/binutils/objdump.c index 1e9d97058b..52cd3d005c 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 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -102,6 +102,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 +128,9 @@ struct objdump_disasm_info arelent ** dynrelbuf; long dynrelcount; disassembler_ftype disassemble_fn; +#ifdef DISASSEMBLER_NEEDS_RELOCS + arelent * reloc; +#endif }; /* Architecture to disassemble for, or default if NULL. */ @@ -153,6 +157,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; @@ -213,6 +221,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,6 +273,7 @@ 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'}, {"stabs", no_argument, NULL, 'G'}, {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, @@ -283,12 +293,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 +332,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 +367,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 +470,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 +860,10 @@ 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. */ +#ifdef DISASSEMBLER_NEEDS_RELOCS + bfd_boolean skip_find = FALSE; +#endif if (sorted_symcount < 1) { @@ -850,7 +873,25 @@ objdump_print_addr (bfd_vma vma, } aux = (struct objdump_disasm_info *) info->application_data; - sym = find_symbol_for_address (vma, info, NULL); + +#ifdef DISASSEMBLER_NEEDS_RELOCS + 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) +#endif + sym = find_symbol_for_address (vma, info, NULL); + objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info, skip_zeroes); } @@ -1194,9 +1235,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 @@ -1205,9 +1244,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. */ @@ -1228,7 +1265,10 @@ 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; @@ -1273,8 +1313,14 @@ disassemble_bytes (struct disassemble_info * info, while (addr_offset < stop_offset) { bfd_vma z; - int octets = 0; bfd_boolean need_nl = FALSE; +#ifdef DISASSEMBLER_NEEDS_RELOCS + int previous_octets; + + /* Remember the length of the previous instruction. */ + previous_octets = octets; +#endif + octets = 0; /* If we see more than SKIP_ZEROES octets of zeroes, we just print `...'. */ @@ -1284,9 +1330,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"); @@ -1336,22 +1382,43 @@ disassemble_bytes (struct disassemble_info * info, { 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 + if (*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; + } #endif - info->flags = 0; - octets = (*disassemble_fn) (section->vma + addr_offset, info); info->fprintf_func = (fprintf_ftype) fprintf; info->stream = stdout; @@ -1402,6 +1469,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--) @@ -1568,13 +1636,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; @@ -1775,6 +1844,7 @@ disassemble_data (bfd *abfd) { struct disassemble_info disasm_info; struct objdump_disasm_info aux; + long i; print_files = NULL; prev_functionname = NULL; @@ -1782,10 +1852,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, sorted_symcount); - sorted_symcount = remove_useless_symbols (sorted_syms, 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); @@ -1797,6 +1875,9 @@ disassemble_data (bfd *abfd) aux.require_sec = FALSE; aux.dynrelbuf = NULL; aux.dynrelcount = 0; +#ifdef DISASSEMBLER_NEEDS_RELOCS + aux.reloc = NULL; +#endif disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; @@ -1836,6 +1917,8 @@ 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; if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; @@ -2034,7 +2117,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); } @@ -2261,13 +2345,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; @@ -2288,9 +2374,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"); @@ -2545,8 +2631,16 @@ dump_bfd (bfd *abfd) if (dump_symtab || dump_reloc_info || disassemble || dump_debugging) 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); @@ -2591,6 +2685,16 @@ dump_bfd (bfd *abfd) free (dynsyms); dynsyms = NULL; } + + if (synthsyms) + { + free (synthsyms); + synthsyms = NULL; + } + + symcount = 0; + dynsymcount = 0; + synthcount = 0; } static void