X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=binutils%2Fobjdump.c;h=4adabd2e56203b3492971d82e090bec00541af1b;hb=6b3bf560900b549065d93d5d43a9b6af0e3a5e95;hp=4cff97b1e5a6d3f7443bbf0c8c08c31bb98e0cea;hpb=30727aa6d12fb866494020c0b62ab265a2bdcdfe;p=external%2Fbinutils.git diff --git a/binutils/objdump.c b/binutils/objdump.c index 4cff97b..4adabd2 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1,5 +1,5 @@ /* objdump.c -- dump information about an object file. - Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999 + Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -29,12 +29,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "debug.h" #include "budbg.h" -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - /* Internal headers for the ELF .stab-dump code - sorry. */ #define BYTES_IN_WORD 32 #include "aout/aout64.h" @@ -44,6 +38,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ extern int fprintf PARAMS ((FILE *, const char *, ...)); #endif +/* Exit status. */ +static int exit_status = 0; + static char *default_target = NULL; /* default at runtime */ static int show_version = 0; /* show the version number */ @@ -72,6 +69,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 bfd_vma adjust_section_vma = 0; /* --adjust-vma */ +static int file_start_context = 0; /* --file-start-context */ /* Extra info to pass to the disassembler address printing function. */ struct objdump_disasm_info { @@ -113,6 +111,9 @@ static void usage PARAMS ((FILE *, int)); static void +nonfatal PARAMS ((const char *)); + +static void display_file PARAMS ((char *filename, char *target)); static void @@ -219,25 +220,55 @@ usage (stream, status) FILE *stream; int status; { + fprintf (stream, _("Usage: %s file(s)\n"), program_name); + fprintf (stream, _(" At least one of the following switches must be given:\n")); fprintf (stream, _("\ -Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] \n\ - [-j section-name] [-M disassembler-options]\n\ - [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\ - [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\ - [--section-headers] [--headers]\n\ - [--info] [--section=section-name] [--line-numbers] [--source]\n"), - program_name); - fprintf (stream, _("\ - [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\ - [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\ - [--wide] [--version] [--help] [--private-headers]\n\ - [--start-address=addr] [--stop-address=addr]\n\ - [--prefix-addresses] [--[no-]show-raw-insn] [--demangle]\n\ - [--adjust-vma=offset] [-EB|-EL] [--endian={big|little}] objfile...\n\ -at least one option besides -l (--line-numbers) must be given\n")); - list_supported_targets (program_name, stream); + -a --archive-headers Display archive header information\n\ + -f --file-headers Display the contents of the overall file header\n\ + -p --private-headers Display object format specific file header contents\n\ + -h --[section-]headers Display the contents of the section headers\n\ + -x --all-headers Display the contents of all headers\n\ + -d --disassemble Display assembler contents of executable sections\n\ + -D --disassemble-all Display assembler contents of all sections\n\ + -S --source Intermix source code with disassembly\n\ + -s --full-contents Display the full contents of all sections requested\n\ + -g --debugging Display debug information in object file\n\ + -G --stabs Display the STABS contents of an ELF format file\n\ + -t --syms Display the contents of the symbol table(s)\n\ + -T --dynamic-syms Display the contents of the dynamic symbol table\n\ + -r --reloc Display the relocation entries in the file\n\ + -R --dynamic-reloc Display the dynamic relocation entries in the file\n\ + -V --version Display this program's version number\n\ + -i --info List object formats and architectures supported\n\ + -H --help Display this information\n\ +")); + if (status != 2) + { + fprintf (stream, _("\n The following switches are optional:\n")); + fprintf (stream, _("\ + -b --target Specify the target object format as \n\ + -m --architecture Specify the target architecture as \n\ + -j --section Only display information for section \n\ + -M --disassembler-options Pass text on to the disassembler\n\ + -EB --endian=big Assume big endian format when disassembling\n\ + -EL --endian=little Assume little endian format when disassembling\n\ + --file-start-context Include context from start of file (with -S)\n\ + -l --line-numbers Include line numbers and filenames in output\n\ + -C --demangle Decode mangled/processed symbol names\n\ + -w --wide Format output for more than 80 columns\n\ + -z --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\ + --start-address Only process data whoes address is >= \n\ + --stop-address Only process data whoes address is <= \n\ + --prefix-addresses Print complete address alongside disassembly\n\ + --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\ + --adjust-vma Add to all displayed section addresses\n\ +\n")); + list_supported_targets (program_name, stream); + + disassembler_usage (stream); + } if (status == 0) - fprintf (stream, _("Report bugs to bug-gnu-utils@gnu.org\n")); + fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO); exit (status); } @@ -255,16 +286,17 @@ static struct option long_options[]= {"private-headers", no_argument, NULL, 'p'}, {"architecture", required_argument, NULL, 'm'}, {"archive-headers", no_argument, NULL, 'a'}, - {"debugging", no_argument, &dump_debugging, 1}, - {"demangle", no_argument, &do_demangle, 1}, + {"debugging", no_argument, NULL, 'g'}, + {"demangle", no_argument, NULL, 'C'}, {"disassemble", no_argument, NULL, 'd'}, {"disassemble-all", no_argument, NULL, 'D'}, {"disassembler-options", required_argument, NULL, 'M'}, - {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1}, + {"disassemble-zeroes", no_argument, NULL, 'z'}, {"dynamic-reloc", no_argument, NULL, 'R'}, {"dynamic-syms", no_argument, NULL, 'T'}, {"endian", required_argument, NULL, OPTION_ENDIAN}, {"file-headers", no_argument, NULL, 'f'}, + {"file-start-context", no_argument, &file_start_context, 1}, {"full-contents", no_argument, NULL, 's'}, {"headers", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'H'}, @@ -277,27 +309,36 @@ 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'}, - {"stabs", no_argument, &dump_stab_section_info, 1}, + {"stabs", no_argument, NULL, 'G'}, {"start-address", required_argument, NULL, OPTION_START_ADDRESS}, {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS}, {"syms", no_argument, NULL, 't'}, {"target", required_argument, NULL, 'b'}, - {"version", no_argument, &show_version, 1}, - {"wide", no_argument, &wide_output, 'w'}, + {"version", no_argument, NULL, 'V'}, + {"wide", no_argument, NULL, 'w'}, {0, no_argument, 0, 0} }; static void +nonfatal (msg) + const char *msg; +{ + bfd_nonfatal (msg); + exit_status = 1; +} + +static void dump_section_header (abfd, section, ignored) bfd *abfd ATTRIBUTE_UNUSED; asection *section; PTR ignored ATTRIBUTE_UNUSED; { char *comma = ""; + unsigned int opb = bfd_octets_per_byte (abfd); printf ("%3d %-13s %08lx ", section->index, bfd_get_section_name (abfd, section), - (unsigned long) bfd_section_size (abfd, section)); + (unsigned long) bfd_section_size (abfd, section) / opb); printf_vma (bfd_get_section_vma (abfd, section)); printf (" "); printf_vma (section->lma); @@ -329,7 +370,10 @@ dump_section_header (abfd, section, ignored) PF (SEC_NEVER_LOAD, "NEVER_LOAD"); PF (SEC_EXCLUDE, "EXCLUDE"); PF (SEC_SORT_ENTRIES, "SORT_ENTRIES"); - PF (SEC_SHORT, "SHORT"); + PF (SEC_BLOCK, "BLOCK"); + PF (SEC_CLINK, "CLINK"); + PF (SEC_SMALL_DATA, "SMALL_DATA"); + PF (SEC_SHARED, "SHARED"); if ((section->flags & SEC_LINK_ONCE) != 0) { @@ -353,6 +397,11 @@ dump_section_header (abfd, section, ignored) break; } printf ("%s%s", comma, ls); + + if (section->comdat != NULL) + printf (" (COMDAT %s %ld)", section->comdat->name, + section->comdat->symbol); + comma = ", "; } @@ -365,11 +414,17 @@ dump_headers (abfd) bfd *abfd; { printf (_("Sections:\n")); + #ifndef BFD64 - printf (_("Idx Name Size VMA LMA File off Algn\n")); + printf (_("Idx Name Size VMA LMA File off Algn")); #else - printf (_("Idx Name Size VMA LMA File off Algn\n")); + printf (_("Idx Name Size VMA LMA File off Algn")); #endif + + if (wide_output) + printf (_(" Flags")); + printf ("\n"); + bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL); } @@ -382,7 +437,7 @@ slurp_symtab (abfd) if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) { - fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd)); + non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); symcount = 0; return NULL; } @@ -399,7 +454,7 @@ slurp_symtab (abfd) if (symcount < 0) bfd_fatal (bfd_get_filename (abfd)); if (symcount == 0) - fprintf (stderr, _("%s: no symbols\n"), bfd_get_filename (abfd)); + non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); return sy; } @@ -417,8 +472,7 @@ slurp_dynamic_symtab (abfd) { if (!(bfd_get_file_flags (abfd) & DYNAMIC)) { - fprintf (stderr, _("%s: %s: not a dynamic object\n"), - program_name, bfd_get_filename (abfd)); + non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd)); dynsymcount = 0; return NULL; } @@ -434,8 +488,7 @@ slurp_dynamic_symtab (abfd) if (dynsymcount < 0) bfd_fatal (bfd_get_filename (abfd)); if (dynsymcount == 0) - fprintf (stderr, _("%s: %s: No dynamic symbols\n"), - program_name, bfd_get_filename (abfd)); + non_fatal (_("%s: No dynamic symbols"), bfd_get_filename (abfd)); return sy; } @@ -684,6 +737,7 @@ find_symbol_for_address (abfd, sec, vma, require_sec, place) long min = 0; long max = sorted_symcount; long thisplace; + unsigned int opb = bfd_octets_per_byte (abfd); if (sorted_symcount < 1) return NULL; @@ -731,7 +785,7 @@ find_symbol_for_address (abfd, sec, vma, require_sec, place) || ((abfd->flags & HAS_RELOC) != 0 && vma >= bfd_get_section_vma (abfd, sec) && vma < (bfd_get_section_vma (abfd, sec) - + bfd_section_size (abfd, sec))))) + + bfd_section_size (abfd, sec) / opb)))) { long i; @@ -955,10 +1009,10 @@ skip_to_line (p, line, show) listing. */ static void -show_line (abfd, section, off) +show_line (abfd, section, addr_offset) bfd *abfd; asection *section; - bfd_vma off; + bfd_vma addr_offset; { CONST char *filename; CONST char *functionname; @@ -967,7 +1021,7 @@ show_line (abfd, section, off) if (! with_line_numbers && ! with_source_code) return; - if (! bfd_find_nearest_line (abfd, section, syms, off, &filename, + if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename, &functionname, &line)) return; @@ -1019,8 +1073,8 @@ show_line (abfd, section, off) else { l = line - SHOW_PRECEDING_CONTEXT_LINES; - if (l <= 0) - l = 1; + if (l < 0) + l = 0; } if (p->f == NULL) @@ -1070,9 +1124,12 @@ show_line (abfd, section, off) p->next = print_files; print_files = p; - l = line - SHOW_PRECEDING_CONTEXT_LINES; - if (l <= 0) - l = 1; + if (file_start_context) + l = 0; + else + l = line - SHOW_PRECEDING_CONTEXT_LINES; + if (l < 0) + l = 0; skip_to_line (p, l, false); if (p->f != NULL) skip_to_line (p, line, true); @@ -1134,8 +1191,7 @@ objdump_sprintf (va_alist) if (buf == NULL) { - fprintf (stderr, _("Out of virtual memory\n")); - exit (1); + fatal (_("Out of virtual memory")); } n = strlen (buf); @@ -1176,31 +1232,33 @@ objdump_sprintf (va_alist) /* Disassemble some data in memory between given values. */ static void -disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, +disassemble_bytes (info, disassemble_fn, insns, data, + start_offset, stop_offset, relppp, relppend) struct disassemble_info *info; disassembler_ftype disassemble_fn; boolean insns; bfd_byte *data; - bfd_vma start; - bfd_vma stop; + bfd_vma start_offset; + bfd_vma stop_offset; arelent ***relppp; arelent **relppend; { struct objdump_disasm_info *aux; asection *section; - int bytes_per_line; + int octets_per_line; boolean done_dot; int skip_addr_chars; - bfd_vma i; + bfd_vma addr_offset; + int opb = info->octets_per_byte; aux = (struct objdump_disasm_info *) info->application_data; section = aux->sec; if (insns) - bytes_per_line = 4; + octets_per_line = 4; else - bytes_per_line = 16; + octets_per_line = 16; /* Figure out how many characters to skip at the start of an address, to make the disassembly look nicer. We discard leading @@ -1212,8 +1270,8 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, char buf[30]; char *s; - sprintf_vma (buf, - section->vma + bfd_section_size (section->owner, section)); + sprintf_vma (buf, section->vma + + bfd_section_size (section->owner, section) / opb); s = buf; while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0' && s[4] == '0') @@ -1226,34 +1284,35 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, info->insn_info_valid = 0; done_dot = false; - i = start; - while (i < stop) + addr_offset = start_offset; + while (addr_offset < stop_offset) { bfd_vma z; - int bytes = 0; + int octets = 0; boolean need_nl = false; - /* If we see more than SKIP_ZEROES bytes of zeroes, we just + /* If we see more than SKIP_ZEROES octets of zeroes, we just print `...'. */ - for (z = i; z < stop; z++) + for (z = addr_offset * opb; z < stop_offset * opb; z++) if (data[z] != 0) break; if (! disassemble_zeroes && (info->insn_info_valid == 0 || info->branch_delay_insns == 0) - && (z - i >= SKIP_ZEROES - || (z == stop && z - i < SKIP_ZEROES_AT_END))) + && (z - addr_offset * opb >= SKIP_ZEROES + || (z == stop_offset * opb && + z - addr_offset * opb < SKIP_ZEROES_AT_END))) { printf ("\t...\n"); - /* If there are more nonzero bytes to follow, we only skip + /* If there are more nonzero octets to follow, we only skip zeroes in multiples of 4, to try to avoid running over the start of an instruction which happens to start with zero. */ - if (z != stop) - z = i + ((z - i) &~ 3); + if (z != stop_offset * opb) + z = addr_offset * opb + ((z - addr_offset * opb) &~ 3); - bytes = z - i; + octets = z - addr_offset * opb; } else { @@ -1265,13 +1324,13 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, done_dot = false; if (with_line_numbers || with_source_code) - show_line (aux->abfd, section, i); + show_line (aux->abfd, section, addr_offset); if (! prefix_addresses) { char *s; - sprintf_vma (buf, section->vma + i); + sprintf_vma (buf, section->vma + addr_offset); for (s = buf + skip_addr_chars; *s == '0'; s++) *s = ' '; if (*s == '\0') @@ -1281,7 +1340,7 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, else { aux->require_sec = true; - objdump_print_address (section->vma + i, info); + objdump_print_address (section->vma + addr_offset, info); aux->require_sec = false; putchar (' '); } @@ -1296,21 +1355,21 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, info->bytes_per_line = 0; info->bytes_per_chunk = 0; - /* FIXME: This is wrong. It tests the number of bytes + /* FIXME: This is wrong. It tests the number of octets in the last instruction, not the current one. */ if (*relppp < relppend - && (**relppp)->address >= i - && (**relppp)->address < i + bytes) + && (**relppp)->address >= addr_offset + && (**relppp)->address < addr_offset + octets / opb) info->flags = INSN_HAS_RELOC; else info->flags = 0; - bytes = (*disassemble_fn) (section->vma + i, info); + octets = (*disassemble_fn) (section->vma + addr_offset, info); info->fprintf_func = (fprintf_ftype) fprintf; info->stream = stdout; if (info->bytes_per_line != 0) - bytes_per_line = info->bytes_per_line; - if (bytes < 0) + octets_per_line = info->bytes_per_line; + if (octets < 0) { if (sfile.current != sfile.buffer) printf ("%s\n", sfile.buffer); @@ -1322,18 +1381,18 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, { bfd_vma j; - bytes = bytes_per_line; - if (i + bytes > stop) - bytes = stop - i; + octets = octets_per_line; + if (addr_offset + octets / opb > stop_offset) + octets = (stop_offset - addr_offset) * opb; - for (j = i; j < i + bytes; ++j) + for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j) { if (isprint (data[j])) - buf[j - i] = data[j]; + buf[j - addr_offset * opb] = data[j]; else - buf[j - i] = '.'; + buf[j - addr_offset * opb] = '.'; } - buf[j - i] = '\0'; + buf[j - addr_offset * opb] = '\0'; } if (prefix_addresses @@ -1343,17 +1402,17 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, bfd_vma j; /* If ! prefix_addresses and ! wide_output, we print - bytes_per_line bytes per line. */ - pb = bytes; - if (pb > bytes_per_line && ! prefix_addresses && ! wide_output) - pb = bytes_per_line; + octets_per_line octets per line. */ + pb = octets; + if (pb > octets_per_line && ! prefix_addresses && ! wide_output) + pb = octets_per_line; if (info->bytes_per_chunk) bpc = info->bytes_per_chunk; else bpc = 1; - for (j = i; j < i + pb; j += bpc) + for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc) { int k; if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE) @@ -1370,7 +1429,7 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, } } - for (; pb < bytes_per_line; pb += bpc) + for (; pb < octets_per_line; pb += bpc) { int k; @@ -1398,25 +1457,25 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, ? show_raw_insn > 0 : show_raw_insn >= 0) { - while (pb < bytes) + while (pb < octets) { bfd_vma j; char *s; putchar ('\n'); - j = i + pb; + j = addr_offset * opb + pb; - sprintf_vma (buf, section->vma + j); + sprintf_vma (buf, section->vma + j / opb); for (s = buf + skip_addr_chars; *s == '0'; s++) *s = ' '; if (*s == '\0') *--s = '0'; printf ("%s:\t", buf + skip_addr_chars); - pb += bytes_per_line; - if (pb > bytes) - pb = bytes; - for (; j < i + pb; j += bpc) + pb += octets_per_line; + if (pb > octets) + pb = octets; + for (; j < addr_offset * opb + pb; j += bpc) { int k; @@ -1446,8 +1505,8 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, && (section->flags & SEC_RELOC) != 0) { while ((*relppp) < relppend - && ((**relppp)->address >= (bfd_vma) i - && (**relppp)->address < (bfd_vma) i + bytes)) + && ((**relppp)->address >= (bfd_vma) addr_offset + && (**relppp)->address < (bfd_vma) addr_offset + octets / opb)) { arelent *q; @@ -1498,7 +1557,7 @@ disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp, if (need_nl) printf ("\n"); - i += bytes; + addr_offset += octets / opb; } } @@ -1508,11 +1567,12 @@ static void disassemble_data (abfd) bfd *abfd; { - long i; + 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; @@ -1540,10 +1600,7 @@ disassemble_data (abfd) const bfd_arch_info_type *info = bfd_scan_arch (machine); if (info == NULL) { - fprintf (stderr, _("%s: Can't use supplied machine %s\n"), - program_name, - machine); - exit (1); + fatal (_("Can't use supplied machine %s"), machine); } abfd->arch_info = info; } @@ -1561,16 +1618,19 @@ disassemble_data (abfd) disassemble_fn = disassembler (abfd); if (!disassemble_fn) { - fprintf (stderr, _("%s: Can't disassemble for architecture %s\n"), - program_name, - bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); + 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; @@ -1590,7 +1650,7 @@ disassemble_data (abfd) arelent **relbuf = NULL; arelent **relpp = NULL; arelent **relppend = NULL; - long stop; + unsigned long stop_offset; asymbol *sym = NULL; long place = 0; @@ -1653,37 +1713,37 @@ disassemble_data (abfd) disasm_info.buffer_length = datasize; if (start_address == (bfd_vma) -1 || start_address < disasm_info.buffer_vma) - i = 0; + addr_offset = 0; else - i = start_address - disasm_info.buffer_vma; + addr_offset = start_address - disasm_info.buffer_vma; if (stop_address == (bfd_vma) -1) - stop = datasize; + stop_offset = datasize / opb; else { if (stop_address < disasm_info.buffer_vma) - stop = 0; + stop_offset = 0; else - stop = stop_address - disasm_info.buffer_vma; - if (stop > disasm_info.buffer_length) - stop = disasm_info.buffer_length; + 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 + i, + sym = find_symbol_for_address (abfd, section, section->vma + addr_offset, true, &place); - while (i < stop) + while (addr_offset < stop_offset) { asymbol *nextsym; - long nextstop; + unsigned long nextstop_offset; boolean insns; - if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + i) + 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 + i); + && bfd_asymbol_value (sorted_syms[x]) <= section->vma + addr_offset); ++x) continue; disasm_info.symbols = & sorted_syms[place]; @@ -1696,20 +1756,23 @@ disassemble_data (abfd) { printf ("\n"); objdump_print_addr_with_sym (abfd, section, sym, - section->vma + i, + section->vma + addr_offset, &disasm_info, false); printf (":\n"); } - if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i) + 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 - /* ??? Why the test for != section? */ && (sorted_syms[place]->section != section || (bfd_asymbol_value (sorted_syms[place]) <= bfd_asymbol_value (sym)))) @@ -1720,19 +1783,19 @@ disassemble_data (abfd) nextsym = sorted_syms[place]; } - if (sym != NULL && bfd_asymbol_value (sym) > section->vma + i) + if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset) { - nextstop = bfd_asymbol_value (sym) - section->vma; - if (nextstop > stop) - nextstop = stop; + nextstop_offset = bfd_asymbol_value (sym) - section->vma; + if (nextstop_offset > stop_offset) + nextstop_offset = stop_offset; } else if (nextsym == NULL) - nextstop = stop; + nextstop_offset = stop_offset; else { - nextstop = bfd_asymbol_value (nextsym) - section->vma; - if (nextstop > stop) - nextstop = stop; + 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 @@ -1740,7 +1803,7 @@ disassemble_data (abfd) disassembling them. */ if (disassemble_all || sym == NULL - || bfd_asymbol_value (sym) > section->vma + i + || bfd_asymbol_value (sym) > section->vma + addr_offset || ((sym->flags & BSF_OBJECT) == 0 && (strstr (bfd_asymbol_name (sym), "gnu_compiled") == NULL) @@ -1751,10 +1814,10 @@ disassemble_data (abfd) else insns = false; - disassemble_bytes (&disasm_info, disassemble_fn, insns, data, i, - nextstop, &relpp, relppend); + disassemble_bytes (&disasm_info, disassemble_fn, insns, data, + addr_offset, nextstop_offset, &relpp, relppend); - i = nextstop; + addr_offset = nextstop_offset; sym = nextsym; } @@ -1815,8 +1878,9 @@ read_section_stabs (abfd, stabsect_name, strsect_name) stabstrsect = bfd_get_section_by_name (abfd, strsect_name); if (0 == stabstrsect) { - fprintf (stderr, _("%s: %s has no %s section\n"), program_name, - bfd_get_filename (abfd), strsect_name); + non_fatal (_("%s has no %s section"), + bfd_get_filename (abfd), strsect_name); + exit_status = 1; return false; } @@ -1828,22 +1892,24 @@ read_section_stabs (abfd, stabsect_name, strsect_name) if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size)) { - fprintf (stderr, _("%s: Reading %s section of %s failed: %s\n"), - program_name, stabsect_name, bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); + 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)) { - fprintf (stderr, _("%s: Reading %s section of %s failed: %s\n"), - program_name, strsect_name, bfd_get_filename (abfd), - bfd_errmsg (bfd_get_error ())); + 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; } @@ -2009,23 +2075,12 @@ bfd *abfd; bfd_print_private_bfd_data (abfd, stdout); } +/* Dump selected contents of ABFD */ + static void -display_bfd (abfd) +dump_bfd (abfd) bfd *abfd; { - char **matching; - - if (!bfd_check_format_matches (abfd, bfd_object, &matching)) - { - bfd_nonfatal (bfd_get_filename (abfd)); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) - { - list_matching_formats (matching); - free (matching); - } - return; - } - /* If we are adjusting section VMA's, change them all now. Changing the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ @@ -2081,8 +2136,11 @@ display_bfd (abfd) if (dhandle != NULL) { if (! print_debugging_info (stdout, dhandle)) - fprintf (stderr, _("%s: printing debugging information failed\n"), - bfd_get_filename (abfd)); + { + non_fatal (_("%s: printing debugging information failed"), + bfd_get_filename (abfd)); + exit_status = 1; + } } } if (syms) @@ -2098,6 +2156,47 @@ display_bfd (abfd) } static void +display_bfd (abfd) + bfd *abfd; +{ + char **matching; + + if (bfd_check_format_matches (abfd, bfd_object, &matching)) + { + dump_bfd (abfd); + return; + } + + if (bfd_get_error () == bfd_error_file_ambiguously_recognized) + { + nonfatal (bfd_get_filename (abfd)); + list_matching_formats (matching); + free (matching); + return; + } + + if (bfd_get_error () != bfd_error_file_not_recognized) + { + nonfatal (bfd_get_filename (abfd)); + return; + } + + if (bfd_check_format_matches (abfd, bfd_core, &matching)) + { + dump_bfd (abfd); + return; + } + + nonfatal (bfd_get_filename (abfd)); + + if (bfd_get_error () == bfd_error_file_ambiguously_recognized) + { + list_matching_formats (matching); + free (matching); + } +} + +static void display_file (filename, target) char *filename; char *target; @@ -2107,7 +2206,7 @@ display_file (filename, target) file = bfd_openr (filename, target); if (file == NULL) { - bfd_nonfatal (filename); + nonfatal (filename); return; } @@ -2124,9 +2223,7 @@ display_file (filename, target) if (arfile == NULL) { if (bfd_get_error () != bfd_error_no_more_archived_files) - { - bfd_nonfatal (bfd_get_filename (file)); - } + nonfatal (bfd_get_filename (file)); break; } @@ -2155,8 +2252,9 @@ dump_data (abfd) asection *section; bfd_byte *data = 0; bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; + bfd_size_type addr_offset; + bfd_size_type start_offset, stop_offset; + unsigned int opb = bfd_octets_per_byte (abfd); for (section = abfd->sections; section != NULL; section = section->next) @@ -2180,28 +2278,31 @@ dump_data (abfd) if (start_address == (bfd_vma) -1 || start_address < section->vma) - start = 0; + start_offset = 0; else - start = start_address - section->vma; + start_offset = start_address - section->vma; if (stop_address == (bfd_vma) -1) - stop = bfd_section_size (abfd, section); + stop_offset = bfd_section_size (abfd, section) / opb; else { if (stop_address < section->vma) - stop = 0; + stop_offset = 0; else - stop = stop_address - section->vma; - if (stop > bfd_section_size (abfd, section)) - stop = bfd_section_size (abfd, section); + stop_offset = stop_address - section->vma; + if (stop_offset > bfd_section_size (abfd, section) / opb) + stop_offset = bfd_section_size (abfd, section) / opb; } - for (i = start; i < stop; i += onaline) + for (addr_offset = start_offset; + addr_offset < stop_offset; addr_offset += onaline) { bfd_size_type j; - printf (" %04lx ", (unsigned long int) (i + section->vma)); - for (j = i; j < i + onaline; j++) + printf (" %04lx ", (unsigned long int) + (addr_offset + section->vma)); + for (j = addr_offset * opb; + j < addr_offset * opb + onaline; j++) { - if (j < stop) + if (j < stop_offset * opb) printf ("%02x", (unsigned) (data[j])); else printf (" "); @@ -2210,9 +2311,9 @@ dump_data (abfd) } printf (" "); - for (j = i; j < i + onaline; j++) + for (j = addr_offset; j < addr_offset * opb + onaline; j++) { - if (j >= stop) + if (j >= stop_offset * opb) printf (" "); else printf ("%c", isprint (data[j]) ? data[j] : '.'); @@ -2531,7 +2632,7 @@ display_target_list () char *dummy_name; int t; - dummy_name = choose_temp_base (); + dummy_name = make_temp_file (NULL); for (t = 0; bfd_target_vector[t]; t++) { bfd_target *p = bfd_target_vector[t]; @@ -2544,14 +2645,15 @@ display_target_list () if (abfd == NULL) { - bfd_nonfatal (dummy_name); + nonfatal (dummy_name); continue; } if (! bfd_set_format (abfd, bfd_object)) { if (bfd_get_error () != bfd_error_invalid_operation) - bfd_nonfatal (p->name); + nonfatal (p->name); + bfd_close_all_done (abfd); continue; } @@ -2559,6 +2661,7 @@ display_target_list () if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0)) printf (" %s\n", bfd_printable_arch_mach ((enum bfd_architecture) a, 0)); + bfd_close_all_done (abfd); } unlink (dummy_name); free (dummy_name); @@ -2583,7 +2686,7 @@ display_info_table (first, last) printf ("%s ", bfd_target_vector[t]->name); putchar ('\n'); - dummy_name = choose_temp_base (); + dummy_name = make_temp_file (NULL); for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++) if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0) { @@ -2597,7 +2700,7 @@ display_info_table (first, last) if (abfd == NULL) { - bfd_nonfatal (p->name); + nonfatal (p->name); ok = false; } @@ -2606,7 +2709,7 @@ display_info_table (first, last) if (! bfd_set_format (abfd, bfd_object)) { if (bfd_get_error () != bfd_error_invalid_operation) - bfd_nonfatal (p->name); + nonfatal (p->name); ok = false; } } @@ -2626,6 +2729,8 @@ display_info_table (first, last) putchar ('-'); putchar (' '); } + if (abfd != NULL) + bfd_close_all_done (abfd); } putchar ('\n'); } @@ -2702,12 +2807,10 @@ main (argc, argv) bfd_init (); set_default_bfd_target (); - while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahrRtTxsSj:wE:", + while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahHrRtTxsSj:wE:zgG", long_options, (int *) 0)) != EOF) { - if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS) - seenflag = true; switch (c) { case 0: @@ -2722,102 +2825,131 @@ main (argc, argv) only = optarg; break; case 'l': - with_line_numbers = 1; + with_line_numbers = true; break; case 'b': target = optarg; break; + case 'C': + do_demangle = true; + break; + case 'w': + wide_output = true; + break; + case OPTION_ADJUST_VMA: + adjust_section_vma = parse_vma (optarg, "--adjust-vma"); + break; + case OPTION_START_ADDRESS: + start_address = parse_vma (optarg, "--start-address"); + break; + case OPTION_STOP_ADDRESS: + stop_address = parse_vma (optarg, "--stop-address"); + break; + case 'E': + if (strcmp (optarg, "B") == 0) + endian = BFD_ENDIAN_BIG; + else if (strcmp (optarg, "L") == 0) + endian = BFD_ENDIAN_LITTLE; + else + { + non_fatal (_("unrecognized -E option")); + usage (stderr, 1); + } + break; + case OPTION_ENDIAN: + if (strncmp (optarg, "big", strlen (optarg)) == 0) + endian = BFD_ENDIAN_BIG; + else if (strncmp (optarg, "little", strlen (optarg)) == 0) + endian = BFD_ENDIAN_LITTLE; + else + { + non_fatal (_("unrecognized --endian type `%s'"), optarg); + usage (stderr, 1); + } + break; + case 'f': dump_file_header = true; + seenflag = true; break; case 'i': formats_info = true; + seenflag = true; break; case 'p': - dump_private_headers = 1; + dump_private_headers = true; + seenflag = true; break; case 'x': - dump_private_headers = 1; - dump_symtab = 1; - dump_reloc_info = 1; + dump_private_headers = true; + dump_symtab = true; + dump_reloc_info = true; dump_file_header = true; - dump_ar_hdrs = 1; - dump_section_headers = 1; + dump_ar_hdrs = true; + dump_section_headers = true; + seenflag = true; break; case 't': - dump_symtab = 1; + dump_symtab = true; + seenflag = true; break; case 'T': - dump_dynamic_symtab = 1; - break; - case 'C': - do_demangle = 1; + dump_dynamic_symtab = true; + seenflag = true; break; case 'd': disassemble = true; + seenflag = true; + break; + case 'z': + disassemble_zeroes = true; break; case 'D': - disassemble = disassemble_all = true; + disassemble = true; + disassemble_all = true; + seenflag = true; break; case 'S': disassemble = true; with_source_code = true; + seenflag = true; + break; + case 'g': + dump_debugging = 1; + seenflag = true; + break; + case 'G': + dump_stab_section_info = true; + seenflag = true; break; case 's': - dump_section_contents = 1; + dump_section_contents = true; + seenflag = true; break; case 'r': - dump_reloc_info = 1; + dump_reloc_info = true; + seenflag = true; break; case 'R': - dump_dynamic_reloc_info = 1; + dump_dynamic_reloc_info = true; + seenflag = true; break; case 'a': - dump_ar_hdrs = 1; + dump_ar_hdrs = true; + seenflag = true; break; case 'h': - dump_section_headers = 1; + dump_section_headers = true; + seenflag = true; break; case 'H': usage (stdout, 0); + seenflag = true; case 'V': - show_version = 1; - break; - case 'w': - wide_output = 1; - break; - case OPTION_ADJUST_VMA: - adjust_section_vma = parse_vma (optarg, "--adjust-vma"); - break; - case OPTION_START_ADDRESS: - start_address = parse_vma (optarg, "--start-address"); - break; - case OPTION_STOP_ADDRESS: - stop_address = parse_vma (optarg, "--stop-address"); - break; - case 'E': - if (strcmp (optarg, "B") == 0) - endian = BFD_ENDIAN_BIG; - else if (strcmp (optarg, "L") == 0) - endian = BFD_ENDIAN_LITTLE; - else - { - fprintf (stderr, _("%s: unrecognized -E option\n"), program_name); - usage (stderr, 1); - } - break; - case OPTION_ENDIAN: - if (strncmp (optarg, "big", strlen (optarg)) == 0) - endian = BFD_ENDIAN_BIG; - else if (strncmp (optarg, "little", strlen (optarg)) == 0) - endian = BFD_ENDIAN_LITTLE; - else - { - fprintf (stderr, _("%s: unrecognized --endian type `%s'\n"), - program_name, optarg); - usage (stderr, 1); - } + show_version = true; + seenflag = true; break; + default: usage (stderr, 1); } @@ -2827,12 +2959,10 @@ main (argc, argv) print_version ("objdump"); if (seenflag == false) - usage (stderr, 1); + usage (stderr, 2); if (formats_info) - { - display_info (); - } + display_info (); else { if (optind == argc) @@ -2844,5 +2974,5 @@ main (argc, argv) END_PROGRESS (program_name); - return 0; + return exit_status; }