{
case FULL_HEX:
nc = printf ("0x");
- /* Drop through. */
+ /* Fall through. */
case LONG_HEX:
#ifdef BFD64
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);
rtype = elf_msp430x_reloc_type (type);
break;
}
+ /* Fall through. */
case EM_MSP430_OLD:
rtype = elf_msp430_reloc_type (type);
break;
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;
default:
/* xgettext:c-format */
error (_("Invalid option '-%c'\n"), c);
- /* Drop through. */
+ /* Fall through. */
case '?':
usage (stderr);
}
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);
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);
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));
/* 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
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 :
}
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);
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;
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:
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"),
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 (_("<corrupt>\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 (_("<corrupt>\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");
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 (_("<corrupt>\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;
}
goto do_numlist;
case 3:
printf (_("Symbol Attributes:"));
+ /* Fall through. */
do_numlist:
for (;;)
{
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;
}
return process_nds32_specific (file);
break;
case EM_PPC:
+ case EM_PPC64:
return process_power_specific (file);
break;
case EM_S390:
/* 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;