aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2021-10-17 11:20:16 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2021-10-17 11:20:21 +0000
commitf9246e14848820664539763b72b6fdef408d20e4 (patch)
tree8c89a558f26dac851bfda834afa643e34af3955c
parent75a9d95b4d0a043ac0f3f8d1efc0982156337eac (diff)
downloadsrc-f9246e14848820664539763b72b6fdef408d20e4.tar.gz
src-f9246e14848820664539763b72b6fdef408d20e4.zip
linux: Implement some bits of PTRACE_PEEKUSER
This makes Linux gdb from Bionic a little less broken. Sponsored By: EPSRC Differential Revision: https://reviews.freebsd.org/D32455
-rw-r--r--sys/amd64/linux/linux_ptrace.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/sys/amd64/linux/linux_ptrace.c b/sys/amd64/linux/linux_ptrace.c
index a59702757972..39587ec9b2ad 100644
--- a/sys/amd64/linux/linux_ptrace.c
+++ b/sys/amd64/linux/linux_ptrace.c
@@ -97,6 +97,11 @@ __FBSDID("$FreeBSD$");
#define LINUX_PTRACE_SYSCALL_INFO_ENTRY 1
#define LINUX_PTRACE_SYSCALL_INFO_EXIT 2
+#define LINUX_PTRACE_PEEKUSER_ORIG_RAX 120
+#define LINUX_PTRACE_PEEKUSER_RIP 128
+#define LINUX_PTRACE_PEEKUSER_CS 136
+#define LINUX_PTRACE_PEEKUSER_DS 184
+
#define LINUX_ARCH_AMD64 0xc000003e
static int
@@ -286,9 +291,37 @@ linux_ptrace_peek(struct thread *td, pid_t pid, void *addr, void *data)
static int
linux_ptrace_peekuser(struct thread *td, pid_t pid, void *addr, void *data)
{
+ struct reg b_reg;
+ uint64_t val;
+ int error;
- linux_msg(td, "PTRACE_PEEKUSER not implemented; returning EINVAL");
- return (EINVAL);
+ error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0);
+ if (error != 0)
+ return (error);
+
+ switch ((uintptr_t)addr) {
+ case LINUX_PTRACE_PEEKUSER_ORIG_RAX:
+ val = b_reg.r_rax;
+ break;
+ case LINUX_PTRACE_PEEKUSER_RIP:
+ val = b_reg.r_rip;
+ break;
+ case LINUX_PTRACE_PEEKUSER_CS:
+ val = b_reg.r_cs;
+ break;
+ case LINUX_PTRACE_PEEKUSER_DS:
+ val = b_reg.r_ds;
+ break;
+ default:
+ linux_msg(td, "PTRACE_PEEKUSER offset %ld not implemented; "
+ "returning EINVAL", (uintptr_t)addr);
+ return (EINVAL);
+ }
+
+ error = copyout(&val, data, sizeof(val));
+ td->td_retval[0] = error;
+
+ return (error);
}
static int