[RFC][PATCH] Add Solaris specific ELF note processing.
Libor Bukata
libor.bukata@oracle.com
Mon Jul 19 07:09:47 GMT 2021
>From f22881a7543ae96a00d0b6d7c5183d4451af7a8d Mon Sep 17 00:00:00 2001
From: Libor Bukata <libor.bukata@oracle.com>
Date: Wed, 14 Jul 2021 11:53:56 +0200
Subject: [PATCH] [bfd] Add Solaris specific ELF note processing.
Added elfcore_grok_solaris_note function that enables to
obtain process status, register values, and program info
from Solaris's core files.
Tested on Solaris x86_64/sparcv9 and Linux x86_64.
bfd/ChangeLog:
2021-07-16 Libor Bukata <libor.bukata@oracle.com>
* elf-bfd.h (elf_backend_grok_lwpstatus): Added function.
* elfxx-target.h (elf_backend_data): Updated ELF backend data.
* bfd/elf.c (elfcore_grok_solaris_note): Solaris specific ELF
note parser. Better GDB's coredump analysis on Solaris...
(elfcore_grok_solaris_note_impl): New function.
(elfcore_grok_solaris_prstatus): New function.
(elfcore_grok_solaris_info): New function.
(elfcore_grok_solaris_lwpstatus): New function.
(elf_parse_notes): Added "CORE" groker element.
include/ChangeLog:
2021-07-16 Libor Bukata <libor.bukata@oracle.com>
* include/elf/common.h: Note segment constants
for core files on Solaris systems.
---
bfd/ChangeLog | 12 +++
bfd/elf-bfd.h | 5 ++
bfd/elf.c | 203 ++++++++++++++++++++++++++++++++++++++++++-
bfd/elfxx-target.h | 4 +
include/ChangeLog | 5 ++
include/elf/common.h | 23 +++++
6 files changed, 249 insertions(+), 3 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4dc3d685255..18098dc0f0d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2021-07-16 Libor Bukata <libor.bukata@oracle.com>
+
+ * elf-bfd.h (elf_backend_grok_lwpstatus): Added function.
+ * elfxx-target.h (elf_backend_data): Updated ELF backend data.
+ * bfd/elf.c (elfcore_grok_solaris_note): Solaris specific ELF
+ note parser. Better GDB's coredump analysis on Solaris...
+ (elfcore_grok_solaris_note_impl): New function.
+ (elfcore_grok_solaris_prstatus): New function.
+ (elfcore_grok_solaris_info): New function.
+ (elfcore_grok_solaris_lwpstatus): New function.
+ (elf_parse_notes): Added "CORE" groker element.
+
2021-07-10 Alan Modra <amodra@gmail.com>
* dwarf2.c (read_address): Remove accidental commit.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b3f56b8c2ce..2427fcb1414 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1377,6 +1377,11 @@ struct elf_backend_data
bool (*elf_backend_grok_freebsd_prstatus)
(bfd *, Elf_Internal_Note *);
+ /* This function, if defined, is called when a "Solaris" NT_LWPSTATUS
+ note is found in a core file. */
+ bool (*elf_backend_grok_lwpstatus)
+ (bfd *, Elf_Internal_Note *);
+
/* This function, if defined, is called to write a note to a corefile. */
char *(*elf_backend_write_core_note)
(bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
diff --git a/bfd/elf.c b/bfd/elf.c
index de5abafabf0..d39b4bd3b88 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9717,7 +9717,10 @@ elfcore_make_note_pseudosection (bfd *abfd,
static bool
elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
{
- return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+ asection *sect = bfd_get_section_by_name (abfd, ".reg2");
+ if (sect == NULL)
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+ return true;
}
/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
@@ -10365,6 +10368,9 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
#if defined (HAVE_LWPSTATUS_T)
case NT_LWPSTATUS:
+ if (bed->elf_backend_grok_lwpstatus)
+ if ((*bed->elf_backend_grok_lwpstatus) (abfd, note))
+ return true;
return elfcore_grok_lwpstatus (abfd, note);
#endif
@@ -11083,6 +11089,196 @@ elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
return true;
}
+/* Processes Solaris's process status note.
+ sig_off ~ offsetof(prstatus_t, pr_cursig)
+ pid_off ~ offsetof(prstatus_t, pr_pid)
+ lwpid_off ~ offsetof(prstatus_t, pr_who)
+ gregset_size ~ sizeof(gregset_t)
+ gregset_offset ~ offsetof(prstatus_t, pr_reg) */
+static bool
+elfcore_grok_solaris_prstatus (bfd *abfd, Elf_Internal_Note* note,
+ int sig_off, int pid_off, int lwpid_off, size_t gregset_size,
+ size_t gregset_offset)
+{
+ asection *sect = NULL;
+ elf_tdata (abfd)->core->signal =
+ bfd_get_16 (abfd, note->descdata + sig_off);
+ elf_tdata (abfd)->core->pid =
+ bfd_get_32 (abfd, note->descdata + pid_off);
+ elf_tdata (abfd)->core->lwpid =
+ bfd_get_32 (abfd, note->descdata + lwpid_off);
+
+ sect = bfd_get_section_by_name (abfd, ".reg");
+ if (sect != NULL)
+ sect->size = gregset_size;
+
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ gregset_size, note->descpos + gregset_offset);
+}
+
+/* Gets program and arguments from a core.
+ prog_off ~ offsetof(prpsinfo | psinfo_t, pr_fname)
+ comm_off ~ offsetof(prpsinfo | psinfo_t, pr_psargs) */
+static bool
+elfcore_grok_solaris_info(bfd *abfd, Elf_Internal_Note* note,
+ int prog_off, int comm_off)
+{
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + prog_off, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + comm_off, 80);
+
+ return true;
+}
+
+/* Processes Solaris's LWP status note.
+ gregset_size ~ sizeof(gregset_t)
+ gregset_off ~ offsetof(lwpstatus_t, pr_reg)
+ fpregset_size ~ sizeof(fpregset_t)
+ fpregset_off ~ offsetof(lwpstatus_t, pr_fpreg)
+*/
+static bool
+elfcore_grok_solaris_lwpstatus (bfd *abfd, Elf_Internal_Note* note,
+ size_t gregset_size, int gregset_off, size_t fpregset_size, int fpregset_off)
+{
+ asection *sect = NULL;
+ char reg2_section_name[16] = { 0 };
+ (void) snprintf (reg2_section_name, 16, "%s/%i", ".reg2",
+ elf_tdata (abfd)->core->lwpid);
+
+ /* offsetof(lwpstatus_t, pr_lwpid) */
+ elf_tdata (abfd)->core->lwpid =
+ bfd_get_32 (abfd, note->descdata + 4);
+ /* offsetof(lwpstatus_t, pr_cursig) */
+ elf_tdata (abfd)->core->signal =
+ bfd_get_16 (abfd, note->descdata + 12);
+
+ sect = bfd_get_section_by_name (abfd, ".reg");
+ if (sect != NULL)
+ {
+ sect->size = gregset_size;
+ }
+ else
+ {
+ if ((_bfd_elfcore_make_pseudosection (abfd, ".reg",
+ gregset_size, note->descpos + gregset_off)) != true)
+ return false;
+ }
+
+ sect = bfd_get_section_by_name (abfd, reg2_section_name);
+ if (sect != NULL)
+ {
+ sect->size = fpregset_size;
+ sect->filepos = note->descpos + fpregset_off;
+ sect->alignment_power = 2;
+ }
+ else
+ {
+ if ((_bfd_elfcore_make_pseudosection (abfd, ".reg2",
+ fpregset_size, note->descpos + fpregset_off)) != true)
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+elfcore_grok_solaris_note_impl (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (note == NULL)
+ return false;
+
+ /* core files are identified as 32- or 64-bit, SPARC or x86,
+ by the size of the descsz which matches the sizeof()
+ the type appropriate for that note type (e.g., prstatus_t for
+ SOLARIS_NT_PRSTATUS) for the corresponding architecture
+ on Solaris. The core file bitness may differ from the bitness of
+ gdb itself, so fixed values are used instead of sizeof().
+ Appropriate fixed offsets are also used to obtain data from
+ the note */
+
+ switch ((int) note->type)
+ {
+ case SOLARIS_NT_PRSTATUS:
+ switch (note->descsz)
+ {
+ case 508: /* sizeof(prstatus_t) SPARC 32-bit */
+ return elfcore_grok_solaris_prstatus(abfd, note, 136, 216, 308, 152, 356);
+ case 904: /* sizeof(prstatus_t) SPARC 64-bit */
+ return elfcore_grok_solaris_prstatus(abfd, note, 264, 360, 520, 304, 600);
+ case 432: /* sizeof(prstatus_t) Intel 32-bit */
+ return elfcore_grok_solaris_prstatus(abfd, note, 136, 216, 308, 76, 356);
+ case 824: /* sizeof(prstatus_t) Intel 64-bit */
+ return elfcore_grok_solaris_prstatus(abfd, note, 264, 360, 520, 224, 600);
+ default:
+ return true;
+ }
+
+ case SOLARIS_NT_PSINFO:
+ case SOLARIS_NT_PRPSINFO:
+ switch (note->descsz)
+ {
+ case 260: /* sizeof(prpsinfo_t) SPARC and Intel 32-bit */
+ return elfcore_grok_solaris_info(abfd, note, 84, 100);
+ case 328: /* sizeof(prpsinfo_t) SPARC and Intel 64-bit */
+ return elfcore_grok_solaris_info(abfd, note, 120, 136);
+ case 360: /* sizeof(psinfo_t) SPARC and Intel 32-bit */
+ return elfcore_grok_solaris_info(abfd, note, 88, 104);
+ case 440: /* sizeof(psinfo_t) SPARC and Intel 64-bit */
+ return elfcore_grok_solaris_info(abfd, note, 136, 152);
+ default:
+ return true;
+ }
+
+ case SOLARIS_NT_LWPSTATUS:
+ switch (note->descsz)
+ {
+ case 896: /* sizeof(lwpstatus_t) SPARC 32-bit */
+ return elfcore_grok_solaris_lwpstatus(abfd, note, 152, 344, 400, 496);
+ case 1392: /* sizeof(lwpstatus_t) SPARC 64-bit */
+ return elfcore_grok_solaris_lwpstatus(abfd, note, 304, 544, 544, 848);
+ case 800: /* sizeof(lwpstatus_t) Intel 32-bit */
+ return elfcore_grok_solaris_lwpstatus(abfd, note, 76, 344, 380, 420);
+ case 1296: /* sizeof(lwpstatus_t) Intel 64-bit */
+ return elfcore_grok_solaris_lwpstatus(abfd, note, 224, 544, 528, 768);
+ default:
+ return true;
+ }
+
+ case SOLARIS_NT_LWPSINFO:
+ /* sizeof(lwpsinfo_t) on 32- and 64-bit, respectively */
+ if (note->descsz == 128 || note->descsz == 152)
+ {
+ elf_tdata (abfd)->core->lwpid =
+ bfd_get_32 (abfd, note->descdata + 4);
+ }
+ else
+ {
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* For name starting with "CORE" this may be either a Solaris
+ core file or a gdb-generated core file. Do Solaris-specific
+ processing on selected note types first with
+ elfcore_grok_solaris_note(), then process the note
+ in elfcore_grok_note(). */
+static bool
+elfcore_grok_solaris_note (bfd *abfd, Elf_Internal_Note *note)
+{
+ if (! elfcore_grok_solaris_note_impl (abfd, note)) {
+ return false;
+ } else {
+ return elfcore_grok_note (abfd, note);
+ }
+}
+
static bool
elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
{
@@ -12240,10 +12436,11 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset,
GROKER_ELEMENT ("", elfcore_grok_note),
GROKER_ELEMENT ("FreeBSD", elfcore_grok_freebsd_note),
GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note),
- GROKER_ELEMENT ( "OpenBSD", elfcore_grok_openbsd_note),
+ GROKER_ELEMENT ("OpenBSD", elfcore_grok_openbsd_note),
GROKER_ELEMENT ("QNX", elfcore_grok_nto_note),
GROKER_ELEMENT ("SPU/", elfcore_grok_spu_note),
- GROKER_ELEMENT ("GNU", elfobj_grok_gnu_note)
+ GROKER_ELEMENT ("GNU", elfobj_grok_gnu_note),
+ GROKER_ELEMENT ("CORE", elfcore_grok_solaris_note)
};
#undef GROKER_ELEMENT
int i;
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 4c6b1f20340..edd337dfd7b 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -624,6 +624,9 @@
#ifndef elf_backend_grok_psinfo
#define elf_backend_grok_psinfo NULL
#endif
+#ifndef elf_backend_grok_lwpstatus
+#define elf_backend_grok_lwpstatus NULL
+#endif
#ifndef elf_backend_grok_freebsd_prstatus
#define elf_backend_grok_freebsd_prstatus NULL
#endif
@@ -875,6 +878,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_sort_relocs_p,
elf_backend_grok_prstatus,
elf_backend_grok_psinfo,
+ elf_backend_grok_lwpstatus,
elf_backend_grok_freebsd_prstatus,
elf_backend_write_core_note,
elf_backend_lookup_section_flags_hook,
diff --git a/include/ChangeLog b/include/ChangeLog
index 11001a3d1e3..b242eeb7df2 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-16 Libor Bukata <libor.bukata@oracle.com>
+
+ * include/elf/common.h: Note segment constants
+ for core files on Solaris systems.
+
2021-07-03 Nick Clifton <nickc@redhat.com>
* 2.37 release branch created.
diff --git a/include/elf/common.h b/include/elf/common.h
index 0d381f0d27b..7a00542cbdc 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -739,6 +739,29 @@
#define NT_OPENBSD_WCOOKIE 23
+/* Note segments for core files on Solaris systems. Note name
+ must start with "CORE". */
+#define SOLARIS_NT_PRSTATUS 1
+#define SOLARIS_NT_PRFPREG 2
+#define SOLARIS_NT_PRPSINFO 3
+#define SOLARIS_NT_PRXREG 4
+#define SOLARIS_NT_PLATFORM 5
+#define SOLARIS_NT_AUXV 6
+#define SOLARIS_NT_GWINDOWS 7
+#define SOLARIS_NT_ASRS 8
+#define SOLARIS_NT_LDT 9
+#define SOLARIS_NT_PSTATUS 10
+#define SOLARIS_NT_PSINFO 13
+#define SOLARIS_NT_PRCRED 14
+#define SOLARIS_NT_UTSNAME 15
+#define SOLARIS_NT_LWPSTATUS 16
+#define SOLARIS_NT_LWPSINFO 17
+#define SOLARIS_NT_PRPRIV 18
+#define SOLARIS_NT_PRPRIVINFO 19
+#define SOLARIS_NT_CONTENT 20
+#define SOLARIS_NT_ZONENAME 21
+#define SOLARIS_NT_PRCPUXREG 22
+
/* Note segments for core files on SPU systems. Note name
must start with "SPU/". */
--
2.31.1
More information about the Binutils
mailing list