blob: 15c0361b5d6074be4481c4db9aa8649b3f4dfc14 [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{
25 if (WIFSTOPPED(status) && WSTOPSIG(status)==SIGTRAP) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020026 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, 4*ORIG_EAX, 0);
Juan Cespedes35d70631998-03-15 14:05:40 +010027 if (*sysnum>=0) {
28 if (proc->current_syscall!=*sysnum) {
29 return 1;
30 } else {
31 return 2;
32 }
Juan Cespedesf0fdae91998-03-11 00:03:00 +010033 }
34 }
Juan Cespedes35d70631998-03-15 14:05:40 +010035 return 0;
Juan Cespedes5e01f651998-03-08 22:31:44 +010036}
37
38void continue_after_breakpoint(struct process *proc, struct breakpoint * sbp, int delete_it)
39{
40 delete_breakpoint(proc->pid, sbp);
41 ptrace(PTRACE_POKEUSER, proc->pid, 4*EIP, sbp->addr);
42 if (delete_it) {
43 continue_process(proc->pid);
44 } else {
45 proc->breakpoint_being_enabled = sbp;
46 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
47 }
48}
49
50long gimme_arg(enum tof type, struct process * proc, int arg_num)
51{
52 if (arg_num==-1) { /* return value */
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020053 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EAX, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010054 }
55
56 if (type==LT_TOF_FUNCTION) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020057 return ptrace(PTRACE_PEEKTEXT, proc->pid, proc->stack_pointer+4*(arg_num+1), 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010058 } else if (type==LT_TOF_SYSCALL) {
59#if 0
60 switch(arg_num) {
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020061 case 0: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EBX, 0);
62 case 1: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ECX, 0);
63 case 2: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDX, 0);
64 case 3: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*ESI, 0);
65 case 4: return ptrace(PTRACE_PEEKUSER, proc->pid, 4*EDI, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010066 default:
67 fprintf(stderr, "gimme_arg called with wrong arguments\n");
68 exit(2);
69 }
70#else
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020071 return ptrace(PTRACE_PEEKUSER, proc->pid, 4*arg_num, 0);
Juan Cespedes5e01f651998-03-08 22:31:44 +010072#endif
73 } else {
74 fprintf(stderr, "gimme_arg called with wrong arguments\n");
75 exit(1);
76 }
77
78 return 0;
79}
80
81int umovestr(struct process * proc, void * addr, int len, void * laddr)
82{
83 long a;
84 int i;
85 int offset=0;
86
87 while(offset<len) {
88 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
89 for(i=0; i<sizeof(long); i++) {
90 if (((char*)&a)[i] && offset+i < len) {
91 *(char *)(laddr+offset+i) = ((char*)&a)[i];
92 } else {
93 *(char *)(laddr+offset+i) = '\0';
94 return 0;
95 }
96 }
97 offset += sizeof(long);
98 }
99 *(char *)(laddr+offset) = '\0';
100 return 0;
101}