git: 7256167dfd80 - stable/13 - linux: refactor bsd_to_linux_regset() out of linux_ptrace.c

From: Edward Tomasz Napierala <trasz_at_FreeBSD.org>
Date: Mon, 21 Feb 2022 13:48:49 UTC
The branch stable/13 has been updated by trasz:

URL: https://cgit.FreeBSD.org/src/commit/?id=7256167dfd80bcbdbbe564a3e7348f09df6c4c7c

commit 7256167dfd80bcbdbbe564a3e7348f09df6c4c7c
Author:     Edward Tomasz Napierala <trasz@FreeBSD.org>
AuthorDate: 2021-05-21 06:22:25 +0000
Commit:     Edward Tomasz Napierala <trasz@FreeBSD.org>
CommitDate: 2022-02-21 12:46:06 +0000

    linux: refactor bsd_to_linux_regset() out of linux_ptrace.c
    
    This will be used for Linux coredump support.
    
    Sponsored By:   EPSRC
    Differential Revision:  https://reviews.freebsd.org/D30365
    
    (cherry picked from commit 95c19e1d65619624db4a7a21afc1685f122a05c1)
---
 sys/amd64/linux/linux.h             | 36 +++++++++++++++++++++++++++++
 sys/amd64/linux/linux_ptrace.c      | 46 ++++++-------------------------------
 sys/amd64/linux32/linux.h           | 26 +++++++++++++++++++++
 sys/amd64/linux32/linux32_machdep.c | 24 +++++++++++++++++++
 4 files changed, 93 insertions(+), 39 deletions(-)

diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h
index dc4986817d11..4e27fd51a72d 100644
--- a/sys/amd64/linux/linux.h
+++ b/sys/amd64/linux/linux.h
@@ -446,4 +446,40 @@ struct linux_robust_list_head {
 	l_uintptr_t			pending_list;
 };
 
+/* This corresponds to 'struct user_regs_struct' in Linux. */
+struct linux_pt_regset {
+	l_ulong	r15;
+	l_ulong	r14;
+	l_ulong	r13;
+	l_ulong	r12;
+	l_ulong	rbp;
+	l_ulong	rbx;
+	l_ulong	r11;
+	l_ulong	r10;
+	l_ulong	r9;
+	l_ulong	r8;
+	l_ulong	rax;
+	l_ulong	rcx;
+	l_ulong	rdx;
+	l_ulong	rsi;
+	l_ulong	rdi;
+	l_ulong	orig_rax;
+	l_ulong	rip;
+	l_ulong	cs;
+	l_ulong	eflags;
+	l_ulong	rsp;
+	l_ulong	ss;
+	l_ulong fs_base;
+	l_ulong gs_base;
+	l_ulong ds;
+	l_ulong es;
+	l_ulong fs;
+	l_ulong gs;
+};
+
+struct reg;
+
+void	bsd_to_linux_regset(struct reg *b_reg,
+	    struct linux_pt_regset *l_regset);
+
 #endif /* !_AMD64_LINUX_H_ */
diff --git a/sys/amd64/linux/linux_ptrace.c b/sys/amd64/linux/linux_ptrace.c
index 4557cea0502e..8fb87a8536b6 100644
--- a/sys/amd64/linux/linux_ptrace.c
+++ b/sys/amd64/linux/linux_ptrace.c
@@ -173,36 +173,6 @@ struct linux_pt_reg {
 	l_ulong	ss;
 };
 
-struct linux_pt_regset {
-	l_ulong	r15;
-	l_ulong	r14;
-	l_ulong	r13;
-	l_ulong	r12;
-	l_ulong	rbp;
-	l_ulong	rbx;
-	l_ulong	r11;
-	l_ulong	r10;
-	l_ulong	r9;
-	l_ulong	r8;
-	l_ulong	rax;
-	l_ulong	rcx;
-	l_ulong	rdx;
-	l_ulong	rsi;
-	l_ulong	rdi;
-	l_ulong	orig_rax;
-	l_ulong	rip;
-	l_ulong	cs;
-	l_ulong	eflags;
-	l_ulong	rsp;
-	l_ulong	ss;
-	l_ulong fs_base;
-	l_ulong gs_base;
-	l_ulong ds;
-	l_ulong es;
-	l_ulong fs;
-	l_ulong gs;
-};
-
 /*
  * Translate amd64 ptrace registers between Linux and FreeBSD formats.
  * The translation is pretty straighforward, for all registers but
@@ -235,9 +205,8 @@ map_regs_to_linux(struct reg *b_reg, struct linux_pt_reg *l_reg)
 	l_reg->ss = b_reg->r_ss;
 }
 
-static void
-map_regs_to_linux_regset(struct reg *b_reg, unsigned long fs_base,
-    unsigned long gs_base, struct linux_pt_regset *l_regset)
+void
+bsd_to_linux_regset(struct reg *b_reg, struct linux_pt_regset *l_regset)
 {
 
 	l_regset->r15 = b_reg->r_r15;
@@ -261,8 +230,8 @@ map_regs_to_linux_regset(struct reg *b_reg, unsigned long fs_base,
 	l_regset->eflags = b_reg->r_rflags;
 	l_regset->rsp = b_reg->r_rsp;
 	l_regset->ss = b_reg->r_ss;
-	l_regset->fs_base = fs_base;
-	l_regset->gs_base = gs_base;
+	l_regset->fs_base = 0;
+	l_regset->gs_base = 0;
 	l_regset->ds = b_reg->r_ds;
 	l_regset->es = b_reg->r_es;
 	l_regset->fs = b_reg->r_fs;
@@ -476,7 +445,6 @@ linux_ptrace_getregset_prstatus(struct thread *td, pid_t pid, l_ulong data)
 	struct linux_pt_regset l_regset;
 	struct iovec iov;
 	struct pcb *pcb;
-	unsigned long fsbase, gsbase;
 	size_t len;
 	int error;
 
@@ -493,10 +461,10 @@ linux_ptrace_getregset_prstatus(struct thread *td, pid_t pid, l_ulong data)
 	pcb = td->td_pcb;
 	if (td == curthread)
 		update_pcb_bases(pcb);
-	fsbase = pcb->pcb_fsbase;
-	gsbase = pcb->pcb_gsbase;
 
-	map_regs_to_linux_regset(&b_reg, fsbase, gsbase, &l_regset);
+	bsd_to_linux_regset(&b_reg, &l_regset);
+	l_regset.fs_base = pcb->pcb_fsbase;
+	l_regset.gs_base = pcb->pcb_gsbase;
 
 	error = kern_ptrace(td, PT_LWPINFO, pid, &lwpinfo, sizeof(lwpinfo));
 	if (error != 0) {
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 244daba4b5c0..286b9b52801c 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -630,4 +630,30 @@ struct linux_robust_list_head {
 	l_uintptr_t			pending_list;
 };
 
+/* This corresponds to 'struct user_regs_struct32' in Linux. */
+struct linux_pt_regset32 {
+	l_uint ebx;
+	l_uint ecx;
+	l_uint edx;
+	l_uint esi;
+	l_uint edi;
+	l_uint ebp;
+	l_uint eax;
+	l_uint ds;
+	l_uint es;
+	l_uint fs;
+	l_uint gs;
+	l_uint orig_eax;
+	l_uint eip;
+	l_uint cs;
+	l_uint eflags;
+	l_uint esp;
+	l_uint ss;
+};
+
+struct reg32;
+
+void	bsd_to_linux_regset32(struct reg32 *b_reg,
+	    struct linux_pt_regset32 *l_regset);
+
 #endif /* !_AMD64_LINUX_H_ */
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index ffb04daa852e..1cfda5d60e13 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 #include <machine/psl.h>
+#include <machine/reg.h>
 #include <machine/segments.h>
 #include <machine/specialreg.h>
 #include <x86/ifunc.h>
@@ -703,6 +704,29 @@ linux_set_thread_area(struct thread *td,
 	return (0);
 }
 
+void
+bsd_to_linux_regset32(struct reg32 *b_reg, struct linux_pt_regset32 *l_regset)
+{
+
+	l_regset->ebx = b_reg->r_ebx;
+	l_regset->ecx = b_reg->r_ecx;
+	l_regset->edx = b_reg->r_edx;
+	l_regset->esi = b_reg->r_esi;
+	l_regset->edi = b_reg->r_edi;
+	l_regset->ebp = b_reg->r_ebp;
+	l_regset->eax = b_reg->r_eax;
+	l_regset->ds = b_reg->r_ds;
+	l_regset->es = b_reg->r_es;
+	l_regset->fs = b_reg->r_fs;
+	l_regset->gs = b_reg->r_gs;
+	l_regset->orig_eax = b_reg->r_eax;
+	l_regset->eip = b_reg->r_eip;
+	l_regset->cs = b_reg->r_cs;
+	l_regset->eflags = b_reg->r_eflags;
+	l_regset->esp = b_reg->r_esp;
+	l_regset->ss = b_reg->r_ss;
+}
+
 int futex_xchgl_nosmap(int oparg, uint32_t *uaddr, int *oldval);
 int futex_xchgl_smap(int oparg, uint32_t *uaddr, int *oldval);
 DEFINE_IFUNC(, int, futex_xchgl, (int, uint32_t *, int *))