aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>1999-08-31 16:54:56 +0000
committerNick Clifton <nickc@redhat.com>1999-08-31 16:54:56 +0000
commit779fe533129b601b4a21b902364dd550eb8a1c6e (patch)
tree93d1d3f128fbb218fe8f02394bda189d8775283d /binutils
parent757acbc5935e66e1e03f27bc55e8bd72383c33eb (diff)
downloadgdb-779fe533129b601b4a21b902364dd550eb8a1c6e.zip
gdb-779fe533129b601b4a21b902364dd550eb8a1c6e.tar.gz
gdb-779fe533129b601b4a21b902364dd550eb8a1c6e.tar.bz2
Apply patch from Scott Bambrough to display the contents of a NOTES segment
in a core file.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog12
-rw-r--r--binutils/binutils.texi9
-rw-r--r--binutils/readelf.c178
3 files changed, 195 insertions, 4 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 1e22647..bfe7ee4 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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
diff --git a/binutils/binutils.texi b/binutils/binutils.texi
index 6fea836..7c83ac9 100644
--- a/binutils/binutils.texi
+++ b/binutils/binutils.texi
@@ -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
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0409506..ef33ea2 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -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);