blob: df00e59975977745991002d93b8a6120c3cb94da [file] [log] [blame]
Juan Cespedes5e01f651998-03-08 22:31:44 +01001#include <stdio.h>
Juan Cespedes504a3852003-02-04 23:24:38 +01002#include <stdlib.h>
Juan Cespedes1fe93d51998-03-13 00:29:21 +01003#include <string.h>
4#include <errno.h>
Juan Cespedes8f8282f2002-03-03 18:58:40 +01005#include <unistd.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01006#include <sys/types.h>
7#include <sys/ptrace.h>
8#include <asm/unistd.h>
9
10#include "ltrace.h"
11#include "options.h"
12
Juan Cespedes81690ef1998-03-13 19:31:29 +010013/* Returns 1 if the sysnum may make a new child to be created
14 * (ie, with fork() or clone())
15 * Returns 0 otherwise.
16 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010017int
18fork_p(int sysnum) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020019 return 0
20#if defined(__NR_fork)
21 || (sysnum == __NR_fork)
22#endif
23#if defined(__NR_clone)
24 || (sysnum == __NR_clone)
25#endif
26#if defined(__NR_vfork)
27 || (sysnum == __NR_vfork)
28#endif
29 ;
Juan Cespedes5e01f651998-03-08 22:31:44 +010030}
31
Juan Cespedes81690ef1998-03-13 19:31:29 +010032/* Returns 1 if the sysnum may make the process exec other program
33 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010034int
35exec_p(int sysnum) {
Juan Cespedes81690ef1998-03-13 19:31:29 +010036 return (sysnum == __NR_execve);
37}
38
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010039void
40trace_me(void) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010041 if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) {
42 perror("PTRACE_TRACEME");
43 exit(1);
44 }
45}
46
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010047int
48trace_pid(pid_t pid) {
Juan Cespedes1fe93d51998-03-13 00:29:21 +010049 if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010050 return -1;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010051 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010052 return 0;
53}
54
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010055void
56untrace_pid(pid_t pid) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010057 ptrace(PTRACE_DETACH, pid, 1, 0);
Juan Cespedes1fe93d51998-03-13 00:29:21 +010058}
59
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010060void
61continue_after_signal(pid_t pid, int signum) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010062 /* We should always trace syscalls to be able to control fork(), clone(), execve()... */
Juan Cespedes5916fda2002-02-25 00:19:21 +010063 ptrace(PTRACE_SYSCALL, pid, 0, signum);
Juan Cespedes5e01f651998-03-08 22:31:44 +010064}
65
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010066void
67continue_process(pid_t pid) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010068 continue_after_signal(pid, 0);
69}
70
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010071void
72continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020073 enable_breakpoint(pid, sbp);
Juan Cespedes5e01f651998-03-08 22:31:44 +010074 continue_process(pid);
75}
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010076
Juan Cespedes8f8282f2002-03-03 18:58:40 +010077void
78continue_after_breakpoint(struct process *proc, struct breakpoint * sbp) {
79 if (sbp->enabled) disable_breakpoint(proc->pid, sbp);
80 set_instruction_pointer(proc->pid, sbp->addr);
81 if (sbp->enabled == 0) {
82 continue_process(proc->pid);
83 } else {
84 proc->breakpoint_being_enabled = sbp;
85 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
86 }
87}
88
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010089int
90umovestr(struct process * proc, void * addr, int len, void * laddr) {
91 long a;
92 int i;
93 int offset=0;
94
95 while(offset<len) {
96 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
97 for(i=0; i<sizeof(long); i++) {
98 if (((char*)&a)[i] && offset+i < len) {
99 *(char *)(laddr+offset+i) = ((char*)&a)[i];
100 } else {
101 *(char *)(laddr+offset+i) = '\0';
102 return 0;
103 }
104 }
105 offset += sizeof(long);
106 }
107 *(char *)(laddr+offset) = '\0';
108 return 0;
109}