Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Date | Mon, 24 Feb 2003 15:05:14 +0100 (CET) | From | fcorneli@elis ... | Subject | [PATCH] ptrace PTRACE_READDATA/WRITEDATA, kernel 2.5.62 |
| |
Hi,
I ported some generic SunOS ptrace requests from my 2.4 exptrace kernel patch to the 2.5 tree. The PTRACE_READDATA/WRITEDATA requests have been available for a long time for the sparc architecture but I think they're also very useful on the i386 arch since PTRACE_PEEKDATA/POKEDATA are way too slow when handling large data blocks.
Frank.
diff -Nur linux-2.5.62.orig/arch/i386/kernel/ptrace.c linux-2.5.62/arch/i386/kernel/ptrace.c --- linux-2.5.62.orig/arch/i386/kernel/ptrace.c 2003-02-17 23:56:10.000000000 +0100 +++ linux-2.5.62/arch/i386/kernel/ptrace.c 2003-02-24 14:12:02.000000000 +0100 @@ -229,7 +229,7 @@ return 0; } -asmlinkage int sys_ptrace(long request, long pid, long addr, long data) +asmlinkage int sys_ptrace(long request, long pid, long addr, long data, long addr2) { struct task_struct *child; struct user * dummy = NULL; @@ -355,6 +355,34 @@ } break; + case PTRACE_READDATA: + case PTRACE_READTEXT: { + int res; + ret = 0; + res = ptrace_readdata(child, addr, (void *)addr2, data); + if (res == data) + break; + if (res >= 0) + ret = -EIO; + else + ret = res; + break; + } + + case PTRACE_WRITEDATA: + case PTRACE_WRITETEXT: { + int res; + ret = 0; + res = ptrace_writedata(child, (void *)addr2, addr, data); + if (res == data) + break; + if (res >= 0) + ret = -EIO; + else + ret = res; + break; + } + case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ long tmp; diff -Nur linux-2.5.62.orig/include/asm-i386/ptrace.h linux-2.5.62/include/asm-i386/ptrace.h --- linux-2.5.62.orig/include/asm-i386/ptrace.h 2003-02-17 23:55:51.000000000 +0100 +++ linux-2.5.62/include/asm-i386/ptrace.h 2003-02-24 13:54:33.000000000 +0100 @@ -53,6 +53,10 @@ #define PTRACE_GET_THREAD_AREA 25 #define PTRACE_SET_THREAD_AREA 26 +#define PTRACE_READDATA 27 +#define PTRACE_WRITEDATA 28 +#define PTRACE_READTEXT 29 +#define PTRACE_WRITETEXT 30 #ifdef __KERNEL__ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) ----------------------------------------------------------------------- Demo: #include <stdio.h> #include <stdlib.h> #include <sys/ptrace.h> #include <asm/ptrace.h> #include <sys/wait.h> #include <sched.h> #include <syscall.h> #include <errno.h> #define STACK_SIZE (1024*2)
#define DATA_SIZE (1024*64)
#ifndef __NR_ptrace5 #define __NR_ptrace5 __NR_ptrace #endif
// we need to pass 5 parameters to PTRACE_READDATA/WRITEDATA _syscall5 (int, ptrace5, int, request, pid_t, pid, void *, addr, void *, data, void *, addr2);
static int child_func(void *param); static volatile int go = 0; static char *common_data;
int main() { int status, pid, i; char *stack, *buf; stack = malloc(STACK_SIZE); common_data = malloc(DATA_SIZE); srand(0); for (i = 0; i < DATA_SIZE; i++) common_data[i] = (int)(255.0 * rand() / (RAND_MAX + 1.0)); pid = clone(child_func, stack + STACK_SIZE, SIGCHLD | CLONE_VM, NULL); ptrace(PTRACE_ATTACH, pid, NULL, NULL); waitpid(pid, &status, 0); go = 1; buf = malloc(DATA_SIZE); for (i = 0; i < DATA_SIZE; i++) buf[i] = '\0'; while (1) { ptrace(PTRACE_SYSCALL, pid, NULL, NULL); waitpid(pid, &status, 0); if (WIFEXITED(status)) exit(0); if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { printf("syscall: %d (EAX: %d)\n", (int)ptrace(PTRACE_PEEKUSER, pid, ORIG_EAX * 4, NULL), (int)ptrace(PTRACE_PEEKUSER, pid, EAX * 4, NULL)); if (ptrace5(PTRACE_READDATA, pid, common_data, (void *)DATA_SIZE, buf)) { perror("PTRACE_READDATA"); exit(1); } for (i = 0; i < DATA_SIZE; i++) if (buf[i] != common_data[i]) { fprintf(stderr, "PTRACE_READDATA error.\n"); exit(1); } } } } static int child_func(void *param) { while (!go) ; getpid(); getppid(); return 0; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |