trace.c revision f1bfe203f5f1c0e11a614f9d593a68406f5cb47e
1#if HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include <sys/types.h> 6#include <sys/wait.h> 7#include <signal.h> 8#include <sys/ptrace.h> 9#include <asm/ptrace.h> 10 11#include "ltrace.h" 12 13#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 14# define PTRACE_PEEKUSER PTRACE_PEEKUSR 15#endif 16 17#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 18# define PTRACE_POKEUSER PTRACE_POKEUSR 19#endif 20 21/* Returns 1 if syscall, 2 if sysret, 0 otherwise. 22 */ 23#define SYSCALL_INSN 0x44000002 24int 25syscall_p(struct process * proc, int status, int * sysnum) { 26 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) { 27 int pc = ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_NIP, 0); 28 int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc-4, 0); 29 30 if (insn == SYSCALL_INSN) { 31 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_RO, 0); 32 if (proc->callstack_depth > 0 && 33 proc->callstack[proc->callstack_depth-1].is_syscall) { 34 return 2; 35 } 36 if (*sysnum >= 0 && *sysnum <= 255) { 37 return 1; 38 } 39 } 40 } 41 return 0; 42} 43 44long 45gimme_arg(enum tof type, struct process * proc, int arg_num) { 46 if (arg_num==-1) { /* return value */ 47 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*PT_R3, 0); 48 } 49 50 if (type==LT_TOF_FUNCTION || type==LT_TOF_SYSCALL) { 51 if (arg_num < 8) { 52 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*(arg_num+PT_R3), 0); 53 } else { 54 return ptrace(PTRACE_PEEKDATA, proc->pid, proc->stack_pointer+4*(arg_num-8), 0); /* Check */ 55 } 56 } else { 57 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 58 exit(1); 59 } 60 return 0; 61} 62