X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=binutils%2Freadelf.c;h=3f424c4e63d6779c27c83a2ad8a0d02217fb696b;hb=c22b42ce308eb538050b4b5789e406b63102b35a;hp=92353c596f4bd2bef7a2bc280ad3a7f472dacda9;hpb=bdc6c06e3b08ec48ec5ee2174dedc846969c36fd;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index 92353c596f..3f424c4e63 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1,5 +1,5 @@ /* readelf.c -- display contents of an ELF format file - Copyright (C) 1998-2018 Free Software Foundation, Inc. + Copyright (C) 1998-2019 Free Software Foundation, Inc. Originally developed by Eric Youngdale Modifications by Nick Clifton @@ -398,10 +398,11 @@ get_data (void * var, return NULL; } - /* Be kind to memory chekers (eg valgrind, address sanitizer) by not + /* Be kind to memory checkers (eg valgrind, address sanitizer) by not attempting to allocate memory when the read is bound to fail. */ - if (amt > filedata->file_size - || offset + archive_file_offset + amt > filedata->file_size) + if (archive_file_offset > filedata->file_size + || offset > filedata->file_size - archive_file_offset + || amt > filedata->file_size - archive_file_offset - offset) { if (reason) error (_("Reading %s bytes extends past end of file for %s\n"), @@ -3404,7 +3405,9 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine) case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break; case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break; case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break; - case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break; + case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break; + case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break; + case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break; case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break; case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break; case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break; @@ -3687,6 +3690,8 @@ get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine) ? ", uses String instructions" : ", bans String instructions"); if (e_flags & E_FLAG_RX_V2) strcat (buf, ", V2"); + if (e_flags & E_FLAG_RX_V3) + strcat (buf, ", V3"); break; case EM_S390: @@ -3928,6 +3933,7 @@ get_segment_type (Filedata * filedata, unsigned long p_type) case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; case PT_GNU_STACK: return "GNU_STACK"; case PT_GNU_RELRO: return "GNU_RELRO"; + case PT_GNU_PROPERTY: return "GNU_PROPERTY"; default: if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI) @@ -4199,6 +4205,16 @@ get_v850_section_type_name (unsigned int sh_type) } } +static const char * +get_riscv_section_type_name (unsigned int sh_type) +{ + switch (sh_type) + { + case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES"; + default: return NULL; + } +} + static const char * get_section_type_name (Filedata * filedata, unsigned int sh_type) { @@ -4279,6 +4295,9 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type) case EM_CYGNUS_V850: result = get_v850_section_type_name (sh_type); break; + case EM_RISCV: + result = get_riscv_section_type_name (sh_type); + break; default: result = NULL; break; @@ -5217,7 +5236,8 @@ process_program_headers (Filedata * filedata) segment. Check this after matching against the section headers so we don't warn on debuginfo file (which have NOBITS .dynamic sections). */ - if (dynamic_addr + dynamic_size >= filedata->file_size) + if (dynamic_addr > filedata->file_size + || dynamic_size > filedata->file_size - dynamic_addr) { error (_("the dynamic segment offset + size exceeds the size of the file\n")); dynamic_addr = dynamic_size = 0; @@ -6297,14 +6317,21 @@ process_section_headers (Filedata * filedata) /* Check the sh_link field. */ switch (section->sh_type) { + case SHT_REL: + case SHT_RELA: + if (section->sh_link == 0 + && (filedata->file_header.e_type == ET_EXEC + || filedata->file_header.e_type == ET_DYN)) + /* A dynamic relocation section where all entries use a + zero symbol index need not specify a symtab section. */ + break; + /* Fall through. */ case SHT_SYMTAB_SHNDX: case SHT_GROUP: case SHT_HASH: case SHT_GNU_HASH: case SHT_GNU_versym: - case SHT_REL: - case SHT_RELA: - if (section->sh_link < 1 + if (section->sh_link == 0 || section->sh_link >= filedata->file_header.e_shnum || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM)) @@ -6318,7 +6345,7 @@ process_section_headers (Filedata * filedata) case SHT_GNU_verneed: case SHT_GNU_verdef: case SHT_GNU_LIBLIST: - if (section->sh_link < 1 + if (section->sh_link == 0 || section->sh_link >= filedata->file_header.e_shnum || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB) warn (_("[%2u]: Link field (%u) should index a string section.\n"), @@ -6351,29 +6378,24 @@ process_section_headers (Filedata * filedata) { case SHT_REL: case SHT_RELA: - if (section->sh_info < 1 + if (section->sh_info == 0 + && (filedata->file_header.e_type == ET_EXEC + || filedata->file_header.e_type == ET_DYN)) + /* Dynamic relocations apply to segments, so they do not + need to specify the section they relocate. */ + break; + if (section->sh_info == 0 || section->sh_info >= filedata->file_header.e_shnum || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY + && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY + && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY /* FIXME: Are other section types valid ? */ && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS)) - { - if (section->sh_info == 0 - && (filedata->file_header.e_type == ET_EXEC - || filedata->file_header.e_type == ET_DYN - /* These next two tests may be redundant, but - they have been left in for paranoia's sake. */ - || streq (SECTION_NAME (section), ".rel.dyn") - || streq (SECTION_NAME (section), ".rela.dyn"))) - /* Dynamic relocations apply to segments, not sections, so - they do not need an sh_info value. */ - ; - else - warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"), - i, section->sh_info); - } + warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"), + i, section->sh_info); break; case SHT_DYNAMIC: @@ -7593,14 +7615,14 @@ slurp_ia64_unwind_table (Filedata * filedata, for (rp = rela; rp < rela + nrelas; ++rp) { - relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info)); - sym = aux->symtab + get_reloc_symindex (rp->r_info); + unsigned int sym_ndx; + unsigned int r_type = get_reloc_type (filedata, rp->r_info); + relname = elf_ia64_reloc_type (r_type); /* PR 17531: file: 9fa67536. */ if (relname == NULL) { - warn (_("Skipping unknown relocation type: %u\n"), - get_reloc_type (filedata, rp->r_info)); + warn (_("Skipping unknown relocation type: %u\n"), r_type); continue; } @@ -7619,6 +7641,15 @@ slurp_ia64_unwind_table (Filedata * filedata, continue; } + sym_ndx = get_reloc_symindex (rp->r_info); + if (sym_ndx >= aux->nsyms) + { + warn (_("Skipping reloc with invalid symbol index: %u\n"), + sym_ndx); + continue; + } + sym = aux->symtab + sym_ndx; + switch (rp->r_offset / eh_addr_size % 3) { case 0: @@ -8049,19 +8080,40 @@ slurp_hppa_unwind_table (Filedata * filedata, for (rp = rela; rp < rela + nrelas; ++rp) { - relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info)); - sym = aux->symtab + get_reloc_symindex (rp->r_info); + unsigned int sym_ndx; + unsigned int r_type = get_reloc_type (filedata, rp->r_info); + relname = elf_hppa_reloc_type (r_type); + + if (relname == NULL) + { + warn (_("Skipping unknown relocation type: %u\n"), r_type); + continue; + } /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */ if (! const_strneq (relname, "R_PARISC_SEGREL")) { - warn (_("Skipping unexpected relocation type %s\n"), relname); + warn (_("Skipping unexpected relocation type: %s\n"), relname); continue; } i = rp->r_offset / unw_ent_size; + if (i >= aux->table_len) + { + warn (_("Skipping reloc with overlarge offset: %lx\n"), i); + continue; + } - switch ((rp->r_offset % unw_ent_size) / eh_addr_size) + sym_ndx = get_reloc_symindex (rp->r_info); + if (sym_ndx >= aux->nsyms) + { + warn (_("Skipping reloc with invalid symbol index: %u\n"), + sym_ndx); + continue; + } + sym = aux->symtab + sym_ndx; + + switch ((rp->r_offset % unw_ent_size) / 4) { case 0: aux->table[i].start.section = sym->st_shndx; @@ -8129,7 +8181,7 @@ hppa_process_unwind (Filedata * filedata) { if (streq (SECTION_NAME (sec), ".PARISC.unwind")) { - unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8); + unsigned long num_unwind = sec->sh_size / 16; printf (ngettext ("\nUnwind section '%s' at offset 0x%lx " "contains %lu entry:\n", @@ -8802,21 +8854,28 @@ decode_tic6x_unwind_bytecode (Filedata * filedata, } printf (_("pop frame {")); - reg = nregs - 1; - for (i = i * 2; i > 0; i--) + if (nregs == 0) { - if (regpos[reg].offset == i - 1) + printf (_("*corrupt* - no registers specified")); + } + else + { + reg = nregs - 1; + for (i = i * 2; i > 0; i--) { - name = tic6x_unwind_regnames[regpos[reg].reg]; - if (reg > 0) - reg--; - } - else - name = _("[pad]"); + if (regpos[reg].offset == i - 1) + { + name = tic6x_unwind_regnames[regpos[reg].reg]; + if (reg > 0) + reg--; + } + else + name = _("[pad]"); - fputs (name, stdout); - if (i > 1) - printf (", "); + fputs (name, stdout); + if (i > 1) + printf (", "); + } } printf ("}"); @@ -12382,7 +12441,8 @@ is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type) case EM_68HC12: return reloc_type == 6; /* R_M68HC11_32. */ case EM_S12Z: - return reloc_type == 6; /* R_S12Z_EXT32. */ + return reloc_type == 7 || /* R_S12Z_EXT32 */ + reloc_type == 6; /* R_S12Z_CW32. */ case EM_MCORE: return reloc_type == 1; /* R_MCORE_ADDR32. */ case EM_CYGNUS_MEP: @@ -12534,6 +12594,8 @@ is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type) return reloc_type == 26; /* R_PPC_REL32. */ case EM_PPC64: return reloc_type == 26; /* R_PPC64_REL32. */ + case EM_RISCV: + return reloc_type == 57; /* R_RISCV_32_PCREL. */ case EM_S390_OLD: case EM_S390: return reloc_type == 5; /* R_390_PC32. */ @@ -13028,7 +13090,6 @@ apply_relocations (Filedata * filedata, { Elf_Internal_Shdr * relsec; unsigned char * end = start + size; - bfd_boolean res = TRUE; if (relocs_return != NULL) { @@ -13157,7 +13218,6 @@ apply_relocations (Filedata * filedata, warn (_("unable to apply unsupported reloc type %d to section %s\n"), reloc_type, printable_section_name (filedata, section)); prev_reloc = reloc_type; - res = FALSE; continue; } @@ -13167,7 +13227,6 @@ apply_relocations (Filedata * filedata, warn (_("skipping invalid relocation offset 0x%lx in section %s\n"), (unsigned long) rp->r_offset, printable_section_name (filedata, section)); - res = FALSE; continue; } @@ -13176,7 +13235,6 @@ apply_relocations (Filedata * filedata, { warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"), sym_index, printable_section_name (filedata, section)); - res = FALSE; continue; } sym = symtab + sym_index; @@ -13202,7 +13260,6 @@ apply_relocations (Filedata * filedata, get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)), printable_section_name (filedata, relsec), (long int)(rp - relocs)); - res = FALSE; continue; } @@ -13269,7 +13326,7 @@ apply_relocations (Filedata * filedata, break; } - return res; + return TRUE; } #ifdef SUPPORT_DISASSEMBLY @@ -13395,12 +13452,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata) printable_section_name (filedata, section), chdr.ch_type); return FALSE; } - else if (chdr.ch_addralign != section->sh_addralign) - { - warn (_("compressed section '%s' is corrupted\n"), - printable_section_name (filedata, section)); - return FALSE; - } uncompressed_size = chdr.ch_size; start += compression_header_size; new_size -= compression_header_size; @@ -13542,12 +13593,6 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, printable_section_name (filedata, section), chdr.ch_type); return FALSE; } - else if (chdr.ch_addralign != section->sh_addralign) - { - warn (_("compressed section '%s' is corrupted\n"), - printable_section_name (filedata, section)); - return FALSE; - } uncompressed_size = chdr.ch_size; start += compression_header_size; new_size -= compression_header_size; @@ -13717,12 +13762,6 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, section->name, chdr.ch_type); return FALSE; } - else if (chdr.ch_addralign != sec->sh_addralign) - { - warn (_("compressed section '%s' is corrupted\n"), - section->name); - return FALSE; - } uncompressed_size = chdr.ch_size; start += compression_header_size; size -= compression_header_size; @@ -15220,7 +15259,7 @@ display_raw_attribute (unsigned char * p, unsigned char const * const end) unsigned long addr = 0; size_t bytes = end - p; - assert (end > p); + assert (end >= p); while (bytes) { int j; @@ -15345,6 +15384,88 @@ display_msp430x_attribute (unsigned char * p, return p; } +struct riscv_attr_tag_t { + const char *name; + int tag; +}; + +static struct riscv_attr_tag_t riscv_attr_tag[] = +{ +#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag} + T(arch), + T(priv_spec), + T(priv_spec_minor), + T(priv_spec_revision), + T(unaligned_access), + T(stack_align), +#undef T +}; + +static unsigned char * +display_riscv_attribute (unsigned char *p, + const unsigned char * const end) +{ + unsigned int len; + int val; + int tag; + struct riscv_attr_tag_t *attr = NULL; + unsigned i; + + tag = read_uleb128 (p, &len, end); + p += len; + + /* Find the name of attribute. */ + for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++) + { + if (riscv_attr_tag[i].tag == tag) + { + attr = &riscv_attr_tag[i]; + break; + } + } + + if (attr) + printf (" %s: ", attr->name); + else + return display_tag_value (tag, p, end); + + switch (tag) + { + case Tag_RISCV_priv_spec: + case Tag_RISCV_priv_spec_minor: + case Tag_RISCV_priv_spec_revision: + val = read_uleb128 (p, &len, end); + p += len; + printf (_("%d\n"), val); + break; + case Tag_RISCV_unaligned_access: + val = read_uleb128 (p, &len, end); + p += len; + switch (val) + { + case 0: + printf (_("No unaligned access\n")); + break; + case 1: + printf (_("Unaligned access\n")); + break; + } + break; + case Tag_RISCV_stack_align: + val = read_uleb128 (p, &len, end); + p += len; + printf (_("%d-bytes\n"), val); + break; + case Tag_RISCV_arch: + p = display_tag_value (-1, p, end); + break; + default: + return display_tag_value (tag, p, end); + } + + return p; +} + static bfd_boolean process_attributes (Filedata * filedata, const char * public_name, @@ -15655,6 +15776,8 @@ print_mips_ases (unsigned int mask) fputs ("\n\tLoongson CAM ASE", stdout); if (mask & AFL_ASE_LOONGSON_EXT) fputs ("\n\tLoongson EXT ASE", stdout); + if (mask & AFL_ASE_LOONGSON_EXT2) + fputs ("\n\tLoongson EXT2 ASE", stdout); if (mask == 0) fprintf (stdout, "\n\t%s", _("None")); else if ((mask & ~AFL_ASE_MASK) != 0) @@ -15681,9 +15804,6 @@ print_mips_isa_ext (unsigned int isa_ext) case AFL_EXT_OCTEONP: fputs ("Cavium Networks OcteonP", stdout); break; - case AFL_EXT_LOONGSON_3A: - fputs ("Loongson 3A", stdout); - break; case AFL_EXT_OCTEON: fputs ("Cavium Networks Octeon", stdout); break; @@ -17035,13 +17155,11 @@ decode_x86_compat_isa (unsigned int bitmask) static void decode_x86_isa (unsigned int bitmask) { - if (bitmask == GNU_PROPERTY_X86_UINT32_VALID) + if (!bitmask) { printf (_("")); return; } - else - bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID; while (bitmask) { @@ -17134,13 +17252,11 @@ decode_x86_isa (unsigned int bitmask) static void decode_x86_feature_1 (unsigned int bitmask) { - if (bitmask == GNU_PROPERTY_X86_UINT32_VALID) + if (!bitmask) { printf (_("")); return; } - else - bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID; while (bitmask) { @@ -17167,13 +17283,11 @@ decode_x86_feature_1 (unsigned int bitmask) static void decode_x86_feature_2 (unsigned int bitmask) { - if (bitmask == GNU_PROPERTY_X86_UINT32_VALID) + if (!bitmask) { printf (_("")); return; } - else - bitmask &= ~GNU_PROPERTY_X86_UINT32_VALID; while (bitmask) { @@ -17269,13 +17383,7 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) unsigned int bitmask; if (datasz == 4) - { - bitmask = byte_get (ptr, 4); - if ((filedata->file_header.e_type == ET_EXEC - || filedata->file_header.e_type == ET_DYN) - && !(bitmask & GNU_PROPERTY_X86_UINT32_VALID)) - printf ("Invalid "); - } + bitmask = byte_get (ptr, 4); else bitmask = 0; @@ -18642,7 +18750,7 @@ process_notes_at (Filedata * filedata, one version of Linux (RedHat 6.0) generates corefiles that don't comply with the ELF spec by failing to include the null byte in namesz. */ - if (inote.namedata[inote.namesz - 1] != '\0') + if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0') { if ((size_t) (inote.descdata - inote.namedata) == inote.namesz) { @@ -18892,6 +19000,11 @@ process_arch_specific (Filedata * filedata) display_msp430x_attribute, display_generic_attribute); + case EM_RISCV: + return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES, + display_riscv_attribute, + display_generic_attribute); + case EM_NDS32: return process_nds32_specific (filedata); @@ -19394,7 +19507,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) /* Read the next archive header. */ if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0) { - error (_("%s: failed to seek to next archive header\n"), filedata->file_name); + error (_("%s: failed to seek to next archive header\n"), arch.file_name); return FALSE; } got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle); @@ -19402,7 +19515,10 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) { if (got == 0) break; - error (_("%s: failed to read archive header\n"), filedata->file_name); + /* PR 24049 - we cannot use filedata->file_name as this will + have already been freed. */ + error (_("%s: failed to read archive header\n"), arch.file_name); + ret = FALSE; break; } @@ -19422,7 +19538,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) name = get_archive_member_name (&arch, &nested_arch); if (name == NULL) { - error (_("%s: bad archive file name\n"), filedata->file_name); + error (_("%s: bad archive file name\n"), arch.file_name); ret = FALSE; break; } @@ -19431,7 +19547,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) qualified_name = make_qualified_name (&arch, &nested_arch, name); if (qualified_name == NULL) { - error (_("%s: bad archive file name\n"), filedata->file_name); + error (_("%s: bad archive file name\n"), arch.file_name); ret = FALSE; break; } @@ -19477,7 +19593,7 @@ process_archive (Filedata * filedata, bfd_boolean is_thin_archive) if (nested_arch.file == NULL) { error (_("%s: contains corrupt thin archive: %s\n"), - filedata->file_name, name); + qualified_name, name); ret = FALSE; break; }