/* ** S390 specific part of trace.c ** ** Other routines are in ../trace.c and need to be combined ** at link time with this code. ** ** S/390 version ** Copyright (C) 2001 IBM Poughkeepsie, IBM Corporation */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "ltrace.h" #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) # define PTRACE_PEEKUSER PTRACE_PEEKUSR #endif #if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) # define PTRACE_POKEUSER PTRACE_POKEUSR #endif void get_arch_dep(struct process *proc) { } /* Returns 1 if syscall, 2 if sysret, 0 otherwise. */ int syscall_p(struct process *proc, int status, int *sysnum) { long pswa; long svcinst; long svcno; long svcop; if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) { pswa = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0); svcinst = ptrace(PTRACE_PEEKTEXT, proc->pid, (char *)(pswa - 4), 0); svcop = (svcinst >> 8) & 0xFF; svcno = svcinst & 0xFF; *sysnum = svcno; if (*sysnum == -1) { return 0; } if (svcop == 0 && svcno == 1) { /* Breakpoint was hit... */ return 0; } if (svcop == 10 && *sysnum >= 0) { /* System call was encountered... */ if (proc->callstack_depth > 0 && proc->callstack[proc->callstack_depth - 1].is_syscall) { return 2; } else { return 1; } } else { /* Unknown trap was encountered... */ return 0; } } /* Unknown status... */ return 0; } long gimme_arg(enum tof type, struct process *proc, int arg_num) { switch (arg_num) { case -1: /* return value */ return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0); case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0); case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0); case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0); case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0); case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0); default: fprintf(stderr, "gimme_arg called with wrong arguments\n"); exit(2); } } void save_register_args(enum tof type, struct process *proc) { }