2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <sys/param.h>
42 #include <machine/reg.h>
47 #if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
48 #include <linux/ptrace.h>
51 #if defined(LINUX) && defined(IA64)
52 #include <asm/ptrace_offsets.h>
57 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
58 #elif defined(HAVE_LINUX_PTRACE_H)
60 #include <linux/ptrace.h>
63 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
64 #include <sys/utsname.h>
65 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
67 #if defined(LINUX) && defined(SPARC)
71 #if !defined(__GLIBC__)
73 #include <linux/unistd.h>
75 #define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
77 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
81 __asm__ volatile ("or %%g0, %1, %%o0\n\t" \
82 "or %%g0, %2, %%o1\n\t" \
83 "or %%g0, %3, %%o2\n\t" \
84 "or %%g0, %4, %%o3\n\t" \
85 "or %%g0, %5, %%o4\n\t" \
86 "or %%g0, %6, %%g1\n\t" \
89 "or %%g0, %%o0, %0\n\t" \
90 "sub %%g0, %%o0, %0\n\t" \
93 : "0" ((long)(arg1)),"1" ((long)(arg2)), \
94 "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
95 "i" (__NR_##syscall) \
96 : "g1", "o0", "o1", "o2", "o3", "o4"); \
98 return (type) __res; \
103 static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
113 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
116 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
133 return a->tv_sec || a->tv_usec;
138 struct timeval *a, *b;
140 if (a->tv_sec < b->tv_sec
141 || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
143 if (a->tv_sec > b->tv_sec
144 || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
153 return tv->tv_sec + tv->tv_usec/1000000.0;
158 struct timeval *tv, *a, *b;
160 tv->tv_sec = a->tv_sec + b->tv_sec;
161 tv->tv_usec = a->tv_usec + b->tv_usec;
162 if (tv->tv_usec > 1000000) {
164 tv->tv_usec -= 1000000;
170 struct timeval *tv, *a, *b;
172 tv->tv_sec = a->tv_sec - b->tv_sec;
173 tv->tv_usec = a->tv_usec - b->tv_usec;
174 if (((long) tv->tv_usec) < 0) {
176 tv->tv_usec += 1000000;
182 struct timeval *tv, *a;
185 tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
186 tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
187 tv->tv_usec %= 1000000;
192 struct timeval *tv, *a;
195 tv->tv_usec = a->tv_usec * n;
196 tv->tv_sec = a->tv_sec * n + a->tv_usec / 1000000;
197 tv->tv_usec %= 1000000;
205 for (; xlat->str != NULL; xlat++)
206 if (xlat->val == val)
212 * Print entry in struct xlat table, if there.
215 printxval(xlat, val, dflt)
220 char *str = xlookup(xlat, val);
225 tprintf("%#x /* %s */", val, dflt);
229 * Interpret `xlat' as an array of flags
230 * print the entries whose bits are on in `flags'
231 * return # of flags printed.
234 addflags(xlat, flags)
240 for (n = 0; xlat->str; xlat++) {
241 if (xlat->val && (flags & xlat->val) == xlat->val) {
242 tprintf("|%s", xlat->str);
248 tprintf("|%#x", flags);
255 printflags(xlat, flags)
262 if (flags == 0 && xlat->val == 0) {
263 tprintf("%s", xlat->str);
268 for (n = 0; xlat->str; xlat++) {
269 if (xlat->val && (flags & xlat->val) == xlat->val) {
270 tprintf("%s%s", sep, xlat->str);
277 tprintf("%s%#x", sep, flags);
284 printnum(tcp, addr, fmt)
295 if (umove(tcp, addr, &num) < 0) {
296 tprintf("%#lx", addr);
304 static char path[MAXPATHLEN + 1];
310 char buf[2 * MAXPATHLEN + 1];
313 if (!strpbrk(str, "\"\'\\")) {
314 tprintf("\"%s\"", str);
317 for (s = buf; *str; str++) {
319 case '\"': case '\'': case '\\':
320 *s++ = '\\'; *s++ = *str; break;
326 tprintf("\"%s\"", buf);
334 if (umovestr(tcp, addr, MAXPATHLEN, path) < 0)
335 tprintf("%#lx", addr);
342 printpathn(tcp, addr, n)
347 if (umovestr(tcp, addr, n, path) < 0)
348 tprintf("%#lx", addr);
356 printstr(tcp, addr, len)
361 static unsigned char *str = NULL;
371 if ((str = malloc(max_strlen)) == NULL
372 || (outstr = malloc(2*max_strlen)) == NULL) {
373 fprintf(stderr, "printstr: no memory\n");
374 tprintf("%#lx", addr);
378 outend = outstr + max_strlen * 2 - 10;
381 if (umovestr(tcp, addr, n, (char *) str) < 0) {
382 tprintf("%#lx", addr);
387 n = MIN(len, max_strlen);
388 if (umoven(tcp, addr, n, (char *) str) < 0) {
389 tprintf("%#lx", addr);
398 for (i = 0; i < n; i++) {
400 if (len < 0 && c == '\0')
402 if (!isprint(c) && !isspace(c)) {
413 for (i = 0; i < n; i++) {
415 if (len < 0 && c == '\0')
417 sprintf(s, "\\x%02x", c);
424 for (i = 0; i < n; i++) {
426 if (len < 0 && c == '\0')
429 case '\"': case '\'': case '\\':
430 *s++ = '\\'; *s++ = c; break;
432 *s++ = '\\'; *s++ = 'f'; break;
434 *s++ = '\\'; *s++ = 'n'; break;
436 *s++ = '\\'; *s++ = 'r'; break;
438 *s++ = '\\'; *s++ = 't'; break;
440 *s++ = '\\'; *s++ = 'v'; break;
444 else if (i < n - 1 && isdigit(str[i + 1])) {
445 sprintf(s, "\\%03o", c);
449 sprintf(s, "\\%o", c);
460 if (i < len || (len < 0 && (i == n || s > outend))) {
461 *s++ = '.'; *s++ = '.'; *s++ = '.';
464 tprintf("%s", outstr);
468 dumpstr(tcp, addr, len)
473 static int strsize = -1;
474 static unsigned char *str;
475 static char outstr[80];
482 if ((str = malloc(len)) == NULL) {
483 fprintf(stderr, "dump: no memory\n");
489 if (umoven(tcp, addr, len, (char *) str) < 0)
492 for (i = 0; i < len; i += 16) {
494 sprintf(s, " | %05x ", i);
496 for (j = 0; j < 16; j++) {
500 sprintf(s, " %02x", str[i + j]);
504 *s++ = ' '; *s++ = ' '; *s++ = ' ';
507 *s++ = ' '; *s++ = ' ';
508 for (j = 0; j < 16; j++) {
512 if (isprint(str[i + j]))
520 tprintf("%s |\n", outstr);
524 #define PAGMASK (~(PAGSIZ - 1))
526 * move `len' bytes of data from process `pid'
527 * at address `addr' to our space at `laddr'
530 umoven(tcp, addr, len, laddr)
543 char x[sizeof(long)];
546 if (addr & (sizeof(long) - 1)) {
547 /* addr not a multiple of sizeof(long) */
548 n = addr - (addr & -sizeof(long)); /* residue */
549 addr &= -sizeof(long); /* residue */
551 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
553 if (started && (errno==EPERM || errno==EIO)) {
554 /* Ran into 'end of memory' - stupid "printpath" */
557 /* But if not started, we had a bogus address. */
558 perror("ptrace: umoven");
562 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
563 addr += sizeof(long), laddr += m, len -= m;
567 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
569 if (started && (errno==EPERM || errno==EIO)) {
570 /* Ran into 'end of memory' - stupid "printpath" */
573 perror("ptrace: umoven");
577 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
578 addr += sizeof(long), laddr += m, len -= m;
588 char x[sizeof(long)];
591 if (addr & (sizeof(long) - 1)) {
592 /* addr not a multiple of sizeof(long) */
593 n = addr - (addr & -sizeof(long)); /* residue */
594 addr &= -sizeof(long); /* residue */
596 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
601 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
602 addr += sizeof(long), laddr += m, len -= m;
606 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
611 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
612 addr += sizeof(long), laddr += m, len -= m;
618 n = MIN(len, PAGSIZ);
619 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
620 if (ptrace(PTRACE_READDATA, pid,
621 (char *) addr, len, laddr) < 0) {
622 perror("umoven: ptrace(PTRACE_READDATA, ...)");
634 #ifdef HAVE_MP_PROCFS
635 int fd = tcp->pfd_as;
639 lseek(fd, addr, SEEK_SET);
640 if (read(fd, laddr, len) == -1)
642 #endif /* USE_PROCFS */
648 * like `umove' but make the additional effort of looking
649 * for a terminating zero byte.
652 umovestr(tcp, addr, len, laddr)
659 #ifdef HAVE_MP_PROCFS
660 int fd = tcp->pfd_as;
664 /* Some systems (e.g. FreeBSD) can be upset if we read off the
665 end of valid memory, avoid this by trying to read up
666 to page boundaries. But we don't know what a page is (and
667 getpagesize(2) (if it exists) doesn't necessarily return
668 hardware page size). Assume all pages >= 1024 (a-historical
671 int page = 1024; /* How to find this? */
672 int move = page - (addr & (page - 1));
675 lseek(fd, addr, SEEK_SET);
678 if (move > left) move = left;
679 if ((move = read(fd, laddr, move)) == -1)
680 return left != len ? 0 : -1;
681 if (memchr (laddr, 0, move)) break;
687 #else /* !USE_PROCFS */
693 char x[sizeof(long)];
696 if (addr & (sizeof(long) - 1)) {
697 /* addr not a multiple of sizeof(long) */
698 n = addr - (addr & -sizeof(long)); /* residue */
699 addr &= -sizeof(long); /* residue */
701 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
703 if (started && (errno==EPERM || errno==EIO)) {
704 /* Ran into 'end of memory' - stupid "printpath" */
711 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
712 while (n & (sizeof(long) - 1))
713 if (u.x[n++] == '\0')
715 addr += sizeof(long), laddr += m, len -= m;
719 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
721 if (started && (errno==EPERM || errno==EIO)) {
722 /* Ran into 'end of memory' - stupid "printpath" */
729 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
730 for (i = 0; i < sizeof(long); i++)
734 addr += sizeof(long), laddr += m, len -= m;
736 #endif /* !USE_PROCFS */
742 #define PTRACE_WRITETEXT 101
743 #define PTRACE_WRITEDATA 102
750 uload(cmd, pid, addr, len, laddr)
761 n = MIN(len, PAGSIZ);
762 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
763 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
764 perror("uload: ptrace(PTRACE_WRITE, ...)");
776 char x[sizeof(long)];
779 if (cmd == PTRACE_WRITETEXT) {
780 peek = PTRACE_PEEKTEXT;
781 poke = PTRACE_POKETEXT;
784 peek = PTRACE_PEEKDATA;
785 poke = PTRACE_POKEDATA;
787 if (addr & (sizeof(long) - 1)) {
788 /* addr not a multiple of sizeof(long) */
789 n = addr - (addr & -sizeof(long)); /* residue */
790 addr &= -sizeof(long);
792 u.val = ptrace(peek, pid, (char *) addr, 0);
794 perror("uload: POKE");
797 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
798 if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
799 perror("uload: POKE");
802 addr += sizeof(long), laddr += m, len -= m;
805 if (len < sizeof(long))
806 u.val = ptrace(peek, pid, (char *) addr, 0);
807 memcpy(u.x, laddr, m = MIN(sizeof(long), len));
808 if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
809 perror("uload: POKE");
812 addr += sizeof(long), laddr += m, len -= m;
819 tload(pid, addr, len, laddr)
824 return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
828 dload(pid, addr, len, laddr)
834 return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
849 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
851 static int is_sun4m = -1;
854 /* Round up the usual suspects. */
855 if (is_sun4m == -1) {
856 if (uname(&name) < 0) {
857 perror("upeek: uname?");
860 is_sun4m = strcmp(name.machine, "sun4m") == 0;
862 extern struct xlat struct_user_offsets[];
865 for (x = struct_user_offsets; x->str; x++)
872 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
874 val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
875 if (val == -1 && errno) {
876 perror("upeek: ptrace(PTRACE_PEEKUSER, ... )");
883 #endif /* !USE_PROCFS */
893 if (upeek(tcp->pid, 4*EIP, &pc) < 0)
896 if (upeek(tcp->pid, PT_B0, &pc) < 0)
899 if (upeek(tcp->pid, 4*15, &pc) < 0)
901 #elif defined(POWERPC)
902 if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
905 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
908 if (upeek(tcp->pid, REG_PC, &pc) < 0)
911 if (upeek(tcp->pid, REG_EPC, &pc) < 0)
915 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
919 if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
921 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
929 * Return current program counter for `pid'
930 * Assumes PC is never 0xffffffff
934 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) {
935 perror("getpc: ptrace(PTRACE_GETREGS, ...)");
948 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
962 if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
963 tprintf("[????????] ");
966 tprintf("[%08lx] ", eip);
970 if (upeek(tcp->pid, PT_B0, &ip) < 0) {
971 tprintf("[????????] ");
974 tprintf("[%08lx] ", ip);
975 #elif defined(POWERPC)
978 if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0) {
979 tprintf ("[????????] ");
982 tprintf("[%08lx] ", pc);
986 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
987 tprintf ("[????????] ");
990 tprintf("[%08lx] ", pc);
994 if (upeek(tcp->pid, REG_PC, &pc) < 0) {
995 tprintf ("[????????] ");
998 tprintf("[%08lx] ", pc);
1001 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) {
1002 tprintf("[????????] ");
1005 tprintf("[%08lx] ", regs.r_pc);
1009 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1010 tprintf ("[????????] ");
1013 tprintf("[%08lx] ", pc);
1017 if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
1018 tprintf ("[????????] ");
1021 tprintf("[%08lx] ", pc);
1022 #endif /* !architecture */
1028 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) {
1029 perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1030 tprintf("[????????] ");
1033 tprintf("[%08x] ", regs.r_o7);
1038 tprintf("[????????] ");
1043 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
1044 tprintf("[%08x] ", regs.r_eip);
1045 #endif /* FREEBSD */
1057 /* We simply use the SunOS breakpoint code. */
1060 #define LOOPA 0x30800000 /* ba,a 0 */
1062 if (tcp->flags & TCB_BPTSET) {
1063 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1066 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
1067 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1070 tcp->baddr = regs.r_o7 + 8;
1072 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1074 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1079 * XXX - BRUTAL MODE ON
1080 * We cannot set a real BPT in the child, since it will not be
1081 * traced at the moment it will reach the trap and would probably
1082 * die with a core dump.
1083 * Thus, we are force our way in by taking out two instructions
1084 * and insert an eternal loop instead, in expectance of the SIGSTOP
1085 * generated by out PTRACE_ATTACH.
1086 * Of cause, if we evaporate ourselves in the middle of all this...
1089 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOPA);
1091 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1094 tcp->flags |= TCB_BPTSET;
1099 * Our strategy here is to replace the bundle that contained
1100 * the clone() syscall with a bundle of the form:
1102 * { 1: br 1b; br 1b; br 1b }
1104 * This ensures that the newly forked child will loop
1105 * endlessly until we've got a chance to attach to it.
1108 # define LOOP0 0x0000100000000017
1109 # define LOOP1 0x4000000000200000
1110 unsigned long addr, ipsr;
1114 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1116 if (upeek(pid, PT_CR_IIP, &addr) < 0)
1118 tcp->baddr = addr | ((ipsr >> 41) & 0x3); /* store "ri" in low two bits */
1121 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0, 0);
1122 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8, 0);
1124 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1129 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1130 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1132 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1135 tcp->flags |= TCB_BPTSET;
1140 #define LOOP 0x0000feeb
1141 #elif defined (M68K)
1142 #define LOOP 0x60fe0000
1143 #elif defined (ALPHA)
1144 #define LOOP 0xc3ffffff
1145 #elif defined (POWERPC)
1146 #define LOOP 0x0000feeb
1148 #define LOOP 0xEAFFFFFE
1150 #define LOOP 0x1000ffff
1152 #define LOOP 0xa7f40000 /* BRC 15,0 */
1154 #define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */
1156 #error unknown architecture
1159 if (tcp->flags & TCB_BPTSET) {
1160 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1164 if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
1166 #elif defined (M68K)
1167 if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
1169 #elif defined (ALPHA)
1173 #elif defined (MIPS)
1174 return -1; /* FIXME: I do not know what i do - Flo */
1175 #elif defined (POWERPC)
1176 if (upeek(tcp->pid, 4*PT_NIP, &tcp->baddr) < 0)
1179 if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
1182 if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1184 tcp->baddr &= ~0x03;
1186 #error unknown architecture
1189 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1190 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1192 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1195 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1197 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1200 tcp->flags |= TCB_BPTSET;
1207 #ifdef SPARC /* This code is slightly sparc specific */
1210 #define BPT 0x91d02001 /* ta 1 */
1211 #define LOOP 0x10800000 /* ba 0 */
1212 #define LOOPA 0x30800000 /* ba,a 0 */
1213 #define NOP 0x01000000
1215 static int loopdeloop[1] = {LOOPA};
1217 static int loopdeloop[2] = {LOOP, NOP};
1220 if (tcp->flags & TCB_BPTSET) {
1221 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1224 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
1225 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1228 tcp->baddr = regs.r_o7 + 8;
1229 if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1230 sizeof tcp->inst, (char *)tcp->inst) < 0) {
1231 perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1236 * XXX - BRUTAL MODE ON
1237 * We cannot set a real BPT in the child, since it will not be
1238 * traced at the moment it will reach the trap and would probably
1239 * die with a core dump.
1240 * Thus, we are force our way in by taking out two instructions
1241 * and insert an eternal loop in stead, in expectance of the SIGSTOP
1242 * generated by out PTRACE_ATTACH.
1243 * Of cause, if we evaporate ourselves in the middle of all this...
1245 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1246 sizeof loopdeloop, (char *) loopdeloop) < 0) {
1247 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1250 tcp->flags |= TCB_BPTSET;
1266 #elif defined(POWERPC)
1270 #elif defined(ALPHA)
1274 #endif /* architecture */
1277 /* Again, we borrow the SunOS breakpoint code. */
1278 if (!(tcp->flags & TCB_BPTSET)) {
1279 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1283 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1285 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1288 tcp->flags &= ~TCB_BPTSET;
1291 unsigned long addr, ipsr;
1296 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1298 if (upeek(pid, PT_CR_IIP, &addr) < 0)
1301 /* restore original bundle: */
1303 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
1304 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
1306 perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
1310 /* restore original "ri" in ipsr: */
1311 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
1313 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
1315 perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
1319 tcp->flags &= ~TCB_BPTSET;
1321 if (addr != (tcp->baddr & ~0x3)) {
1322 /* the breakpoint has not been reached yet. */
1324 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1329 #else /* !IA64 && ! SPARC */
1332 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1333 if (!(tcp->flags & TCB_BPTSET)) {
1334 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1338 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1340 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1343 tcp->flags &= ~TCB_BPTSET;
1346 if (upeek(tcp->pid, 4*EIP, &eip) < 0)
1348 if (eip != tcp->baddr) {
1349 /* The breakpoint has not been reached yet. */
1352 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1356 #elif defined(POWERPC)
1357 if (upeek(tcp->pid, 4*PT_NIP, &pc) < 0)
1359 if (pc != tcp->baddr) {
1360 /* The breakpoint has not been reached yet. */
1362 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1367 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
1369 if (pc != tcp->baddr) {
1370 /* The breakpoint has not been reached yet. */
1372 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1376 #elif defined(ALPHA)
1377 if (upeek(tcp->pid, REG_PC, &pc) < 0)
1379 if (pc != tcp->baddr) {
1380 /* The breakpoint has not been reached yet. */
1382 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1387 if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1390 if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1391 /* The breakpoint has not been reached yet. */
1393 fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1397 iaoq = tcp->baddr | 3;
1398 /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1399 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1400 * has no significant effect.
1402 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1403 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1405 #endif /* !SPARC && !IA64 */
1415 if (!(tcp->flags & TCB_BPTSET)) {
1416 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1419 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1420 sizeof tcp->inst, (char *) tcp->inst) < 0) {
1421 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
1424 tcp->flags &= ~TCB_BPTSET;
1428 * Since we don't have a single instruction breakpoint, we may have
1429 * to adjust the program counter after removing the our `breakpoint'.
1431 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
1432 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
1435 if ((regs.r_pc < tcp->baddr) ||
1436 (regs.r_pc > tcp->baddr + 4)) {
1437 /* The breakpoint has not been reached yet */
1440 "NOTE: PC not at bpt (pc %#x baddr %#x)\n",
1441 regs.r_pc, tcp->parent->baddr);
1444 if (regs.r_pc != tcp->baddr)
1446 fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
1447 regs.r_pc, tcp->baddr);
1449 regs.r_pc = tcp->baddr;
1450 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) {
1451 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
1461 #endif /* !USE_PROCFS */
1472 for (n = 0; n < sizeof *hdr; n += 4) {
1474 if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
1476 memcpy(((char *) hdr) + n, &res, 4);
1479 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
1480 hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
1481 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
1482 hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
1493 * Change `vfork' in a freshly exec'ed dynamically linked
1494 * executable's (internal) symbol table to plain old `fork'
1498 struct link_dynamic dyn;
1499 struct link_dynamic_2 ld;
1502 if (getex(pid, &hdr) < 0)
1507 if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
1508 fprintf(stderr, "Cannot read DYNAMIC\n");
1511 if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
1512 fprintf(stderr, "Cannot read link_dynamic_2\n");
1515 if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
1516 fprintf(stderr, "fixvfork: out of memory\n");
1519 if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1520 (int)ld.ld_symb_size, strtab) < 0)
1524 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1525 fprintf(stderr, "[symbol: %s]\n", cp);
1530 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
1531 if (strcmp(cp, "_vfork") == 0) {
1533 fprintf(stderr, "fixvfork: FOUND _vfork\n");
1534 strcpy(cp, "_fork");
1539 if (cp < strtab + ld.ld_symb_size)
1541 * Write entire symbol table back to avoid
1542 * memory alignment bugs in ptrace
1544 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
1545 (int)ld.ld_symb_size, strtab) < 0)