blob: fb862ad83778614ade44a2770546bff50cd1f1ca [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
Juan Cespedes5e0acdb1998-04-04 08:34:07 +02008#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
9# define PTRACE_PEEKUSER PTRACE_PEEKUSR
10#endif
11
12#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
13# define PTRACE_POKEUSER PTRACE_POKEUSR
14#endif
15
Juan Cespedes35d70631998-03-15 14:05:40 +010016/* Returns 1 if syscall, 2 if sysret, 0 otherwise.
Juan Cespedes5e01f651998-03-08 22:31:44 +010017 */
Juan Cespedes35d70631998-03-15 14:05:40 +010018int syscall_p(struct process * proc, int status, int * sysnum)
Juan Cespedes5e01f651998-03-08 22:31:44 +010019{
20 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020021 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
Juan Cespedes35d70631998-03-15 14:05:40 +010022 if (*sysnum>=0) {
23 if (proc->current_syscall!=*sysnum) {
24 return 1;
25 } else {
26 return 2;
27 }
Juan Cespedesf0fdae91998-03-11 00:03:00 +010028 }
29 }
Juan Cespedes35d70631998-03-15 14:05:40 +010030 return 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +010031}
32
33void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp, int delete_it)
34{
35 delete_breakpoint(proc->pid, sbp);
36 ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
37 if (delete_it) {
38 continue_process(proc->pid);
39 } else {
40 proc->breakpoint_being_enabled = sbp;
41 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
42 }
43}
44
45long gimme_arg(enum tof type, struct process * proc, int arg_num)
46{
47 if (arg_num==-1) { /* return value */
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020048 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010049 }
50
51 if (type==LT_TOF_FUNCTION) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020052 return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010053 } else if (type==LT_TOF_SYSCALL) {
54#if 0
55 switch(arg_num) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020056 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
57 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
58 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
59 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
60 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010061 default:
62 fprintf(stderr, "gimme_arg called with wrong arguments\n");
63 exit(2);
64 }
65#else
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020066 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010067#endif
68 } else {
69 fprintf(stderr, "gimme_arg called with wrong arguments\n");
70 exit(1);
71 }
72
73 return 0;
74}
75
76int umovestr(struct process * proc, void * addr, int len, void * laddr)
77{
78 long a;
79 int i;
80 int offset=0;
81
82 while(offset<len) {
83 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
84 for(i=0; i<sizeof(long); i++) {
85 if (((char*)&a)[i] && offset+i < len) {
86 *(char *)(laddr+offset+i) = ((char*)&a)[i];
87 } else {
88 *(char *)(laddr+offset+i) = '\0';
89 return 0;
90 }
91 }
92 offset += sizeof(long);
93 }
94 *(char *)(laddr+offset) = '\0';
95 return 0;
96}