width = - width;
extra_padding = TRUE;
}
+ assert (width != 0);
if (do_wide)
/* Set the remaining width to a very large value.
return num_printed;
}
+/* 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. */
+
+static const char *
+printable_section_name (Elf_Internal_Shdr * sec)
+{
+#define MAX_PRINT_SEC_NAME_LEN 128
+ static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
+ const char * name = SECTION_NAME (sec);
+ char * buf = sec_name_buf;
+ char c;
+ unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
+
+ while ((c = * name ++) != 0)
+ {
+ if (ISCNTRL (c))
+ {
+ if (remaining < 2)
+ break;
+
+ * buf ++ = '^';
+ * buf ++ = c + 0x40;
+ remaining -= 2;
+ }
+ else if (ISPRINT (c))
+ {
+ * buf ++ = c;
+ remaining -= 1;
+ }
+ else
+ {
+ static char hex[17] = "0123456789ABCDEF";
+
+ if (remaining < 4)
+ break;
+ * buf ++ = '<';
+ * buf ++ = hex[(c & 0xf0) >> 4];
+ * buf ++ = hex[c & 0x0f];
+ * buf ++ = '>';
+ remaining -= 4;
+ }
+
+ if (remaining == 0)
+ break;
+ }
+
+ * buf = 0;
+ return sec_name_buf;
+}
+
+static const char *
+printable_section_name_from_index (unsigned long ndx)
+{
+ if (ndx >= elf_header.e_shnum)
+ return _("<corrupt>");
+
+ return printable_section_name (section_headers + ndx);
+}
+
/* Return a pointer to section NAME, or NULL if no such section exists. */
static Elf_Internal_Shdr *
if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
{
if (psym->st_shndx < elf_header.e_shnum)
- sec_name
- = SECTION_NAME (section_headers + psym->st_shndx);
+ sec_name = SECTION_NAME (section_headers + psym->st_shndx);
else if (psym->st_shndx == SHN_ABS)
sec_name = "ABS";
else if (psym->st_shndx == SHN_COMMON)
return 1;
}
-
-static int
+static bfd_boolean
get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
{
Elf32_External_Phdr * phdrs;
Elf32_External_Phdr * external;
Elf_Internal_Phdr * internal;
unsigned int i;
+ unsigned int size = elf_header.e_phentsize;
+ unsigned int num = elf_header.e_phnum;
+
+ /* PR binutils/17531: Cope with unexpected section header sizes. */
+ if (size == 0 || num == 0)
+ return FALSE;
+ if (size < sizeof * phdrs)
+ {
+ error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
+ return FALSE;
+ }
+ if (size > sizeof * phdrs)
+ warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize,
- elf_header.e_phnum,
- _("program headers"));
- if (!phdrs)
- return 0;
+ size, num, _("program headers"));
+ if (phdrs == NULL)
+ return FALSE;
for (i = 0, internal = pheaders, external = phdrs;
i < elf_header.e_phnum;
}
free (phdrs);
-
- return 1;
+ return TRUE;
}
-static int
+static bfd_boolean
get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
{
Elf64_External_Phdr * phdrs;
Elf64_External_Phdr * external;
Elf_Internal_Phdr * internal;
unsigned int i;
+ unsigned int size = elf_header.e_phentsize;
+ unsigned int num = elf_header.e_phnum;
+
+ /* PR binutils/17531: Cope with unexpected section header sizes. */
+ if (size == 0 || num == 0)
+ return FALSE;
+ if (size < sizeof * phdrs)
+ {
+ error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
+ return FALSE;
+ }
+ if (size > sizeof * phdrs)
+ warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
- elf_header.e_phentsize,
- elf_header.e_phnum,
- _("program headers"));
+ size, num, _("program headers"));
if (!phdrs)
- return 0;
+ return FALSE;
for (i = 0, internal = pheaders, external = phdrs;
i < elf_header.e_phnum;
}
free (phdrs);
-
- return 1;
+ return TRUE;
}
/* Returns 1 if the program headers were read into `program_headers'. */
{
if (!ELF_TBSS_SPECIAL (section, segment)
&& ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
- printf ("%s ", SECTION_NAME (section));
+ printf ("%s ", printable_section_name (section));
}
putc ('\n',stdout);
if (section->sh_size > current_file_size)
{
error (_("Section %s has an invalid sh_size of 0x%lx\n"),
- SECTION_NAME (section), (unsigned long) section->sh_size);
+ printable_section_name (section), (unsigned long) section->sh_size);
goto exit_point;
}
if (section->sh_size > current_file_size)
{
error (_("Section %s has an invalid sh_size of 0x%lx\n"),
- SECTION_NAME (section), (unsigned long) section->sh_size);
+ printable_section_name (section), (unsigned long) section->sh_size);
goto exit_point;
}
)
request_dump_bynumber (i, DEBUG_DUMP);
}
-
}
if (! do_sections)
{
printf (" [%2u] ", i);
if (do_section_details)
- {
- print_symbol (INT_MAX, SECTION_NAME (section));
- printf ("\n ");
- }
+ printf ("%s\n ", printable_section_name (section));
else
- {
- print_symbol (-17, SECTION_NAME (section));
- }
+ print_symbol (-17, SECTION_NAME (section));
printf (do_wide ? " %-15s " : " %-15.15s ",
get_section_type_name (section->sh_type));
{
if (section->sh_type == SHT_GROUP)
{
- char * name = SECTION_NAME (section);
- char * group_name;
+ const char * name = printable_section_name (section);
+ const char * group_name;
unsigned char * start;
unsigned char * indices;
unsigned int entry, j, size;
if (do_section_groups)
{
sec = section_headers + entry;
- printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
+ printf (" [%5u] %s\n", entry, printable_section_name (sec));
}
g = (struct group_list *) xmalloc (sizeof (struct group_list));
if (string_table == NULL)
printf ("%d", section->sh_name);
else
- printf ("'%s'", SECTION_NAME (section));
+ printf ("'%s'", printable_section_name (section));
printf (_(" at offset 0x%lx contains %lu entries:\n"),
rel_offset, (unsigned long) (rel_size / section->sh_entsize));
if (string_table == NULL)
printf ("%d", unwsec->sh_name);
else
- printf (_("'%s'"), SECTION_NAME (unwsec));
+ printf ("'%s'", printable_section_name (unwsec));
}
else
{
if (string_table == NULL)
printf ("%d", unwsec->sh_name);
else
- printf (_("'%s'"), SECTION_NAME (unwsec));
+ printf ("'%s'", printable_section_name (unwsec));
printf (_(" at offset 0x%lx contains %lu entries:\n"),
(unsigned long) unwsec->sh_offset,
{
if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
{
- printf (_("\nUnwind section "));
- printf (_("'%s'"), SECTION_NAME (sec));
-
- printf (_(" at offset 0x%lx contains %lu entries:\n"),
+ printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
+ printable_section_name (sec),
(unsigned long) sec->sh_offset,
(unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
unsigned int word;
bfd_boolean wrapped;
+ if (sec == NULL || arm_sec == NULL)
+ return FALSE;
+
addr->section = SHN_UNDEF;
addr->offset = 0;
if (arm_sec->data == NULL)
return FALSE;
+ /* If the offset is invalid then fail. */
+ if (word_offset > sec->sh_size - 4)
+ return FALSE;
+
/* Get the word at the required offset. */
word = byte_get (arm_sec->data + word_offset, 4);
if (rp->r_offset < word_offset)
continue;
+ /* PR 17531: file: 027-161405-0.004 */
+ if (aux->symtab == NULL)
+ continue;
+
sym = aux->symtab + ELF32_R_SYM (rp->r_info);
if (arm_sec->rel_type == SHT_REL)
else if (arm_sec->rel_type == SHT_RELA)
offset = rp->r_addend;
else
- abort ();
+ {
+ error (_("Unknown section relocation type %d encountered\n"),
+ arm_sec->rel_type);
+ break;
+ }
offset += sym->st_value;
prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
prelval >>= 1;
}
else
- /* This function currently only supports ARM and TI unwinders. */
- abort ();
+ {
+ /* This function currently only supports ARM and TI unwinders. */
+ warn (_("Only TI and ARM unwinders are currently supported\n"));
+ break;
+ }
word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
addr->section = sym->st_shndx;
addr->offset = offset;
+
if (sym_name)
* sym_name = sym->st_name;
break;
break;
default:
- error (_("Unsupported architecture type %d encountered when decoding unwind table"),
+ error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
elf_header.e_machine);
}
break;
default:
- error (_("Unsupported architecture type %d encountered when processing unwind table"),
+ error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
elf_header.e_machine);
return;
}
aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
strsec = section_headers + sec->sh_link;
- assert (aux.strtab == NULL);
+
+ /* PR binutils/17531 file: 011-12666-0.004. */
+ if (aux.strtab != NULL)
+ {
+ warn (_("Multiple string tables found in file.\n"));
+ free (aux.strtab);
+ }
aux.strtab = get_data (NULL, file, strsec->sh_offset,
1, strsec->sh_size, _("string table"));
aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
if (sec->sh_type == sec_type)
{
printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
- SECTION_NAME (sec),
+ printable_section_name (sec),
(unsigned long) sec->sh_offset,
(unsigned long) (sec->sh_size / (2 * eh_addr_size)));
found = 1;
- printf
- (_("\nVersion definition section '%s' contains %u entries:\n"),
- SECTION_NAME (section), section->sh_info);
+ printf (_("\nVersion definition section '%s' contains %u entries:\n"),
+ printable_section_name (section),
+ section->sh_info);
printf (_(" Addr: 0x"));
printf_vma (section->sh_addr);
- printf (_(" Offset: %#08lx Link: %u (%s)\n"),
+ printf (_(" Offset: %#08lx Link: %u (%s)"),
(unsigned long) section->sh_offset, section->sh_link,
- section->sh_link < elf_header.e_shnum
- ? SECTION_NAME (section_headers + section->sh_link)
- : _("<corrupt>"));
+ printable_section_name_from_index (section->sh_link));
edefs = (Elf_External_Verdef *)
get_data (NULL, file, section->sh_offset, 1,section->sh_size,
found = 1;
printf (_("\nVersion needs section '%s' contains %u entries:\n"),
- SECTION_NAME (section), section->sh_info);
+ printable_section_name (section), section->sh_info);
printf (_(" Addr: 0x"));
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link: %u (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- section->sh_link < elf_header.e_shnum
- ? SECTION_NAME (section_headers + section->sh_link)
- : _("<corrupt>"));
+ printable_section_name_from_index (section->sh_link));
eneed = (Elf_External_Verneed *) get_data (NULL, file,
section->sh_offset, 1,
}
printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
- SECTION_NAME (section), total);
+ printable_section_name (section), total);
printf (_(" Addr: "));
printf_vma (section->sh_addr);
printf (_(" Offset: %#08lx Link: %u (%s)\n"),
(unsigned long) section->sh_offset, section->sh_link,
- SECTION_NAME (link_section));
+ printable_section_name (link_section));
off = offset_from_vma (file,
version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
else if (type >= SHN_LORESERVE)
sprintf (buff, "RSV[0x%04x]", type & 0xffff);
else if (type >= elf_header.e_shnum)
- sprintf (buff, "bad section index[%3d]", type);
+ sprintf (buff, _("bad section index[%3d]"), type);
else
sprintf (buff, "%3d", type);
break;
Elf_Internal_Sym * psym;
int n;
- psym = dynamic_symbols + si;
-
n = print_vma (si, DEC_5);
if (n < 5)
fputs (&" "[n], stdout);
printf (" %3lu: ", hn);
+
+ if (dynamic_symbols == NULL || si >= num_dynamic_syms)
+ {
+ printf (_("<No info available>\n"));
+ return;
+ }
+
+ psym = dynamic_symbols + si;
print_vma (psym->st_value, LONG_HEX);
putchar (' ');
print_vma (psym->st_size, DEC_5);
if (section->sh_entsize == 0)
{
printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
- SECTION_NAME (section));
+ printable_section_name (section));
continue;
}
printf (_("\nSymbol table '%s' contains %lu entries:\n"),
- SECTION_NAME (section),
+ printable_section_name (section),
(unsigned long) (section->sh_size / section->sh_entsize));
if (is_32bit_elf)
unsigned short int flags = dynamic_syminfo[i].si_flags;
printf ("%4d: ", i);
+ assert (i < num_dynamic_syms);
if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
else
else
{
warn (_("unable to apply unsupported reloc type %d to section %s\n"),
- reloc_type, SECTION_NAME (section));
+ reloc_type, printable_section_name (section));
continue;
}
{
warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
(unsigned long) rp->r_offset,
- SECTION_NAME (section));
+ printable_section_name (section));
continue;
}
if (sym_index >= num_syms)
{
warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
- sym_index, SECTION_NAME (section));
+ sym_index, printable_section_name (section));
continue;
}
sym = symtab + sym_index;
warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
get_symbol_type (ELF_ST_TYPE (sym->st_info)),
(long int)(rp - relocs),
- SECTION_NAME (relsec));
+ printable_section_name (relsec));
continue;
}
static int
disassemble_section (Elf_Internal_Shdr * section, FILE * file)
{
- printf (_("\nAssembly dump of section %s\n"),
- SECTION_NAME (section));
+ printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
- /* XXX -- to be done --- XXX */
+ /* FIXME: XXX -- to be done --- XXX */
return 1;
}
if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
{
printf (_("\nSection '%s' has no data to dump.\n"),
- SECTION_NAME (section));
+ printable_section_name (section));
return NULL;
}
char * data;
char * end;
char * start;
- char * name = SECTION_NAME (section);
bfd_boolean some_strings_shown;
start = get_section_contents (section, file);
if (start == NULL)
return;
- printf (_("\nString dump of section '%s':\n"), name);
+ printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
/* If the section being dumped has relocations against it the user might
be expecting these relocations to have been applied. Check for this
if (start == NULL)
return;
- printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
+ printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
if (relocate)
{
display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
{
char * name = SECTION_NAME (section);
+ const char * print_name = printable_section_name (section);
bfd_size_type length;
int result = 1;
int i;
length = section->sh_size;
if (length == 0)
{
- printf (_("\nSection '%s' has no debugging data.\n"), name);
+ printf (_("\nSection '%s' has no debugging data.\n"), print_name);
return 0;
}
if (section->sh_type == SHT_NOBITS)
which has the NOBITS type - the bits in the file will be random.
This can happen when a file containing a .eh_frame section is
stripped with the --only-keep-debug command line option. */
- printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
+ printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
+ print_name);
return 0;
}
if (i == max)
{
- printf (_("Unrecognized debug section: %s\n"), name);
+ printf (_("Unrecognized debug section: %s\n"), print_name);
result = 0;
}
unsigned long addr = 0;
size_t bytes = end - p;
+ assert (end > p);
while (bytes)
{
int j;
bfd_boolean public_section;
bfd_boolean gnu_section;
+ if (len <= 4)
+ {
+ error (_("Tag section ends prematurely\n"));
+ break;
+ }
section_len = byte_get (p, 4);
p += 4;
(unsigned) section_len, (unsigned) len);
section_len = len;
}
-
+ /* PR 17531: file: 001-101425-0.004 */
+ else if (section_len < 5)
+ {
+ error (_("Attribute length of %u is too small\n"), (unsigned) section_len);
+ break;
+ }
+
len -= section_len;
section_len -= 4;
p += namelen;
section_len -= namelen;
+
while (section_len > 0)
{
- int tag = *(p++);
+ int tag;
int val;
bfd_vma size;
+ /* PR binutils/17531: Safe handling of corrupt files. */
+ if (section_len < 6)
+ {
+ error (_("Unused bytes at end of section\n"));
+ section_len = 0;
+ break;
+ }
+
+ tag = *(p++);
size = byte_get (p, 4);
if (size > section_len)
{
(unsigned) size, (unsigned) section_len);
size = section_len;
}
+ /* PR binutils/17531: Safe handling of corrupt files. */
+ if (size < 6)
+ {
+ error (_("Bad subsection length (%u < 6)\n"),
+ (unsigned) size);
+ section_len = 0;
+ break;
+ }
section_len -= size;
end = p + size - 1;
}
printf (_("\nSection '%s' contains %d entries:\n"),
- SECTION_NAME (sect), cnt);
+ printable_section_name (sect), cnt);
option = iopt;
for (cnt = 0; cnt < conflictsno; ++cnt)
{
- Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
-
printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
- print_vma (psym->st_value, FULL_HEX);
- putchar (' ');
- if (VALID_DYNAMIC_NAME (psym->st_name))
- print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
+
+ if (iconf[cnt] >= num_dynamic_syms)
+ printf (_("<corrupt symbol index>"));
else
- printf (_("<corrupt: %14ld>"), psym->st_name);
+ {
+ Elf_Internal_Sym * psym;
+
+ psym = & dynamic_symbols[iconf[cnt]];
+ print_vma (psym->st_value, FULL_HEX);
+ putchar (' ');
+ if (VALID_DYNAMIC_NAME (psym->st_name))
+ print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
+ else
+ printf (_("<corrupt: %14ld>"), psym->st_name);
+ }
putchar ('\n');
}
ent = pltgot;
addr_size = (is_32bit_elf ? 4 : 8);
local_end = pltgot + local_gotno * addr_size;
- global_end = local_end + (symtabno - gotsym) * addr_size;
+ /* PR binutils/17533 file: 012-111227-0.004 */
+ if (symtabno < gotsym)
+ {
+ error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
+ (long) gotsym, (long) symtabno);
+ return 0;
+ }
+
+ global_end = local_end + (symtabno - gotsym) * addr_size;
+ assert (global_end >= local_end);
offset = offset_from_vma (file, pltgot, global_end - pltgot);
data = (unsigned char *) get_data (NULL, file, offset,
global_end - pltgot, 1,
_("Ndx"), _("Name"));
sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
+
for (i = gotsym; i < symtabno; i++)
{
- Elf_Internal_Sym * psym;
-
- psym = dynamic_symbols + i;
ent = print_mips_got_entry (data, pltgot, ent);
printf (" ");
- print_vma (psym->st_value, LONG_HEX);
- printf (" %-7s %3s ",
- get_symbol_type (ELF_ST_TYPE (psym->st_info)),
- get_symbol_index_type (psym->st_shndx));
- if (VALID_DYNAMIC_NAME (psym->st_name))
- print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+
+ if (dynamic_symbols == NULL)
+ printf (_("<no dynamic symbols>"));
+ else if (i < num_dynamic_syms)
+ {
+ Elf_Internal_Sym * psym = dynamic_symbols + i;
+
+ print_vma (psym->st_value, LONG_HEX);
+ printf (" %-7s %3s ",
+ get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+ get_symbol_index_type (psym->st_shndx));
+
+ if (VALID_DYNAMIC_NAME (psym->st_name))
+ print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+ else
+ printf (_("<corrupt: %14ld>"), psym->st_name);
+ }
else
- printf (_("<corrupt: %14ld>"), psym->st_name);
+ printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
+ (unsigned long) i);
+
printf ("\n");
}
printf ("\n");
sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
for (i = 0; i < count; i++)
{
- Elf_Internal_Sym * psym;
+ unsigned long idx = get_reloc_symindex (rels[i].r_info);
- psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
printf (" ");
- print_vma (psym->st_value, LONG_HEX);
- printf (" %-7s %3s ",
- get_symbol_type (ELF_ST_TYPE (psym->st_info)),
- get_symbol_index_type (psym->st_shndx));
- if (VALID_DYNAMIC_NAME (psym->st_name))
- print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+
+ if (idx >= num_dynamic_syms)
+ printf (_("<corrupt symbol index: %lu>"), idx);
else
- printf (_("<corrupt: %14ld>"), psym->st_name);
+ {
+ Elf_Internal_Sym * psym = dynamic_symbols + idx;
+
+ print_vma (psym->st_value, LONG_HEX);
+ printf (" %-7s %3s ",
+ get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+ get_symbol_index_type (psym->st_shndx));
+ if (VALID_DYNAMIC_NAME (psym->st_name))
+ print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+ else
+ printf (_("<corrupt: %14ld>"), psym->st_name);
+ }
printf ("\n");
}
printf ("\n");
strtab_size = string_sec->sh_size;
printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
- SECTION_NAME (section),
+ printable_section_name (section),
(unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
puts (_(" Library Time Stamp Checksum Version Flags"));