X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=cf395dbe2d6998abc481a918d9f5370441c02200;hb=f954747f10467071b0acde07ee5f5e268ab606a6;hp=f221cce32a948b489977cc3199f5da1a66413fb3;hpb=219d1afa89d0d53ca93a684cac341f16470f3ca0;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index f221cce32a..cf395dbe2d 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -655,7 +655,8 @@ find_section (Filedata * filedata, const char * name) { unsigned int i; - assert (filedata->section_headers != NULL); + if (filedata->section_headers == NULL) + return NULL; for (i = 0; i < filedata->file_header.e_shnum; i++) if (streq (SECTION_NAME (filedata->section_headers + i), name)) @@ -672,6 +673,9 @@ find_section_by_address (Filedata * filedata, bfd_vma addr) { unsigned int i; + if (filedata->section_headers == NULL) + return NULL; + for (i = 0; i < filedata->file_header.e_shnum; i++) { Elf_Internal_Shdr *sec = filedata->section_headers + i; @@ -688,6 +692,9 @@ find_section_by_type (Filedata * filedata, unsigned int type) { unsigned int i; + if (filedata->section_headers == NULL) + return NULL; + for (i = 0; i < filedata->file_header.e_shnum; i++) { Elf_Internal_Shdr *sec = filedata->section_headers + i; @@ -707,6 +714,9 @@ find_section_in_set (Filedata * filedata, const char * name, unsigned int * set) { unsigned int i; + if (filedata->section_headers == NULL) + return NULL; + if (set != NULL) { while ((i = *set++) > 0) @@ -2263,7 +2273,7 @@ get_machine_name (unsigned e_machine) case EM_PARISC: return "HPPA"; case EM_VPP550: return "Fujitsu VPP500"; case EM_SPARC32PLUS: return "Sparc v8+" ; - case EM_960: return "Intel 90860"; + case EM_960: return "Intel 80960"; case EM_PPC: return "PowerPC"; /* 20 */ case EM_PPC64: return "PowerPC64"; @@ -9643,7 +9653,7 @@ process_dynamic_section (Filedata * filedata) if (archive_file_offset != 0) str_tab_len = archive_file_size - offset; else - str_tab_len = filedata->file_size; + str_tab_len = filedata->file_size - offset; if (str_tab_len < 1) { @@ -9999,6 +10009,21 @@ process_dynamic_section (Filedata * filedata) printf (" PIE"); val ^= DF_1_PIE; } + if (val & DF_1_KMOD) + { + printf (" KMOD"); + val ^= DF_1_KMOD; + } + if (val & DF_1_WEAKFILTER) + { + printf (" WEAKFILTER"); + val ^= DF_1_WEAKFILTER; + } + if (val & DF_1_NOCOMMON) + { + printf (" NOCOMMON"); + val ^= DF_1_NOCOMMON; + } if (val != 0) printf (" %lx", val); puts (""); @@ -10202,7 +10227,7 @@ process_dynamic_section (Filedata * filedata) static char * get_ver_flags (unsigned int flags) { - static char buff[32]; + static char buff[128]; buff[0] = 0; @@ -16594,9 +16619,9 @@ get_note_type (Filedata * filedata, unsigned e_type) case NT_ARCH: return _("NT_ARCH (architecture)"); case NT_GNU_BUILD_ATTRIBUTE_OPEN: - return _("NT_GNU_BUILD_ATTRIBUTE_OPEN"); + return _("OPEN"); case NT_GNU_BUILD_ATTRIBUTE_FUNC: - return _("NT_GNU_BUILD_ATTRIBUTE_FUNC"); + return _("func"); default: break; } @@ -17416,13 +17441,16 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) return TRUE; } -/* Print the name of the symbol associated with a build attribute - that is attached to address OFFSET. */ +/* Find the symbol associated with a build attribute that is attached + to address OFFSET. If PNAME is non-NULL then store the name of + the symbol (if found) in the provided pointer, Returns NULL if a + symbol could not be found. */ -static bfd_boolean -print_symbol_for_build_attribute (Filedata * filedata, - unsigned long offset, - bfd_boolean is_open_attr) +static Elf_Internal_Sym * +get_symbol_for_build_attribute (Filedata * filedata, + unsigned long offset, + bfd_boolean is_open_attr, + const char ** pname) { static Filedata * saved_filedata = NULL; static char * strtab; @@ -17461,10 +17489,7 @@ print_symbol_for_build_attribute (Filedata * filedata, } if (symtab == NULL || strtab == NULL) - { - printf ("\n"); - return FALSE; - } + return NULL; /* Find a symbol whose value matches offset. */ for (sym = symtab; sym < symtab + nsyms; sym ++) @@ -17477,6 +17502,13 @@ print_symbol_for_build_attribute (Filedata * filedata, if (strtab[sym->st_name] == 0) continue; + /* The AArch64 and ARM architectures define mapping symbols + (eg $d, $x, $t) which we want to ignore. */ + if (strtab[sym->st_name] == '$' + && strtab[sym->st_name + 1] != 0 + && strtab[sym->st_name + 2] == 0) + continue; + if (is_open_attr) { /* For OPEN attributes we prefer GLOBAL over LOCAL symbols @@ -17484,14 +17516,15 @@ print_symbol_for_build_attribute (Filedata * filedata, FUNC symbols entirely. */ switch (ELF_ST_TYPE (sym->st_info)) { - case STT_FILE: - saved_sym = sym; - /* We can stop searching now. */ - sym = symtab + nsyms; - continue; - case STT_OBJECT: + case STT_FILE: saved_sym = sym; + if (sym->st_size) + { + /* If the symbol has a size associated + with it then we can stop searching. */ + sym = symtab + nsyms; + } continue; case STT_FUNC: @@ -17529,55 +17562,124 @@ print_symbol_for_build_attribute (Filedata * filedata, } } - printf (" (%s: %s)\n", - is_open_attr ? _("file") : _("func"), - saved_sym ? strtab + saved_sym->st_name : _(")")); - return TRUE; + if (saved_sym && pname) + * pname = strtab + saved_sym->st_name; + + return saved_sym; } static bfd_boolean print_gnu_build_attribute_description (Elf_Internal_Note * pnote, Filedata * filedata) { - static unsigned long global_offset = 0; - unsigned long offset; - unsigned int desc_size = is_32bit_elf ? 4 : 8; - bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN; + static unsigned long global_offset = 0; + static unsigned long global_end = 0; + static unsigned long func_offset = 0; + static unsigned long func_end = 0; + + Elf_Internal_Sym * sym; + const char * name; + unsigned long start; + unsigned long end; + bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN; - if (pnote->descsz == 0) + switch (pnote->descsz) { + case 0: + /* A zero-length description means that the range of + the previous note of the same type should be used. */ if (is_open_attr) { - printf (_(" Applies from offset %#lx\n"), global_offset); - return TRUE; + if (global_end > global_offset) + printf (_(" Applies to region from %#lx to %#lx\n"), + global_offset, global_end); + else + printf (_(" Applies to region from %#lx\n"), global_offset); } else { - printf (_(" Applies to func at %#lx"), global_offset); - return print_symbol_for_build_attribute (filedata, global_offset, is_open_attr); + if (func_end > func_offset) + printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end); + else + printf (_(" Applies to region from %#lx\n"), func_offset); } - } + return TRUE; - if (pnote->descsz != desc_size) - { + case 4: + start = byte_get ((unsigned char *) pnote->descdata, 4); + end = 0; + break; + + case 8: + if (is_32bit_elf) + { + /* FIXME: We should check that version 3+ notes are being used here... */ + start = byte_get ((unsigned char *) pnote->descdata, 4); + end = byte_get ((unsigned char *) pnote->descdata + 4, 4); + } + else + { + start = byte_get ((unsigned char *) pnote->descdata, 8); + end = 0; + } + break; + + case 16: + start = byte_get ((unsigned char *) pnote->descdata, 8); + end = byte_get ((unsigned char *) pnote->descdata + 8, 8); + break; + + default: error (_(" \n"), pnote->descsz); printf (_(" ")); return FALSE; } - offset = byte_get ((unsigned char *) pnote->descdata, desc_size); + name = NULL; + sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name); + /* As of version 5 of the annobin plugin, filename symbols are biased by 2 + in order to avoid them being confused with the start address of the + first function in the file... */ + if (sym == NULL && is_open_attr) + sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr, + & name); + + if (end == 0 && sym != NULL && sym->st_size > 0) + end = start + sym->st_size; if (is_open_attr) { - printf (_(" Applies from offset %#lx"), offset); - global_offset = offset; + /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */ + if (global_end > 0 && start > BFD_ALIGN (global_end, 16)) + warn (_("Gap in build notes detected from %#lx to %#lx\n"), + global_end + 1, start - 1); + + printf (_(" Applies to region from %#lx"), start); + global_offset = start; + + if (end) + { + printf (_(" to %#lx"), end); + global_end = end; + } } else { - printf (_(" Applies to func at %#lx"), offset); + printf (_(" Applies to region from %#lx"), start); + func_offset = start; + + if (end) + { + printf (_(" to %#lx"), end); + func_end = end; + } } - return print_symbol_for_build_attribute (filedata, offset, is_open_attr); + if (sym && name) + printf (_(" (%s)"), name); + + printf ("\n"); + return TRUE; } static bfd_boolean @@ -17600,11 +17702,21 @@ print_gnu_build_attribute_name (Elf_Internal_Note * pnote) return FALSE; } - left = 20; + if (do_wide) + left = 28; + else + left = 20; /* Version 2 of the spec adds a "GA" prefix to the name field. */ if (name[0] == 'G' && name[1] == 'A') { + if (pnote->namesz < 4) + { + error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz); + print_symbol (-20, _(" ")); + return FALSE; + } + printf ("GA"); name += 2; left -= 2;