X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fobjdump.c;h=6a1f142a0ebc8f354c2999ba3c5d91aa8148554f;hb=229a22cfd2fd3c82a1b57d4af104f361cb0b0a33;hp=6812ba7853de6cbaad86dec915a6bec59729fdc1;hpb=7e56c51c7932cfdb178e9457011d09d53e98937b;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/objdump.c b/binutils/objdump.c index 6812ba7853..6a1f142a0e 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -123,6 +123,7 @@ static int prefix_strip; /* --prefix-strip */ static size_t prefix_length; static bfd_boolean unwind_inlines; /* --inlines. */ static const char * disasm_sym; /* Disassembly start symbol. */ +static const char * source_comment; /* --source_comment. */ static int demangle_flags = DMGL_ANSI | DMGL_PARAMS; @@ -192,8 +193,6 @@ static bfd_size_type stab_size; static bfd_byte *strtab; static bfd_size_type stabstr_size; -static bfd_boolean is_relocatable = FALSE; - /* Handlers for -P/--private. */ static const struct objdump_private_desc * const objdump_private_vectors[] = { @@ -219,6 +218,7 @@ usage (FILE *stream, int status) -D, --disassemble-all Display assembler contents of all sections\n\ --disassemble= Display assembler contents from \n\ -S, --source Intermix source code with disassembly\n\ + --source-comment[=] Prefix lines of source code with \n\ -s, --full-contents Display the full contents of all sections requested\n\ -g, --debugging Display debug information in object file\n\ -e, --debugging-tags Display debug information using ctags style\n\ @@ -264,7 +264,7 @@ usage (FILE *stream, int status) -w, --wide Format output for more than 80 columns\n\ -z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\ --start-address=ADDR Only process data whose address is >= ADDR\n\ - --stop-address=ADDR Only process data whose address is <= ADDR\n\ + --stop-address=ADDR Only process data whose address is < ADDR\n\ --prefix-addresses Print complete address alongside disassembly\n\ --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ --insn-width=WIDTH Display WIDTH bytes on a single line for -d\n\ @@ -315,6 +315,7 @@ enum option_values OPTION_RECURSE_LIMIT, OPTION_NO_RECURSE_LIMIT, OPTION_INLINES, + OPTION_SOURCE_COMMENT, OPTION_CTF, OPTION_CTF_PARENT }; @@ -356,6 +357,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'}, + {"source-comment", optional_argument, NULL, OPTION_SOURCE_COMMENT}, {"special-syms", no_argument, &dump_special_syms, 1}, {"include", required_argument, NULL, 'I'}, {"dwarf", optional_argument, NULL, OPTION_DWARF}, @@ -530,7 +532,7 @@ static void dump_section_header (bfd *abfd, asection *section, void *data) { char *comma = ""; - unsigned int opb = bfd_octets_per_byte (abfd); + unsigned int opb = bfd_octets_per_byte (abfd, section); int longest_section_name = *((int *) data); /* Ignore linker created section. See elfNN_ia64_object_p in @@ -543,13 +545,13 @@ dump_section_header (bfd *abfd, asection *section, void *data) return; printf ("%3d %-*s %08lx ", section->index, longest_section_name, - sanitize_string (bfd_get_section_name (abfd, section)), - (unsigned long) bfd_section_size (abfd, section) / opb); - bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section)); + sanitize_string (bfd_section_name (section)), + (unsigned long) bfd_section_size (section) / opb); + bfd_printf_vma (abfd, bfd_section_vma (section)); printf (" "); bfd_printf_vma (abfd, section->lma); printf (" %08lx 2**%u", (unsigned long) section->filepos, - bfd_get_section_alignment (abfd, section)); + bfd_section_alignment (section)); if (! wide_output) printf ("\n "); printf (" "); @@ -582,7 +584,10 @@ dump_section_header (bfd *abfd, asection *section, void *data) PF (SEC_COFF_NOREAD, "NOREAD"); } else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - PF (SEC_ELF_PURECODE, "PURECODE"); + { + PF (SEC_ELF_OCTETS, "OCTETS"); + PF (SEC_ELF_PURECODE, "PURECODE"); + } PF (SEC_THREAD_LOCAL, "THREAD_LOCAL"); PF (SEC_GROUP, "GROUP"); if (bfd_get_arch (abfd) == bfd_arch_mep) @@ -629,7 +634,8 @@ dump_section_header (bfd *abfd, asection *section, void *data) DATA which contains the string length of the longest section name. */ static void -find_longest_section_name (bfd *abfd, asection *section, void *data) +find_longest_section_name (bfd *abfd ATTRIBUTE_UNUSED, + asection *section, void *data) { int *longest_so_far = (int *) data; const char *name; @@ -643,7 +649,7 @@ find_longest_section_name (bfd *abfd, asection *section, void *data) if (! process_section_p (section)) return; - name = bfd_get_section_name (abfd, section); + name = bfd_section_name (section); len = (int) strlen (name); if (len > *longest_so_far) *longest_so_far = len; @@ -993,7 +999,7 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *inf, if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0) version_string = bfd_get_symbol_version_string (abfd, sym, &hidden); - if (bfd_is_und_section (bfd_get_section (sym))) + if (bfd_is_und_section (bfd_asymbol_section (sym))) hidden = TRUE; name = sanitize_string (name); @@ -1032,8 +1038,8 @@ sym_ok (bfd_boolean want_section, debug info file, whilst the section we want is in a normal file. So the section pointers will be different, but the section names will be the same. */ - if (strcmp (bfd_section_name (abfd, sorted_syms[place]->section), - bfd_section_name (abfd, sec)) != 0) + if (strcmp (bfd_section_name (sorted_syms[place]->section), + bfd_section_name (sec)) != 0) return FALSE; } @@ -1139,9 +1145,9 @@ find_symbol_for_address (bfd_vma vma, Also give the target a chance to reject symbols. */ want_section = (aux->require_sec || ((abfd->flags & HAS_RELOC) != 0 - && vma >= bfd_get_section_vma (abfd, sec) - && vma < (bfd_get_section_vma (abfd, sec) - + bfd_section_size (abfd, sec) / opb))); + && vma >= bfd_section_vma (sec) + && vma < (bfd_section_vma (sec) + + bfd_section_size (sec) / opb))); if (! sym_ok (want_section, abfd, thisplace, sec, inf)) { @@ -1265,8 +1271,8 @@ objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym, bfd_vma secaddr; (*inf->fprintf_func) (inf->stream, " <%s", - sanitize_string (bfd_get_section_name (abfd, sec))); - secaddr = bfd_get_section_vma (abfd, sec); + sanitize_string (bfd_section_name (sec))); + secaddr = bfd_section_vma (sec); if (vma < secaddr) { (*inf->fprintf_func) (inf->stream, "-0x"); @@ -1349,7 +1355,7 @@ objdump_print_addr (bfd_vma vma, /* Adjust the vma to the reloc. */ vma += bfd_asymbol_value (sym); - if (bfd_is_und_section (bfd_get_section (sym))) + if (bfd_is_und_section (bfd_asymbol_section (sym))) skip_find = TRUE; } @@ -1596,8 +1602,10 @@ print_line (struct print_file_list *p, unsigned int linenum) if (linenum >= p->maxline) return; l = p->linemap [linenum]; - /* Test fwrite return value to quiet glibc warning. */ + if (source_comment != NULL && strlen (l) > 0) + printf ("%s", source_comment); len = strcspn (l, "\n\r"); + /* Test fwrite return value to quiet glibc warning. */ if (len == 0 || fwrite (l, len, 1, stdout) == 1) putchar ('\n'); } @@ -1832,6 +1840,12 @@ objdump_sprintf (SFILE *f, const char *format, ...) #define DEFAULT_SKIP_ZEROES_AT_END 3 +static int +null_print (const void * stream ATTRIBUTE_UNUSED, const char * format ATTRIBUTE_UNUSED, ...) +{ + return 1; +} + /* Disassemble some data in memory between given values. */ static void @@ -1899,10 +1913,7 @@ disassemble_bytes (struct disassemble_info * inf, { bfd_vma z; bfd_boolean need_nl = FALSE; - int previous_octets; - /* Remember the length of the previous instruction. */ - previous_octets = octets; octets = 0; /* Make sure we don't use relocs from previous instructions. */ @@ -1986,26 +1997,46 @@ disassemble_bytes (struct disassemble_info * inf, && *relppp < relppend) { bfd_signed_vma distance_to_rel; + int insn_size = 0; + int max_reloc_offset + = aux->abfd->arch_info->max_reloc_offset_into_insn; - distance_to_rel = (**relppp)->address - - (rel_offset + addr_offset); + distance_to_rel = ((**relppp)->address - rel_offset + - addr_offset); + + if (distance_to_rel > 0 + && (max_reloc_offset < 0 + || distance_to_rel <= max_reloc_offset)) + { + /* This reloc *might* apply to the current insn, + starting somewhere inside it. Discover the length + of the current insn so that the check below will + work. */ + if (insn_width) + insn_size = insn_width; + else + { + /* We find the length by calling the dissassembler + function with a dummy print handler. This should + work unless the disassembler is not expecting to + be called multiple times for the same address. + + This does mean disassembling the instruction + twice, but we only do this when there is a high + probability that there is a reloc that will + affect the instruction. */ + inf->fprintf_func = (fprintf_ftype) null_print; + insn_size = disassemble_fn (section->vma + + addr_offset, inf); + inf->fprintf_func = (fprintf_ftype) objdump_sprintf; + } + } /* 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))) + && distance_to_rel < insn_size / (int) opb)) { inf->flags |= INSN_HAS_RELOC; aux->reloc = **relppp; @@ -2207,8 +2238,8 @@ disassemble_bytes (struct disassemble_info * inf, { asection *sym_sec; - sym_sec = bfd_get_section (*q->sym_ptr_ptr); - sym_name = bfd_get_section_name (aux->abfd, sym_sec); + sym_sec = bfd_asymbol_section (*q->sym_ptr_ptr); + sym_name = bfd_section_name (sym_sec); if (sym_name == NULL || *sym_name == '\0') sym_name = "*unknown*"; printf ("%s", sanitize_string (sym_name)); @@ -2281,7 +2312,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) if (! process_section_p (section)) return; - datasize = bfd_get_section_size (section); + datasize = bfd_section_size (section); if (datasize == 0) return; @@ -2511,7 +2542,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) else { #define is_valid_next_sym(SYM) \ - (strcmp (bfd_section_name (abfd, (SYM)->section), bfd_section_name (abfd, section)) == 0 \ + (strcmp (bfd_section_name ((SYM)->section), bfd_section_name (section)) == 0 \ && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \ && pinfo->symbol_is_valid (SYM, pinfo)) @@ -2654,7 +2685,7 @@ disassemble_data (bfd *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 = bfd_octets_per_byte (abfd); + disasm_info.octets_per_byte = bfd_octets_per_byte (abfd, NULL); disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES; disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END; disasm_info.disassembler_needs_relocs = FALSE; @@ -2723,9 +2754,9 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, section->filename = bfd_get_filename (abfd); section->reloc_info = NULL; section->num_relocs = 0; - section->address = bfd_get_section_vma (abfd, sec); + section->address = bfd_section_vma (sec); section->user_data = sec; - section->size = bfd_get_section_size (sec); + section->size = bfd_section_size (sec); /* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */ alloced = amt = section->size + 1; if (alloced != amt || alloced == 0) @@ -2749,7 +2780,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, /* Ensure any string section has a terminating NUL. */ section->start[section->size] = 0; - if (is_relocatable && debug_displays [debug].relocate) + if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 + && debug_displays [debug].relocate) { long reloc_size; bfd_boolean ret; @@ -2897,7 +2929,7 @@ static void dump_dwarf_section (bfd *abfd, asection *section, void *arg ATTRIBUTE_UNUSED) { - const char *name = bfd_get_section_name (abfd, section); + const char *name = bfd_section_name (section); const char *match; int i; @@ -2943,46 +2975,8 @@ dump_dwarf (bfd *abfd) return; } - is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; - - eh_addr_size = bfd_arch_bits_per_address (abfd) / 8; - switch (bfd_get_arch (abfd)) { - case bfd_arch_i386: - switch (bfd_get_mach (abfd)) - { - case bfd_mach_x86_64: - case bfd_mach_x86_64_intel_syntax: - case bfd_mach_x86_64_nacl: - case bfd_mach_x64_32: - case bfd_mach_x64_32_intel_syntax: - case bfd_mach_x64_32_nacl: - init_dwarf_regnames_x86_64 (); - break; - - default: - init_dwarf_regnames_i386 (); - break; - } - break; - - case bfd_arch_iamcu: - init_dwarf_regnames_iamcu (); - break; - - case bfd_arch_aarch64: - init_dwarf_regnames_aarch64(); - break; - - case bfd_arch_s390: - init_dwarf_regnames_s390 (); - break; - - case bfd_arch_riscv: - init_dwarf_regnames_riscv (); - break; - case bfd_arch_s12z: /* S12Z has a 24 bit address space. But the only known producer of dwarf_info encodes addresses into 32 bits. */ @@ -2990,9 +2984,13 @@ dump_dwarf (bfd *abfd) break; default: + eh_addr_size = bfd_arch_bits_per_address (abfd) / 8; break; } + init_dwarf_regnames_by_bfd_arch_and_mach (bfd_get_arch (abfd), + bfd_get_mach (abfd)); + bfd_map_over_sections (abfd, dump_dwarf_section, NULL); } @@ -3024,7 +3022,7 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr, return NULL; } - *size_ptr = bfd_section_size (abfd, stabsect); + *size_ptr = bfd_section_size (stabsect); if (entsize_ptr) *entsize_ptr = stabsect->entsize; @@ -3255,19 +3253,27 @@ static int dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) { ctf_file_t *parent = (ctf_file_t *) arg; - const char *things[] = {"Labels", "Data objects", "Function objects", - "Variables", "Types", "Strings", ""}; + const char *things[] = {"Header", "Labels", "Data objects", + "Function objects", "Variables", "Types", "Strings", + ""}; const char **thing; size_t i; /* Only print out the name of non-default-named archive members. The name .ctf appears everywhere, even for things that aren't - really archives, so printing it out is liable to be confusing. */ + really archives, so printing it out is liable to be confusing. + + The parent, if there is one, is the default-owned archive member: + avoid importing it into itself. (This does no harm, but looks + confusing.) */ + if (strcmp (name, ".ctf") != 0) - printf (_("\nCTF archive member: %s:\n"), sanitize_string (name)); + { + printf (_("\nCTF archive member: %s:\n"), sanitize_string (name)); + ctf_import (ctf, parent); + } - ctf_import (ctf, parent); - for (i = 1, thing = things; *thing[0]; thing++, i++) + for (i = 0, thing = things; *thing[0]; thing++, i++) { ctf_dump_state_t *s = NULL; char *item; @@ -3295,7 +3301,7 @@ dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg) static void dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name) { - ctf_archive_t *ctfa, *parenta = NULL; + ctf_archive_t *ctfa, *parenta = NULL, *lookparent; bfd_byte *ctfdata, *parentdata = NULL; bfd_size_type ctfsize, parentsize; ctf_sect_t ctfsect; @@ -3328,14 +3334,18 @@ dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name) bfd_fatal (bfd_get_filename (abfd)); } - /* Assume that the applicable parent archive member is the default one. - (This is what all known implementations are expected to do, if they - put CTFs and their parents in archives together.) */ - if ((parent = ctf_arc_open_by_name (parenta, NULL, &err)) == NULL) - { - non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err)); - bfd_fatal (bfd_get_filename (abfd)); - } + lookparent = parenta; + } + else + lookparent = ctfa; + + /* Assume that the applicable parent archive member is the default one. + (This is what all known implementations are expected to do, if they + put CTFs and their parents in archives together.) */ + if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL) + { + non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err)); + bfd_fatal (bfd_get_filename (abfd)); } printf (_("Contents of CTF section %s:\n"), sanitize_string (sect_name)); @@ -3420,7 +3430,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) bfd_vma addr_offset; bfd_vma start_offset; bfd_vma stop_offset; - unsigned int opb = bfd_octets_per_byte (abfd); + unsigned int opb = bfd_octets_per_byte (abfd, section); /* Bytes per line. */ const int onaline = 16; char buf[64]; @@ -3433,7 +3443,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) if (! process_section_p (section)) return; - if ((datasize = bfd_section_size (abfd, section)) == 0) + if ((datasize = bfd_section_size (section)) == 0) return; /* Compute the address range to display. */ @@ -4458,6 +4468,15 @@ main (int argc, char **argv) with_source_code = TRUE; seenflag = TRUE; break; + case OPTION_SOURCE_COMMENT: + disassemble = TRUE; + with_source_code = TRUE; + seenflag = TRUE; + if (optarg) + source_comment = xstrdup (sanitize_string (optarg)); + else + source_comment = xstrdup ("# "); + break; case 'g': dump_debugging = 1; seenflag = TRUE; @@ -4500,11 +4519,11 @@ main (int argc, char **argv) case OPTION_DWARF_CHECK: dwarf_check = TRUE; break; - case OPTION_CTF: - dump_ctf_section_info = TRUE; - dump_ctf_section_name = xstrdup (optarg); - seenflag = TRUE; - break; + case OPTION_CTF: + dump_ctf_section_info = TRUE; + dump_ctf_section_name = xstrdup (optarg); + seenflag = TRUE; + break; case OPTION_CTF_PARENT: dump_ctf_parent_name = xstrdup (optarg); break; @@ -4569,6 +4588,7 @@ main (int argc, char **argv) free_only_list (); free (dump_ctf_section_name); free (dump_ctf_parent_name); + free ((void *) source_comment); END_PROGRESS (program_name);