blob: 8df75d08c644090ead3736089eeb1da84b13c87c [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>
Juan Cespedes5c3fe062004-06-14 18:08:37 +02007#include "ptrace.h"
Juan Cespedes5e01f651998-03-08 22:31:44 +01008#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);
Juan Cespedes5c3fe062004-06-14 18:08:37 +020080 set_instruction_pointer(proc, sbp->addr);
Juan Cespedes8f8282f2002-03-03 18:58:40 +010081 if (sbp->enabled == 0) {
82 continue_process(proc->pid);
83 } else {
84 proc->breakpoint_being_enabled = sbp;
Juan Cespedes5c3fe062004-06-14 18:08:37 +020085#ifdef __sparc__
86 continue_process(proc->pid);
87#else
Juan Cespedes8f8282f2002-03-03 18:58:40 +010088 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0);
Juan Cespedes5c3fe062004-06-14 18:08:37 +020089#endif
Juan Cespedes8f8282f2002-03-03 18:58:40 +010090 }
91}
92
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010093int
94umovestr(struct process * proc, void * addr, int len, void * laddr) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +020095 union { long a; char c[sizeof(long)]; } a;
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010096 int i;
97 int offset=0;
98
99 while(offset<len) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200100 a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0);
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +0100101 for(i=0; i<sizeof(long); i++) {
Juan Cespedes5c3fe062004-06-14 18:08:37 +0200102 if (a.c[i] && offset+i < len) {
103 *(char *)(laddr+offset+i) = a.c[i];
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +0100104 } else {
105 *(char *)(laddr+offset+i) = '\0';
106 return 0;
107 }
108 }
109 offset += sizeof(long);
110 }
111 *(char *)(laddr+offset) = '\0';
112 return 0;
113}