blob: a5728ed2c9f4e18d3e4ba8112b61e409c7d9cc9e [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#include <stdio.h>
Juan Cespedes1fe93d51998-03-13 00:29:21 +01002#include <string.h>
3#include <errno.h>
Juan Cespedes8f8282f2002-03-03 18:58:40 +01004#include <unistd.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01005#include <sys/types.h>
6#include <sys/ptrace.h>
7#include <asm/unistd.h>
8
9#include "ltrace.h"
10#include "options.h"
11
Juan Cespedes81690ef1998-03-13 19:31:29 +010012/* Returns 1 if the sysnum may make a new child to be created
13 * (ie, with fork() or clone())
14 * Returns 0 otherwise.
15 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010016int
17fork_p(int sysnum) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020018 return 0
19#if defined(__NR_fork)
20 || (sysnum == __NR_fork)
21#endif
22#if defined(__NR_clone)
23 || (sysnum == __NR_clone)
24#endif
25#if defined(__NR_vfork)
26 || (sysnum == __NR_vfork)
27#endif
28 ;
Juan Cespedes5e01f651998-03-08 22:31:44 +010029}
30
Juan Cespedes81690ef1998-03-13 19:31:29 +010031/* Returns 1 if the sysnum may make the process exec other program
32 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010033int
34exec_p(int sysnum) {
Juan Cespedes81690ef1998-03-13 19:31:29 +010035 return (sysnum == __NR_execve);
36}
37
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010038void
39trace_me(void) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010040 if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) {
41 perror("PTRACE_TRACEME");
42 exit(1);
43 }
44}
45
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010046int
47trace_pid(pid_t pid) {
Juan Cespedes1fe93d51998-03-13 00:29:21 +010048 if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010049 return -1;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010050 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010051 return 0;
52}
53
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010054void
55untrace_pid(pid_t pid) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010056 ptrace(PTRACE_DETACH, pid, 1, 0);
Juan Cespedes1fe93d51998-03-13 00:29:21 +010057}
58
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010059void
60continue_after_signal(pid_t pid, int signum) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010061 /* We should always trace syscalls to be able to control fork(), clone(), execve()... */
Juan Cespedes5916fda2002-02-25 00:19:21 +010062 ptrace(PTRACE_SYSCALL, pid, 0, signum);
Juan Cespedes5e01f651998-03-08 22:31:44 +010063}
64
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010065void
66continue_process(pid_t pid) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010067 continue_after_signal(pid, 0);
68}
69
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010070void
71continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020072 enable_breakpoint(pid, sbp);
Juan Cespedes5e01f651998-03-08 22:31:44 +010073 continue_process(pid);
74}
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010075
Juan Cespedes8f8282f2002-03-03 18:58:40 +010076void
77continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
78 if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
79 set_instruction_pointer(proc->pid, sbp->addr);
80 if (sbp->enabled == 0) {
81 continue_process(proc->pid);
82 } else {
83 proc->breakpoint_being_enabled = sbp;
84 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
85 }
86}
87
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010088int
89umovestr(struct process * proc, void * addr, int len, void * laddr) {
90 long a;
91 int i;
92 int offset=0;
93
94 while(offset<len) {
95 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
96 for(i=0; i<sizeof(long); i++) {
97 if (((char*)&a)[i] && offset+i < len) {
98 *(char *)(laddr+offset+i) = ((char*)&a)[i];
99 } else {
100 *(char *)(laddr+offset+i) = '\0';
101 return 0;
102 }
103 }
104 offset += sizeof(long);
105 }
106 *(char *)(laddr+offset) = '\0';
107 return 0;
108}