X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fobjdump.c;h=5b848014c7135c65af026e422558ed8f56ca1f3e;hb=97f50151221de0a023a8317559b1992a90f9cb8f;hp=a8c7d05f1e036ec7f485a98d5c90f65e46760671;hpb=b90efa5b79ac1524ec260f8eb89d1be37e0219a7;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/objdump.c b/binutils/objdump.c index a8c7d05f1e..5b848014c7 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1,5 +1,5 @@ /* objdump.c -- dump information about an object file. - Copyright (C) 1990-2015 Free Software Foundation, Inc. + Copyright (C) 1990-2016 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -27,14 +27,14 @@ relocations, debugging directives and more. The flow of execution is as follows: - + 1. Command line arguments are checked for control switches and the information to be displayed is selected. - + 2. Any remaining arguments are assumed to be object files, and they are processed in order by display_bfd(). If the file is an archive each of its elements is processed in turn. - + 3. The file's target architecture and binary file format are determined by bfd_check_format(). If they are recognised, then dump_bfd() is called. @@ -488,9 +488,23 @@ dump_section_header (bfd *abfd, asection *section, } PF (SEC_SMALL_DATA, "SMALL_DATA"); if (bfd_get_flavour (abfd) == bfd_target_coff_flavour) - PF (SEC_COFF_SHARED, "SHARED"); + { + PF (SEC_COFF_SHARED, "SHARED"); + PF (SEC_COFF_NOREAD, "NOREAD"); + } + else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + /* Note - sections can have both the READONLY and NOREAD attributes + set. In this case the NOREAD takes precedence, but we report both + since the user may need to know that both bits are set. */ + PF (SEC_ELF_NOREAD, "NOREAD"); + } PF (SEC_THREAD_LOCAL, "THREAD_LOCAL"); PF (SEC_GROUP, "GROUP"); + if (bfd_get_arch (abfd) == bfd_arch_mep) + { + PF (SEC_MEP_VLIW, "VLIW"); + } if ((section->flags & SEC_LINK_ONCE) != 0) { @@ -924,7 +938,7 @@ find_symbol_for_address (bfd_vma vma, sections have overlapping memory ranges, but in that case there's no way to tell what's desired without looking at the relocation table. - + Also give the target a chance to reject symbols. */ want_section = (aux->require_sec || ((abfd->flags & HAS_RELOC) != 0 @@ -1116,9 +1130,9 @@ struct print_file_list struct print_file_list *next; const char *filename; const char *modname; - const char *map; + const char *map; size_t mapsize; - const char **linemap; + const char **linemap; unsigned maxline; unsigned last_line; int first; @@ -1175,38 +1189,38 @@ slurp_file (const char *fn, size_t *size) /* Precompute array of lines for a mapped file. */ -static const char ** -index_file (const char *map, size_t size, unsigned int *maxline) +static const char ** +index_file (const char *map, size_t size, unsigned int *maxline) { const char *p, *lstart, *end; int chars_per_line = 45; /* First iteration will use 40. */ unsigned int lineno; - const char **linemap = NULL; + const char **linemap = NULL; unsigned long line_map_size = 0; - + lineno = 0; lstart = map; end = map + size; - for (p = map; p < end; p++) - { - if (*p == '\n') - { - if (p + 1 < end && p[1] == '\r') - p++; - } - else if (*p == '\r') - { + for (p = map; p < end; p++) + { + if (*p == '\n') + { + if (p + 1 < end && p[1] == '\r') + p++; + } + else if (*p == '\r') + { if (p + 1 < end && p[1] == '\n') p++; } else continue; - + /* End of line found. */ - if (linemap == NULL || line_map_size < lineno + 1) - { + if (linemap == NULL || line_map_size < lineno + 1) + { unsigned long newsize; chars_per_line -= line_map_decrease; @@ -1219,11 +1233,11 @@ index_file (const char *map, size_t size, unsigned int *maxline) linemap = (const char **) xrealloc (linemap, newsize); } - linemap[lineno++] = lstart; - lstart = p + 1; + linemap[lineno++] = lstart; + lstart = p + 1; } - - *maxline = lineno; + + *maxline = lineno; return linemap; } @@ -1243,7 +1257,7 @@ try_print_file_open (const char *origname, const char *modname) free (p); return NULL; } - + p->linemap = index_file (p->map, p->mapsize, &p->maxline); p->last_line = 0; p->filename = origname; @@ -1293,13 +1307,13 @@ update_source_path (const char *filename) /* Print a source file line. */ -static void +static void print_line (struct print_file_list *p, unsigned int linenum) { const char *l; size_t len; - - --linenum; + + --linenum; if (linenum >= p->maxline) return; l = p->linemap [linenum]; @@ -1316,7 +1330,7 @@ dump_lines (struct print_file_list *p, unsigned int start, unsigned int end) { if (p->map == NULL) return; - while (start <= end) + while (start <= end) { print_line (p, start); start++; @@ -1334,6 +1348,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) unsigned int linenumber; unsigned int discriminator; bfd_boolean reloc; + char *path = NULL; if (! with_line_numbers && ! with_source_code) return; @@ -1354,20 +1369,21 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) { char *path_up; const char *fname = filename; - char *path = (char *) alloca (prefix_length + PATH_MAX + 1); + + path = xmalloc (prefix_length + PATH_MAX + 1); if (prefix_length) memcpy (path, prefix, prefix_length); path_up = path + prefix_length; /* Build relocated filename, stripping off leading directories - from the initial filename if requested. */ + from the initial filename if requested. */ if (prefix_strip > 0) { int level = 0; const char *s; - /* Skip selected directory levels. */ + /* Skip selected directory levels. */ for (s = fname + 1; *s != '\0' && level < prefix_strip; s++) if (IS_DIR_SEPARATOR(*s)) { @@ -1376,7 +1392,7 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) } } - /* Update complete filename. */ + /* Update complete filename. */ strncpy (path_up, fname, PATH_MAX); path_up[PATH_MAX] = '\0'; @@ -1392,9 +1408,9 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) && (prev_functionname == NULL || strcmp (functionname, prev_functionname) != 0)) printf ("%s():\n", functionname); - if (linenumber > 0 && (linenumber != prev_line || + if (linenumber > 0 && (linenumber != prev_line || (discriminator != prev_discriminator))) - { + { if (discriminator > 0) printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename, linenumber, discriminator); @@ -1424,12 +1440,12 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) if (p != NULL && linenumber != p->last_line) { - if (file_start_context && p->first) + if (file_start_context && p->first) l = 1; - else + else { l = linenumber - SHOW_PRECEDING_CONTEXT_LINES; - if (l >= linenumber) + if (l >= linenumber) l = 1; if (p->last_line >= l && p->last_line <= linenumber) l = p->last_line + 1; @@ -1455,6 +1471,9 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) if (discriminator != prev_discriminator) prev_discriminator = discriminator; + + if (path) + free (path); } /* Pseudo FILE object for strings. */ @@ -1476,19 +1495,19 @@ objdump_sprintf (SFILE *f, const char *format, ...) while (1) { size_t space = f->alloc - f->pos; - + va_start (args, format); n = vsnprintf (f->buffer + f->pos, space, format, args); va_end (args); if (space > n) break; - + f->alloc = (f->alloc + n) * 2; f->buffer = (char *) xrealloc (f->buffer, f->alloc); } f->pos += n; - + return n; } @@ -1536,7 +1555,7 @@ disassemble_bytes (struct disassemble_info * inf, sfile.alloc = 120; sfile.buffer = (char *) xmalloc (sfile.alloc); sfile.pos = 0; - + if (insn_width) octets_per_line = insn_width; else if (insns) @@ -1685,7 +1704,18 @@ disassemble_bytes (struct disassemble_info * inf, } } + if (! disassemble_all + && (section->flags & (SEC_CODE | SEC_HAS_CONTENTS)) + == (SEC_CODE | SEC_HAS_CONTENTS)) + /* Set a stop_vma so that the disassembler will not read + beyond the next symbol. We assume that symbols appear on + the boundaries between instructions. We only do this when + disassembling code of course, and when -D is in effect. */ + inf->stop_vma = section->vma + stop_offset; + octets = (*disassemble_fn) (section->vma + addr_offset, inf); + + inf->stop_vma = 0; inf->fprintf_func = (fprintf_ftype) fprintf; inf->stream = stdout; if (insn_width == 0 && inf->bytes_per_line != 0) @@ -1911,7 +1941,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) arelent ** rel_pp = NULL; arelent ** rel_ppstart = NULL; arelent ** rel_ppend; - unsigned long stop_offset; + bfd_vma stop_offset; asymbol * sym = NULL; long place = 0; long rel_count; @@ -2035,7 +2065,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) { bfd_vma addr; asymbol *nextsym; - unsigned long nextstop_offset; + bfd_vma nextstop_offset; bfd_boolean insns; addr = section->vma + addr_offset; @@ -2080,7 +2110,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) ((SYM)->section == section \ && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \ && pinfo->symbol_is_valid (SYM, pinfo)) - + /* 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 @@ -2126,7 +2156,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf) disassemble_bytes (pinfo, paux->disassemble_fn, insns, data, addr_offset, nextstop_offset, rel_offset, &rel_pp, rel_ppend); - + addr_offset = nextstop_offset; sym = nextsym; } @@ -2238,7 +2268,7 @@ disassemble_data (bfd *abfd) if (dump_dynamic_reloc_info) { long relsize = bfd_get_dynamic_reloc_upper_bound (abfd); - + if (relsize < 0) bfd_fatal (bfd_get_filename (abfd)); @@ -2278,6 +2308,8 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, if (section->start != NULL) return 1; + section->reloc_info = NULL; + section->num_relocs = 0; section->address = bfd_get_section_vma (abfd, sec); section->size = bfd_get_section_size (sec); section->start = NULL; @@ -2308,11 +2340,49 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, section->name); return 0; } + + long reloc_size; + + reloc_size = bfd_get_reloc_upper_bound (abfd, sec); + if (reloc_size > 0) + { + unsigned long reloc_count; + arelent **relocs; + + relocs = (arelent **) xmalloc (reloc_size); + + reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, NULL); + if (reloc_count == 0) + free (relocs); + else + { + section->reloc_info = relocs; + section->num_relocs = reloc_count; + } + } } return 1; } +bfd_boolean +reloc_at (struct dwarf_section * dsec, dwarf_vma offset) +{ + arelent ** relocs; + arelent * rp; + + if (dsec == NULL || dsec->reloc_info == NULL) + return FALSE; + + relocs = (arelent **) dsec->reloc_info; + + for (; (rp = * relocs) != NULL; ++ relocs) + if (rp->address == offset) + return TRUE; + + return FALSE; +} + int load_debug_section (enum dwarf_section_display_enum debug, void *file) { @@ -2400,7 +2470,7 @@ dump_dwarf_section (bfd *abfd, asection *section, section, abfd)) { debug_displays [i].display (sec, abfd); - + if (i != info && i != abbrev) free_debug_section ((enum dwarf_section_display_enum) i); } @@ -2449,10 +2519,18 @@ dump_dwarf (bfd *abfd) } 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; + default: break; } @@ -2616,7 +2694,7 @@ find_stabs_section (bfd *abfd, asection *section, void *names) if (strtab == NULL) strtab = read_section_stabs (abfd, sought->string_section_name, &stabstr_size); - + if (strtab) { stabs = (bfd_byte *) read_section_stabs (abfd, section->name, @@ -2750,9 +2828,9 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) { bfd_byte *data = 0; bfd_size_type datasize; - bfd_size_type addr_offset; - bfd_size_type start_offset; - bfd_size_type stop_offset; + bfd_vma addr_offset; + bfd_vma start_offset; + bfd_vma stop_offset; unsigned int opb = bfd_octets_per_byte (abfd); /* Bytes per line. */ const int onaline = 16; @@ -2765,7 +2843,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) return; @@ -2791,7 +2869,7 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) if (start_offset >= stop_offset) return; - + printf (_("Contents of section %s:"), section->name); if (display_file_offsets) printf (_(" (Starting at file offset: 0x%lx)"), @@ -2800,7 +2878,8 @@ dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED) if (!bfd_get_full_section_contents (abfd, section, &data)) { - non_fatal (_("Reading section failed")); + non_fatal (_("Reading section %s failed because: %s"), + section->name, bfd_errmsg (bfd_get_error ())); return; } @@ -3326,7 +3405,7 @@ dump_bfd (bfd *abfd) info in the file, try DWARF instead. */ else if (! dump_dwarf_section_info) { - dwarf_select_sections_all (); + dwarf_select_sections_all (); dump_dwarf (abfd); } } @@ -3409,6 +3488,13 @@ display_any_bfd (bfd *file, int level) if (level == 0) printf (_("In archive %s:\n"), bfd_get_filename (file)); + else if (level > 100) + { + /* Prevent corrupted files from spinning us into an + infinite loop. 100 is an arbitrary heuristic. */ + fatal (_("Archive nesting is too deep")); + return; + } else printf (_("In nested archive %s:\n"), bfd_get_filename (file)); @@ -3488,6 +3574,7 @@ main (int argc, char **argv) program_name = *argv; xmalloc_set_program_name (program_name); + bfd_set_error_program_name (program_name); START_PROGRESS (program_name, 0);