#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
#define STRING_DUMP (1 << 3) /* The -p command line switch. */
#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
-#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
+#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
typedef unsigned char dump_type;
static char program_interpreter[PATH_MAX];
static bfd_vma dynamic_info[DT_ENCODING];
static bfd_vma dynamic_info_DT_GNU_HASH;
+static bfd_vma dynamic_info_DT_MIPS_XHASH;
static bfd_vma version_info[16];
static Elf_Internal_Dyn * dynamic_section;
static elf_section_list * symtab_shndx_list;
(ADDR) &= ~1; \
} \
while (0)
+
+/* Get the correct GNU hash section name. */
+#define GNU_HASH_SECTION_NAME \
+ dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
\f
/* Print a BFD_VMA to an internal buffer, for use in error messages.
BFD_FMA_FMT can't be used in translated strings. */
case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
case DT_MIPS_RWPLT: return "MIPS_RWPLT";
+ case DT_MIPS_XHASH: return "MIPS_XHASH";
default:
return NULL;
}
case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
+ case SHT_MIPS_XHASH: return "MIPS_XHASH";
default:
break;
}
{"dwarf-start", required_argument, 0, OPTION_DWARF_START},
{"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
- {"ctf", required_argument, 0, OPTION_CTF_DUMP},
+ {"ctf", required_argument, 0, OPTION_CTF_DUMP},
{"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
{"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
unsigned int i;
Elf_Internal_Phdr * previous_load = NULL;
+ dynamic_addr = 0;
+ dynamic_size = 0;
+
if (filedata->file_header.e_phnum == 0)
{
/* PR binutils/12467. */
}
}
- dynamic_addr = 0;
- dynamic_size = 0;
-
for (i = 0, segment = filedata->program_headers;
i < filedata->file_header.e_phnum;
i++, segment++)
print_vma (entry->d_un.d_val, DEC);
break;
+ case DT_MIPS_XHASH:
+ dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
+ dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
+ /* Falls through. */
+
default:
print_vma (entry->d_un.d_ptr, PREFIX_HEX);
}
if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
return NULL;
+ *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
max_vd_ndx = 0;
/* Usually we'd only see verdef for defined symbols, and verneed for
ivda.vda_name = BYTE_GET (evda.vda_name);
if (psym->st_name != ivda.vda_name)
- {
- *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
- ? symbol_hidden : symbol_public);
- return (ivda.vda_name < strtab_size
- ? strtab + ivda.vda_name : _("<corrupt>"));
- }
+ return (ivda.vda_name < strtab_size
+ ? strtab + ivda.vda_name : _("<corrupt>"));
}
}
}
bfd_vma ngnubuckets = 0;
bfd_vma * gnubuckets = NULL;
bfd_vma * gnuchains = NULL;
+ bfd_vma * mipsxlat = NULL;
bfd_vma gnusymidx = 0;
bfd_size_type ngnuchains = 0;
gnuchains = get_dynamic_data (filedata, maxchain, 4);
ngnuchains = maxchain;
+ if (gnuchains == NULL)
+ goto no_gnu_hash;
+
+ if (dynamic_info_DT_MIPS_XHASH)
+ {
+ if (fseek (filedata->handle,
+ (archive_file_offset
+ + offset_from_vma (filedata, (buckets_vma
+ + 4 * (ngnubuckets
+ + maxchain)), 4)),
+ SEEK_SET))
+ {
+ error (_("Unable to seek to start of dynamic information\n"));
+ goto no_gnu_hash;
+ }
+
+ mipsxlat = get_dynamic_data (filedata, maxchain, 4);
+ }
+
no_gnu_hash:
+ if (dynamic_info_DT_MIPS_XHASH && mipsxlat == NULL)
+ {
+ free (gnuchains);
+ gnuchains = NULL;
+ }
if (gnuchains == NULL)
{
free (gnubuckets);
if (dynamic_info_DT_GNU_HASH)
{
- printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
+ printf (_("\nSymbol table of `%s' for image:\n"),
+ GNU_HASH_SECTION_NAME);
if (is_32bit_elf)
printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
else
do
{
- print_dynamic_symbol (filedata, si, hn);
+ if (dynamic_info_DT_MIPS_XHASH)
+ print_dynamic_symbol (filedata, mipsxlat[off], hn);
+ else
+ print_dynamic_symbol (filedata, si, hn);
si++;
}
while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
unsigned long nzero_counts = 0;
unsigned long nsyms = 0;
- printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
+ printf (ngettext ("\nHistogram for `%s' bucket list length "
"(total of %lu bucket):\n",
- "\nHistogram for `.gnu.hash' bucket list length "
+ "\nHistogram for `%s' bucket list length "
"(total of %lu buckets):\n",
(unsigned long) ngnubuckets),
+ GNU_HASH_SECTION_NAME,
(unsigned long) ngnubuckets);
lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
free (lengths);
free (gnubuckets);
free (gnuchains);
+ free (mipsxlat);
}
return TRUE;
Elf_Internal_Shdr * parent_sec = NULL;
Elf_Internal_Shdr * symtab_sec = NULL;
Elf_Internal_Shdr * strtab_sec = NULL;
- void * data = NULL;
- void * symdata = NULL;
- void * strdata = NULL;
- void * parentdata = NULL;
- ctf_sect_t ctfsect, symsect, strsect, parentsect;
- ctf_sect_t * symsectp = NULL;
- ctf_sect_t * strsectp = NULL;
- ctf_file_t * ctf = NULL;
- ctf_file_t * parent = NULL;
-
- const char *things[] = {"Labels", "Data objects", "Function objects",
- "Variables", "Types", "Strings", ""};
+ void * data = NULL;
+ void * symdata = NULL;
+ void * strdata = NULL;
+ void * parentdata = NULL;
+ ctf_sect_t ctfsect, symsect, strsect, parentsect;
+ ctf_sect_t * symsectp = NULL;
+ ctf_sect_t * strsectp = NULL;
+ ctf_file_t * ctf = NULL;
+ ctf_file_t * parent = NULL;
+
+ const char *things[] = {"Header", "Labels", "Data objects",
+ "Function objects", "Variables", "Types", "Strings",
+ ""};
const char **thing;
int err;
bfd_boolean ret = FALSE;
data = get_section_contents (section, filedata);
ctfsect.cts_data = data;
- if (dump_ctf_symtab_name)
+ if (!dump_ctf_symtab_name)
+ dump_ctf_symtab_name = strdup (".symtab");
+
+ if (!dump_ctf_strtab_name)
+ dump_ctf_strtab_name = strdup (".strtab");
+
+ if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
{
if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
{
symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
symsect.cts_data = symdata;
}
- if (dump_ctf_strtab_name)
+ if (dump_ctf_strtab_name && dump_ctf_symtab_name[0] != 0)
{
if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
{
printf (_("\nDump of CTF section '%s':\n"),
printable_section_name (filedata, section));
- for (i = 1, thing = things; *thing[0]; thing++, i++)
+ for (i = 0, thing = things; *thing[0]; thing++, i++)
{
ctf_dump_state_t *s = NULL;
char *item;
return FALSE;
}
- printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
+ printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
end = (char *) pnotes + length;
while ((char *) external < end)
for (i = ARRAY_SIZE (dynamic_info); i--;)
dynamic_info[i] = 0;
dynamic_info_DT_GNU_HASH = 0;
+ dynamic_info_DT_MIPS_XHASH = 0;
/* Process the file. */
if (show_name)