Introduce a simple COREDUMP_MACHDEP_LWP_NOTES logic to provide machdep
API for injecting per-LWP notes into coredumps, and use it to append
PT_GETXSTATE note.

Since the XSTATE block uses the same format on i386 and amd64, the code
does not have to conditionalize between 32-bit and 64-bit ELF format
on that.  However, it does need to distinguish between 32-bit and 64-bit
PT_* values.  In order to do that, it reuses PT32_* constant already
present for ptrace(), and adds a matching PT64_GETXSTATE to satisfy
the cpp logic.
---
 sys/arch/amd64/include/ptrace.h | 16 ++++++++++++++++
 sys/arch/i386/include/ptrace.h  | 11 +++++++++++
 sys/kern/core_elf32.c           |  6 +++++-
 3 files changed, 32 insertions(+), 1 deletion(-)

/* CHANGED in v3:
 * added memset() on xstate to prevent leaking data
 */

diff --git a/sys/arch/amd64/include/ptrace.h b/sys/arch/amd64/include/ptrace.h
index 44b38d750f9c..a8338b32fa58 100644
--- a/sys/arch/amd64/include/ptrace.h
+++ b/sys/arch/amd64/include/ptrace.h
@@ -90,6 +90,22 @@
 int process_machdep_doxstate(struct lwp *, struct lwp *, struct uio *);
 int process_machdep_validxstate(struct proc *);
 
+#ifdef EXEC_ELF32
+#include <machine/netbsd32_machdep.h>
+#endif
+#define PT64_GETXSTATE         PT_GETXSTATE
+#define COREDUMP_MACHDEP_LWP_NOTES                                     \
+{                                                                      \
+       struct xstate xstate;                                           \
+       memset(&xstate, 0, sizeof(xstate));                             \
+       error = process_read_xstate(l, &xstate);                        \
+       if (error)                                                      \
+               return (error);                                         \
+       ELFNAMEEND(coredump_savenote)(ns,                               \
+           CONCAT(CONCAT(PT, ELFSIZE), _GETXSTATE), name, &xstate,     \
+           sizeof(xstate));                                            \
+}
+
 #endif /* _KERNEL */
 
 #ifdef _KERNEL_OPT
diff --git a/sys/arch/i386/include/ptrace.h b/sys/arch/i386/include/ptrace.h
index 41ad7a119f0b..c9ec102a12dc 100644
--- a/sys/arch/i386/include/ptrace.h
+++ b/sys/arch/i386/include/ptrace.h
@@ -159,6 +159,17 @@
        { DT_REG, N("xmmregs"), Pmachdep_xmmregs,                       \
          procfs_machdep_validxmmregs },
 
+#define COREDUMP_MACHDEP_LWP_NOTES                                     \
+{                                                                      \
+       struct xstate xstate;                                           \
+       memset(&xstate, 0, sizeof(xstate));                             \
+       error = process_read_xstate(l, &xstate);                        \
+       if (error)                                                      \
+               return (error);                                         \
+       ELFNAMEEND(coredump_savenote)(ns, PT_GETXSTATE, name, &xstate,  \
+           sizeof(xstate));                                            \
+}
+
 struct xmmregs;
 
 /* Functions used by both ptrace(2) and procfs. */
diff --git a/sys/kern/core_elf32.c b/sys/kern/core_elf32.c
index 5b69cab2ab74..ce90a1e44fa9 100644
--- a/sys/kern/core_elf32.c
+++ b/sys/kern/core_elf32.c
@@ -500,7 +500,11 @@ ELFNAMEEND(coredump_note)(struct lwp *l, struct note_state 
*ns)
 
        ELFNAMEEND(coredump_savenote)(ns, PT_GETFPREGS, name, &freg, freglen);
 #endif
-       /* XXX Add hook for machdep per-LWP notes. */
+
+#ifdef COREDUMP_MACHDEP_LWP_NOTES
+       COREDUMP_MACHDEP_LWP_NOTES
+#endif
+
        return (0);
 }
 
-- 
2.22.0

Reply via email to