diff options
-rw-r--r-- | binutils/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/objdump.c | 207 |
2 files changed, 179 insertions, 34 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index daa2146..098332b 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +Tue Aug 31 14:13:35 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + + * objdump.c (ARCH_all): Define ARCH_hppa too. + (dump_headers): Don't test for SEC_BALIGN if it's not defined by + bfd.h. + Tue Aug 31 13:29:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * nlmconv.c (main): Force creation of .bss section. Set up the diff --git a/binutils/objdump.c b/binutils/objdump.c index c5d2aa1..7601c5d 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -56,7 +56,12 @@ int with_line_numbers; /* -l */ int dump_stab_section_info; /* -stabs */ boolean disassemble; /* -d */ boolean info; /* -i */ -char *only; +char *only; /* -j secname */ + +struct objdump_disasm_info { + bfd *abfd; + asection *sec; +}; char *machine = (char *) NULL; asymbol **syms; @@ -86,7 +91,8 @@ usage (stream, status) { fprintf (stream, "\ Usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] [-b bfdname]\n\ - [--syms] [--reloc] [--header] [--version] [--help] objfile...\n", + [--syms] [--reloc] [--header] [--version] [--help] objfile...\n\ + at least one option besides -l must be given\n", program_name); exit (status); } @@ -136,7 +142,9 @@ dump_headers (abfd) PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS"); PF (SEC_LOAD, "LOAD"); PF (SEC_RELOC, "RELOC"); +#ifdef SEC_BALIGN PF (SEC_BALIGN, "BALIGN"); +#endif PF (SEC_READONLY, "READONLY"); PF (SEC_CODE, "CODE"); PF (SEC_DATA, "DATA"); @@ -234,7 +242,14 @@ objdump_print_address (vma, info) struct disassemble_info *info; { /* Perform a binary search looking for the closest symbol to - the required value */ + the required value. */ + /* @@ For relocateable files, should filter out symbols belonging to + the wrong section. Unfortunately, not enough information is supplied + to this routine to determine the correct section in all cases. */ + /* @@ Would it speed things up to cache the last two symbols returned, + and maybe their address ranges? For many processors, only one memory + operand can be present at a time, so the 2-entry cache wouldn't be + constantly churned by code doing heavy memory accesses. */ unsigned int min = 0; unsigned int max = symcount; @@ -280,6 +295,64 @@ objdump_print_address (vma, info) } found: + { + bfd_vma val = syms[thisplace]->value; + int i; + if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING)) + for (i = thisplace - 1; i >= 0; i--) + { + if (syms[i]->value == val + && (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING)) + || ((syms[thisplace]->flags & BSF_DEBUGGING) + && !(syms[i]->flags & BSF_DEBUGGING)))) + { + thisplace = i; + break; + } + } + if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING)) + for (i = thisplace + 1; i < symcount; i++) + { + if (syms[i]->value == val + && (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING)) + || ((syms[thisplace]->flags & BSF_DEBUGGING) + && !(syms[i]->flags & BSF_DEBUGGING)))) + { + thisplace = i; + break; + } + } + } + { + /* If the file is relocateable, and the symbol could be from this + section, prefer a symbol from this section over symbols from + others, even if the other symbol's value might be closer. + + Note that this may be wrong for some symbol references if the + sections have overlapping memory ranges, but in that case there's + no way to tell what's desired without looking at the relocation + table. */ + struct objdump_disasm_info *aux; + int i; + + aux = (struct objdump_disasm_info *) info->application_data; + if (aux->abfd->flags & HAS_RELOC + && vma >= bfd_get_section_vma (aux->abfd, aux->sec) + && vma < (bfd_get_section_vma (aux->abfd, aux->sec) + + bfd_get_section_size_before_reloc (aux->sec)) + && syms[thisplace]->section != aux->sec) + { + for (i = thisplace + 1; i < symcount; i++) + if (syms[i]->value != syms[thisplace]->value) + break; + while (--i >= 0) + if (syms[i]->section == aux->sec) + { + thisplace = i; + break; + } + } + } fprintf (info->stream, " <%s", syms[thisplace]->name); if (syms[thisplace]->value > vma) { @@ -301,6 +374,22 @@ objdump_print_address (vma, info) } } +#ifdef ARCH_all +#define ARCH_a29k +#define ARCH_alpha +#define ARCH_h8300 +#define ARCH_h8500 +#define ARCH_hppa +#define ARCH_i386 +#define ARCH_i960 +#define ARCH_m68k +#define ARCH_m88k +#define ARCH_mips +#define ARCH_sh +#define ARCH_sparc +#define ARCH_z8k +#endif + void disassemble_data (abfd) bfd *abfd; @@ -313,6 +402,7 @@ disassemble_data (abfd) disassembler_ftype disassemble = 0; /* New style */ enum bfd_architecture a; struct disassemble_info disasm_info; + struct objdump_disasm_info aux; int prevline; CONST char *prev_function = ""; @@ -323,6 +413,8 @@ disassemble_data (abfd) boolean done_dot = false; INIT_DISASSEMBLE_INFO(disasm_info, stdout); + disasm_info.application_data = (PTR) &aux; + aux.abfd = abfd; disasm_info.print_address_func = objdump_print_address; for (i = 0; i < symcount; i++) @@ -359,52 +451,83 @@ disassemble_data (abfd) a = bfd_get_arch (abfd); switch (a) { - case bfd_arch_sparc: - disassemble = print_insn_sparc; - break; - case bfd_arch_z8k: - if (bfd_get_mach(abfd) == bfd_mach_z8001) - disassemble = print_insn_z8001; - else - disassemble = print_insn_z8002; - break; - case bfd_arch_i386: - disassemble = print_insn_i386; + /* If you add a case to this table, also add it to the + ARCH_all definition right above this function. */ +#ifdef ARCH_a29k + case bfd_arch_a29k: + /* As far as I know we only handle big-endian 29k objects. */ + disassemble = print_insn_big_a29k; break; - case bfd_arch_h8500: - disassemble = print_insn_h8500; +#endif +#ifdef ARCH_alpha + case bfd_arch_alpha: + disassemble = print_insn_alpha; break; +#endif +#ifdef ARCH_h8300 case bfd_arch_h8300: if (bfd_get_mach(abfd) == bfd_mach_h8300h) disassemble = print_insn_h8300h; else disassemble = print_insn_h8300; break; - case bfd_arch_sh: - disassemble = print_insn_sh; - break; - case bfd_arch_alpha: - disassemble = print_insn_alpha; +#endif +#ifdef ARCH_h8500 + case bfd_arch_h8500: + disassemble = print_insn_h8500; break; - case bfd_arch_m68k: - disassemble = print_insn_m68k; +#endif +#ifdef ARCH_hppa + case bfd_arch_hppa: + disassemble = print_insn_hppa; break; - case bfd_arch_a29k: - /* As far as I know we only handle big-endian 29k objects. */ - disassemble = print_insn_big_a29k; +#endif +#ifdef ARCH_i386 + case bfd_arch_i386: + disassemble = print_insn_i386; break; +#endif +#ifdef ARCH_i960 case bfd_arch_i960: disassemble = print_insn_i960; break; +#endif +#ifdef ARCH_m68k + case bfd_arch_m68k: + disassemble = print_insn_m68k; + break; +#endif +#ifdef ARCH_m88k case bfd_arch_m88k: disassemble = print_insn_m88k; break; +#endif +#ifdef ARCH_mips case bfd_arch_mips: if (abfd->xvec->byteorder_big_p) disassemble = print_insn_big_mips; else disassemble = print_insn_little_mips; break; +#endif +#ifdef ARCH_sh + case bfd_arch_sh: + disassemble = print_insn_sh; + break; +#endif +#ifdef ARCH_sparc + case bfd_arch_sparc: + disassemble = print_insn_sparc; + break; +#endif +#ifdef ARCH_z8k + case bfd_arch_z8k: + if (bfd_get_mach(abfd) == bfd_mach_z8001) + disassemble = print_insn_z8001; + else + disassemble = print_insn_z8002; + break; +#endif default: fprintf (stderr, "%s: Can't disassemble for architecture %s\n", program_name, @@ -418,6 +541,7 @@ disassemble_data (abfd) section != (asection *) NULL; section = section->next) { + aux.sec = section; if ((section->flags & SEC_LOAD) && (only == (char *) NULL || strcmp (only, section->name) == 0)) @@ -427,7 +551,7 @@ disassemble_data (abfd) if (bfd_get_section_size_before_reloc (section) == 0) continue; - data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section)); + data = (bfd_byte *) malloc ((size_t) bfd_get_section_size_before_reloc (section)); if (data == (bfd_byte *) NULL) { @@ -798,7 +922,7 @@ dump_data (abfd) if (bfd_get_section_size_before_reloc (section) == 0) continue; - data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section)); + data = (bfd_byte *) malloc ((size_t) bfd_get_section_size_before_reloc (section)); if (data == (bfd_byte *) NULL) { fprintf (stderr, "%s: memory exhausted.\n", program_name); @@ -889,6 +1013,14 @@ dump_relocs (abfd) if (bfd_is_com_section (a)) continue; + if (only) + { + if (strcmp (only, a->name)) + continue; + } + else if ((a->flags & SEC_RELOC) == 0) + continue; + printf ("RELOCATION RECORDS FOR [%s]:", a->name); if (bfd_get_reloc_upper_bound (abfd, a) == 0) @@ -909,16 +1041,23 @@ dump_relocs (abfd) else { printf ("\n"); - printf ("OFFSET TYPE VALUE \n"); + /* Get column headers lined up reasonably. */ + { + static int width; + if (width == 0) + { + char buf[30]; + sprintf_vma (buf, (bfd_vma) -1); + width = strlen (buf) - 7; + } + printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, ""); + } for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--) { arelent *q = *p; CONST char *sym_name; - - /* CONST char *section_name = q->section == (asection *)NULL ? "*abs" :*/ - /* q->section->name;*/ CONST char *section_name = (*(q->sym_ptr_ptr))->section->name; if (q->sym_ptr_ptr && *q->sym_ptr_ptr) @@ -932,14 +1071,14 @@ dump_relocs (abfd) if (sym_name) { printf_vma (q->address); - printf (" %-8s %s", + printf (" %-16s %s", q->howto->name, sym_name); } else { printf_vma (q->address); - printf (" %-8s [%s]", + printf (" %-16s [%s]", q->howto->name, section_name); } |