trace.c revision efe85f0668a077b1e851df4b3f87a380cf2269fd
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** Copyright (C) 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->callstack_depth > 0 &&
59					proc->callstack[proc->callstack_depth-1].is_syscall) {
60				return 2;
61			} else {
62				return 1;
63			}
64		}
65		else {
66			/* Unknown trap was encountered... */
67			return 0;
68		}
69	}
70	/* Unknown status... */
71	return 0;
72}
73
74long
75gimme_arg(enum tof type, struct process * proc, int arg_num) {
76	switch(arg_num) {
77		case -1: /* return value */
78			return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR2, 0);
79		case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_ORIGGPR2, 0);
80		case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR3, 0);
81		case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR4, 0);
82		case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR5, 0);
83		case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, PT_GPR6, 0);
84		default:
85				fprintf(stderr, "gimme_arg called with wrong arguments\n");
86				exit(2);
87	}
88}
89