From 1449284bd80db7bb4cbe7fef21e1e8b753135af6 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 17 Oct 2016 15:29:43 +0100 Subject: 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. --- binutils/ChangeLog | 16 ++++ binutils/readelf.c | 144 ++++++++++++++++++++++-------- binutils/testsuite/binutils-all/readelf.n | 2 +- 3 files changed, 124 insertions(+), 38 deletions(-) (limited to 'binutils') diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 4f33ba0..ac2f1c5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,21 @@ 2016-10-17 Nick Clifton + * 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 + * readelf.c (get_dynamic_type): Add DT_SYMTAB_SHNDX. (get_machine_type): Add EM_CLOUDSHIELD, EM_COREA_1ST, EM_COREA_2ND, EM_OPEN8, EM_VIDEOCORE5, EM_56800EX, EM_BA1, EM_BA2, diff --git a/binutils/readelf.c b/binutils/readelf.c index 55b687f..cb46451 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -287,7 +287,7 @@ enum versioned_symbol_info symbol_public }; -static const char *get_symbol_version_string +static const char * get_symbol_version_string (FILE *file, int is_dynsym, const char *strtab, unsigned long int strtab_size, unsigned int si, Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info, @@ -556,7 +556,7 @@ print_symbol (int width, const char *symbol) return num_printed; } -/* Returns a pointer to a static buffer containing a printable version of +/* 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. */ @@ -2347,8 +2347,8 @@ get_machine_name (unsigned e_machine) case EM_OPEN8: return "Open8 8-bit RISC soft processor core"; case EM_VIDEOCORE5: return "Broadcom VideoCore V processor"; case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)"; - case EM_BA1: return "Beyond BA1 CPU architecture"; - case EM_BA2: return "Beyond BA2 CPU architecture"; + case EM_BA1 : return "Beyond BA1 CPU architecture"; + case EM_BA2 : return "Beyond BA2 CPU architecture"; case EM_XCORE: return "XMOS xCORE processor family"; case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family"; case EM_KM32: return "KM211 KM32 32-bit processor"; @@ -2356,12 +2356,12 @@ get_machine_name (unsigned e_machine) case EM_KMX16: return "KM211 KMX16 16-bit processor"; case EM_KMX8: return "KM211 KMX8 8-bit processor"; case EM_KVARC: return "KM211 KVARC processor"; - case EM_CDP: return "Paneve CDP architecture family"; + case EM_CDP : return "Paneve CDP architecture family"; case EM_COGE: return "Cognitive Smart Memory Processor"; case EM_COOL: return "Bluechip Systems CoolEngine"; case EM_NORC: return "Nanoradio Optimized RISC"; case EM_CSR_KALIMBA: return "CSR Kalimba architecture family"; - case EM_Z80: return "Zilog Z80"; + case EM_Z80 : return "Zilog Z80"; case EM_AMDGPU: return "AMD GPU architecture"; case EM_RISCV: return "RISC-V"; default: @@ -6279,7 +6279,7 @@ process_section_headers (FILE * file) static const char * get_group_flags (unsigned int flags) { - static char buff[32]; + static char buff[128]; if (flags == 0) return ""; @@ -10773,12 +10773,14 @@ print_dynamic_symbol (bfd_vma si, unsigned long hn) } static const char * -get_symbol_version_string (FILE *file, int is_dynsym, - const char *strtab, - unsigned long int strtab_size, - unsigned int si, Elf_Internal_Sym *psym, - enum versioned_symbol_info *sym_info, - unsigned short *vna_other) +get_symbol_version_string (FILE * file, + bfd_boolean is_dynsym, + const char * strtab, + unsigned long int strtab_size, + unsigned int si, + Elf_Internal_Sym * psym, + enum versioned_symbol_info * sym_info, + unsigned short * vna_other) { unsigned char data[2]; unsigned short vers_data; @@ -12182,7 +12184,7 @@ apply_relocations (void * file, const Elf_Internal_Shdr * section, unsigned char * start, bfd_size_type size, - void ** relocs_return, + void ** relocs_return, unsigned long * num_relocs_return) { Elf_Internal_Shdr * relsec; @@ -12238,6 +12240,9 @@ apply_relocations (void * file, is_rela = FALSE; 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); for (rp = relocs; rp < relocs + num_relocs; ++rp) @@ -15579,8 +15584,7 @@ print_core_note (Elf_Internal_Note *pnote) static const char * 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) { case NT_GNU_ABI_TAG: @@ -15592,16 +15596,19 @@ get_gnu_elf_note_type (unsigned e_type) case NT_GNU_GOLD_VERSION: return _("NT_GNU_GOLD_VERSION (gold version)"); default: - break; - } + { + static char buff[64]; - snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); - return buff; + snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type); + return buff; + } + } } static int print_gnu_note (Elf_Internal_Note *pnote) { + /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */ switch (pnote->type) { case NT_GNU_BUILD_ID: @@ -15675,6 +15682,42 @@ print_gnu_note (Elf_Internal_Note *pnote) printf ("\n"); } 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 (_("\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; @@ -16057,7 +16100,9 @@ print_ia64_vms_note (Elf_Internal_Note * pnote) If the value of namesz is zero, there is no name present. */ 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 * nt; @@ -16102,7 +16147,9 @@ process_note (Elf_Internal_Note * pnote) note type strings. */ 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")) return print_ia64_vms_note (pnote); @@ -16112,13 +16159,25 @@ process_note (Elf_Internal_Note * pnote) return print_stapsdt_note (pnote); else if (const_strneq (pnote->namedata, "CORE")) return print_core_note (pnote); - else - return 1; -} + 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; +} 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 * external; @@ -16128,15 +16187,26 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) if (length <= 0) return 0; - pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length, - _("notes")); + 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, + _("notes")); if (pnotes == NULL) return 0; external = pnotes; - printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"), - (unsigned long) offset, (unsigned long) length); + 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"), + (unsigned long) offset, (unsigned long) length); + printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size")); end = (char *) pnotes + length; @@ -16236,7 +16306,7 @@ process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length) inote.namedata = temp; } - res &= process_note (& inote); + res &= process_note (& inote, file, section); if (temp != NULL) { @@ -16265,9 +16335,9 @@ process_corefile_note_segments (FILE * file) i++, segment++) { if (segment->p_type == PT_NOTE) - res &= process_corefile_note_segment (file, - (bfd_vma) segment->p_offset, - (bfd_vma) segment->p_filesz); + res &= process_notes_at (file, NULL, + (bfd_vma) segment->p_offset, + (bfd_vma) segment->p_filesz); } return res; @@ -16368,9 +16438,9 @@ process_note_sections (FILE * file) { if (section->sh_type == SHT_NOTE) { - res &= process_corefile_note_segment (file, - (bfd_vma) section->sh_offset, - (bfd_vma) section->sh_size); + res &= process_notes_at (file, section, + (bfd_vma) section->sh_offset, + (bfd_vma) section->sh_size); n++; } diff --git a/binutils/testsuite/binutils-all/readelf.n b/binutils/testsuite/binutils-all/readelf.n index 7a44731..9c0f828 100644 --- a/binutils/testsuite/binutils-all/readelf.n +++ b/binutils/testsuite/binutils-all/readelf.n @@ -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 Version 1.0[ ]*0x0*0[ ]*NT_VERSION \(version\) #pass -- cgit v1.1