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
This commit is contained in:
Edward Tomasz Napierala 2021-10-17 12:20:16 +01:00
parent 75a9d95b4d
commit f9246e1484

View file

@ -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