diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-09-16 01:59:30 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-09-16 01:59:30 +0000 |
commit | d5464baad0bdb3e00c15f33090d6bb9fff1fc209 (patch) | |
tree | 831ce618ff34550e92c1808c8d9bd1e27814d75b /binutils/objdump.c | |
parent | e36830425e70e585c2071128b17cc49976f4d1a8 (diff) | |
download | gdb-d5464baad0bdb3e00c15f33090d6bb9fff1fc209.zip gdb-d5464baad0bdb3e00c15f33090d6bb9fff1fc209.tar.gz gdb-d5464baad0bdb3e00c15f33090d6bb9fff1fc209.tar.bz2 |
* objdump.c (disassemble_all): New global variable.
(usage): Document --disassemble-all.
(long_options): Add disassemble-all as a synonym for -D.
(compare_symbols): Make pointers const.
(compare_relocs): New static function.
(disassemble_data): Rename disassemble to disassemble_fn to avoid
shadowing. If dump_reloc_info, print relocs along with
disassembly. Skip sections which are not SEC_CODE unless
disassemble_all or only is set.
(display_bfd): Don't call dump_relocs if disassemble is set.
(main): Accept and handle -D.
* binutils.texi: Document -D/--disassemble-all.
* objdump.1: Likewise.
PR 5059.
Diffstat (limited to 'binutils/objdump.c')
-rw-r--r-- | binutils/objdump.c | 184 |
1 files changed, 160 insertions, 24 deletions
diff --git a/binutils/objdump.c b/binutils/objdump.c index b158c53..e531f20 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -50,6 +50,7 @@ int dump_ar_hdrs; /* -a */ int with_line_numbers; /* -l */ int dump_stab_section_info; /* --stabs */ boolean disassemble; /* -d */ +boolean disassemble_all; /* -D */ boolean formats_info; /* -i */ char *only; /* -j secname */ @@ -106,11 +107,12 @@ usage (stream, status) int status; { fprintf (stream, "\ -Usage: %s [-ahifdrRtTxsl] [-b bfdname] [-m machine] [-j section-name]\n\ - [--archive-headers] [--target=bfdname] [--disassemble] [--file-headers]\n\ - [--section-headers] [--headers] [--info] [--section=section-name]\n\ - [--line-numbers] [--architecture=machine] [--reloc] [--full-contents]\n\ - [--stabs] [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\ +Usage: %s [-ahifdDrRtTxsl] [-b bfdname] [-m machine] [-j section-name]\n\ + [--archive-headers] [--target=bfdname] [--disassemble]\n\ + [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\ + [--info] [--section=section-name] [--line-numbers]\n\ + [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\ + [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\ [--version] [--help] objfile...\n\ at least one option besides -l (--line-numbers) must be given\n", program_name); @@ -123,6 +125,7 @@ static struct option long_options[]= {"architecture", required_argument, NULL, 'm'}, {"archive-headers", no_argument, NULL, 'a'}, {"disassemble", no_argument, NULL, 'd'}, + {"disassemble-all", no_argument, NULL, 'D'}, {"dynamic-reloc", no_argument, NULL, 'R'}, {"dynamic-syms", no_argument, NULL, 'T'}, {"file-headers", no_argument, NULL, 'f'}, @@ -285,11 +288,11 @@ remove_useless_symbols (symbols, count) static int compare_symbols (ap, bp) - PTR ap; - PTR bp; + const PTR ap; + const PTR bp; { - asymbol *a = *(asymbol **)ap; - asymbol *b = *(asymbol **)bp; + const asymbol *a = *(const asymbol **)ap; + const asymbol *b = *(const asymbol **)bp; if (a->value > b->value) return 1; @@ -303,6 +306,25 @@ compare_symbols (ap, bp) return 0; } +/* Sort relocs into address order. */ + +static int +compare_relocs (ap, bp) + const PTR ap; + const PTR bp; +{ + const arelent *a = *(const arelent **)ap; + const arelent *b = *(const arelent **)bp; + + if (a->address > b->address) + return 1; + else if (a->address < b->address) + return -1; + + return compare_symbols ((const PTR) a->sym_ptr_ptr, + (const PTR) b->sym_ptr_ptr); +} + /* Print VMA symbolically to INFO if possible. */ static void @@ -447,7 +469,7 @@ disassemble_data (abfd) { long i; unsigned int (*print) () = 0; /* Old style */ - disassembler_ftype disassemble = 0; /* New style */ + disassembler_ftype disassemble_fn = 0; /* New style */ struct disassemble_info disasm_info; struct objdump_disasm_info aux; @@ -458,6 +480,51 @@ disassemble_data (abfd) boolean done_dot = false; + /* If we are dumping relocation information, read the relocs for + each section we are going to disassemble. We must do this before + we sort the symbols. */ + if (dump_reloc_info) + { + for (section = abfd->sections; + section != (asection *) NULL; + section = section->next) + { + long relsize; + arelent **relpp; + + 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) + continue; + + /* We store the reloc information in the reloc_count and + orelocation fields. */ + + relsize = bfd_get_reloc_upper_bound (abfd, section); + if (relsize < 0) + bfd_fatal (bfd_get_filename (abfd)); + + if (relsize == 0) + section->reloc_count = 0; + else + { + long relcount; + + relpp = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); + if (relcount < 0) + bfd_fatal (bfd_get_filename (abfd)); + section->reloc_count = relcount; + section->orelocation = relpp; + } + } + } + /* Replace symbol section relative values with abs values. */ for (i = 0; i < symcount; i++) { @@ -495,8 +562,8 @@ disassemble_data (abfd) } else { - disassemble = disassembler (abfd); - if (!disassemble) + disassemble_fn = disassembler (abfd); + if (!disassemble_fn) { fprintf (stderr, "%s: Can't disassemble for architecture %s\n", program_name, @@ -511,12 +578,27 @@ disassemble_data (abfd) { bfd_byte *data = NULL; bfd_size_type datasize = 0; + arelent **relpp = NULL; + arelent **relppend = NULL; - if (!(section->flags & SEC_LOAD)) + 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 (dump_reloc_info + && (section->flags & SEC_RELOC) != 0) + { + /* Sort the relocs by address. */ + qsort (section->orelocation, section->reloc_count, + sizeof (arelent *), compare_relocs); + relpp = section->orelocation; + relppend = relpp + section->reloc_count; + } + printf ("Disassembly of section %s:\n", section->name); datasize = bfd_get_section_size_before_reloc (section); @@ -534,6 +616,8 @@ disassemble_data (abfd) i = 0; while (i < disasm_info.buffer_length) { + int bytes; + if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 && data[i + 3] == 0) { @@ -542,7 +626,7 @@ disassemble_data (abfd) printf ("...\n"); done_dot = true; } - i += 4; + bytes = 4; } else { @@ -584,20 +668,69 @@ disassemble_data (abfd) objdump_print_address (section->vma + i, &disasm_info); putchar (' '); - if (disassemble) /* New style */ + if (disassemble_fn) { - int bytes = (*disassemble)(section->vma + i, - &disasm_info); + /* New style */ + bytes = (*disassemble_fn) (section->vma + i, &disasm_info); if (bytes < 0) break; - i += bytes; } - else /* Old style */ - i += print (section->vma + i, - data + i, - stdout); + else + { + /* Old style */ + bytes = print (section->vma + i, data + i, stdout); + } putchar ('\n'); } + + if (dump_reloc_info + && (section->flags & SEC_RELOC) != 0) + { + while (relpp < relppend + && ((*relpp)->address >= i + && (*relpp)->address < i + bytes)) + { + arelent *q; + const char *sym_name; + + q = *relpp; + + printf ("\t\tRELOC: "); + + printf_vma (section->vma + q->address); + + printf (" %s ", q->howto->name); + + if (q->sym_ptr_ptr != NULL + && *q->sym_ptr_ptr != NULL) + { + sym_name = bfd_asymbol_name (*q->sym_ptr_ptr); + if (sym_name == NULL || *sym_name == '\0') + { + asection *sym_sec; + + sym_sec = bfd_get_section (*q->sym_ptr_ptr); + sym_name = bfd_get_section_name (abfd, sym_sec); + if (sym_name == NULL || *sym_name == '\0') + sym_name = "*unknown*"; + } + } + + printf ("%s", sym_name); + + if (q->addend) + { + printf ("+0x"); + printf_vma (q->addend); + } + + printf ("\n"); + + ++relpp; + } + } + + i += bytes; } free (data); } @@ -868,7 +1001,7 @@ display_bfd (abfd) dump_symbols (abfd, true); if (dump_stab_section_info) dump_stabs (abfd); - if (dump_reloc_info) + if (dump_reloc_info && ! disassemble) dump_relocs (abfd); if (dump_dynamic_reloc_info) dump_dynamic_relocs (abfd); @@ -1371,7 +1504,7 @@ main (argc, argv) bfd_init (); - while ((c = getopt_long (argc, argv, "ib:m:VdlfahrRtTxsj:", long_options, + while ((c = getopt_long (argc, argv, "ib:m:VdDlfahrRtTxsj:", long_options, (int *) 0)) != EOF) { @@ -1414,6 +1547,9 @@ main (argc, argv) case 'd': disassemble = true; break; + case 'D': + disassemble = disassemble_all = true; + break; case 's': dump_section_contents = 1; break; |