blob: 353eb87816c67f135d67fb7499140c0e85271755 [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>
Juan Cespedes64c6dfb1998-07-14 13:49:47 +02005#include <asm/ptrace.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01006
7#include "ltrace.h"
8
Juan Cespedes5e0acdb1998-04-04 08:34:07 +02009#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
10# define PTRACE_PEEKUSER PTRACE_PEEKUSR
11#endif
12
13#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
14# define PTRACE_POKEUSER PTRACE_POKEUSR
15#endif
16
Juan Cespedes35d70631998-03-15 14:05:40 +010017/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
Juan Cespedes5e01f651998-03-08 22:31:44 +010018 */
Juan Cespedes35d70631998-03-15 14:05:40 +010019int syscall_p(struct process * proc, int status, int * sysnum)
Juan Cespedes5e01f651998-03-08 22:31:44 +010020{
21 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020022 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
Juan Cespedes35d70631998-03-15 14:05:40 +010023 if (*sysnum>=0) {
24 if (proc->current_syscall!=*sysnum) {
25 return 1;
26 } else {
27 return 2;
28 }
Juan Cespedesf0fdae91998-03-11 00:03:00 +010029 }
30 }
Juan Cespedes35d70631998-03-15 14:05:40 +010031 return 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +010032}
33
34void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp, int delete_it)
35{
36 delete_breakpoint(proc->pid, sbp);
37 ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
38 if (delete_it) {
39 continue_process(proc->pid);
40 } else {
41 proc->breakpoint_being_enabled = sbp;
42 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
43 }
44}
45
46long gimme_arg(enum tof type, struct process * proc, int arg_num)
47{
48 if (arg_num==-1) { /* return value */
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020049 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010050 }
51
52 if (type==LT_TOF_FUNCTION) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020053 return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010054 } else if (type==LT_TOF_SYSCALL) {
55#if 0
56 switch(arg_num) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020057 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
58 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
59 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
60 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
61 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010062 default:
63 fprintf(stderr, "gimme_arg called with wrong arguments\n");
64 exit(2);
65 }
66#else
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020067 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010068#endif
69 } else {
70 fprintf(stderr, "gimme_arg called with wrong arguments\n");
71 exit(1);
72 }
73
74 return 0;
75}
76
77int umovestr(struct process * proc, void * addr, int len, void * laddr)
78{
79 long a;
80 int i;
81 int offset=0;
82
83 while(offset<len) {
84 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
85 for(i=0; i<sizeof(long); i++) {
86 if (((char*)&a)[i] && offset+i < len) {
87 *(char *)(laddr+offset+i) = ((char*)&a)[i];
88 } else {
89 *(char *)(laddr+offset+i) = '\0';
90 return 0;
91 }
92 }
93 offset += sizeof(long);
94 }
95 *(char *)(laddr+offset) = '\0';
96 return 0;
97}