X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fobjdump.c;h=6b996a14a8598d83218dfeb45cbd76e525caf31a;hb=0377a422afbedee36dbf205f3681ea2b5ac67b13;hp=0334d70dfe177b6d24c9bfecb0adfe46dbe0c946;hpb=fd3a68167e6b986751558ca54fa46f4a18fb5228;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/objdump.c b/binutils/objdump.c index 0334d70dfe..6b996a14a8 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1,6 +1,6 @@ /* objdump.c -- dump information about an object file. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -55,6 +55,7 @@ #include "elf-bfd.h" #include "progress.h" #include "bucomm.h" +#include "elfcomm.h" #include "dwarf.h" #include "getopt.h" #include "safe-ctype.h" @@ -117,13 +118,16 @@ static const char *prefix; /* --prefix */ static int prefix_strip; /* --prefix-strip */ static size_t prefix_length; -/* Pointer to an array of section names provided by - one or more "-j secname" command line options. */ -static char **only; -/* The total number of slots in the only[] array. */ -static size_t only_size = 0; -/* The number of occupied slots in the only[] array. */ -static size_t only_used = 0; +/* A structure to record the sections mentioned in -j switches. */ +struct only +{ + const char * name; /* The name of the section. */ + bfd_boolean seen; /* A flag to indicate that the section has been found in one or more input files. */ + struct only * next; /* Pointer to the next structure in the list. */ +}; +/* Pointer to an array of 'only' structures. + This pointer is NULL if the -j switch has not been used. */ +static struct only * only_list = NULL; /* Variables for handling include file path table. */ static const char **include_paths; @@ -202,7 +206,8 @@ usage (FILE *stream, int status) -G, --stabs Display (in raw form) any STABS info in the file\n\ -W[lLiaprmfFsoRt] or\n\ --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\ - =frames-interp,=str,=loc,=Ranges,=pubtypes]\n\ + =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\ + =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\ Display DWARF info in the 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\ @@ -237,7 +242,7 @@ usage (FILE *stream, int status) --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 signle line for -d\n\ + --insn-width=WIDTH Display WIDTH bytes on a single line for -d\n\ --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\ --special-syms Include special symbols in symbol dumps\n\ --prefix=PREFIX Add PREFIX to absolute paths for -S\n\ @@ -326,17 +331,79 @@ nonfatal (const char *msg) static bfd_boolean process_section_p (asection * section) { - size_t i; + struct only * only; - if (only == NULL) + if (only_list == NULL) return TRUE; - for (i = 0; i < only_used; i++) - if (strcmp (only [i], section->name) == 0) - return TRUE; + for (only = only_list; only; only = only->next) + if (strcmp (only->name, section->name) == 0) + { + only->seen = TRUE; + return TRUE; + } return FALSE; } + +/* Add an entry to the 'only' list. */ + +static void +add_only (char * name) +{ + struct only * only; + + /* First check to make sure that we do not + already have an entry for this name. */ + for (only = only_list; only; only = only->next) + if (strcmp (only->name, name) == 0) + return; + + only = xmalloc (sizeof * only); + only->name = name; + only->seen = FALSE; + only->next = only_list; + only_list = only; +} + +/* Release the memory used by the 'only' list. + PR 11225: Issue a warning message for unseen sections. + Only do this if none of the sections were seen. This is mainly to support + tools like the GAS testsuite where an object file is dumped with a list of + generic section names known to be present in a range of different file + formats. */ + +static void +free_only_list (void) +{ + bfd_boolean at_least_one_seen = FALSE; + struct only * only; + struct only * next; + + if (only_list == NULL) + return; + + for (only = only_list; only; only = only->next) + if (only->seen) + { + at_least_one_seen = TRUE; + break; + } + + for (only = only_list; only; only = next) + { + if (! at_least_one_seen) + { + non_fatal (_("section '%s' mentioned in a -j option, " + "but not found in any input file"), + only->name); + exit_status = 1; + } + next = only->next; + free (only); + } +} + static void dump_section_header (bfd *abfd, asection *section, @@ -445,8 +512,6 @@ dump_headers (bfd *abfd) if (wide_output) printf (_(" Flags")); - if (abfd->flags & HAS_LOAD_PAGE) - printf (_(" Pg")); printf ("\n"); bfd_map_over_sections (abfd, dump_section_header, NULL); @@ -490,6 +555,7 @@ slurp_dynamic_symtab (bfd *abfd) if (!(bfd_get_file_flags (abfd) & DYNAMIC)) { non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd)); + exit_status = 1; dynsymcount = 0; return NULL; } @@ -1145,9 +1211,6 @@ update_source_path (const char *filename) const char *fname; int i; - if (filename == NULL) - return NULL; - p = try_print_file_open (filename, filename); if (p != NULL) return p; @@ -1285,7 +1348,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) unsigned l; for (pp = &print_files; *pp != NULL; pp = &(*pp)->next) - if (strcmp ((*pp)->filename, filename) == 0) + if (filename_cmp ((*pp)->filename, filename) == 0) break; p = *pp; @@ -1393,7 +1456,6 @@ disassemble_bytes (struct disassemble_info * inf, struct objdump_disasm_info *aux; asection *section; int octets_per_line; - bfd_boolean done_dot; int skip_addr_chars; bfd_vma addr_offset; unsigned int opb = inf->octets_per_byte; @@ -1440,7 +1502,6 @@ disassemble_bytes (struct disassemble_info * inf, inf->insn_info_valid = 0; - done_dot = FALSE; addr_offset = start_offset; while (addr_offset < stop_offset) { @@ -1452,6 +1513,9 @@ disassemble_bytes (struct disassemble_info * inf, previous_octets = octets; octets = 0; + /* Make sure we don't use relocs from previous instructions. */ + aux->reloc = NULL; + /* If we see more than SKIP_ZEROES octets of zeroes, we just print `...'. */ for (z = addr_offset * opb; z < stop_offset * opb; z++) @@ -1490,8 +1554,6 @@ disassemble_bytes (struct disassemble_info * inf, int bpc = 0; int pb = 0; - done_dot = FALSE; - if (with_line_numbers || with_source_code) show_line (aux->abfd, section, addr_offset); @@ -1555,8 +1617,6 @@ disassemble_bytes (struct disassemble_info * inf, inf->flags |= INSN_HAS_RELOC; aux->reloc = **relppp; } - else - aux->reloc = NULL; } octets = (*disassemble_fn) (section->vma + addr_offset, inf); @@ -1564,10 +1624,16 @@ disassemble_bytes (struct disassemble_info * inf, inf->stream = stdout; if (insn_width == 0 && inf->bytes_per_line != 0) octets_per_line = inf->bytes_per_line; - if (octets < 0) + if (octets < (int) opb) { if (sfile.pos) printf ("%s\n", sfile.buffer); + if (octets >= 0) + { + non_fatal (_("disassemble_fn returned length %d"), + octets); + exit_status = 1; + } break; } } @@ -1782,7 +1848,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) /* Sections that do not contain machine code are not normally disassembled. */ if (! disassemble_all - && only == NULL + && only_list == NULL && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS)) != (SEC_CODE | SEC_HAS_CONTENTS))) return; @@ -2045,7 +2111,7 @@ disassemble_data (bfd *abfd) const bfd_arch_info_type *inf = bfd_scan_arch (machine); if (inf == NULL) - fatal (_("Can't use supplied machine %s"), machine); + fatal (_("can't use supplied machine %s"), machine); abfd->arch_info = inf; } @@ -2064,7 +2130,7 @@ disassemble_data (bfd *abfd) aux.disassemble_fn = disassembler (abfd); if (!aux.disassemble_fn) { - non_fatal (_("Can't disassemble for architecture %s\n"), + non_fatal (_("can't disassemble for architecture %s\n"), bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); exit_status = 1; return; @@ -2131,26 +2197,15 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, struct dwarf_section *section = &debug_displays [debug].section; bfd *abfd = (bfd *) file; bfd_boolean ret; - int section_is_compressed; /* If it is already loaded, do nothing. */ if (section->start != NULL) return 1; - section_is_compressed = section->name == section->compressed_name; - section->address = 0; section->size = bfd_get_section_size (sec); - section->start = (unsigned char *) xmalloc (section->size); - - if (is_relocatable && debug_displays [debug].relocate) - ret = bfd_simple_get_relocated_section_contents (abfd, - sec, - section->start, - syms) != NULL; - else - ret = bfd_get_section_contents (abfd, sec, section->start, 0, - section->size); + section->start = NULL; + ret = bfd_get_full_section_contents (abfd, sec, §ion->start); if (! ret) { @@ -2160,16 +2215,28 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, return 0; } - if (section_is_compressed) + if (is_relocatable && debug_displays [debug].relocate) { - bfd_size_type size = section->size; - if (! bfd_uncompress_section_contents (§ion->start, &size)) + /* We want to relocate the data we've already read (and + decompressed), so we store a pointer to the data in + the bfd_section, and tell it that the contents are + already in memory. */ + sec->contents = section->start; + sec->flags |= SEC_IN_MEMORY; + sec->size = section->size; + + ret = bfd_simple_get_relocated_section_contents (abfd, + sec, + section->start, + syms) != NULL; + + if (! ret) { free_debug_section (debug); - printf (_("\nCan't uncompress section '%s'.\n"), section->name); + printf (_("\nCan't get contents for section '%s'.\n"), + section->name); return 0; } - section->size = size; } return 1; @@ -2260,9 +2327,7 @@ dump_dwarf (bfd *abfd) { is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; - /* FIXME: bfd_get_arch_size may return -1. We assume that 64bit - targets will return 64. */ - eh_addr_size = bfd_get_arch_size (abfd) == 64 ? 8 : 4; + eh_addr_size = bfd_arch_bits_per_address (abfd) / 8; if (bfd_big_endian (abfd)) byte_get = byte_get_big_endian; @@ -2271,10 +2336,24 @@ dump_dwarf (bfd *abfd) else abort (); - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) + switch (bfd_get_arch (abfd)) { - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - init_dwarf_regnames (bed->elf_machine_code); + case bfd_arch_i386: + switch (bfd_get_mach (abfd)) + { + case bfd_mach_x86_64: + case bfd_mach_x86_64_intel_syntax: + init_dwarf_regnames_x86_64 (); + break; + + default: + init_dwarf_regnames_i386 (); + break; + } + break; + + default: + break; } bfd_map_over_sections (abfd, dump_dwarf_section, NULL); @@ -2304,11 +2383,11 @@ read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr) if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size)) { - non_fatal (_("Reading %s section of %s failed: %s"), + non_fatal (_("reading %s section of %s failed: %s"), sect_name, bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); - free (contents); exit_status = 1; + free (contents); return NULL; } @@ -2482,7 +2561,7 @@ dump_bfd_header (bfd *abfd) printf (_("architecture: %s, "), bfd_printable_arch_mach (bfd_get_arch (abfd), bfd_get_mach (abfd))); - printf (_("flags 0x%08x:\n"), abfd->flags); + printf (_("flags 0x%08x:\n"), abfd->flags & ~BFD_FLAGS_FOR_BFD_USE_MASK); #define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";} PF (HAS_RELOC, "HAS_RELOC"); @@ -2565,9 +2644,11 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) (unsigned long) (section->filepos + start_offset)); printf ("\n"); - data = (bfd_byte *) xmalloc (datasize); - - bfd_get_section_contents (abfd, section, data, 0, datasize); + if (!bfd_get_full_section_contents (abfd, section, &data)) + { + non_fatal (_("Reading section failed")); + return; + } width = 4; @@ -2775,7 +2856,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) && (linenumber != last_line || (filename != NULL && last_filename != NULL - && strcmp (filename, last_filename) != 0))) + && filename_cmp (filename, last_filename) != 0))) { printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); last_line = linenumber; @@ -3111,6 +3192,10 @@ display_file (char *filename, char *target) return; } + /* Decompress sections unless dumping the section contents. */ + if (!dump_section_contents) + file->flags |= BFD_DECOMPRESS; + /* If the file is an archive, process all of its elements. */ if (bfd_check_format (file, bfd_archive)) { @@ -3193,12 +3278,7 @@ main (int argc, char **argv) disassembler_options = optarg; break; case 'j': - if (only_used == only_size) - { - only_size += 8; - only = (char **) xrealloc (only, only_size * sizeof (char *)); - } - only [only_used++] = optarg; + add_only (optarg); break; case 'F': display_file_offsets = TRUE; @@ -3263,7 +3343,7 @@ main (int argc, char **argv) endian = BFD_ENDIAN_LITTLE; else { - non_fatal (_("unrecognized -E option")); + nonfatal (_("unrecognized -E option")); usage (stderr, 1); } break; @@ -3275,6 +3355,7 @@ main (int argc, char **argv) else { non_fatal (_("unrecognized --endian type `%s'"), optarg); + exit_status = 1; usage (stderr, 1); } break; @@ -3409,6 +3490,8 @@ main (int argc, char **argv) display_file (argv[optind++], target); } + free_only_list (); + END_PROGRESS (program_name); return exit_status;