trace.c revision 2d45b1a8e26a36a9f85dc49e721c4390ca93dc40
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/* syscall tracing protocol: ArmLinux 22 on the way in, ip is 0 23 on the way out, ip is non-zero 24*/ 25#define off_r0 0 26#define off_ip 48 27#define off_pc 60 28 29void get_arch_dep(struct process *proc) 30{ 31} 32 33/* Returns 1 if syscall, 2 if sysret, 0 otherwise. 34 */ 35int syscall_p(struct process *proc, int status, int *sysnum) 36{ 37 if (WIFSTOPPED(status) 38 && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 39 /* get the user's pc (plus 8) */ 40 int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); 41 /* fetch the SWI instruction */ 42 int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0); 43 44 *sysnum = insn & 0xFFFF; 45 /* if it is a syscall, return 1 or 2 */ 46 if ((insn & 0xFFFF0000) == 0xef900000) { 47 return ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 48 0) ? 2 : 1; 49 } 50 } 51 return 0; 52} 53 54long gimme_arg(enum tof type, struct process *proc, int arg_num) 55{ 56 if (arg_num == -1) { /* return value */ 57 return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0); 58 } 59 60 /* deal with the ARM calling conventions */ 61 if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { 62 if (arg_num < 4) { 63 return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 64 0); 65 } else { 66 return ptrace(PTRACE_PEEKDATA, proc->pid, 67 proc->stack_pointer + 4 * (arg_num - 4), 68 0); 69 } 70 } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { 71 if (arg_num < 5) { 72 return ptrace(PTRACE_PEEKUSER, proc->pid, 4 * arg_num, 73 0); 74 } else { 75 return ptrace(PTRACE_PEEKDATA, proc->pid, 76 proc->stack_pointer + 4 * (arg_num - 5), 77 0); 78 } 79 } else { 80 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 81 exit(1); 82 } 83 84 return 0; 85} 86 87void save_register_args(enum tof type, struct process *proc) 88{ 89} 90