Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106156929
D20152.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D20152.diff
View Options
Index: head/sys/amd64/linux/linux_ptrace.c
===================================================================
--- head/sys/amd64/linux/linux_ptrace.c
+++ head/sys/amd64/linux/linux_ptrace.c
@@ -131,6 +131,36 @@
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
@@ -164,6 +194,40 @@
}
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)
+{
+
+ l_regset->r15 = b_reg->r_r15;
+ l_regset->r14 = b_reg->r_r14;
+ l_regset->r13 = b_reg->r_r13;
+ l_regset->r12 = b_reg->r_r12;
+ l_regset->rbp = b_reg->r_rbp;
+ l_regset->rbx = b_reg->r_rbx;
+ l_regset->r11 = b_reg->r_r11;
+ l_regset->r10 = b_reg->r_r10;
+ l_regset->r9 = b_reg->r_r9;
+ l_regset->r8 = b_reg->r_r8;
+ l_regset->rax = b_reg->r_rax;
+ l_regset->rcx = b_reg->r_rcx;
+ l_regset->rdx = b_reg->r_rdx;
+ l_regset->rsi = b_reg->r_rsi;
+ l_regset->rdi = b_reg->r_rdi;
+ l_regset->orig_rax = b_reg->r_rax;
+ l_regset->rip = b_reg->r_rip;
+ l_regset->cs = b_reg->r_cs;
+ 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->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;
+}
+
+static void
map_regs_from_linux(struct reg *b_reg, struct linux_pt_reg *l_reg)
{
b_reg->r_r15 = l_reg->r15;
@@ -306,14 +370,75 @@
}
static int
+linux_ptrace_getregset_prstatus(struct thread *td, pid_t pid, l_ulong data)
+{
+ struct ptrace_lwpinfo lwpinfo;
+ struct reg b_reg;
+ struct linux_pt_regset l_regset;
+ struct iovec iov;
+ struct pcb *pcb;
+ unsigned long fsbase, gsbase;
+ size_t len;
+ int error;
+
+ error = copyin((const void *)data, &iov, sizeof(iov));
+ if (error != 0) {
+ printf("%s: copyin error %d\n", __func__, error);
+ return (error);
+ }
+
+ error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0);
+ if (error != 0)
+ return (error);
+
+ 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);
+
+ /*
+ * The strace(1) utility depends on RAX being set to -ENOSYS
+ * on syscall entry; otherwise it loops printing those:
+ *
+ * [ Process PID=928 runs in 64 bit mode. ]
+ * [ Process PID=928 runs in x32 mode. ]
+ */
+ error = kern_ptrace(td, PT_LWPINFO, pid, &lwpinfo, sizeof(lwpinfo));
+ if (error != 0) {
+ printf("%s: PT_LWPINFO failed with error %d\n",
+ __func__, error);
+ return (error);
+ }
+ if (lwpinfo.pl_flags & PL_FLAG_SCE)
+ l_regset.rax = -38; // XXX: Don't hardcode?
+
+ len = MIN(iov.iov_len, sizeof(l_regset));
+ error = copyout(&l_regset, (void *)iov.iov_base, len);
+ if (error != 0) {
+ printf("%s: copyout error %d\n", __func__, error);
+ return (error);
+ }
+
+ iov.iov_len -= len;
+ error = copyout(&iov, (void *)data, sizeof(iov));
+ if (error != 0) {
+ printf("%s: iov copyout error %d\n", __func__, error);
+ return (error);
+ }
+
+ return (error);
+}
+
+static int
linux_ptrace_getregset(struct thread *td, pid_t pid, l_ulong addr, l_ulong data)
{
switch (addr) {
case LINUX_NT_PRSTATUS:
- printf("%s: NT_PRSTATUS not implemented; returning EINVAL\n",
- __func__);
- return (EINVAL);
+ return (linux_ptrace_getregset_prstatus(td, pid, data));
default:
printf("%s: PTRACE_GETREGSET request %ld not implemented; "
"returning EINVAL\n", __func__, addr);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 27, 8:07 AM (10 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15612456
Default Alt Text
D20152.diff (3 KB)
Attached To
Mode
D20152: Support NT_PRSTATUS in Linux ptrace(2)
Attached
Detach File
Event Timeline
Log In to Comment