Display unknown notes. Decode NT_GNU_HWCAP notes.

* readelf.c (apply_relocations): Fail if the symbol table section
	linked to by the reloc section does not have either the SHT_SYMTAB
	or SHT_DYNSYM type.
	(print_gnu_note): Decode the contents of NT_GNU_HWCAP notes.
	Print the contents of unknown note types.
	(process_note): Add the file and section to the parameter list.
	Use print_symbol to display the note name.
	Display the contents of unknown note types.
	(process_corefile_note_segment): Rename to process_notes_at.
	Add section parameter.  Apply relocations to the notes when
	loading from a section.  Display section name when processing
	notes in a section.
	* testsuite/binutils-all/readelf.n: Update expected output.
This commit is contained in:
Nick Clifton 2016-10-17 15:29:43 +01:00
parent decf5bd157
commit 1449284bd8
3 changed files with 124 additions and 38 deletions

View file

@ -1,3 +1,19 @@
2016-10-17 Nick Clifton <nickc@redhat.com>
* readelf.c (apply_relocations): Fail if the symbol table section
linked to by the reloc section does not have either the SHT_SYMTAB
or SHT_DYNSYM type.
(print_gnu_note): Decode the contents of NT_GNU_HWCAP notes.
Print the contents of unknown note types.
(process_note): Add the file and section to the parameter list.
Use print_symbol to display the note name.
Display the contents of unknown note types.
(process_corefile_note_segment): Rename to process_notes_at.
Add section parameter. Apply relocations to the notes when
loading from a section. Display section name when processing
notes in a section.
* testsuite/binutils-all/readelf.n: Update expected output.
2016-10-17 Nick Clifton <nickc@redhat.com> 2016-10-17 Nick Clifton <nickc@redhat.com>
* readelf.c (get_dynamic_type): Add DT_SYMTAB_SHNDX. * readelf.c (get_dynamic_type): Add DT_SYMTAB_SHNDX.

View file

@ -6279,7 +6279,7 @@ process_section_headers (FILE * file)
static const char * static const char *
get_group_flags (unsigned int flags) get_group_flags (unsigned int flags)
{ {
static char buff[32]; static char buff[128];
if (flags == 0) if (flags == 0)
return ""; return "";
@ -10773,10 +10773,12 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn)
} }
static const char * static const char *
get_symbol_version_string (FILE *file, int is_dynsym, get_symbol_version_string (FILE * file,
bfd_boolean is_dynsym,
const char * strtab, const char * strtab,
unsigned long int strtab_size, unsigned long int strtab_size,
unsigned int si, Elf_Internal_Sym *psym, unsigned int si,
Elf_Internal_Sym * psym,
enum versioned_symbol_info * sym_info, enum versioned_symbol_info * sym_info,
unsigned short * vna_other) unsigned short * vna_other)
{ {
@ -12238,6 +12240,9 @@ apply_relocations (void * file,
is_rela = FALSE; is_rela = FALSE;
symsec = section_headers + relsec->sh_link; 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); symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
for (rp = relocs; rp < relocs + num_relocs; ++rp) for (rp = relocs; rp < relocs + num_relocs; ++rp)
@ -15579,8 +15584,7 @@ print_core_note (Elf_Internal_Note *pnote)
static const char * static const char *
get_gnu_elf_note_type (unsigned e_type) 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) switch (e_type)
{ {
case NT_GNU_ABI_TAG: case NT_GNU_ABI_TAG:
@ -15592,16 +15596,19 @@ get_gnu_elf_note_type (unsigned e_type)
case NT_GNU_GOLD_VERSION: case NT_GNU_GOLD_VERSION:
return _("NT_GNU_GOLD_VERSION (gold version)"); return _("NT_GNU_GOLD_VERSION (gold version)");
default: default:
break; {
} static char buff[64];
snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
return buff; return buff;
} }
}
}
static int static int
print_gnu_note (Elf_Internal_Note *pnote) print_gnu_note (Elf_Internal_Note *pnote)
{ {
/* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
switch (pnote->type) switch (pnote->type)
{ {
case NT_GNU_BUILD_ID: case NT_GNU_BUILD_ID:
@ -15675,6 +15682,42 @@ print_gnu_note (Elf_Internal_Note *pnote)
printf ("\n"); printf ("\n");
} }
break; 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 (_("<corrupt GNU_HWCAP>\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; return 1;
@ -16057,7 +16100,9 @@ print_ia64_vms_note (Elf_Internal_Note * pnote)
If the value of namesz is zero, there is no name present. */ If the value of namesz is zero, there is no name present. */
static int 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 * name = pnote->namesz ? pnote->namedata : "(NONE)";
const char * nt; const char * nt;
@ -16102,7 +16147,9 @@ process_note (Elf_Internal_Note * pnote)
note type strings. */ note type strings. */
nt = get_note_type (pnote->type); 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")) if (const_strneq (pnote->namedata, "IPF/VMS"))
return print_ia64_vms_note (pnote); return print_ia64_vms_note (pnote);
@ -16112,13 +16159,25 @@ process_note (Elf_Internal_Note * pnote)
return print_stapsdt_note (pnote); return print_stapsdt_note (pnote);
else if (const_strneq (pnote->namedata, "CORE")) else if (const_strneq (pnote->namedata, "CORE"))
return print_core_note (pnote); return print_core_note (pnote);
else
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; return 1;
} }
static int 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 * pnotes;
Elf_External_Note * external; Elf_External_Note * external;
@ -16128,6 +16187,13 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
if (length <= 0) if (length <= 0)
return 0; return 0;
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, pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
_("notes")); _("notes"));
if (pnotes == NULL) if (pnotes == NULL)
@ -16135,8 +16201,12 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
external = pnotes; external = pnotes;
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"), printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
(unsigned long) offset, (unsigned long) length); (unsigned long) offset, (unsigned long) length);
printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size")); printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
end = (char *) pnotes + length; end = (char *) pnotes + length;
@ -16236,7 +16306,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
inote.namedata = temp; inote.namedata = temp;
} }
res &= process_note (& inote); res &= process_note (& inote, file, section);
if (temp != NULL) if (temp != NULL)
{ {
@ -16265,7 +16335,7 @@ process_corefile_note_segments (FILE * file)
i++, segment++) i++, segment++)
{ {
if (segment->p_type == PT_NOTE) if (segment->p_type == PT_NOTE)
res &= process_corefile_note_segment (file, res &= process_notes_at (file, NULL,
(bfd_vma) segment->p_offset, (bfd_vma) segment->p_offset,
(bfd_vma) segment->p_filesz); (bfd_vma) segment->p_filesz);
} }
@ -16368,7 +16438,7 @@ process_note_sections (FILE * file)
{ {
if (section->sh_type == SHT_NOTE) if (section->sh_type == SHT_NOTE)
{ {
res &= process_corefile_note_segment (file, res &= process_notes_at (file, section,
(bfd_vma) section->sh_offset, (bfd_vma) section->sh_offset,
(bfd_vma) section->sh_size); (bfd_vma) section->sh_size);
n++; n++;

View file

@ -1,5 +1,5 @@
Displaying notes found at file offset 0x0*0.. with length 0x0*018: Displaying notes found in: \.note
Owner[ ]*Data size[ ]*Description Owner[ ]*Data size[ ]*Description
Version 1.0[ ]*0x0*0[ ]*NT_VERSION \(version\) Version 1.0[ ]*0x0*0[ ]*NT_VERSION \(version\)
#pass #pass