📄 objdump.c
字号:
objdump_print_value (section->vma + q->address, info, true); printf (": %s\t", q->howto->name); if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL) printf ("*unknown*"); else { const char *sym_name; sym_name = bfd_asymbol_name (*q->sym_ptr_ptr); if (sym_name != NULL && *sym_name != '\0') objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr); else { asection *sym_sec; sym_sec = bfd_get_section (*q->sym_ptr_ptr); sym_name = bfd_get_section_name (aux->abfd, sym_sec); if (sym_name == NULL || *sym_name == '\0') sym_name = "*unknown*"; printf ("%s", sym_name); } } if (q->addend) { printf ("+0x"); objdump_print_value (q->addend, info, true); } printf ("\n"); need_nl = false; ++(*relppp); } } if (need_nl) printf ("\n"); addr_offset += octets / opb; }}/* Disassemble the contents of an object file. */static voiddisassemble_data (abfd) bfd *abfd;{ unsigned long addr_offset; disassembler_ftype disassemble_fn; struct disassemble_info disasm_info; struct objdump_disasm_info aux; asection *section; unsigned int opb; print_files = NULL; prev_functionname = NULL; prev_line = -1; /* We make a copy of syms to sort. We don't want to sort syms because that will screw up the relocs. */ sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *)); memcpy (sorted_syms, syms, symcount * sizeof (asymbol *)); sorted_symcount = remove_useless_symbols (sorted_syms, symcount); /* Sort the symbols into section and symbol order */ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); INIT_DISASSEMBLE_INFO(disasm_info, stdout, fprintf); disasm_info.application_data = (PTR) &aux; aux.abfd = abfd; aux.require_sec = false; disasm_info.print_address_func = objdump_print_address; disasm_info.symbol_at_address_func = objdump_symbol_at_address; if (machine != (char *) NULL) { const bfd_arch_info_type *info = bfd_scan_arch (machine); if (info == NULL) { fatal (_("Can't use supplied machine %s"), machine); } abfd->arch_info = info; } if (endian != BFD_ENDIAN_UNKNOWN) { struct bfd_target *xvec; xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target)); memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); xvec->byteorder = endian; abfd->xvec = xvec; } disassemble_fn = disassembler (abfd); if (!disassemble_fn) { non_fatal (_("Can't disassemble for architecture %s\n"), bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); exit_status = 1; return; } opb = bfd_octets_per_byte (abfd); disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); disasm_info.disassembler_options = disassembler_options; disasm_info.octets_per_byte = opb; if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; else /* ??? Aborting here seems too drastic. We could default to big or little instead. */ disasm_info.endian = BFD_ENDIAN_UNKNOWN; for (section = abfd->sections; section != (asection *) NULL; section = section->next) { bfd_byte *data = NULL; bfd_size_type datasize = 0; arelent **relbuf = NULL; arelent **relpp = NULL; arelent **relppend = NULL; unsigned long stop_offset; asymbol *sym = NULL; long place = 0; if ((section->flags & SEC_LOAD) == 0 || (! disassemble_all && only == NULL && (section->flags & SEC_CODE) == 0)) continue; if (only != (char *) NULL && strcmp (only, section->name) != 0) continue; if ((section->flags & SEC_RELOC) != 0#ifndef DISASSEMBLER_NEEDS_RELOCS && dump_reloc_info#endif ) { long relsize; relsize = bfd_get_reloc_upper_bound (abfd, section); if (relsize < 0) bfd_fatal (bfd_get_filename (abfd)); if (relsize > 0) { long relcount; relbuf = (arelent **) xmalloc (relsize); relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms); if (relcount < 0) bfd_fatal (bfd_get_filename (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; } } } printf (_("Disassembly of section %s:\n"), section->name); datasize = bfd_get_section_size_before_reloc (section); if (datasize == 0) continue; data = (bfd_byte *) xmalloc ((size_t) datasize); bfd_get_section_contents (abfd, section, data, 0, datasize); aux.sec = section; disasm_info.buffer = data; disasm_info.buffer_vma = section->vma; disasm_info.buffer_length = datasize; if (start_address == (bfd_vma) -1 || start_address < disasm_info.buffer_vma) addr_offset = 0; else addr_offset = start_address - disasm_info.buffer_vma; if (stop_address == (bfd_vma) -1) stop_offset = datasize / opb; else { if (stop_address < disasm_info.buffer_vma) stop_offset = 0; else stop_offset = stop_address - disasm_info.buffer_vma; if (stop_offset > disasm_info.buffer_length / opb) stop_offset = disasm_info.buffer_length / opb; } sym = find_symbol_for_address (abfd, section, section->vma + addr_offset, true, &place); while (addr_offset < stop_offset) { asymbol *nextsym; unsigned long nextstop_offset; boolean insns; 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); ++x) continue; disasm_info.symbols = & sorted_syms[place]; disasm_info.num_symbols = x - place; } else disasm_info.symbols = NULL; if (! prefix_addresses) { printf ("\n"); objdump_print_addr_with_sym (abfd, section, sym, section->vma + addr_offset, &disasm_info, false); printf (":\n"); } if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) nextsym = sym; else if (sym == NULL) nextsym = NULL; else { /* Search forward for the next appropriate symbol in SECTION. Note that all the symbols are sorted together into one big array, and that some sections may have overlapping addresses. */ while (place < sorted_symcount && (sorted_syms[place]->section != section || (bfd_asymbol_value (sorted_syms[place]) <= bfd_asymbol_value (sym)))) ++place; if (place >= sorted_symcount) nextsym = NULL; else nextsym = sorted_syms[place]; } if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) { nextstop_offset = bfd_asymbol_value (sym) - section->vma; if (nextstop_offset > stop_offset) nextstop_offset = stop_offset; } else if (nextsym == NULL) nextstop_offset = stop_offset; else { nextstop_offset = bfd_asymbol_value (nextsym) - section->vma; if (nextstop_offset > stop_offset) nextstop_offset = stop_offset; } /* If a symbol is explicitly marked as being an object rather than a function, just dump the bytes without disassembling them. */ if (disassemble_all || sym == NULL || bfd_asymbol_value (sym) > section->vma + addr_offset || ((sym->flags & BSF_OBJECT) == 0 && (strstr (bfd_asymbol_name (sym), "gnu_compiled") == NULL) && (strstr (bfd_asymbol_name (sym), "gcc2_compiled") == NULL)) || (sym->flags & BSF_FUNCTION) != 0) insns = true; else insns = false; disassemble_bytes (&disasm_info, disassemble_fn, insns, data, addr_offset, nextstop_offset, &relpp, relppend); addr_offset = nextstop_offset; sym = nextsym; } free (data); if (relbuf != NULL) free (relbuf); } free (sorted_syms);}/* Define a table of stab values and print-strings. We wish the initializer could be a direct-mapped table, but instead we build one the first time we need it. */static void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name, char *strsect_name));/* Dump the stabs sections from an object file that has a section that uses Sun stabs encoding. */static voiddump_stabs (abfd) bfd *abfd;{ dump_section_stabs (abfd, ".stab", ".stabstr"); dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr"); dump_section_stabs (abfd, ".stab.index", ".stab.indexstr"); dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");}static bfd_byte *stabs;static bfd_size_type stab_size;static char *strtab;static bfd_size_type stabstr_size;/* Read ABFD's stabs section STABSECT_NAME into `stabs' and string table section STRSECT_NAME into `strtab'. If the section exists and was read, allocate the space and return true. Otherwise return false. */static booleanread_section_stabs (abfd, stabsect_name, strsect_name) bfd *abfd; const char *stabsect_name; const char *strsect_name;{ asection *stabsect, *stabstrsect; stabsect = bfd_get_section_by_name (abfd, stabsect_name); if (0 == stabsect) { printf (_("No %s section present\n\n"), stabsect_name); return false; } stabstrsect = bfd_get_section_by_name (abfd, strsect_name); if (0 == stabstrsect) { non_fatal (_("%s has no %s section"), bfd_get_filename (abfd), strsect_name); exit_status = 1; return false; } stab_size = bfd_section_size (abfd, stabsect); stabstr_size = bfd_section_size (abfd, stabstrsect); stabs = (bfd_byte *) xmalloc (stab_size); strtab = (char *) xmalloc (stabstr_size); if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size)) { non_fatal (_("Reading %s section of %s failed: %s"), stabsect_name, bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); free (stabs); free (strtab); exit_status = 1; return false; } if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0, stabstr_size)) { non_fatal (_("Reading %s section of %s failed: %s\n"), strsect_name, bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); free (stabs); free (strtab); exit_status = 1; return false; } return true;}/* Stabs entries use a 12 byte format: 4 byte string table index 1 byte stab type 1 byte stab other field 2 byte stab desc field 4 byte stab value FIXME: This will have to change for a 64 bit object format. */#define STRDXOFF (0)#define TYPEOFF (4)#define OTHEROFF (5)#define DESCOFF (6)#define VALOFF (8)#define STABSIZE (12)/* Print ABFD's stabs section STABSECT_NAME (in `stabs'), using string table section STRSECT_NAME (in `strtab'). */static voidprint_section_stabs (abfd, stabsect_name, strsect_name) bfd *abfd; const char *stabsect_name; const char *strsect_name ATTRIBUTE_UNUSED;{ int i; unsigned file_string_table_offset = 0, next_file_string_table_offset = 0; bfd_byte *stabp, *stabs_end; stabp = stabs; stabs_end = stabp + stab_size; printf (_("Contents of %s section:\n\n"), stabsect_name); printf ("Symnum n_type n_othr n_desc n_value n_strx String\n"); /* Loop through all symbols and print them. We start the index at -1 because there is a dummy symbol on the front of stabs-in-{coff,elf} sections that supplies sizes. */ for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++) { const char *name; unsigned long strx; unsigned char type, other; unsigned short desc; bfd_vma value; strx = bfd_h_get_32 (abfd, stabp + STRDXOFF); type = bfd_h_get_8 (abfd, stabp + TYPEOFF); other = bfd_h_get_8 (abfd, stabp + OTHEROFF); desc = bfd_h_get_16 (abfd, stabp + DESCOFF); value = bfd_h_get_32 (abfd, stabp + VALOFF); printf ("\n%-6d ", i); /* Either print the stab name, or, if unnamed, print its number again (makes consistent formatting for tools like awk). */ name = bfd_get_stab_name (type); if (name != NULL) printf ("%-6s", name); else if (type == N_UNDF) printf ("HdrSym"); else printf ("%-6d", type); printf (" %-6d %-6d ", other, desc); printf_vma (value); printf (" %-6lu", strx); /* Symbols with type == 0 (N_UNDF) specify the length of the string table associated with this file. We use that info to know how to relocate the *next* file's string table indices. */ if (type == N_UNDF) { file_string_table_offset = next_file_string_table_offset; next_file_string_table_offset += value; } else { /* Using the (possibly updated) string table offset, print the string (if any) associated with this symbol. */ if ((strx + file_string_table_offset) < stabstr_size) printf (" %s", &strtab[strx + file_string_table_offset]); else printf (" *"); } } printf ("\n\n");}static voiddump_section_stabs (abfd, stabsect_name, strsect_name) bfd *abfd; char *stabsect_name; char *strsect_name;{ asection *s; /* Check for section names for which stabsect_name is a prefix, to handle .stab0, etc. */ for (s = abfd->sections; s != NULL; s = s->next) { int len; len = strlen (stabsect_name); /* If the prefix matches, and the files section name ends with a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -