This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Commit: Improve readelf's display of notes


Hi Yao,

>>   I am checking in the attached patch to improve readelf's display of
>>   notes.  The patch basically does three things:

> Where is the patch?

*sigh*  Here it is.  Sorry about forgetting it the first time. :-(

Cheers
  Nick

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  <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>
+
 	* 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 (_("<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;
@@ -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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]