#include "elf/sparc.h"
#include "elf/spu.h"
#include "elf/tic6x.h"
+#include "elf/tilegx.h"
+#include "elf/tilepro.h"
#include "elf/v850.h"
#include "elf/vax.h"
#include "elf/x86-64.h"
} \
while (0)
\f
+/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
+ Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
+ using malloc and fill that. In either case return the pointer to the start of
+ the retrieved data or NULL if something went wrong. If something does go wrong
+ emit an error message using REASON as part of the context. */
+
static void *
get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
const char * reason)
case EM_SPARCV9:
case EM_SPU:
case EM_TI_C6000:
+ case EM_TILEGX:
+ case EM_TILEPRO:
case EM_V850:
case EM_CYGNUS_V850:
case EM_VAX:
case EM_TI_C6000:
rtype = elf_tic6x_reloc_type (type);
break;
+
+ case EM_TILEGX:
+ rtype = elf_tilegx_reloc_type (type);
+ break;
+
+ case EM_TILEPRO:
+ rtype = elf_tilepro_reloc_type (type);
+ break;
}
if (rtype == NULL)
case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
case EM_TILE64: return "Tilera TILE64 multicore architecture family";
case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
+ case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
case EM_CUDA: return "NVIDIA CUDA architecture";
default:
snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
case ELFOSABI_NONE: return "UNIX - System V";
case ELFOSABI_HPUX: return "UNIX - HP-UX";
case ELFOSABI_NETBSD: return "UNIX - NetBSD";
- case ELFOSABI_LINUX: return "UNIX - Linux";
- case ELFOSABI_HURD: return "GNU/Hurd";
+ case ELFOSABI_GNU: return "UNIX - GNU";
case ELFOSABI_SOLARIS: return "UNIX - Solaris";
case ELFOSABI_AIX: return "UNIX - AIX";
case ELFOSABI_IRIX: return "UNIX - IRIX";
else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
else
- snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
+ /* This message is probably going to be displayed in a 15
+ character wide field, so put the hex value first. */
+ snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
return buff;
}
#define OPTION_DEBUG_DUMP 512
#define OPTION_DYN_SYMS 513
+#define OPTION_DWARF_DEPTH 514
+#define OPTION_DWARF_START 515
static struct option options[] =
{
#endif
{"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
+ {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
+ {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
+
{"version", no_argument, 0, 'v'},
{"wide", no_argument, 0, 'W'},
{"help", no_argument, 0, 'H'},
=frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
=gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
Display the contents of DWARF2 debug sections\n"));
+ fprintf (stream, _("\
+ --dwarf-depth=N Do not display DIEs at depth N or greater\n\
+ --dwarf-start=N Display DIEs starting with N, at the same depth\n\
+ or deeper\n"));
#ifdef SUPPORT_DISASSEMBLY
fprintf (stream, _("\
-i --instruction-dump=<number|name>\n\
dwarf_select_sections_by_names (optarg);
}
break;
+ case OPTION_DWARF_DEPTH:
+ {
+ char *cp;
+
+ dwarf_cutoff_level = strtoul (optarg, & cp, 0);
+ }
+ break;
+ case OPTION_DWARF_START:
+ {
+ char *cp;
+
+ dwarf_start_die = strtoul (optarg, & cp, 0);
+ }
+ break;
case OPTION_DYN_SYMS:
do_dyn_syms++;
break;
dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
1, section->sh_size,
_("dynamic strings"));
- dynamic_strings_length = section->sh_size;
+ dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
}
else if (section->sh_type == SHT_SYMTAB_SHNDX)
{
start = (unsigned char *) get_data (NULL, file, section->sh_offset,
1, section->sh_size,
_("section data"));
+ if (start == NULL)
+ continue;
indices = start;
size = (section->sh_size / section->sh_entsize) - 1;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = section_headers + sec->sh_link;
+ assert (aux.strtab == NULL);
aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
1, strsec->sh_size,
_("string table"));
}
else
{
- aux.info_size = sec->sh_size;
aux.info_addr = sec->sh_addr;
aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
- aux.info_size,
+ sec->sh_size,
_("unwind info"));
+ aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
printf (_("\nUnwind section "));
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = section_headers + sec->sh_link;
+ assert (aux.strtab == NULL);
aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
1, strsec->sh_size,
_("string table"));
arm_sec->sec = sec;
arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
sec->sh_size, _("unwind data"));
-
arm_sec->rela = NULL;
arm_sec->nrelas = 0;
aux.symtab = GET_ELF_SYMBOLS (file, sec);
strsec = section_headers + sec->sh_link;
+ assert (aux.strtab == NULL);
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;
dynamic_strings = (char *) get_data (NULL, file, offset, 1,
str_tab_len,
_("dynamic string table"));
- dynamic_strings_length = str_tab_len;
+ dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
break;
}
}
edefs = (Elf_External_Verdef *)
get_data (NULL, file, section->sh_offset, 1,section->sh_size,
_("version definition section"));
- endbuf = (char *) edefs + section->sh_size;
if (!edefs)
break;
+ endbuf = (char *) edefs + section->sh_size;
for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
{
section->sh_offset, 1,
section->sh_size,
_("version need section"));
- endbuf = (char *) eneed + section->sh_size;
if (!eneed)
break;
+ endbuf = (char *) eneed + section->sh_size;
for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
{
Elf_External_Vernaux evna;
unsigned long a_off;
- get_data (&evn, file, offset, sizeof (evn), 1,
- _("version need"));
-
+ if (get_data (&evn, file, offset, sizeof (evn), 1,
+ _("version need")) == NULL)
+ break;
+
ivn.vn_aux = BYTE_GET (evn.vn_aux);
ivn.vn_next = BYTE_GET (evn.vn_next);
do
{
- get_data (&evna, file, a_off, sizeof (evna),
- 1, _("version need aux (2)"));
-
- ivna.vna_next = BYTE_GET (evna.vna_next);
- ivna.vna_other = BYTE_GET (evna.vna_other);
+ if (get_data (&evna, file, a_off, sizeof (evna),
+ 1, _("version need aux (2)")) == NULL)
+ {
+ ivna.vna_next = 0;
+ ivna.vna_other = 0;
+ }
+ else
+ {
+ ivna.vna_next = BYTE_GET (evna.vna_next);
+ ivna.vna_other = BYTE_GET (evna.vna_other);
+ }
a_off += ivna.vna_next;
}
do
{
- get_data (&evd, file, offset, sizeof (evd), 1,
- _("version def"));
-
- ivd.vd_next = BYTE_GET (evd.vd_next);
- ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+ if (get_data (&evd, file, offset, sizeof (evd), 1,
+ _("version def")) == NULL)
+ {
+ ivd.vd_next = 0;
+ ivd.vd_ndx = 0;
+ }
+ else
+ {
+ ivd.vd_next = BYTE_GET (evd.vd_next);
+ ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+ }
offset += ivd.vd_next;
}
ivd.vd_aux = BYTE_GET (evd.vd_aux);
- get_data (&evda, file,
- offset - ivd.vd_next + ivd.vd_aux,
- sizeof (evda), 1,
- _("version def aux"));
+ if (get_data (&evda, file,
+ offset - ivd.vd_next + ivd.vd_aux,
+ sizeof (evda), 1,
+ _("version def aux")) == NULL)
+ break;
ivda.vda_name = BYTE_GET (evda.vda_name);
else if (binding >= STB_LOOS && binding <= STB_HIOS)
{
if (binding == STB_GNU_UNIQUE
- && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
- /* GNU/Linux is still using the default value 0. */
+ && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
+ /* GNU is still using the default value 0. */
|| elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
return "UNIQUE";
snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
}
if (type == STT_GNU_IFUNC
- && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
- /* GNU/Linux is still using the default value 0. */
+ && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
+ /* GNU is still using the default value 0. */
|| elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
return "IFUNC";
print_symbol (25, psym->st_name < strtab_size
? strtab + psym->st_name : _("<corrupt>"));
- if (section->sh_type == SHT_DYNSYM &&
- version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
+ if (section->sh_type == SHT_DYNSYM
+ && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
{
unsigned char data[2];
unsigned short vers_data;
(file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
sizeof data + si * sizeof (vers_data));
- get_data (&data, file, offset + si * sizeof (vers_data),
- sizeof (data), 1, _("version data"));
+ if (get_data (&data, file, offset + si * sizeof (vers_data),
+ sizeof (data), 1, _("version data")) == NULL)
+ break;
vers_data = byte_get (data, 2);
{
unsigned long vna_off;
- get_data (&evn, file, offset, sizeof (evn), 1,
- _("version need"));
+ if (get_data (&evn, file, offset, sizeof (evn), 1,
+ _("version need")) == NULL)
+ {
+ ivna.vna_next = 0;
+ ivna.vna_other = 0;
+ ivna.vna_name = 0;
+ break;
+ }
ivn.vn_aux = BYTE_GET (evn.vn_aux);
ivn.vn_next = BYTE_GET (evn.vn_next);
{
Elf_External_Vernaux evna;
- get_data (&evna, file, vna_off,
- sizeof (evna), 1,
- _("version need aux (3)"));
-
- ivna.vna_other = BYTE_GET (evna.vna_other);
- ivna.vna_next = BYTE_GET (evna.vna_next);
- ivna.vna_name = BYTE_GET (evna.vna_name);
+ if (get_data (&evna, file, vna_off,
+ sizeof (evna), 1,
+ _("version need aux (3)")) == NULL)
+ {
+ ivna.vna_next = 0;
+ ivna.vna_other = 0;
+ ivna.vna_name = 0;
+ }
+ else
+ {
+ ivna.vna_other = BYTE_GET (evna.vna_other);
+ ivna.vna_next = BYTE_GET (evna.vna_next);
+ ivna.vna_name = BYTE_GET (evna.vna_name);
+ }
vna_off += ivna.vna_next;
}
{
Elf_External_Verdef evd;
- get_data (&evd, file, off, sizeof (evd),
- 1, _("version def"));
-
- ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
- ivd.vd_aux = BYTE_GET (evd.vd_aux);
- ivd.vd_next = BYTE_GET (evd.vd_next);
+ if (get_data (&evd, file, off, sizeof (evd),
+ 1, _("version def")) == NULL)
+ {
+ ivd.vd_ndx = 0;
+ ivd.vd_aux = 0;
+ ivd.vd_next = 0;
+ }
+ else
+ {
+ ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
+ ivd.vd_aux = BYTE_GET (evd.vd_aux);
+ ivd.vd_next = BYTE_GET (evd.vd_next);
+ }
off += ivd.vd_next;
}
off -= ivd.vd_next;
off += ivd.vd_aux;
- get_data (&evda, file, off, sizeof (evda),
- 1, _("version def aux"));
+ if (get_data (&evda, file, off, sizeof (evda),
+ 1, _("version def aux")) == NULL)
+ break;
ivda.vda_name = BYTE_GET (evda.vda_name);
return reloc_type == 6; /* R_SPU_ADDR32 */
case EM_TI_C6000:
return reloc_type == 1; /* R_C6000_ABS32. */
+ case EM_TILEGX:
+ return reloc_type == 2; /* R_TILEGX_32. */
+ case EM_TILEPRO:
+ return reloc_type == 1; /* R_TILEPRO_32. */
case EM_CYGNUS_V850:
case EM_V850:
return reloc_type == 6; /* R_V850_ABS32. */
return reloc_type == 6; /* R_SPARC_DISP32. */
case EM_SPU:
return reloc_type == 13; /* R_SPU_REL32. */
+ case EM_TILEGX:
+ return reloc_type == 6; /* R_TILEGX_32_PCREL. */
+ case EM_TILEPRO:
+ return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
case EM_X86_64:
case EM_L1OM:
return reloc_type == 2; /* R_X86_64_PC32. */
return reloc_type == 1; /* R_X86_64_64. */
case EM_S390_OLD:
case EM_S390:
- return reloc_type == 22; /* R_S390_64 */
+ return reloc_type == 22; /* R_S390_64. */
+ case EM_TILEGX:
+ return reloc_type == 1; /* R_TILEGX_64. */
case EM_MIPS:
- return reloc_type == 18; /* R_MIPS_64 */
+ return reloc_type == 18; /* R_MIPS_64. */
default:
return FALSE;
}
switch (elf_header.e_machine)
{
case EM_ALPHA:
- return reloc_type == 11; /* R_ALPHA_SREL64 */
+ return reloc_type == 11; /* R_ALPHA_SREL64. */
case EM_IA_64:
- return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
+ return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
case EM_PARISC:
- return reloc_type == 72; /* R_PARISC_PCREL64 */
+ return reloc_type == 72; /* R_PARISC_PCREL64. */
case EM_PPC64:
- return reloc_type == 44; /* R_PPC64_REL64 */
+ return reloc_type == 44; /* R_PPC64_REL64. */
case EM_SPARC32PLUS:
case EM_SPARCV9:
case EM_SPARC:
- return reloc_type == 46; /* R_SPARC_DISP64 */
+ return reloc_type == 46; /* R_SPARC_DISP64. */
case EM_X86_64:
case EM_L1OM:
- return reloc_type == 24; /* R_X86_64_PC64 */
+ return reloc_type == 24; /* R_X86_64_PC64. */
case EM_S390_OLD:
case EM_S390:
- return reloc_type == 23; /* R_S390_PC64 */
+ return reloc_type == 23; /* R_S390_PC64. */
+ case EM_TILEGX:
+ return reloc_type == 5; /* R_TILEGX_64_PCREL. */
default:
return FALSE;
}
case EM_MOXIE: /* R_MOXIE_NONE. */
case EM_M32R: /* R_M32R_NONE. */
case EM_TI_C6000:/* R_C6000_NONE. */
+ case EM_TILEGX: /* R_TILEGX_NONE. */
+ case EM_TILEPRO: /* R_TILEPRO_NONE. */
case EM_XC16X:
case EM_C166: /* R_XC16X_NONE. */
return reloc_type == 0;
snprintf (buf, sizeof (buf), _("%s section data"), section->name);
section->address = sec->sh_addr;
- section->size = sec->sh_size;
section->start = (unsigned char *) get_data (NULL, (FILE *) file,
sec->sh_offset, 1,
sec->sh_size, buf);
- if (uncompress_section_contents (§ion->start, §ion->size))
- sec->sh_size = section->size;
+ if (section->start == NULL)
+ section->size = 0;
+ else
+ {
+ section->size = sec->sh_size;
+ if (uncompress_section_contents (§ion->start, §ion->size))
+ sec->sh_size = section->size;
+ }
if (section->start == NULL)
return 0;
offset = offset_from_vma (file, pltgot, global_end - pltgot);
data = (unsigned char *) get_data (NULL, file, offset,
global_end - pltgot, 1, _("GOT"));
+ if (data == NULL)
+ return 0;
+
printf (_("\nPrimary GOT:\n"));
printf (_(" Canonical gp value: "));
print_vma (pltgot + 0x7ff0, LONG_HEX);
offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
1, _("PLT GOT"));
+ if (data == NULL)
+ return 0;
+
printf (_("\nPLT GOT:\n\n"));
printf (_(" Reserved entries:\n"));
printf (_(" %*s %*s Purpose\n"),
strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
string_sec->sh_size,
_("liblist string table"));
- strtab_size = string_sec->sh_size;
-
if (strtab == NULL
|| section->sh_entsize != sizeof (Elf32_External_Lib))
{
free (strtab);
break;
}
+ strtab_size = string_sec->sh_size;
printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
SECTION_NAME (section),
return _("NT_S390_CTRS (s390 control registers)");
case NT_S390_PREFIX:
return _("NT_S390_PREFIX (s390 prefix register)");
+ case NT_ARM_VFP:
+ return _("NT_ARM_VFP (arm VFP registers)");
case NT_PSTATUS:
return _("NT_PSTATUS (pstatus structure)");
case NT_FPREGS:
return buff;
}
+static const char *
+get_stapsdt_note_type (unsigned e_type)
+{
+ static char buff[64];
+
+ switch (e_type)
+ {
+ case NT_STAPSDT:
+ return _("NT_STAPSDT (SystemTap probe descriptors)");
+
+ default:
+ break;
+ }
+
+ snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
+ return buff;
+}
+
+static int
+print_stapsdt_note (Elf_Internal_Note *pnote)
+{
+ int addr_size = is_32bit_elf ? 4 : 8;
+ char *data = pnote->descdata;
+ char *data_end = pnote->descdata + pnote->descsz;
+ bfd_vma pc, base_addr, semaphore;
+ char *provider, *probe, *arg_fmt;
+
+ pc = byte_get ((unsigned char *) data, addr_size);
+ data += addr_size;
+ base_addr = byte_get ((unsigned char *) data, addr_size);
+ data += addr_size;
+ semaphore = byte_get ((unsigned char *) data, addr_size);
+ data += addr_size;
+
+ provider = data;
+ data += strlen (data) + 1;
+ probe = data;
+ data += strlen (data) + 1;
+ arg_fmt = data;
+ data += strlen (data) + 1;
+
+ printf (_(" Provider: %s\n"), provider);
+ printf (_(" Name: %s\n"), probe);
+ printf (_(" Location: "));
+ print_vma (pc, FULL_HEX);
+ printf (_(", Base: "));
+ print_vma (base_addr, FULL_HEX);
+ printf (_(", Semaphore: "));
+ print_vma (semaphore, FULL_HEX);
+ printf (_("\n"));
+ printf (_(" Arguments: %s\n"), arg_fmt);
+
+ return data == data_end;
+}
+
static const char *
get_ia64_vms_note_type (unsigned e_type)
{
/* VMS/ia64-specific file notes. */
nt = get_ia64_vms_note_type (pnote->type);
+ else if (const_strneq (pnote->namedata, "stapsdt"))
+ nt = get_stapsdt_note_type (pnote->type);
+
else
/* Don't recognize this note name; just use the default set of
note type strings. */
return print_ia64_vms_note (pnote);
else if (const_strneq (pnote->namedata, "GNU"))
return print_gnu_note (pnote);
+ else if (const_strneq (pnote->namedata, "stapsdt"))
+ return print_stapsdt_note (pnote);
else
return 1;
}