Apply patch from Scott Bambrough to display the contents of a NOTES segment
authorNick Clifton <nickc@redhat.com>
Tue, 31 Aug 1999 16:54:56 +0000 (16:54 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 31 Aug 1999 16:54:56 +0000 (16:54 +0000)
in a core file.

binutils/ChangeLog
binutils/binutils.texi
binutils/readelf.c

index 1e22647bfb56e8f65cfe0edeb5c0f416470e401c..bfe7ee4dd3a47fe933918735dcdb6f4ddb898271 100644 (file)
@@ -1,3 +1,15 @@
+1999-08-31  Scott Bambrough <scottb@netwinder.org>
+
+       * readelf.c (get_note_type): New function:  Decode the e_type
+       value of a note.
+       (process_note): New function: Display the contents of a core note.
+       (process_corefile_note_segment): New function.
+       (process_corefile_note_segments): New function.
+       (process_corefile_contents): New function.
+       (process_arch_specific): Add call to process_corefile_contents.
+       (parse_args): Add parsing of -n/--notes command line switch.
+       (usage): Document new command line switch.
+
 1999-08-31  Ian Lance Taylor  <ian@zembu.com>
 
        * binutils.texi (Bug Reporting): Clarify that large files should
index 6fea8365dc22f3c26c6e93e2aae88935c8f83832..7c83ac93c63b41334f3254e34974d4d6e6c20264 100644 (file)
@@ -2360,6 +2360,7 @@ readelf [ -a | --all ]
         [ -S | --section-headers | --sections]
         [ -e | --headers]
         [ -s | --syms | --symbols]
+        [ -n | --notes]
         [ -r | --relocs]
         [ -d | --dynamic]
         [ -V | --version-info]
@@ -2388,7 +2389,8 @@ given.
 @itemx --all
 Equivalent to specifiying @samp{--file-header},
 @samp{--program-headers}, @samp{--sections}, @samp{--symbols},
-@samp{--relocs}, @samp{--dynamic} and @samp{--version-info}.
+@samp{--relocs}, @samp{--dynamic}, @samp{--notes} and
+@samp{--version-info}. 
 
 @item -h
 @itemx --file-header
@@ -2421,6 +2423,11 @@ Displays the entries in symbol table section of the file, if it has one.
 @itemx --headers
 Display all the headers in the file.  Equivalent to @samp{-h -l -S}.
 
+@item -n
+@itemx --notes
+@cindex ELF core notes
+Displays the contents of the NOTE segment, if it exists.
+
 @item -r
 @itemx --relocs
 @cindex ELF reloc information
index 040950602c5cc57b4f5cb158b0a94e1f71341070..ef33ea2dac607549f52dd5d2c53073cb2cdb1441 100644 (file)
@@ -114,6 +114,7 @@ int                     do_debug_lines;
 int                     do_debug_pubnames;
 int                     do_debug_aranges;
 int                     do_arch;
+int                     do_notes;
 int                    is_32bit_elf;
 
 /* A dynamic array of flags indicating which sections require dumping.  */
@@ -193,6 +194,11 @@ static const char *       get_elf_class               PARAMS ((unsigned char));
 static const char *       get_data_encoding           PARAMS ((unsigned char));
 static const char *       get_osabi_name              PARAMS ((unsigned char));
 static int               guess_is_rela               PARAMS ((unsigned long));
+static char *            get_note_type                  PARAMS ((unsigned int));
+static int               process_note                   PARAMS ((Elf_External_Note *));
+static int               process_corefile_note_segment  PARAMS ((FILE *, unsigned long, unsigned long));
+static int               process_corefile_note_segments PARAMS ((FILE *));
+static int               process_corefile_contents      PARAMS ((FILE *));
 
 typedef int Elf32_Word;
 
@@ -1335,6 +1341,7 @@ struct option options [] =
   {"symbols",          no_argument, 0, 's'},
   {"syms",             no_argument, 0, 's'},
   {"relocs",           no_argument, 0, 'r'},
+  {"notes",            no_argument, 0, 'n'},
   {"dynamic",          no_argument, 0, 'd'},
   {"arch-specific",    no_argument, 0, 'A'},
   {"version-info",     no_argument, 0, 'V'},
@@ -1363,6 +1370,7 @@ usage ()
   fprintf (stdout, _("                            Display the sections' header\n"));
   fprintf (stdout, _("  -e or --headers           Equivalent to: -h -l -S\n"));
   fprintf (stdout, _("  -s or --syms or --symbols Display the symbol table\n"));
+  fprintf (stdout, _("  -n or --notes             Display the core notes (if present)\n"));
   fprintf (stdout, _("  -r or --relocs            Display the relocations (if present)\n"));
   fprintf (stdout, _("  -d or --dynamic           Display the dynamic segment (if present)\n"));
   fprintf (stdout, _("  -V or --version-info      Display the version sections (if present)\n"));
@@ -1426,7 +1434,7 @@ parse_args (argc, argv)
     usage ();
 
   while ((c = getopt_long
-         (argc, argv, "ersahldSDAIw::x:i:vV", options, NULL)) != EOF)
+         (argc, argv, "ersahnldSDAIw::x:i:vV", options, NULL)) != EOF)
     {
       char *    cp;
       int      section;
@@ -1450,6 +1458,7 @@ parse_args (argc, argv)
          do_version ++;
          do_histogram ++;
          do_arch ++;
+         do_notes ++;
          break;
        case 'e':
          do_header ++;
@@ -1483,6 +1492,9 @@ parse_args (argc, argv)
        case 'I':
          do_histogram ++;
          break;
+       case 'n':
+         do_notes ++;
+         break;
        case 'x':
          do_dump ++;
          section = strtoul (optarg, & cp, 0);
@@ -1561,7 +1573,7 @@ parse_args (argc, argv)
 
   if (!do_dynamic && !do_syms && !do_reloc && !do_sections
       && !do_segments && !do_header && !do_dump && !do_version
-      && !do_histogram && !do_debugging && !do_arch)
+      && !do_histogram && !do_debugging && !do_arch && !do_notes)
     usage ();
   else if (argc < 3)
     {
@@ -6349,6 +6361,164 @@ process_mips_specific (file)
   return 1;
 }
 
+static char *
+get_note_type (e_type)
+     unsigned e_type;
+{
+  static char buff[64];
+  
+  switch (e_type)
+    {
+    case NT_PRSTATUS:  return _("NT_PRSTATUS (prstatus structure)");
+    case NT_FPREGSET:  return _("NT_FPREGSET (floating point registers)");
+    case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
+    case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
+    case NT_PSTATUS:   return _("NT_PSTATUS (pstatus structure)");
+    case NT_FPREGS:    return _("NT_FPREGS (floating point registers)");
+    case NT_PSINFO:    return _("NT_PSINFO (psinfo structure)");
+    case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
+    case NT_LWPSINFO:  return _("NT_LWPSINFO (lwpsinfo_t structure)");
+    default:
+      sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+      return buff;
+    }
+}
+
+static int
+process_note (pnote)
+  Elf_External_Note * pnote;
+{
+  Elf32_Internal_Note * internal;
+  char * pname;
+  
+  internal = (Elf32_Internal_Note *) pnote;
+  pname = malloc (internal->namesz + 1);
+  
+  if (pname == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  memcpy (pname, pnote->name, internal->namesz);
+  pname[internal->namesz] = '\0';
+
+  printf ("  %s\t\t0x%08lx\t%s\n", 
+         pname, internal->descsz, get_note_type (internal->type));
+          
+  free (pname);
+
+  return 1;
+}
+
+static int
+process_corefile_note_segment (file, offset, length)
+     FILE * file;
+     unsigned long offset;
+     unsigned long length;
+{
+  Elf_External_Note *  pnotes;
+  Elf_External_Note *  external;
+  Elf32_Internal_Note* internal;
+  unsigned int        notesz;
+  unsigned int         nlength;
+  unsigned char *      p;
+  int                  res = 1;
+  
+  if (length <= 0)
+    return 0;
+    
+  GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
+
+  external = pnotes; 
+  p = (unsigned char *) pnotes;
+  nlength = length;
+  printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length);
+  printf (_("  Owner\t\tData size\tDescription\n"));
+  
+  while (nlength > 0)
+    {
+      res &= process_note (external);
+      
+      internal = (Elf32_Internal_Note *) p;
+      notesz   = 3 * sizeof(unsigned long) + internal->namesz + internal->descsz;
+      nlength -= notesz;
+      p       += notesz;
+      external = (Elf_External_Note *) p;
+    }
+
+  free (pnotes);
+  
+  return res;
+}
+
+static int
+process_corefile_note_segments (file)
+     FILE * file;
+{
+  Elf_Internal_Phdr * program_headers;
+  Elf_Internal_Phdr * segment;
+  unsigned int       i;
+  int                 res = 1;
+  
+  program_headers = (Elf_Internal_Phdr *) malloc
+    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+  if (program_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  if (is_32bit_elf)
+    i = get_32bit_program_headers (file, program_headers);
+  else
+    i = get_64bit_program_headers (file, program_headers);
+
+  if (i == 0)
+    {
+      free (program_headers);
+      return 0;
+    }
+  
+  for (i = 0, segment = program_headers;
+       i < elf_header.e_phnum;
+       i ++, segment ++)
+    {
+      if (segment->p_type == PT_NOTE)
+       res &= process_corefile_note_segment (file, 
+                                             (unsigned long)segment->p_offset,
+                                             (unsigned long)segment->p_filesz);
+    }
+    
+  free (program_headers);
+
+  return res;
+}
+
+static int
+process_corefile_contents (file)
+     FILE * file;
+{
+  /* If we have not been asked to display the notes then do nothing.  */
+  if (! do_notes)
+    return 1;
+  
+  /* If file is not a core file then exit.  */
+  if (elf_header.e_type != ET_CORE)
+    return 1;
+    
+  /* No program headers means no NOTE segment.  */
+  if (elf_header.e_phnum == 0)
+    {
+      printf (_("No note segments present in the core file.\n"));
+      return 1;
+   }
+
+  return process_corefile_note_segments (file);
+}
+
 static int
 process_arch_specific (file)
      FILE * file;
@@ -6506,7 +6676,9 @@ process_file (file_name)
   process_version_sections (file);
 
   process_section_contents (file);
-
+  
+  process_corefile_contents (file);
+  
   process_arch_specific (file);
 
   fclose (file);