X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Freadelf.c;h=e782e9561f2069d7ec2e7ac8b63ab73fb34d6183;hb=128e85e3ab36b8e30f6612fb50de3cbb4ede6824;hp=fe23d458a5e81a673da97d1daf23358f7220b823;hpb=a9522a2168c8233e8f15c42a32e7376c2a40ac12;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/readelf.c b/binutils/readelf.c index fe23d458a5..e782e9561f 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -124,6 +124,7 @@ #include "elf/metag.h" #include "elf/microblaze.h" #include "elf/mips.h" +#include "elf/riscv.h" #include "elf/mmix.h" #include "elf/mn10200.h" #include "elf/mn10300.h" @@ -346,8 +347,9 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, || (bfd_size_type) ((size_t) nmemb) != nmemb)) { if (reason) - error (_("Size truncation prevents reading 0x%llx elements of size 0x%llx for %s\n"), - (unsigned long long) nmemb, (unsigned long long) size, reason); + error (_("Size truncation prevents reading 0x%" BFD_VMA_FMT "x" + " elements of size 0x%" BFD_VMA_FMT "x for %s\n"), + nmemb, size, reason); return NULL; } @@ -355,8 +357,9 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, if (amt < nmemb) { if (reason) - error (_("Size overflow prevents reading 0x%llx elements of size 0x%llx for %s\n"), - (unsigned long long) nmemb, (unsigned long long) size, reason); + error (_("Size overflow prevents reading 0x%" BFD_VMA_FMT "x" + " elements of size 0x%" BFD_VMA_FMT "x for %s\n"), + nmemb, size, reason); return NULL; } @@ -366,8 +369,9 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, || offset + archive_file_offset + amt > current_file_size) { if (reason) - error (_("Reading 0x%llx bytes extends past end of file for %s\n"), - (unsigned long long) amt, reason); + error (_("Reading 0x%" BFD_VMA_FMT "x" + " bytes extends past end of file for %s\n"), + amt, reason); return NULL; } @@ -375,7 +379,7 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, { if (reason) error (_("Unable to seek to 0x%lx for %s\n"), - (unsigned long) archive_file_offset + offset, reason); + archive_file_offset + offset, reason); return NULL; } @@ -390,8 +394,9 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, if (mvar == NULL) { if (reason) - error (_("Out of memory allocating 0x%llx bytes for %s\n"), - (unsigned long long) amt, reason); + error (_("Out of memory allocating 0x%" BFD_VMA_FMT "x" + " bytes for %s\n"), + amt, reason); return NULL; } @@ -401,8 +406,8 @@ get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size, if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb) { if (reason) - error (_("Unable to read in 0x%llx bytes of %s\n"), - (unsigned long long) amt, reason); + error (_("Unable to read in 0x%" BFD_VMA_FMT "x bytes of %s\n"), + amt, reason); if (mvar != var) free (mvar); return NULL; @@ -422,7 +427,7 @@ print_vma (bfd_vma vma, print_mode mode) { case FULL_HEX: nc = printf ("0x"); - /* Drop through. */ + /* Fall through. */ case LONG_HEX: #ifdef BFD64 @@ -435,11 +440,11 @@ print_vma (bfd_vma vma, print_mode mode) case DEC_5: if (vma <= 99999) return printf ("%5" BFD_VMA_FMT "d", vma); - /* Drop through. */ + /* Fall through. */ case PREFIX_HEX: nc = printf ("0x"); - /* Drop through. */ + /* Fall through. */ case HEX: return nc + printf ("%" BFD_VMA_FMT "x", vma); @@ -552,7 +557,7 @@ print_symbol (int width, const char *symbol) return num_printed; } -/* Returns a pointer to a static buffer containing a printable version of +/* Returns a pointer to a static buffer containing a printable version of the given section's name. Like print_symbol, except that it does not try to print multibyte characters, it just interprets them as hex values. */ @@ -771,6 +776,7 @@ guess_is_rela (unsigned int e_machine) case EM_OR1K: case EM_PPC64: case EM_PPC: + case EM_RISCV: case EM_RL78: case EM_RX: case EM_S390: @@ -1288,6 +1294,7 @@ dump_relocations (FILE * file, rtype = elf_msp430x_reloc_type (type); break; } + /* Fall through. */ case EM_MSP430_OLD: rtype = elf_msp430_reloc_type (type); break; @@ -1309,6 +1316,10 @@ dump_relocations (FILE * file, rtype = elf_mips_reloc_type (type); break; + case EM_RISCV: + rtype = elf_riscv_reloc_type (type); + break; + case EM_ALPHA: rtype = elf_alpha_reloc_type (type); break; @@ -1846,6 +1857,34 @@ get_ia64_dynamic_type (unsigned long type) } } +static const char * +get_solaris_section_type (unsigned long type) +{ + switch (type) + { + case 0x6fffffee: return "SUNW_ancillary"; + case 0x6fffffef: return "SUNW_capchain"; + case 0x6ffffff0: return "SUNW_capinfo"; + case 0x6ffffff1: return "SUNW_symsort"; + case 0x6ffffff2: return "SUNW_tlssort"; + case 0x6ffffff3: return "SUNW_LDYNSYM"; + case 0x6ffffff4: return "SUNW_dof"; + case 0x6ffffff5: return "SUNW_cap"; + case 0x6ffffff6: return "SUNW_SIGNATURE"; + case 0x6ffffff7: return "SUNW_ANNOTATE"; + case 0x6ffffff8: return "SUNW_DEBUGSTR"; + case 0x6ffffff9: return "SUNW_DEBUG"; + case 0x6ffffffa: return "SUNW_move"; + case 0x6ffffffb: return "SUNW_COMDAT"; + case 0x6ffffffc: return "SUNW_syminfo"; + case 0x6ffffffd: return "SUNW_verdef"; + case 0x6ffffffe: return "SUNW_verneed"; + case 0x6fffffff: return "SUNW_versym"; + case 0x70000000: return "SPARC_GOTDATA"; + default: return NULL; + } +} + static const char * get_alpha_dynamic_type (unsigned long type) { @@ -1900,6 +1939,43 @@ get_nios2_dynamic_type (unsigned long type) } } +static const char * +get_solaris_dynamic_type (unsigned long type) +{ + switch (type) + { + case 0x6000000d: return "SUNW_AUXILIARY"; + case 0x6000000e: return "SUNW_RTLDINF"; + case 0x6000000f: return "SUNW_FILTER"; + case 0x60000010: return "SUNW_CAP"; + case 0x60000011: return "SUNW_SYMTAB"; + case 0x60000012: return "SUNW_SYMSZ"; + case 0x60000013: return "SUNW_SORTENT"; + case 0x60000014: return "SUNW_SYMSORT"; + case 0x60000015: return "SUNW_SYMSORTSZ"; + case 0x60000016: return "SUNW_TLSSORT"; + case 0x60000017: return "SUNW_TLSSORTSZ"; + case 0x60000018: return "SUNW_CAPINFO"; + case 0x60000019: return "SUNW_STRPAD"; + case 0x6000001a: return "SUNW_CAPCHAIN"; + case 0x6000001b: return "SUNW_LDMACH"; + case 0x6000001d: return "SUNW_CAPCHAINENT"; + case 0x6000001f: return "SUNW_CAPCHAINSZ"; + case 0x60000021: return "SUNW_PARENT"; + case 0x60000023: return "SUNW_ASLR"; + case 0x60000025: return "SUNW_RELAX"; + case 0x60000029: return "SUNW_NXHEAP"; + case 0x6000002b: return "SUNW_NXSTACK"; + + case 0x70000001: return "SPARC_REGISTER"; + case 0x7ffffffd: return "AUXILIARY"; + case 0x7ffffffe: return "USED"; + case 0x7fffffff: return "FILTER"; + + default: return NULL; + } +} + static const char * get_dynamic_type (unsigned long type) { @@ -1941,6 +2017,7 @@ get_dynamic_type (unsigned long type) case DT_PREINIT_ARRAY: return "PREINIT_ARRAY"; case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ"; + case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX"; case DT_CHECKSUM: return "CHECKSUM"; case DT_PLTPADSZ: return "PLTPADSZ"; @@ -2018,7 +2095,10 @@ get_dynamic_type (unsigned long type) result = get_nios2_dynamic_type (type); break; default: - result = NULL; + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_dynamic_type (type); + else + result = NULL; break; } @@ -2042,7 +2122,10 @@ get_dynamic_type (unsigned long type) result = get_ia64_dynamic_type (type); break; default: - result = NULL; + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_dynamic_type (type); + else + result = NULL; break; } @@ -2250,6 +2333,7 @@ get_machine_name (unsigned e_machine) case EM_CR16: case EM_MICROBLAZE: case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze"; + case EM_RISCV: return "RISC-V"; case EM_RL78: return "Renesas RL78"; case EM_RX: return "Renesas RX"; case EM_METAG: return "Imagination Technologies Meta processor architecture"; @@ -2264,6 +2348,28 @@ get_machine_name (unsigned e_machine) case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family"; case EM_CUDA: return "NVIDIA CUDA architecture"; case EM_XGATE: return "Motorola XGATE embedded processor"; + case EM_CLOUDSHIELD: return "CloudShield architecture family"; + case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family"; + case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family"; + case EM_OPEN8: return "Open8 8-bit RISC soft processor core"; + case EM_VIDEOCORE5: return "Broadcom VideoCore V processor"; + case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)"; + case EM_BA1: return "Beyond BA1 CPU architecture"; + case EM_BA2: return "Beyond BA2 CPU architecture"; + case EM_XCORE: return "XMOS xCORE processor family"; + case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family"; + case EM_KM32: return "KM211 KM32 32-bit processor"; + case EM_KMX32: return "KM211 KMX32 32-bit processor"; + case EM_KMX16: return "KM211 KMX16 16-bit processor"; + case EM_KMX8: return "KM211 KMX8 8-bit processor"; + case EM_KVARC: return "KM211 KVARC processor"; + case EM_CDP: return "Paneve CDP architecture family"; + case EM_COGE: return "Cognitive Smart Memory Processor"; + case EM_COOL: return "Bluechip Systems CoolEngine"; + case EM_NORC: return "Nanoradio Optimized RISC"; + case EM_CSR_KALIMBA: return "CSR Kalimba architecture family"; + case EM_Z80: return "Zilog Z80"; + case EM_AMDGPU: return "AMD GPU architecture"; default: snprintf (buff, sizeof (buff), _(": 0x%x"), e_machine); return buff; @@ -3208,6 +3314,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine) decode_NDS32_machine_flags (e_flags, buf, sizeof buf); break; + case EM_RISCV: + if (e_flags & EF_RISCV_RVC) + strcat (buf, ", RVC"); + if (e_flags & EF_RISCV_SOFT_FLOAT) + strcat (buf, ", soft-float ABI"); + break; + case EM_SH: switch ((e_flags & EF_SH_MACH_MASK)) { @@ -3458,6 +3571,8 @@ get_osabi_name (unsigned int osabi) case ELFOSABI_NSK: return "HP - Non-Stop Kernel"; case ELFOSABI_AROS: return "AROS"; case ELFOSABI_FENIXOS: return "FenixOS"; + case ELFOSABI_CLOUDABI: return "Nuxi CloudABI"; + case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS"; default: if (osabi >= 64) switch (elf_header.e_machine) @@ -3610,6 +3725,23 @@ get_tic6x_segment_type (unsigned long type) return NULL; } +static const char * +get_solaris_segment_type (unsigned long type) +{ + switch (type) + { + case 0x6464e550: return "PT_SUNW_UNWIND"; + case 0x6474e550: return "PT_SUNW_EH_FRAME"; + case 0x6ffffff7: return "PT_LOSUNW"; + case 0x6ffffffa: return "PT_SUNWBSS"; + case 0x6ffffffb: return "PT_SUNWSTACK"; + case 0x6ffffffc: return "PT_SUNWDTRACE"; + case 0x6ffffffd: return "PT_SUNWCAP"; + case 0x6fffffff: return "PT_HISUNW"; + default: return NULL; + } +} + static const char * get_segment_type (unsigned long p_type) { @@ -3680,7 +3812,10 @@ get_segment_type (unsigned long p_type) result = get_ia64_segment_type (p_type); break; default: - result = NULL; + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_segment_type (p_type); + else + result = NULL; break; } @@ -3974,7 +4109,10 @@ get_section_type_name (unsigned int sh_type) result = get_ia64_section_type_name (sh_type); break; default: - result = NULL; + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_section_type (sh_type); + else + result = NULL; break; } @@ -4140,10 +4278,13 @@ request_dump_bynumber (unsigned int section, dump_type type) error (_("Out of memory allocating dump request table.\n")); else { - /* Copy current flag settings. */ - memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects)); + if (dump_sects) + { + /* Copy current flag settings. */ + memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects)); - free (dump_sects); + free (dump_sects); + } dump_sects = new_dump_sects; num_dump_sects = section + 1; @@ -4349,7 +4490,7 @@ parse_args (int argc, char ** argv) default: /* xgettext:c-format */ error (_("Invalid option '-%c'\n"), c); - /* Drop through. */ + /* Fall through. */ case '?': usage (stderr); } @@ -4958,6 +5099,10 @@ get_32bit_section_headers (FILE * file, bfd_boolean probe) internal->sh_info = BYTE_GET (shdrs[i].sh_info); internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign); internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize); + if (!probe && internal->sh_link > num) + warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link); + if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num) + warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info); } free (shdrs); @@ -5016,6 +5161,10 @@ get_64bit_section_headers (FILE * file, bfd_boolean probe) internal->sh_info = BYTE_GET (shdrs[i].sh_info); internal->sh_offset = BYTE_GET (shdrs[i].sh_offset); internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign); + if (!probe && internal->sh_link > num) + warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link); + if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num) + warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info); } free (shdrs); @@ -5293,7 +5442,7 @@ get_elf_section_flags (bfd_vma sh_flags) /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") }, /* ARM specific. */ /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") }, - /* 22 */ { STRING_COMMA_LEN ("ARM_NOREAD") }, + /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") }, /* 23 */ { STRING_COMMA_LEN ("COMDEF") } }; @@ -5369,7 +5518,7 @@ get_elf_section_flags (bfd_vma sh_flags) switch (flag) { case SHF_ENTRYSECT: sindex = 21; break; - case SHF_ARM_NOREAD: sindex = 22; break; + case SHF_ARM_PURECODE: sindex = 22; break; case SHF_COMDEF: sindex = 23; break; default: break; } @@ -5428,7 +5577,7 @@ get_elf_section_flags (bfd_vma sh_flags) && flag == SHF_X86_64_LARGE) *p = 'l'; else if (elf_header.e_machine == EM_ARM - && flag == SHF_ARM_NOREAD) + && flag == SHF_ARM_PURECODE) *p = 'y'; else if (flag & SHF_MASKOS) { @@ -5516,6 +5665,7 @@ get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) if (is_32bit_elf) { Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf; + chdr->ch_type = BYTE_GET (echdr->ch_type); chdr->ch_size = BYTE_GET (echdr->ch_size); chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); @@ -5524,6 +5674,7 @@ get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) else { Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf; + chdr->ch_type = BYTE_GET (echdr->ch_type); chdr->ch_size = BYTE_GET (echdr->ch_size); chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); @@ -5814,6 +5965,122 @@ process_section_headers (FILE * file) i < elf_header.e_shnum; i++, section++) { + /* Run some sanity checks on the section header. */ + + /* Check the sh_link field. */ + switch (section->sh_type) + { + 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 + || section->sh_link >= elf_header.e_shnum + || (section_headers[section->sh_link].sh_type != SHT_SYMTAB + && section_headers[section->sh_link].sh_type != SHT_DYNSYM)) + warn (_("[%2u]: Link field (%u) should index a symtab section.\n"), + i, section->sh_link); + break; + + case SHT_DYNAMIC: + case SHT_SYMTAB: + case SHT_DYNSYM: + case SHT_GNU_verneed: + case SHT_GNU_verdef: + case SHT_GNU_LIBLIST: + if (section->sh_link < 1 + || section->sh_link >= elf_header.e_shnum + || section_headers[section->sh_link].sh_type != SHT_STRTAB) + warn (_("[%2u]: Link field (%u) should index a string section.\n"), + i, section->sh_link); + break; + + case SHT_INIT_ARRAY: + case SHT_FINI_ARRAY: + case SHT_PREINIT_ARRAY: + if (section->sh_type < SHT_LOOS && section->sh_link != 0) + warn (_("[%2u]: Unexpected value (%u) in link field.\n"), + i, section->sh_link); + break; + + default: + /* FIXME: Add support for target specific section types. */ +#if 0 /* Currently we do not check other section types as there are too + many special cases. Stab sections for example have a type + of SHT_PROGBITS but an sh_link field that links to the .stabstr + section. */ + if (section->sh_type < SHT_LOOS && section->sh_link != 0) + warn (_("[%2u]: Unexpected value (%u) in link field.\n"), + i, section->sh_link); +#endif + break; + } + + /* Check the sh_info field. */ + switch (section->sh_type) + { + case SHT_REL: + case SHT_RELA: + if (section->sh_info < 1 + || section->sh_info >= elf_header.e_shnum + || (section_headers[section->sh_info].sh_type != SHT_PROGBITS + && section_headers[section->sh_info].sh_type != SHT_NOBITS + && section_headers[section->sh_info].sh_type != SHT_NOTE + && section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY + /* FIXME: Are other section types valid ? */ + && section_headers[section->sh_info].sh_type < SHT_LOOS)) + { + if (section->sh_info == 0 + && (streq (SECTION_NAME (section), ".rel.dyn") + || streq (SECTION_NAME (section), ".rela.dyn"))) + /* The .rel.dyn and .rela.dyn sections have an sh_info field + of zero. No idea why. I would have expected the index + of the .plt section. */ + ; + else + warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"), + i, section->sh_info); + } + break; + + case SHT_DYNAMIC: + case SHT_HASH: + case SHT_SYMTAB_SHNDX: + case SHT_INIT_ARRAY: + case SHT_FINI_ARRAY: + case SHT_PREINIT_ARRAY: + if (section->sh_info != 0) + warn (_("[%2u]: Unexpected value (%u) in info field.\n"), + i, section->sh_info); + break; + + case SHT_GROUP: + case SHT_SYMTAB: + case SHT_DYNSYM: + /* A symbol index - we assume that it is valid. */ + break; + + default: + /* FIXME: Add support for target specific section types. */ + if (section->sh_type == SHT_NOBITS) + /* NOBITS section headers with non-zero sh_info fields can be + created when a binary is stripped of everything but its debug + information. The stripped sections have their headers preserved but their types set to SHT_NOBITS. so do not check this type of section. */ + ; + else if (section->sh_flags & SHF_INFO_LINK) + { + if (section->sh_info < 1 || section->sh_info >= elf_header.e_shnum) + warn (_("[%2u]: Expected link to another section in info field"), i); + } + else if (section->sh_type < SHT_LOOS && section->sh_info != 0) + warn (_("[%2u]: Unexpected value (%u) in info field.\n"), + i, section->sh_info); + break; + } + printf (" [%2u] ", i); if (do_section_details) printf ("%s\n ", printable_section_name (section)); @@ -5980,12 +6247,15 @@ process_section_headers (FILE * file) /* Minimum section size is 12 bytes for 32-bit compression header + 12 bytes for compressed data header. */ unsigned char buf[24]; + assert (sizeof (buf) >= sizeof (Elf64_External_Chdr)); if (get_data (&buf, (FILE *) file, section->sh_offset, 1, sizeof (buf), _("compression header"))) { Elf_Internal_Chdr chdr; - get_compression_header (&chdr, buf); + + (void) get_compression_header (&chdr, buf); + if (chdr.ch_type == ELFCOMPRESS_ZLIB) printf (" ZLIB, "); else @@ -6006,13 +6276,13 @@ process_section_headers (FILE * file) printf (_("Key to Flags:\n\ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\ L (link order), O (extra OS processing required), G (group), T (TLS),\n\ - C (compressed), x (unknown), o (OS specific), E (exclude),\n")); + C (compressed), x (unknown), o (OS specific), E (exclude),\n ")); if (elf_header.e_machine == EM_X86_64 || elf_header.e_machine == EM_L1OM || elf_header.e_machine == EM_K1OM) printf (_("l (large), ")); else if (elf_header.e_machine == EM_ARM) - printf (_("y (noread), ")); + printf (_("y (purecode), ")); printf ("p (processor specific)\n"); } @@ -6022,19 +6292,32 @@ process_section_headers (FILE * file) static const char * get_group_flags (unsigned int flags) { - static char buff[32]; - switch (flags) - { - case 0: - return ""; + static char buff[128]; - case GRP_COMDAT: - return "COMDAT "; + if (flags == 0) + return ""; + else if (flags == GRP_COMDAT) + return "COMDAT "; - default: - snprintf (buff, sizeof (buff), _("[: 0x%x] "), flags); - break; + snprintf (buff, 14, _("[0x%x: "), flags); + + flags &= ~ GRP_COMDAT; + if (flags & GRP_MASKOS) + { + strcat (buff, ""); + flags &= ~ GRP_MASKOS; + } + + if (flags & GRP_MASKPROC) + { + strcat (buff, ""); + flags &= ~ GRP_MASKPROC; } + + if (flags) + strcat (buff, ""); + + strcat (buff, "]"); return buff; } @@ -8605,7 +8888,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) case DT_MIPS_TIME_STAMP: { - char timebuf[20]; + char timebuf[128]; struct tm * tmp; time_t atime = entry->d_un.d_val; @@ -8634,7 +8917,7 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry) case DT_MIPS_DELTA_SYM_NO: case DT_MIPS_DELTA_CLASSSYM_NO: case DT_MIPS_COMPACT_SIZE: - print_vma (entry->d_un.d_ptr, DEC); + print_vma (entry->d_un.d_val, DEC); break; default: @@ -9449,6 +9732,7 @@ process_dynamic_section (FILE * file) case DT_SYMENT : case DT_RELENT : dynamic_info[entry->d_tag] = entry->d_un.d_val; + /* Fall through. */ case DT_PLTPADSZ: case DT_MOVEENT : case DT_MOVESZ : @@ -10201,6 +10485,18 @@ get_symbol_visibility (unsigned int visibility) } } +static const char * +get_solaris_symbol_visibility (unsigned int visibility) +{ + switch (visibility) + { + case 4: return "EXPORTED"; + case 5: return "SINGLETON"; + case 6: return "ELIMINATE"; + default: return get_symbol_visibility (visibility); + } +} + static const char * get_mips_symbol_other (unsigned int other) { @@ -10324,6 +10620,7 @@ get_symbol_other (unsigned int other) result = get_ppc64_symbol_other (other); break; default: + result = NULL; break; } @@ -10390,8 +10687,9 @@ get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size) if (sizeof (size_t) < sizeof (bfd_size_type) && (bfd_size_type) ((size_t) number) != number) { - error (_("Size truncation prevents reading %llu elements of size %u\n"), - (unsigned long long) number, ent_size); + error (_("Size truncation prevents reading %" BFD_VMA_FMT "u" + " elements of size %u\n"), + number, ent_size); return NULL; } @@ -10399,23 +10697,23 @@ get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size) attempting to allocate memory when the read is bound to fail. */ if (ent_size * number > current_file_size) { - error (_("Invalid number of dynamic entries: %llu\n"), - (unsigned long long) number); + error (_("Invalid number of dynamic entries: %" BFD_VMA_FMT "u\n"), + number); return NULL; } e_data = (unsigned char *) cmalloc ((size_t) number, ent_size); if (e_data == NULL) { - error (_("Out of memory reading %llu dynamic entries\n"), - (unsigned long long) number); + error (_("Out of memory reading %" BFD_VMA_FMT "u dynamic entries\n"), + number); return NULL; } if (fread (e_data, ent_size, (size_t) number, file) != number) { - error (_("Unable to read in %llu bytes of dynamic data\n"), - (unsigned long long) (number * ent_size)); + error (_("Unable to read in %" BFD_VMA_FMT "u bytes of dynamic data\n"), + number * ent_size); free (e_data); return NULL; } @@ -10423,8 +10721,9 @@ get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size) i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data)); if (i_data == NULL) { - error (_("Out of memory allocating space for %llu dynamic entries\n"), - (unsigned long long) number); + error (_("Out of memory allocating space for %" BFD_VMA_FMT "u" + " dynamic entries\n"), + number); free (e_data); return NULL; } @@ -10462,13 +10761,22 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn) printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); - printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); - /* Check to see if any other bits in the st_other field are set. - Note - displaying this information disrupts the layout of the - table being generated, but for the moment this case is very - rare. */ - if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) - printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); + + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + printf (" %-7s", get_solaris_symbol_visibility (psym->st_other)); + else + { + unsigned int vis = ELF_ST_VISIBILITY (psym->st_other); + + printf (" %-7s", get_symbol_visibility (vis)); + /* Check to see if any other bits in the st_other field are set. + Note - displaying this information disrupts the layout of the + table being generated, but for the moment this case is very + rare. */ + if (psym->st_other ^ vis) + printf (" [%s] ", get_symbol_other (psym->st_other ^ vis)); + } + printf (" %3.3s ", get_symbol_index_type (psym->st_shndx)); if (VALID_DYNAMIC_NAME (psym->st_name)) print_symbol (25, GET_DYNAMIC_NAME (psym->st_name)); @@ -10478,12 +10786,14 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn) } static const char * -get_symbol_version_string (FILE *file, int is_dynsym, - const char *strtab, - unsigned long int strtab_size, - unsigned int si, Elf_Internal_Sym *psym, - enum versioned_symbol_info *sym_info, - unsigned short *vna_other) +get_symbol_version_string (FILE * file, + bfd_boolean is_dynsym, + const char * strtab, + unsigned long int strtab_size, + unsigned int si, + Elf_Internal_Sym * psym, + enum versioned_symbol_info * sym_info, + unsigned short * vna_other) { unsigned char data[2]; unsigned short vers_data; @@ -10947,12 +11257,19 @@ process_symbol_table (FILE * file) print_vma (psym->st_size, DEC_5); printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info))); printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info))); - printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other))); - /* Check to see if any other bits in the st_other field are set. - Note - displaying this information disrupts the layout of the - table being generated, but for the moment this case is very rare. */ - if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)) - printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))); + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + printf (" %-7s", get_solaris_symbol_visibility (psym->st_other)); + else + { + unsigned int vis = ELF_ST_VISIBILITY (psym->st_other); + + printf (" %-7s", get_symbol_visibility (vis)); + /* Check to see if any other bits in the st_other field are set. + Note - displaying this information disrupts the layout of the + table being generated, but for the moment this case is very rare. */ + if (psym->st_other ^ vis) + printf (" [%s] ", get_symbol_other (psym->st_other ^ vis)); + } printf (" %4s ", get_symbol_index_type (psym->st_shndx)); print_symbol (25, psym->st_name < strtab_size ? strtab + psym->st_name : _("")); @@ -10972,6 +11289,16 @@ process_symbol_table (FILE * file) } putchar ('\n'); + + if (ELF_ST_BIND (psym->st_info) == STB_LOCAL + && si >= section->sh_info + /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */ + && elf_header.e_machine != EM_MIPS + /* Solaris binaries have been found to violate this requirement as + well. Not sure if this is a bug or an ABI requirement. */ + && elf_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS) + warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"), + si, printable_section_name (section), section->sh_info); } free (symtab); @@ -11223,6 +11550,7 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc, case 10: /* R_MSP430_SYM_DIFF */ if (uses_msp430x_relocs ()) break; + /* Fall through. */ case 21: /* R_MSP430X_SYM_DIFF */ saved_sym = symtab + get_reloc_symindex (reloc->r_info); return TRUE; @@ -11357,6 +11685,7 @@ target_specific_reloc_handling (Elf_Internal_Rela * reloc, static bfd_boolean is_32bit_abs_reloc (unsigned int reloc_type) { + /* Please keep this table alpha-sorted for ease of visual lookup. */ switch (elf_header.e_machine) { case EM_386: @@ -11370,6 +11699,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 2; /* R_960_32. */ case EM_AARCH64: return reloc_type == 258; /* R_AARCH64_ABS32 */ + case EM_ADAPTEVA_EPIPHANY: + return reloc_type == 3; case EM_ALPHA: return reloc_type == 1; /* R_ALPHA_REFLONG. */ case EM_ARC: @@ -11382,8 +11713,6 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_AVR_OLD: case EM_AVR: return reloc_type == 1; - case EM_ADAPTEVA_EPIPHANY: - return reloc_type == 3; case EM_BLACKFIN: return reloc_type == 0x12; /* R_byte4_data. */ case EM_CRIS: @@ -11472,6 +11801,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 1; /* R_PPC64_ADDR32. */ case EM_PPC: return reloc_type == 1; /* R_PPC_ADDR32. */ + case EM_RISCV: + return reloc_type == 1; /* R_RISCV_32. */ case EM_RL78: return reloc_type == 1; /* R_RL78_DIR32. */ case EM_RX: @@ -11542,6 +11873,7 @@ static bfd_boolean is_32bit_pcrel_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) + /* Please keep this table alpha-sorted for ease of visual lookup. */ { case EM_386: case EM_IAMCU: @@ -11559,6 +11891,9 @@ is_32bit_pcrel_reloc (unsigned int reloc_type) return reloc_type == 49; /* R_ARC_32_PCREL. */ case EM_ARM: return reloc_type == 3; /* R_ARM_REL32 */ + case EM_AVR_OLD: + case EM_AVR: + return reloc_type == 36; /* R_AVR_32_PCREL. */ case EM_MICROBLAZE: return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */ case EM_OR1K: @@ -11621,6 +11956,8 @@ is_64bit_abs_reloc (unsigned int reloc_type) return reloc_type == 80; /* R_PARISC_DIR64. */ case EM_PPC64: return reloc_type == 38; /* R_PPC64_ADDR64. */ + case EM_RISCV: + return reloc_type == 2; /* R_RISCV_64. */ case EM_SPARC32PLUS: case EM_SPARCV9: case EM_SPARC: @@ -11688,6 +12025,8 @@ is_24bit_abs_reloc (unsigned int reloc_type) case EM_CYGNUS_MN10200: case EM_MN10200: return reloc_type == 4; /* R_MN10200_24. */ + case EM_FT32: + return reloc_type == 5; /* R_FT32_20. */ default: return FALSE; } @@ -11699,17 +12038,18 @@ is_24bit_abs_reloc (unsigned int reloc_type) static bfd_boolean is_16bit_abs_reloc (unsigned int reloc_type) { + /* Please keep this table alpha-sorted for ease of visual lookup. */ switch (elf_header.e_machine) { case EM_ARC: case EM_ARC_COMPACT: case EM_ARC_COMPACT2: return reloc_type == 2; /* R_ARC_16. */ + case EM_ADAPTEVA_EPIPHANY: + return reloc_type == 5; case EM_AVR_OLD: case EM_AVR: return reloc_type == 4; /* R_AVR_16. */ - case EM_ADAPTEVA_EPIPHANY: - return reloc_type == 5; case EM_CYGNUS_D10V: case EM_D10V: return reloc_type == 3; /* R_D10V_16. */ @@ -11723,9 +12063,16 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_M32C_OLD: case EM_M32C: return reloc_type == 1; /* R_M32C_16 */ + case EM_CYGNUS_MN10200: + case EM_MN10200: + return reloc_type == 2; /* R_MN10200_16. */ + case EM_CYGNUS_MN10300: + case EM_MN10300: + return reloc_type == 2; /* R_MN10300_16. */ case EM_MSP430: if (uses_msp430x_relocs ()) return reloc_type == 2; /* R_MSP430_ABS16. */ + /* Fall through. */ case EM_MSP430_OLD: return reloc_type == 5; /* R_MSP430_16_BYTE. */ case EM_NDS32: @@ -11738,17 +12085,11 @@ is_16bit_abs_reloc (unsigned int reloc_type) return reloc_type == 2; /* R_OR1K_16. */ case EM_TI_C6000: return reloc_type == 2; /* R_C6000_ABS16. */ + case EM_VISIUM: + return reloc_type == 2; /* R_VISIUM_16. */ case EM_XC16X: case EM_C166: return reloc_type == 2; /* R_XC16C_ABS_16. */ - case EM_CYGNUS_MN10200: - case EM_MN10200: - return reloc_type == 2; /* R_MN10200_16. */ - case EM_CYGNUS_MN10300: - case EM_MN10300: - return reloc_type == 2; /* R_MN10300_16. */ - case EM_VISIUM: - return reloc_type == 2; /* R_VISIUM_16. */ case EM_XGATE: return reloc_type == 3; /* R_XGATE_16. */ default: @@ -11764,44 +12105,54 @@ is_none_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) { - case EM_68K: /* R_68K_NONE. */ case EM_386: /* R_386_NONE. */ - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_SPARC: /* R_SPARC_NONE. */ - case EM_MIPS: /* R_MIPS_NONE. */ - case EM_PARISC: /* R_PARISC_NONE. */ - case EM_ALPHA: /* R_ALPHA_NONE. */ + case EM_68K: /* R_68K_NONE. */ case EM_ADAPTEVA_EPIPHANY: - case EM_PPC: /* R_PPC_NONE. */ - case EM_PPC64: /* R_PPC64_NONE. */ + case EM_ALPHA: /* R_ALPHA_NONE. */ + case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */ case EM_ARC: /* R_ARC_NONE. */ - case EM_ARC_COMPACT: /* R_ARC_NONE. */ case EM_ARC_COMPACT2: /* R_ARC_NONE. */ + case EM_ARC_COMPACT: /* R_ARC_NONE. */ case EM_ARM: /* R_ARM_NONE. */ - case EM_IA_64: /* R_IA64_NONE. */ - case EM_SH: /* R_SH_NONE. */ - case EM_S390_OLD: - case EM_S390: /* R_390_NONE. */ + case EM_C166: /* R_XC16X_NONE. */ case EM_CRIS: /* R_CRIS_NONE. */ - case EM_X86_64: /* R_X86_64_NONE. */ - case EM_L1OM: /* R_X86_64_NONE. */ + case EM_FT32: /* R_FT32_NONE. */ + case EM_IA_64: /* R_IA64_NONE. */ case EM_K1OM: /* R_X86_64_NONE. */ + case EM_L1OM: /* R_X86_64_NONE. */ + case EM_M32R: /* R_M32R_NONE. */ + case EM_MIPS: /* R_MIPS_NONE. */ case EM_MN10300: /* R_MN10300_NONE. */ - case EM_FT32: /* R_FT32_NONE. */ case EM_MOXIE: /* R_MOXIE_NONE. */ - case EM_M32R: /* R_M32R_NONE. */ - case EM_TI_C6000:/* R_C6000_NONE. */ + case EM_NIOS32: /* R_NIOS_NONE. */ + case EM_OR1K: /* R_OR1K_NONE. */ + case EM_PARISC: /* R_PARISC_NONE. */ + case EM_PPC64: /* R_PPC64_NONE. */ + case EM_PPC: /* R_PPC_NONE. */ + case EM_RISCV: /* R_RISCV_NONE. */ + case EM_S390: /* R_390_NONE. */ + case EM_S390_OLD: + case EM_SH: /* R_SH_NONE. */ + case EM_SPARC32PLUS: + case EM_SPARC: /* R_SPARC_NONE. */ + case EM_SPARCV9: case EM_TILEGX: /* R_TILEGX_NONE. */ case EM_TILEPRO: /* R_TILEPRO_NONE. */ + case EM_TI_C6000:/* R_C6000_NONE. */ + case EM_X86_64: /* R_X86_64_NONE. */ case EM_XC16X: - case EM_C166: /* R_XC16X_NONE. */ - case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */ - case EM_NIOS32: /* R_NIOS_NONE. */ - case EM_OR1K: /* R_OR1K_NONE. */ return reloc_type == 0; + case EM_AARCH64: return reloc_type == 0 || reloc_type == 256; + case EM_AVR_OLD: + case EM_AVR: + return (reloc_type == 0 /* R_AVR_NONE. */ + || reloc_type == 30 /* R_AVR_DIFF8. */ + || reloc_type == 31 /* R_AVR_DIFF16. */ + || reloc_type == 32 /* R_AVR_DIFF32. */); + case EM_METAG: + return reloc_type == 3; /* R_METAG_NONE. */ case EM_NDS32: return (reloc_type == 0 /* R_XTENSA_NONE. */ || reloc_type == 204 /* R_NDS32_DIFF8. */ @@ -11814,8 +12165,6 @@ is_none_reloc (unsigned int reloc_type) || reloc_type == 17 /* R_XTENSA_DIFF8. */ || reloc_type == 18 /* R_XTENSA_DIFF16. */ || reloc_type == 19 /* R_XTENSA_DIFF32. */); - case EM_METAG: - return reloc_type == 3; /* R_METAG_NONE. */ } return FALSE; } @@ -11853,7 +12202,7 @@ apply_relocations (void * file, const Elf_Internal_Shdr * section, unsigned char * start, bfd_size_type size, - void ** relocs_return, + void ** relocs_return, unsigned long * num_relocs_return) { Elf_Internal_Shdr * relsec; @@ -11909,6 +12258,9 @@ apply_relocations (void * file, is_rela = FALSE; symsec = section_headers + relsec->sh_link; + if (symsec->sh_type != SHT_SYMTAB + && symsec->sh_type != SHT_DYNSYM) + return; symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms); for (rp = relocs; rp < relocs + num_relocs; ++rp) @@ -12421,8 +12773,19 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, if ((sec->sh_flags & SHF_COMPRESSED) != 0) { Elf_Internal_Chdr chdr; - unsigned int compression_header_size - = get_compression_header (&chdr, start); + unsigned int compression_header_size; + + if (size < (is_32bit_elf + ? sizeof (Elf32_External_Chdr) + : sizeof (Elf64_External_Chdr))) + { + warn (_("compressed section %s is too small to contain a compression header"), + section->name); + return 0; + } + + compression_header_size = get_compression_header (&chdr, start); + if (chdr.ch_type != ELFCOMPRESS_ZLIB) { warn (_("section '%s' has unsupported compress type: %d\n"), @@ -12811,6 +13174,8 @@ static const char * arm_attr_tag_FP_HP_extension[] = {"Not Allowed", "Allowed"}; static const char * arm_attr_tag_ABI_FP_16bit_format[] = {"None", "IEEE 754", "Alternative Format"}; +static const char * arm_attr_tag_DSP_extension[] = + {"Follow architecture", "Allowed"}; static const char * arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"}; static const char * arm_attr_tag_DIV_use[] = @@ -12861,6 +13226,7 @@ static arm_attr_public_tag arm_attr_public_tags[] = LOOKUP(38, ABI_FP_16bit_format), LOOKUP(42, MPextension_use), LOOKUP(44, DIV_use), + LOOKUP(46, DSP_extension), {64, "nodefaults", 0, NULL}, {65, "also_compatible_with", 0, NULL}, LOOKUP(66, T2EE_use), @@ -13082,47 +13448,77 @@ display_power_gnu_attribute (unsigned char * p, const unsigned char * const end) { unsigned int len; - int val; + unsigned int val; if (tag == Tag_GNU_Power_ABI_FP) { val = read_uleb128 (p, &len, end); p += len; printf (" Tag_GNU_Power_ABI_FP: "); + if (len == 0) + { + printf (_("\n")); + return p; + } - switch (val) + if (val > 15) + printf ("(%#x), ", val); + + switch (val & 3) { case 0: - printf (_("Hard or soft float\n")); + printf (_("unspecified hard/soft float, ")); break; case 1: - printf (_("Hard float\n")); + printf (_("hard float, ")); break; case 2: - printf (_("Soft float\n")); + printf (_("soft float, ")); break; case 3: - printf (_("Single-precision hard float\n")); + printf (_("single-precision hard float, ")); break; - default: - printf ("??? (%d)\n", val); + } + + switch (val & 0xC) + { + case 0: + printf (_("unspecified long double\n")); + break; + case 4: + printf (_("128-bit IBM long double\n")); + break; + case 8: + printf (_("64-bit long double\n")); + break; + case 12: + printf (_("128-bit IEEE long double\n")); break; } return p; - } + } if (tag == Tag_GNU_Power_ABI_Vector) { val = read_uleb128 (p, &len, end); p += len; printf (" Tag_GNU_Power_ABI_Vector: "); - switch (val) + if (len == 0) + { + printf (_("\n")); + return p; + } + + if (val > 3) + printf ("(%#x), ", val); + + switch (val & 3) { case 0: - printf (_("Any\n")); + printf (_("unspecified\n")); break; case 1: - printf (_("Generic\n")); + printf (_("generic\n")); break; case 2: printf ("AltiVec\n"); @@ -13130,39 +13526,39 @@ display_power_gnu_attribute (unsigned char * p, case 3: printf ("SPE\n"); break; - default: - printf ("??? (%d)\n", val); - break; } return p; - } + } if (tag == Tag_GNU_Power_ABI_Struct_Return) { - if (p == end) + val = read_uleb128 (p, &len, end); + p += len; + printf (" Tag_GNU_Power_ABI_Struct_Return: "); + if (len == 0) { - warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n")); + printf (_("\n")); return p; } - val = read_uleb128 (p, &len, end); - p += len; - printf (" Tag_GNU_Power_ABI_Struct_Return: "); - switch (val) - { - case 0: - printf (_("Any\n")); - break; - case 1: - printf ("r3/r4\n"); - break; - case 2: - printf (_("Memory\n")); - break; - default: - printf ("??? (%d)\n", val); - break; - } + if (val > 2) + printf ("(%#x), ", val); + + switch (val & 3) + { + case 0: + printf (_("unspecified\n")); + break; + case 1: + printf ("r3/r4\n"); + break; + case 2: + printf (_("memory\n")); + break; + case 3: + printf ("???\n"); + break; + } return p; } @@ -13911,6 +14307,7 @@ process_attributes (FILE * file, goto do_numlist; case 3: printf (_("Symbol Attributes:")); + /* Fall through. */ do_numlist: for (;;) { @@ -14073,6 +14470,8 @@ print_mips_ases (unsigned int mask) fputs ("\n\tDSP ASE", stdout); if (mask & AFL_ASE_DSPR2) fputs ("\n\tDSP R2 ASE", stdout); + if (mask & AFL_ASE_DSPR3) + fputs ("\n\tDSP R3 ASE", stdout); if (mask & AFL_ASE_EVA) fputs ("\n\tEnhanced VA Scheme", stdout); if (mask & AFL_ASE_MCU) @@ -14332,7 +14731,7 @@ process_mips_specific (FILE * file) { Elf32_Lib liblist; time_t atime; - char timebuf[20]; + char timebuf[128]; struct tm * tmp; liblist.l_name = BYTE_GET (elib[cnt].l_name); @@ -14419,7 +14818,7 @@ process_mips_specific (FILE * file) cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt)); if (iopt == NULL) { - error (_("Out of memory allocatinf space for MIPS options\n")); + error (_("Out of memory allocating space for MIPS options\n")); return 0; } @@ -14986,7 +15385,7 @@ process_gnu_liblist (FILE * file) { Elf32_Lib liblist; time_t atime; - char timebuf[20]; + char timebuf[128]; struct tm * tmp; liblist.l_name = BYTE_GET (elib[cnt].l_name); @@ -15203,8 +15602,7 @@ print_core_note (Elf_Internal_Note *pnote) static const char * get_gnu_elf_note_type (unsigned e_type) { - static char buff[64]; - + /* NB/ Keep this switch statement in sync with print_gnu_note (). */ switch (e_type) { case NT_GNU_ABI_TAG: @@ -15216,16 +15614,19 @@ get_gnu_elf_note_type (unsigned e_type) case NT_GNU_GOLD_VERSION: return _("NT_GNU_GOLD_VERSION (gold version)"); default: - break; - } + { + static char buff[64]; - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; + snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); + return buff; + } + } } static int print_gnu_note (Elf_Internal_Note *pnote) { + /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */ switch (pnote->type) { case NT_GNU_BUILD_ID: @@ -15299,6 +15700,42 @@ print_gnu_note (Elf_Internal_Note *pnote) printf ("\n"); } break; + + case NT_GNU_HWCAP: + { + unsigned long num_entries, mask; + + /* Hardware capabilities information. Word 0 is the number of entries. + Word 1 is a bitmask of enabled entries. The rest of the descriptor + is a series of entries, where each entry is a single byte followed + by a nul terminated string. The byte gives the bit number to test + if enabled in the bitmask. */ + printf (_(" Hardware Capabilities: ")); + if (pnote->descsz < 8) + { + printf (_("\n")); + break; + } + num_entries = byte_get ((unsigned char *) pnote->descdata, 4); + mask = byte_get ((unsigned char *) pnote->descdata + 4, 4); + printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask); + /* FIXME: Add code to display the entries... */ + } + break; + + default: + /* Handle unrecognised types. An error message should have already been + created by get_gnu_elf_note_type(), so all that we need to do is to + display the data. */ + { + unsigned long i; + + printf (_(" Description data: ")); + for (i = 0; i < pnote->descsz; ++i) + printf ("%02x ", pnote->descdata[i] & 0xff); + printf ("\n"); + } + break; } return 1; @@ -15383,7 +15820,7 @@ print_v850_note (Elf_Internal_Note * pnote) return 0; } -static int +static int process_netbsd_elf_note (Elf_Internal_Note * pnote) { unsigned int version; @@ -15396,11 +15833,11 @@ process_netbsd_elf_note (Elf_Internal_Note * pnote) printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz, version, version / 100000000, (version / 1000000) % 100, (version / 10000) % 100 > 26 ? "Z" : "", - 'A' + (version / 10000) % 26); + 'A' + (version / 10000) % 26); else printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz, version, version / 100000000, (version / 1000000) % 100, - (version / 100) % 100); + (version / 100) % 100); return 1; case NT_NETBSD_MARCH: @@ -15681,7 +16118,9 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) If the value of namesz is zero, there is no name present. */ static int -process_note (Elf_Internal_Note * pnote) +process_note (Elf_Internal_Note * pnote, + FILE * file ATTRIBUTE_UNUSED, + Elf_Internal_Shdr * section ATTRIBUTE_UNUSED) { const char * name = pnote->namesz ? pnote->namedata : "(NONE)"; const char * nt; @@ -15726,7 +16165,9 @@ process_note (Elf_Internal_Note * pnote) note type strings. */ nt = get_note_type (pnote->type); - printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt); + printf (" "); + print_symbol (-20, name); + printf (" 0x%08lx\t%s\n", pnote->descsz, nt); if (const_strneq (pnote->namedata, "IPF/VMS")) return print_ia64_vms_note (pnote); @@ -15736,13 +16177,25 @@ process_note (Elf_Internal_Note * pnote) return print_stapsdt_note (pnote); else if (const_strneq (pnote->namedata, "CORE")) return print_core_note (pnote); - else - return 1; -} + else if (pnote->descsz) + { + unsigned long i; + + printf (_(" description data: ")); + for (i = 0; i < pnote->descsz; i++) + printf ("%02x ", pnote->descdata[i]); + printf ("\n"); + } + + return 1; +} static int -process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) +process_notes_at (FILE * file, + Elf_Internal_Shdr * section, + bfd_vma offset, + bfd_vma length) { Elf_External_Note * pnotes; Elf_External_Note * external; @@ -15752,15 +16205,26 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) if (length <= 0) return 0; - pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length, - _("notes")); + if (section) + { + pnotes = (Elf_External_Note *) get_section_contents (section, file); + if (pnotes) + apply_relocations (file, section, (unsigned char *) pnotes, length, NULL, NULL); + } + else + pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length, + _("notes")); if (pnotes == NULL) return 0; external = pnotes; - printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"), - (unsigned long) offset, (unsigned long) length); + if (section) + printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (section)); + else + printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"), + (unsigned long) offset, (unsigned long) length); + printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size")); end = (char *) pnotes + length; @@ -15860,7 +16324,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) inote.namedata = temp; } - res &= process_note (& inote); + res &= process_note (& inote, file, section); if (temp != NULL) { @@ -15889,9 +16353,9 @@ process_corefile_note_segments (FILE * file) i++, segment++) { if (segment->p_type == PT_NOTE) - res &= process_corefile_note_segment (file, - (bfd_vma) segment->p_offset, - (bfd_vma) segment->p_filesz); + res &= process_notes_at (file, NULL, + (bfd_vma) segment->p_offset, + (bfd_vma) segment->p_filesz); } return res; @@ -15992,9 +16456,9 @@ process_note_sections (FILE * file) { if (section->sh_type == SHT_NOTE) { - res &= process_corefile_note_segment (file, - (bfd_vma) section->sh_offset, - (bfd_vma) section->sh_size); + res &= process_notes_at (file, section, + (bfd_vma) section->sh_offset, + (bfd_vma) section->sh_size); n++; } @@ -16053,6 +16517,7 @@ process_arch_specific (FILE * file) return process_nds32_specific (file); break; case EM_PPC: + case EM_PPC64: return process_power_specific (file); break; case EM_S390: @@ -16085,8 +16550,8 @@ get_file_header (FILE * file) /* Determine how to read the rest of the header. */ switch (elf_header.e_ident[EI_DATA]) { - default: /* fall through */ - case ELFDATANONE: /* fall through */ + default: + case ELFDATANONE: case ELFDATA2LSB: byte_get = byte_get_little_endian; byte_put = byte_put_little_endian;