Add Linux ptrace() tutorial

This commit is contained in:
Justine Tunney 2022-03-24 08:00:21 -07:00
parent 98909b1391
commit 3b9e66ecba
14 changed files with 1290 additions and 23 deletions

View file

@ -17,16 +17,73 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/sysv/consts/ptrace.h"
#include "libc/sysv/errfuns.h"
static const char *__ptrace_describe_request(int x) {
if (x == -1) return "-1";
if (x == PTRACE_TRACEME) return "PTRACE_TRACEME";
if (x == PTRACE_PEEKDATA) return "PTRACE_PEEKDATA";
if (x == PTRACE_GETFPREGS) return "PTRACE_GETFPREGS";
if (x == PTRACE_PEEKTEXT) return "PTRACE_PEEKTEXT";
if (x == PTRACE_POKEDATA) return "PTRACE_POKEDATA";
if (x == PTRACE_PEEKUSER) return "PTRACE_PEEKUSER";
if (x == PTRACE_POKETEXT) return "PTRACE_POKETEXT";
if (x == PTRACE_POKEUSER) return "PTRACE_POKEUSER";
if (x == PTRACE_GETREGS) return "PTRACE_GETREGS";
if (x == PTRACE_GETREGSET) return "PTRACE_GETREGSET";
if (x == PTRACE_SETFPREGS) return "PTRACE_SETFPREGS";
if (x == PTRACE_SETREGS) return "PTRACE_SETREGS";
if (x == PTRACE_SETREGSET) return "PTRACE_SETREGSET";
if (x == PTRACE_GETSIGINFO) return "PTRACE_GETSIGINFO";
if (x == PTRACE_SETSIGINFO) return "PTRACE_SETSIGINFO";
if (x == PTRACE_PEEKSIGINFO) return "PTRACE_PEEKSIGINFO";
if (x == PTRACE_GETSIGMASK) return "PTRACE_GETSIGMASK";
if (x == PTRACE_SETSIGMASK) return "PTRACE_SETSIGMASK";
if (x == PTRACE_SETOPTIONS) return "PTRACE_SETOPTIONS";
if (x == PTRACE_GETEVENTMSG) return "PTRACE_GETEVENTMSG";
if (x == PTRACE_CONT) return "PTRACE_CONT";
if (x == PTRACE_SINGLESTEP) return "PTRACE_SINGLESTEP";
if (x == PTRACE_SYSCALL) return "PTRACE_SYSCALL";
if (x == PTRACE_LISTEN) return "PTRACE_LISTEN";
if (x == PTRACE_KILL) return "PTRACE_KILL";
if (x == PTRACE_INTERRUPT) return "PTRACE_INTERRUPT";
if (x == PTRACE_ATTACH) return "PTRACE_ATTACH";
if (x == PTRACE_SEIZE) return "PTRACE_SEIZE";
if (x == PTRACE_SECCOMP_GET_FILTER) return "PTRACE_SECCOMP_GET_FILTER";
if (x == PTRACE_DETACH) return "PTRACE_DETACH";
return "PTRACE_WUT";
}
/**
* Traces process.
*
* @param request can be PTRACE_xxx
* @note de facto linux only atm
*/
long ptrace(int request, int pid, void *addr, void *data) {
/* TODO(jart): FreeBSD addr and data args are different */
if (request == -1) return einval(); /* see consts.sh */
return sys_ptrace(request, pid, addr, data);
long ptrace(int request, ...) {
// TODO(jart): FreeBSD addr and data args are different
int pid;
va_list va;
bool ispeek;
long rc, peek;
void *addr, *data;
va_start(va, request);
pid = va_arg(va, int);
addr = va_arg(va, void *);
data = va_arg(va, void *);
va_end(va);
if (request == -1) {
rc = einval(); /* see consts.sh */
} else {
ispeek = IsLinux() && request - 1u < 3;
if (ispeek) data = &peek;
rc = sys_ptrace(request, pid, addr, data);
if (rc != -1 && ispeek) rc = peek;
}
STRACE("ptrace(%s, %d, %p, %p) → %ld% m", __ptrace_describe_request(request),
pid, addr, data);
return rc;
}