blob: 797fc13a790e094cc02fcd8e6a547e4c1cc7ddb6 [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 Cespedes5e01f651998-03-08 22:31:44 +01004#include <sys/types.h>
5#include <sys/ptrace.h>
6#include <asm/unistd.h>
7
8#include "ltrace.h"
9#include "options.h"
10
Juan Cespedes81690ef1998-03-13 19:31:29 +010011/* Returns 1 if the sysnum may make a new child to be created
12 * (ie, with fork() or clone())
13 * Returns 0 otherwise.
14 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010015int
16fork_p(int sysnum) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020017 return 0
18#if defined(__NR_fork)
19 || (sysnum == __NR_fork)
20#endif
21#if defined(__NR_clone)
22 || (sysnum == __NR_clone)
23#endif
24#if defined(__NR_vfork)
25 || (sysnum == __NR_vfork)
26#endif
27 ;
Juan Cespedes5e01f651998-03-08 22:31:44 +010028}
29
Juan Cespedes81690ef1998-03-13 19:31:29 +010030/* Returns 1 if the sysnum may make the process exec other program
31 */
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010032int
33exec_p(int sysnum) {
Juan Cespedes81690ef1998-03-13 19:31:29 +010034 return (sysnum == __NR_execve);
35}
36
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010037void
38trace_me(void) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010039 if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) {
40 perror("PTRACE_TRACEME");
41 exit(1);
42 }
43}
44
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010045int
46trace_pid(pid_t pid) {
Juan Cespedes1fe93d51998-03-13 00:29:21 +010047 if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010048 return -1;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010049 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010050 return 0;
51}
52
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010053void
54untrace_pid(pid_t pid) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010055 ptrace(PTRACE_DETACH, pid, 1, 0);
Juan Cespedes1fe93d51998-03-13 00:29:21 +010056}
57
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010058void
59continue_after_signal(pid_t pid, int signum) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010060 /* We should always trace syscalls to be able to control fork(), clone(), execve()... */
Juan Cespedes5916fda2002-02-25 00:19:21 +010061 ptrace(PTRACE_SYSCALL, pid, 0, signum);
Juan Cespedes5e01f651998-03-08 22:31:44 +010062}
63
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010064void
65continue_process(pid_t pid) {
Juan Cespedes5e01f651998-03-08 22:31:44 +010066 continue_after_signal(pid, 0);
67}
68
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010069void
70continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) {
Juan Cespedes5b3ffdf2001-07-02 00:52:45 +020071 enable_breakpoint(pid, sbp);
Juan Cespedes5e01f651998-03-08 22:31:44 +010072 continue_process(pid);
73}
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010074
75int
76umovestr(struct process * proc, void * addr, int len, void * laddr) {
77 long a;
78 int i;
79 int offset=0;
80
81 while(offset<len) {
82 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
83 for(i=0; i<sizeof(long); i++) {
84 if (((char*)&a)[i] && offset+i < len) {
85 *(char *)(laddr+offset+i) = ((char*)&a)[i];
86 } else {
87 *(char *)(laddr+offset+i) = '\0';
88 return 0;
89 }
90 }
91 offset += sizeof(long);
92 }
93 *(char *)(laddr+offset) = '\0';
94 return 0;
95}