Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/linux/linux_ptrace.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
#define LINUX_PTRACE_GETREGS 12 | #define LINUX_PTRACE_GETREGS 12 | ||||
#define LINUX_PTRACE_SETREGS 13 | #define LINUX_PTRACE_SETREGS 13 | ||||
#define LINUX_PTRACE_GETFPREGS 14 | #define LINUX_PTRACE_GETFPREGS 14 | ||||
#define LINUX_PTRACE_SETFPREGS 15 | #define LINUX_PTRACE_SETFPREGS 15 | ||||
#define LINUX_PTRACE_ATTACH 16 | #define LINUX_PTRACE_ATTACH 16 | ||||
#define LINUX_PTRACE_DETACH 17 | #define LINUX_PTRACE_DETACH 17 | ||||
#define LINUX_PTRACE_SYSCALL 24 | #define LINUX_PTRACE_SYSCALL 24 | ||||
#define LINUX_PTRACE_SETOPTIONS 0x4200 | #define LINUX_PTRACE_SETOPTIONS 0x4200 | ||||
#define LINUX_PTRACE_GETSIGINFO 0x4202 | |||||
#define LINUX_PTRACE_GETREGSET 0x4204 | #define LINUX_PTRACE_GETREGSET 0x4204 | ||||
#define LINUX_PTRACE_SEIZE 0x4206 | #define LINUX_PTRACE_SEIZE 0x4206 | ||||
#define LINUX_PTRACE_O_TRACESYSGOOD 1 | #define LINUX_PTRACE_O_TRACESYSGOOD 1 | ||||
#define LINUX_PTRACE_O_TRACEFORK 2 | #define LINUX_PTRACE_O_TRACEFORK 2 | ||||
#define LINUX_PTRACE_O_TRACEVFORK 4 | #define LINUX_PTRACE_O_TRACEVFORK 4 | ||||
#define LINUX_PTRACE_O_TRACECLONE 8 | #define LINUX_PTRACE_O_TRACECLONE 8 | ||||
#define LINUX_PTRACE_O_TRACEEXEC 16 | #define LINUX_PTRACE_O_TRACEEXEC 16 | ||||
▲ Show 20 Lines • Show All 283 Lines • ▼ Show 20 Lines | linux_msg(td, "PTRACE_O_TRACEEXIT not implemented; " | ||||
"returning EINVAL"); | "returning EINVAL"); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
return (kern_ptrace(td, PT_SET_EVENT_MASK, pid, &mask, sizeof(mask))); | return (kern_ptrace(td, PT_SET_EVENT_MASK, pid, &mask, sizeof(mask))); | ||||
} | } | ||||
static int | static int | ||||
linux_ptrace_getsiginfo(struct thread *td, pid_t pid, l_ulong data) | |||||
{ | |||||
struct ptrace_lwpinfo lwpinfo; | |||||
l_siginfo_t l_siginfo; | |||||
int error, sig; | |||||
error = kern_ptrace(td, PT_LWPINFO, pid, &lwpinfo, sizeof(lwpinfo)); | |||||
if (error != 0) { | |||||
linux_msg(td, "PT_LWPINFO failed with error %d", error); | |||||
return (error); | |||||
} | |||||
if ((lwpinfo.pl_flags & PL_FLAG_SI) == 0) { | |||||
error = EINVAL; | |||||
linux_msg(td, "no PL_FLAG_SI, returning %d", error); | |||||
return (error); | |||||
} | |||||
sig = bsd_to_linux_signal(lwpinfo.pl_siginfo.si_signo); | |||||
siginfo_to_lsiginfo(&lwpinfo.pl_siginfo, &l_siginfo, sig); | |||||
error = copyout(&l_siginfo, (void *)data, sizeof(l_siginfo)); | |||||
return (error); | |||||
} | |||||
static int | |||||
linux_ptrace_getregs(struct thread *td, pid_t pid, void *data) | linux_ptrace_getregs(struct thread *td, pid_t pid, void *data) | ||||
{ | { | ||||
struct ptrace_lwpinfo lwpinfo; | struct ptrace_lwpinfo lwpinfo; | ||||
struct reg b_reg; | struct reg b_reg; | ||||
struct linux_pt_reg l_reg; | struct linux_pt_reg l_reg; | ||||
int error; | int error; | ||||
error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0); | error = kern_ptrace(td, PT_GETREGS, pid, &b_reg, 0); | ||||
▲ Show 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | linux_ptrace(struct thread *td, struct linux_ptrace_args *uap) | ||||
case LINUX_PTRACE_SYSCALL: | case LINUX_PTRACE_SYSCALL: | ||||
error = map_signum(uap->data, &sig); | error = map_signum(uap->data, &sig); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
error = kern_ptrace(td, PT_SYSCALL, pid, (void *)1, sig); | error = kern_ptrace(td, PT_SYSCALL, pid, (void *)1, sig); | ||||
break; | break; | ||||
case LINUX_PTRACE_SETOPTIONS: | case LINUX_PTRACE_SETOPTIONS: | ||||
error = linux_ptrace_setoptions(td, pid, uap->data); | error = linux_ptrace_setoptions(td, pid, uap->data); | ||||
break; | |||||
case LINUX_PTRACE_GETSIGINFO: | |||||
error = linux_ptrace_getsiginfo(td, pid, uap->data); | |||||
break; | break; | ||||
case LINUX_PTRACE_GETREGSET: | case LINUX_PTRACE_GETREGSET: | ||||
error = linux_ptrace_getregset(td, pid, uap->addr, uap->data); | error = linux_ptrace_getregset(td, pid, uap->addr, uap->data); | ||||
break; | break; | ||||
case LINUX_PTRACE_SEIZE: | case LINUX_PTRACE_SEIZE: | ||||
error = linux_ptrace_seize(td, pid, uap->addr, uap->data); | error = linux_ptrace_seize(td, pid, uap->addr, uap->data); | ||||
break; | break; | ||||
default: | default: | ||||
linux_msg(td, "ptrace(%ld, ...) not implemented; " | linux_msg(td, "ptrace(%ld, ...) not implemented; " | ||||
"returning EINVAL", uap->req); | "returning EINVAL", uap->req); | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } |