blob: 047ae5130d513c3930d9a0b23b087fa46940dacc [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes5e01f651998-03-08 22:31:44 +01005#include <sys/types.h>
6#include <sys/wait.h>
7#include <signal.h>
8#include <sys/ptrace.h>
Juan Cespedes64c6dfb1998-07-14 13:49:47 +02009#include <asm/ptrace.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +010010
11#include "ltrace.h"
12
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020013#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
Juan Cespedes35d70631998-03-15 14:05:40 +010021/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
Juan Cespedes5e01f651998-03-08 22:31:44 +010022 */
Juan Cespedes35d70631998-03-15 14:05:40 +010023int syscall_p(struct process * proc, int status, int * sysnum)
Juan Cespedes5e01f651998-03-08 22:31:44 +010024{
Juan Cespedes21c63a12001-07-07 20:56:56 +020025 static int syscall_active = 0;
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020026
Juan Cespedes5e01f651998-03-08 22:31:44 +010027 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020028 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
Juan Cespedes21c63a12001-07-07 20:56:56 +020029
30 if (proc->callstack_depth > 0 &&
31 proc->callstack[proc->callstack_depth-1].is_syscall) {
32 return 2;
33 }
34
Juan Cespedes35d70631998-03-15 14:05:40 +010035 if (*sysnum>=0) {
Juan Cespedes21c63a12001-07-07 20:56:56 +020036 return 1;
Juan Cespedesf0fdae91998-03-11 00:03:00 +010037 }
38 }
Juan Cespedes35d70631998-03-15 14:05:40 +010039 return 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +010040}
41
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020042void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp)
Juan Cespedes5e01f651998-03-08 22:31:44 +010043{
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020044 if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
Juan Cespedes5e01f651998-03-08 22:31:44 +010045 ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020046 if (sbp->enabled == 0) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010047 continue_process(proc->pid);
48 } else {
49 proc->breakpoint_being_enabled = sbp;
50 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
51 }
52}
53
54long gimme_arg(enum tof type, struct process * proc, int arg_num)
55{
56 if (arg_num==-1) { /* return value */
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020057 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010058 }
59
60 if (type==LT_TOF_FUNCTION) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020061 return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010062 } else if (type==LT_TOF_SYSCALL) {
63#if 0
64 switch(arg_num) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020065 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
66 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
67 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
68 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
69 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010070 default:
71 fprintf(stderr, "gimme_arg called with wrong arguments\n");
72 exit(2);
73 }
74#else
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020075 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010076#endif
77 } else {
78 fprintf(stderr, "gimme_arg called with wrong arguments\n");
79 exit(1);
80 }
81
82 return 0;
83}
84
85int umovestr(struct process * proc, void * addr, int len, void * laddr)
86{
87 long a;
88 int i;
89 int offset=0;
90
91 while(offset<len) {
92 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
93 for(i=0; i<sizeof(long); i++) {
94 if (((char*)&a)[i] && offset+i < len) {
95 *(char *)(laddr+offset+i) = ((char*)&a)[i];
96 } else {
97 *(char *)(laddr+offset+i) = '\0';
98 return 0;
99 }
100 }
101 offset += sizeof(long);
102 }
103 *(char *)(laddr+offset) = '\0';
104 return 0;
105}