trace.c revision b1dd77d66f93eeaa6cbf8b101d3e9cf70981e000
1/* 2** S390 specific part of trace.c 3** 4** Other routines are in ../trace.c and need to be combined 5** at link time with this code. 6** 7** S/390 version 8** (C) Copyright 2001 IBM Poughkeepsie, IBM Corporation 9*/ 10 11#if HAVE_CONFIG_H 12#include "config.h" 13#endif 14 15#include <sys/types.h> 16#include <sys/wait.h> 17#include <signal.h> 18#include <sys/ptrace.h> 19#include <asm/ptrace.h> 20 21#include "ltrace.h" 22 23#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 24# define PTRACE_PEEKUSER PTRACE_PEEKUSR 25#endif 26 27#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 28# define PTRACE_POKEUSER PTRACE_POKEUSR 29#endif 30 31/* Returns 1 if syscall, 2 if sysret, 0 otherwise. 32 */ 33int 34syscall_p(struct process * proc, int status, int * sysnum) { 35 long pswa; 36 long svcinst; 37 long svcno; 38 long svcop; 39 40 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) { 41 42 pswa = ptrace(PTRACE_PEEKUSER, proc->pid, PT_PSWADDR, 0); 43 svcinst = ptrace(PTRACE_PEEKTEXT, proc->pid, (char *)(pswa-4),0); 44 svcop = (svcinst >> 8) & 0xFF; 45 svcno = svcinst & 0xFF; 46 47 *sysnum = svcno; 48 49 if (*sysnum == -1) { 50 return 0; 51 } 52 if (svcop == 0 && svcno == 1) { 53 /* Breakpoint was hit... */ 54 return 0; 55 } 56 if (svcop == 10 && *sysnum>=0) { 57 /* System call was encountered... */ 58 if (proc->current_syscall!=*sysnum) { 59 return 1; 60 } else { 61 return 2; 62 } 63 } 64 else { 65 /* Unknown trap was encountered... */ 66 return 0; 67 } 68 } 69 /* Unknown status... */ 70 return 0; 71} 72 73void 74continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) { 75 if (sbp->enabled) disable_breakpoint(proc->pid, sbp); 76 ptrace(PTRACE_POKEUSER, proc->pid, PT_PSWADDR, sbp->addr); 77 if (sbp->enabled == 0) { 78 continue_process(proc->pid); 79 } else { 80 proc->breakpoint_being_enabled = sbp; 81 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0); 82 } 83} 84 85long 86gimme_arg(enum tof type, struct process * proc, int arg_num) { 87 if (arg_num==-1) { /* return value */ 88 return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0); 89 } 90 91 if (type==LT_TOF_FUNCTION) { 92 switch(arg_num) { 93 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0); 94 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0); 95 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0); 96 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0); 97 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0); 98 default: 99 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 100 exit(2); 101 } 102 103 } else if (type==LT_TOF_SYSCALL) { 104 switch(arg_num) { 105 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0); 106 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0); 107 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0); 108 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0); 109 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0); 110 default: 111 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 112 exit(2); 113 } 114 } else { 115 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 116 exit(1); 117 } 118 119 return 0; 120} 121