* [RFC][PATCH] Add Solaris specific ELF note processing.
@ 2021-07-19 7:09 Libor Bukata
2021-07-28 9:14 ` Alan Modra
0 siblings, 1 reply; 4+ messages in thread
From: Libor Bukata @ 2021-07-19 7:09 UTC (permalink / raw)
To: binutils; +Cc: Libor Bukata
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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC][PATCH] Add Solaris specific ELF note processing.
2021-07-19 7:09 [RFC][PATCH] Add Solaris specific ELF note processing Libor Bukata
@ 2021-07-28 9:14 ` Alan Modra
2021-07-30 15:18 ` Libor Bukata
0 siblings, 1 reply; 4+ messages in thread
From: Alan Modra @ 2021-07-28 9:14 UTC (permalink / raw)
To: Libor Bukata; +Cc: binutils
On Mon, Jul 19, 2021 at 07:09:47AM +0000, Libor Bukata via Binutils wrote:
> 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 *);
> +
Why did you add this? There is no place where it is defined as
anything other than NULL.
> /* 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
The above was not described or mentioned in a ChangeLog. Why do you
need this?
There are also rather a lot of formatting errors in the rest of the
patch.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Re: [RFC][PATCH] Add Solaris specific ELF note processing.
2021-07-28 9:14 ` Alan Modra
@ 2021-07-30 15:18 ` Libor Bukata
2021-09-30 7:08 ` Alan Modra
0 siblings, 1 reply; 4+ messages in thread
From: Libor Bukata @ 2021-07-30 15:18 UTC (permalink / raw)
To: Alan Modra; +Cc: binutils, Simon Marchi
[-- Attachment #1: Type: text/plain, Size: 2920 bytes --]
Hi Alan,
thank you for looking into it.
On 7/28/21 11:14 AM, Alan Modra wrote:
> On Mon, Jul 19, 2021 at 07:09:47AM +0000, Libor Bukata via Binutils wrote:
>> 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 *);
>> +
> Why did you add this? There is no place where it is defined as
> anything other than NULL.
Frankly speaking, I am not the original author of the patch but I
maintain, update, and refactor it on behalf of Oracle. I got the
approvals from Oracle to contribute it to binutils project. I removed
elf_backend_grok_lwpstatus since it is obviously not needed.
>
>> /* 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
> The above was not described or mentioned in a ChangeLog. Why do you
> need this?
Maybe it was required with older GDB versions. I removed it and
retested. Note that elfcore_make_note_pseudosection returns false only
in case of errors and the existence of a section is not considered an
error...
>
> There are also rather a lot of formatting errors in the rest of the
> patch.
>
I hopefully improved the code formatting (lines with at max 79
characters, aligned function arguments). Let me know if more work is
needed. Thanks.
Testing:
Solaris: Verified that general and float registers are loaded from core
files on both x86 and sparc.
Linux: No regressions in binutils unit tests. Loaded a core file
generated by GDB.
I have some issues with my email client, therefore, I attached the patch
instead of inlining the text.
I have a favor to ask you, could you please check the following auxv fix
from binutils side?
https://sourceware.org/pipermail/gdb-patches/2021-July/180967.html
I need an approval of AT_SUN_CAP_HW3 constant addition. Simon Marchi
approved GDB changes. Many thanks.
Regards,
Libor
[-- Attachment #2: 0001-bfd-Add-Solaris-specific-ELF-note-processing.patch --]
[-- Type: text/x-patch, Size: 11377 bytes --]
From 6dd9a6a1d8e1d6013efed97c3330417ca30a8f40 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>
* 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 | 10 +++
bfd/elf.c | 204 ++++++++++++++++++++++++++++++++++++++++++-
include/ChangeLog | 5 ++
include/elf/common.h | 23 +++++
4 files changed, 240 insertions(+), 2 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4dc3d685255..84af0079eba 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2021-07-16 Libor Bukata <libor.bukata@oracle.com>
+
+ * 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.c b/bfd/elf.c
index de5abafabf0..5d0be59a2ed 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -11083,6 +11083,205 @@ 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 +12439,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/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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Re: [RFC][PATCH] Add Solaris specific ELF note processing.
2021-07-30 15:18 ` Libor Bukata
@ 2021-09-30 7:08 ` Alan Modra
0 siblings, 0 replies; 4+ messages in thread
From: Alan Modra @ 2021-09-30 7:08 UTC (permalink / raw)
To: Libor Bukata; +Cc: binutils, Simon Marchi
On Fri, Jul 30, 2021 at 05:18:40PM +0200, Libor Bukata wrote:
> I hopefully improved the code formatting (lines with at max 79 characters,
> aligned function arguments). Let me know if more work is needed. Thanks.
I've made a few more style/formatting fixes and now committed the
patch. Sorry for the long delay, your email got lost in my inbox.
> I have a favor to ask you, could you please check the following auxv fix
> from binutils side?
> https://sourceware.org/pipermail/gdb-patches/2021-July/180967.html
>
> I need an approval of AT_SUN_CAP_HW3 constant addition. Simon Marchi
> approved GDB changes. Many thanks.
OK, and it's completely fine by me for Simon or any of the gdb global
maintainers to OK patches like this in shared directories.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-09-30 7:08 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-19 7:09 [RFC][PATCH] Add Solaris specific ELF note processing Libor Bukata
2021-07-28 9:14 ` Alan Modra
2021-07-30 15:18 ` Libor Bukata
2021-09-30 7:08 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).