blob: 8577d0e78436f9a60adfe1769b3c235de6ca56a8 [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#include <sys/types.h>
2#include <sys/wait.h>
3#include <signal.h>
4#include <sys/ptrace.h>
5
6#include "ltrace.h"
7
8/* Returns syscall number if `pid' stopped because of a syscall.
9 * Returns -1 otherwise
10 */
Juan Cespedesf0fdae91998-03-11 00:03:00 +010011int syscall_p(struct process * proc, int status)
Juan Cespedes5e01f651998-03-08 22:31:44 +010012{
13 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
Juan Cespedesf0fdae91998-03-11 00:03:00 +010014 int tmp = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX);
15 if (tmp>=0 && proc->current_syscall!=tmp) {
16 return tmp;
17 }
18 }
19 return -1;
20}
21
22/* Returns syscall number if `pid' stopped because of a sysret.
23 * Returns -1 otherwise
24 */
25int sysret_p(struct process * proc, int status)
26{
27 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
28 int tmp = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX);
29 if (tmp>=0 && proc->current_syscall==tmp) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010030 return tmp;
31 }
32 }
33 return -1;
34}
35
36void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp, int delete_it)
37{
38 delete_breakpoint(proc->pid, sbp);
39 ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
40 if (delete_it) {
41 continue_process(proc->pid);
42 } else {
43 proc->breakpoint_being_enabled = sbp;
44 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
45 }
46}
47
48long gimme_arg(enum tof type, struct process * proc, int arg_num)
49{
50 if (arg_num==-1) { /* return value */
51 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX);
52 }
53
54 if (type==LT_TOF_FUNCTION) {
55 return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1));
56 } else if (type==LT_TOF_SYSCALL) {
57#if 0
58 switch(arg_num) {
59 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX);
60 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX);
61 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX);
62 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI);
63 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI);
64 default:
65 fprintf(stderr, "gimme_arg called with wrong arguments\n");
66 exit(2);
67 }
68#else
69 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num);
70#endif
71 } else {
72 fprintf(stderr, "gimme_arg called with wrong arguments\n");
73 exit(1);
74 }
75
76 return 0;
77}
78
79int umovestr(struct process * proc, void * addr, int len, void * laddr)
80{
81 long a;
82 int i;
83 int offset=0;
84
85 while(offset<len) {
86 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
87 for(i=0; i<sizeof(long); i++) {
88 if (((char*)&a)[i] && offset+i < len) {
89 *(char *)(laddr+offset+i) = ((char*)&a)[i];
90 } else {
91 *(char *)(laddr+offset+i) = '\0';
92 return 0;
93 }
94 }
95 offset += sizeof(long);
96 }
97 *(char *)(laddr+offset) = '\0';
98 return 0;
99}