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/syscall.h>
41 #include <sys/param.h>
47 #include <machine/reg.h>
52 #if defined(linux) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
53 #include <linux/ptrace.h>
56 #if defined(LINUX) && defined(IA64)
57 # include <asm/ptrace_offsets.h>
63 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
64 #elif defined(HAVE_LINUX_PTRACE_H)
66 # ifdef HAVE_STRUCT_IA64_FPREG
67 # define ia64_fpreg XXX_ia64_fpreg
69 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
70 # define pt_all_user_regs XXX_pt_all_user_regs
72 #include <linux/ptrace.h>
74 # undef pt_all_user_regs
77 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
78 #include <sys/utsname.h>
79 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
81 #if defined(LINUXSPARC)
83 # define fpq kernel_fpq
85 # define fpu kernel_fpu
93 # undef PTRACE_GETREGS
94 # define PTRACE_GETREGS PTRACE_GETREGS64
95 # undef PTRACE_SETREGS
96 # define PTRACE_SETREGS PTRACE_SETREGS64
99 #if !defined(__GLIBC__)
101 #include <linux/unistd.h>
103 #define _hack_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\
104 type5,arg5,syscall) \
105 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
109 __asm__ volatile ("or %%g0, %1, %%o0\n\t" \
110 "or %%g0, %2, %%o1\n\t" \
111 "or %%g0, %3, %%o2\n\t" \
112 "or %%g0, %4, %%o3\n\t" \
113 "or %%g0, %5, %%o4\n\t" \
114 "or %%g0, %6, %%g1\n\t" \
115 #if defined (SPARC64)
121 "or %%g0, %%o0, %0\n\t" \
122 "sub %%g0, %%o0, %0\n\t" \
125 : "0" ((long)(arg1)),"1" ((long)(arg2)), \
126 "2" ((long)(arg3)),"3" ((long)(arg4)),"4" ((long)(arg5)), \
127 "i" (__NR_##syscall) \
128 : "g1", "o0", "o1", "o2", "o3", "o4"); \
130 return (type) __res; \
135 static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,int,__addr2,ptrace)
145 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
148 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
167 return a->tv_sec || a->tv_usec;
172 struct timeval *a, *b;
174 if (a->tv_sec < b->tv_sec
175 || (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec))
177 if (a->tv_sec > b->tv_sec
178 || (a->tv_sec == b->tv_sec && a->tv_usec > b->tv_usec))
187 return tv->tv_sec + tv->tv_usec/1000000.0;
192 struct timeval *tv, *a, *b;
194 tv->tv_sec = a->tv_sec + b->tv_sec;
195 tv->tv_usec = a->tv_usec + b->tv_usec;
196 if (tv->tv_usec >= 1000000) {
198 tv->tv_usec -= 1000000;
204 struct timeval *tv, *a, *b;
206 tv->tv_sec = a->tv_sec - b->tv_sec;
207 tv->tv_usec = a->tv_usec - b->tv_usec;
208 if (((long) tv->tv_usec) < 0) {
210 tv->tv_usec += 1000000;
216 struct timeval *tv, *a;
219 tv->tv_usec = (a->tv_sec % n * 1000000 + a->tv_usec + n / 2) / n;
220 tv->tv_sec = a->tv_sec / n + tv->tv_usec / 1000000;
221 tv->tv_usec %= 1000000;
226 struct timeval *tv, *a;
229 tv->tv_usec = a->tv_usec * n;
230 tv->tv_sec = a->tv_sec * n + tv->tv_usec / 1000000;
231 tv->tv_usec %= 1000000;
235 xlookup(const struct xlat *xlat, int val)
237 for (; xlat->str != NULL; xlat++)
238 if (xlat->val == val)
244 * Print entry in struct xlat table, if there.
247 printxval(const struct xlat *xlat, int val, const char *dflt)
249 const char *str = xlookup(xlat, val);
254 tprintf("%#x /* %s */", val, dflt);
258 * Interpret `xlat' as an array of flags
259 * print the entries whose bits are on in `flags'
260 * return # of flags printed.
263 addflags(xlat, flags)
264 const struct xlat *xlat;
269 for (n = 0; xlat->str; xlat++) {
270 if (xlat->val && (flags & xlat->val) == xlat->val) {
271 tprintf("|%s", xlat->str);
277 tprintf("|%#x", flags);
284 * Interpret `xlat' as an array of flags/
285 * Print to static string the entries whose bits are on in `flags'
286 * Return static string.
289 sprintflags(const char *prefix, const struct xlat *xlat, int flags)
291 static char outstr[1024];
294 strcpy(outstr, prefix);
296 for (; xlat->str; xlat++) {
297 if ((flags & xlat->val) == xlat->val) {
300 strcat(outstr, xlat->str);
308 sprintf(outstr + strlen(outstr), "%#x", flags);
315 printflags(xlat, flags, dflt)
316 const struct xlat *xlat;
323 if (flags == 0 && xlat->val == 0) {
324 tprintf("%s", xlat->str);
329 for (n = 0; xlat->str; xlat++) {
330 if (xlat->val && (flags & xlat->val) == xlat->val) {
331 tprintf("%s%s", sep, xlat->str);
340 tprintf("%s%#x", sep, flags);
345 tprintf("%#x", flags);
347 tprintf(" /* %s */", dflt);
358 printnum(tcp, addr, fmt)
369 if (umove(tcp, addr, &num) < 0) {
370 tprintf("%#lx", addr);
379 printnum_int(tcp, addr, fmt)
390 if (umove(tcp, addr, &num) < 0) {
391 tprintf("%#lx", addr);
405 tprintf((uid == -1) ? "%ld" : "%lu", uid);
408 static char path[MAXPATHLEN + 1];
411 string_quote(const char *instr, char *outstr, int len, int size)
413 const unsigned char *ustr = (const unsigned char *) instr;
415 int usehex = 0, c, i;
420 for (i = 0; i < size; ++i) {
422 if (len < 0 && c == '\0')
424 if (!isprint(c) && !isspace(c)) {
434 for (i = 0; i < size; ++i) {
436 if (len < 0 && c == '\0')
438 sprintf(s, "\\x%02x", c);
442 for (i = 0; i < size; ++i) {
444 if (len < 0 && c == '\0')
447 case '\"': case '\\':
474 else if (i + 1 < size
475 && isdigit(ustr[i + 1])) {
476 sprintf(s, "\\%03o", c);
479 sprintf(s, "\\%o", c);
492 printpathn(struct tcb *tcp, long addr, int n)
494 if (n > sizeof path - 1)
503 if (umovestr(tcp, addr, n + 1, path) < 0)
504 tprintf("%#lx", addr);
506 static char outstr[4*(sizeof path - 1) + sizeof "\"...\""];
507 int trunc = (path[n] != '\0');
511 string_quote(path, outstr, -1, n);
513 strcat(outstr, "...");
514 tprintf("%s", outstr);
519 printpath(struct tcb *tcp, long addr)
521 printpathn(tcp, addr, sizeof path - 1);
525 printstr(struct tcb *tcp, long addr, int len)
527 static char *str = NULL;
536 if ((str = malloc(max_strlen + 1)) == NULL
537 || (outstr = malloc(4*max_strlen
538 + sizeof "\"\"...")) == NULL) {
539 fprintf(stderr, "out of memory\n");
540 tprintf("%#lx", addr);
546 size = max_strlen + 1;
547 if (umovestr(tcp, addr, size, str) < 0) {
548 tprintf("%#lx", addr);
553 size = MIN(len, max_strlen + 1);
554 if (umoven(tcp, addr, size, str) < 0) {
555 tprintf("%#lx", addr);
560 trunc = size > max_strlen && str[--size] != 0;
561 string_quote(str, outstr, len, size);
562 if (size < len || (len < 0 && trunc))
563 strcat(outstr, "...");
565 tprintf("%s", outstr);
570 dumpiov(tcp, len, addr)
575 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
577 struct { u_int32_t base; u_int32_t len; } *iov32;
578 struct { u_int64_t base; u_int64_t len; } *iov64;
580 #define iov iovu.iov64
582 (personality_wordsize[current_personality] == 4 \
583 ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
584 #define iov_iov_base(i) \
585 (personality_wordsize[current_personality] == 4 \
586 ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
587 #define iov_iov_len(i) \
588 (personality_wordsize[current_personality] == 4 \
589 ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
592 #define sizeof_iov sizeof(*iov)
593 #define iov_iov_base(i) iov[i].iov_base
594 #define iov_iov_len(i) iov[i].iov_len
599 size = sizeof_iov * (unsigned long) len;
600 if (size / sizeof_iov != len
601 || (iov = malloc(size)) == NULL) {
602 fprintf(stderr, "out of memory\n");
605 if (umoven(tcp, addr, size, (char *) iov) >= 0) {
606 for (i = 0; i < len; i++) {
607 /* include the buffer number to make it easy to
608 * match up the trace with the source */
609 tprintf(" * %lu bytes in buffer %d\n",
610 (unsigned long)iov_iov_len(i), i);
611 dumpstr(tcp, (long) iov_iov_base(i),
624 dumpstr(tcp, addr, len)
629 static int strsize = -1;
630 static unsigned char *str;
631 static char outstr[80];
638 if ((str = malloc(len)) == NULL) {
639 fprintf(stderr, "out of memory\n");
645 if (umoven(tcp, addr, len, (char *) str) < 0)
648 for (i = 0; i < len; i += 16) {
650 sprintf(s, " | %05x ", i);
652 for (j = 0; j < 16; j++) {
656 sprintf(s, " %02x", str[i + j]);
660 *s++ = ' '; *s++ = ' '; *s++ = ' ';
663 *s++ = ' '; *s++ = ' ';
664 for (j = 0; j < 16; j++) {
668 if (isprint(str[i + j]))
676 tprintf("%s |\n", outstr);
680 #define PAGMASK (~(PAGSIZ - 1))
682 * move `len' bytes of data from process `pid'
683 * at address `addr' to our space at `laddr'
686 umoven(tcp, addr, len, laddr)
699 char x[sizeof(long)];
702 if (addr & (sizeof(long) - 1)) {
703 /* addr not a multiple of sizeof(long) */
704 n = addr - (addr & -sizeof(long)); /* residue */
705 addr &= -sizeof(long); /* residue */
707 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
709 if (started && (errno==EPERM || errno==EIO)) {
710 /* Ran into 'end of memory' - stupid "printpath" */
713 /* But if not started, we had a bogus address. */
714 if (addr != 0 && errno != EIO)
715 perror("ptrace: umoven");
719 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
720 addr += sizeof(long), laddr += m, len -= m;
724 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
726 if (started && (errno==EPERM || errno==EIO)) {
727 /* Ran into 'end of memory' - stupid "printpath" */
730 if (addr != 0 && errno != EIO)
731 perror("ptrace: umoven");
735 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
736 addr += sizeof(long), laddr += m, len -= m;
746 char x[sizeof(long)];
749 if (addr & (sizeof(long) - 1)) {
750 /* addr not a multiple of sizeof(long) */
751 n = addr - (addr & -sizeof(long)); /* residue */
752 addr &= -sizeof(long); /* residue */
754 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
759 memcpy(laddr, &u.x[n], m = MIN(sizeof(long) - n, len));
760 addr += sizeof(long), laddr += m, len -= m;
764 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *) addr, 0);
769 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
770 addr += sizeof(long), laddr += m, len -= m;
776 n = MIN(len, PAGSIZ);
777 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
778 if (ptrace(PTRACE_READDATA, pid,
779 (char *) addr, len, laddr) < 0) {
780 perror("umoven: ptrace(PTRACE_READDATA, ...)");
792 #ifdef HAVE_MP_PROCFS
793 int fd = tcp->pfd_as;
797 lseek(fd, addr, SEEK_SET);
798 if (read(fd, laddr, len) == -1)
800 #endif /* USE_PROCFS */
806 * like `umove' but make the additional effort of looking
807 * for a terminating zero byte.
810 umovestr(tcp, addr, len, laddr)
817 #ifdef HAVE_MP_PROCFS
818 int fd = tcp->pfd_as;
822 /* Some systems (e.g. FreeBSD) can be upset if we read off the
823 end of valid memory, avoid this by trying to read up
824 to page boundaries. But we don't know what a page is (and
825 getpagesize(2) (if it exists) doesn't necessarily return
826 hardware page size). Assume all pages >= 1024 (a-historical
829 int page = 1024; /* How to find this? */
830 int move = page - (addr & (page - 1));
833 lseek(fd, addr, SEEK_SET);
836 if (move > left) move = left;
837 if ((move = read(fd, laddr, move)) <= 0)
838 return left != len ? 0 : -1;
839 if (memchr (laddr, 0, move)) break;
845 #else /* !USE_PROCFS */
851 char x[sizeof(long)];
854 if (addr & (sizeof(long) - 1)) {
855 /* addr not a multiple of sizeof(long) */
856 n = addr - (addr & -sizeof(long)); /* residue */
857 addr &= -sizeof(long); /* residue */
859 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
861 if (started && (errno==EPERM || errno==EIO)) {
862 /* Ran into 'end of memory' - stupid "printpath" */
865 if (addr != 0 && errno != EIO)
870 memcpy(laddr, &u.x[n], m = MIN(sizeof(long)-n,len));
871 while (n & (sizeof(long) - 1))
872 if (u.x[n++] == '\0')
874 addr += sizeof(long), laddr += m, len -= m;
878 u.val = ptrace(PTRACE_PEEKDATA, pid, (char *)addr, 0);
880 if (started && (errno==EPERM || errno==EIO)) {
881 /* Ran into 'end of memory' - stupid "printpath" */
884 if (addr != 0 && errno != EIO)
889 memcpy(laddr, u.x, m = MIN(sizeof(long), len));
890 for (i = 0; i < sizeof(long); i++)
894 addr += sizeof(long), laddr += m, len -= m;
896 #endif /* !USE_PROCFS */
901 #if !defined (SPARC) && !defined(SPARC64)
902 #define PTRACE_WRITETEXT 101
903 #define PTRACE_WRITEDATA 102
904 #endif /* !SPARC && !SPARC64 */
910 uload(cmd, pid, addr, len, laddr)
921 n = MIN(len, PAGSIZ);
922 n = MIN(n, ((addr + PAGSIZ) & PAGMASK) - addr);
923 if (ptrace(cmd, pid, (char *)addr, n, laddr) < 0) {
924 perror("uload: ptrace(PTRACE_WRITE, ...)");
936 char x[sizeof(long)];
939 if (cmd == PTRACE_WRITETEXT) {
940 peek = PTRACE_PEEKTEXT;
941 poke = PTRACE_POKETEXT;
944 peek = PTRACE_PEEKDATA;
945 poke = PTRACE_POKEDATA;
947 if (addr & (sizeof(long) - 1)) {
948 /* addr not a multiple of sizeof(long) */
949 n = addr - (addr & -sizeof(long)); /* residue */
950 addr &= -sizeof(long);
952 u.val = ptrace(peek, pid, (char *) addr, 0);
954 perror("uload: POKE");
957 memcpy(&u.x[n], laddr, m = MIN(sizeof(long) - n, len));
958 if (ptrace(poke, pid, (char *)addr, u.val) < 0) {
959 perror("uload: POKE");
962 addr += sizeof(long), laddr += m, len -= m;
965 if (len < sizeof(long))
966 u.val = ptrace(peek, pid, (char *) addr, 0);
967 memcpy(u.x, laddr, m = MIN(sizeof(long), len));
968 if (ptrace(poke, pid, (char *) addr, u.val) < 0) {
969 perror("uload: POKE");
972 addr += sizeof(long), laddr += m, len -= m;
979 tload(pid, addr, len, laddr)
984 return uload(PTRACE_WRITETEXT, pid, addr, len, laddr);
988 dload(pid, addr, len, laddr)
994 return uload(PTRACE_WRITEDATA, pid, addr, len, laddr);
1002 upeek(pid, off, res)
1009 #ifdef SUNOS4_KERNEL_ARCH_KLUDGE
1011 static int is_sun4m = -1;
1012 struct utsname name;
1014 /* Round up the usual suspects. */
1015 if (is_sun4m == -1) {
1016 if (uname(&name) < 0) {
1017 perror("upeek: uname?");
1020 is_sun4m = strcmp(name.machine, "sun4m") == 0;
1022 extern const struct xlat struct_user_offsets[];
1023 const struct xlat *x;
1025 for (x = struct_user_offsets; x->str; x++)
1032 #endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
1034 val = ptrace(PTRACE_PEEKUSER, pid, (char *) off, 0);
1035 if (val == -1 && errno) {
1037 sprintf(buf,"upeek: ptrace(PTRACE_PEEKUSER,%d,%lu,0)",pid,off);
1045 #endif /* !USE_PROCFS */
1056 if (upeek(tcp->pid, 4*EIP, &pc) < 0)
1058 #elif defined(X86_64)
1059 if (upeek(tcp->pid, 8*RIP, &pc) < 0)
1062 if (upeek(tcp->pid, PT_B0, &pc) < 0)
1065 if (upeek(tcp->pid, 4*15, &pc) < 0)
1067 #elif defined(POWERPC)
1068 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
1071 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
1073 #elif defined(ALPHA)
1074 if (upeek(tcp->pid, REG_PC, &pc) < 0)
1077 if (upeek(tcp->pid, REG_EPC, &pc) < 0)
1079 #elif defined(SPARC) || defined(SPARC64)
1081 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
1084 #elif defined(S390) || defined(S390X)
1085 if(upeek(tcp->pid,PT_PSWADDR,&pc) < 0)
1088 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0)
1091 if (upeek(tcp->pid, 4*REG_PC ,&pc) < 0)
1094 if (upeek(tcp->pid, REG_PC ,&pc) < 0)
1102 * Return current program counter for `pid'
1103 * Assumes PC is never 0xffffffff
1107 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) {
1108 perror("getpc: ptrace(PTRACE_GETREGS, ...)");
1121 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
1123 #endif /* FREEBSD */
1131 #define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
1132 sizeof(long) == 8 ? "[????????????????] " : \
1139 if (upeek(tcp->pid, 4*EIP, &eip) < 0) {
1143 tprintf("[%08lx] ", eip);
1145 #elif defined(S390) || defined(S390X)
1147 if(upeek(tcp->pid,PT_PSWADDR,&psw) < 0) {
1152 tprintf("[%08lx] ", psw);
1154 tprintf("[%16lx] ", psw);
1157 #elif defined(X86_64)
1160 if (upeek(tcp->pid, 8*RIP, &rip) < 0) {
1164 tprintf("[%16lx] ", rip);
1168 if (upeek(tcp->pid, PT_B0, &ip) < 0) {
1172 tprintf("[%08lx] ", ip);
1173 #elif defined(POWERPC)
1176 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
1177 tprintf ("[????????] ");
1180 tprintf("[%08lx] ", pc);
1184 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
1185 tprintf ("[????????] ");
1188 tprintf("[%08lx] ", pc);
1189 #elif defined(ALPHA)
1192 if (upeek(tcp->pid, REG_PC, &pc) < 0) {
1193 tprintf ("[????????????????] ");
1196 tprintf("[%08lx] ", pc);
1197 #elif defined(SPARC) || defined(SPARC64)
1199 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) {
1203 tprintf("[%08lx] ", regs.r_pc);
1207 if(upeek(tcp->pid,PT_IAOQ0,&pc) < 0) {
1208 tprintf ("[????????] ");
1211 tprintf("[%08lx] ", pc);
1215 if (upeek(tcp->pid, REG_EPC, &pc) < 0) {
1216 tprintf ("[????????] ");
1219 tprintf("[%08lx] ", pc);
1223 if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
1224 tprintf ("[????????] ");
1227 tprintf("[%08lx] ", pc);
1231 if (upeek(tcp->pid, REG_PC, &pc) < 0) {
1232 tprintf ("[????????????????] ");
1235 tprintf("[%08lx] ", pc);
1239 if (upeek(tcp->pid, 4*15, &pc) < 0) {
1243 tprintf("[%08lx] ", pc);
1244 #endif /* !architecture */
1250 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *) ®s, 0) < 0) {
1251 perror("printcall: ptrace(PTRACE_GETREGS, ...)");
1255 tprintf("[%08x] ", regs.r_o7);
1265 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
1266 tprintf("[%08x] ", regs.r_eip);
1267 #endif /* FREEBSD */
1274 #include <sys/syscall.h>
1275 #ifndef CLONE_PTRACE
1276 # define CLONE_PTRACE 0x00002000
1278 #ifndef CLONE_STOPPED
1279 # define CLONE_STOPPED 0x02000000
1284 /* We don't have fork()/vfork() syscalls on ia64 itself, but the ia32
1285 subsystem has them for x86... */
1287 #define SYS_vfork 190
1289 typedef unsigned long *arg_setup_state;
1292 arg_setup(struct tcb *tcp, arg_setup_state *state)
1294 unsigned long *bsp, cfm, sof, sol;
1299 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
1301 if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1304 sof = (cfm >> 0) & 0x7f;
1305 sol = (cfm >> 7) & 0x7f;
1306 bsp = ia64_rse_skip_regs(bsp, -sof + sol);
1312 # define arg_finish_change(tcp, state) 0
1316 get_arg0 (struct tcb *tcp, arg_setup_state *state, long *valp)
1321 ret = upeek (tcp->pid, PT_R11, valp);
1324 (unsigned long) ia64_rse_skip_regs(*state, 0),
1325 sizeof(long), (void *) valp);
1330 get_arg1 (struct tcb *tcp, arg_setup_state *state, long *valp)
1335 ret = upeek (tcp->pid, PT_R9, valp);
1338 (unsigned long) ia64_rse_skip_regs(*state, 1),
1339 sizeof(long), (void *) valp);
1345 set_arg0 (struct tcb *tcp, arg_setup_state *state, long val)
1347 int req = PTRACE_POKEDATA;
1351 ap = (void *) (intptr_t) PT_R11; /* r11 == EBX */
1352 req = PTRACE_POKEUSER;
1354 ap = ia64_rse_skip_regs(*state, 0);
1356 ptrace(req, tcp->pid, ap, val);
1357 return errno ? -1 : 0;
1361 set_arg1 (struct tcb *tcp, arg_setup_state *state, long val)
1363 int req = PTRACE_POKEDATA;
1367 ap = (void *) (intptr_t) PT_R9; /* r9 == ECX */
1368 req = PTRACE_POKEUSER;
1370 ap = ia64_rse_skip_regs(*state, 1);
1372 ptrace(req, tcp->pid, ap, val);
1373 return errno ? -1 : 0;
1376 #elif defined (SPARC) || defined (SPARC64)
1378 typedef struct regs arg_setup_state;
1380 # define arg_setup(tcp, state) \
1381 (ptrace (PTRACE_GETREGS, tcp->pid, (char *) (state), 0))
1382 # define arg_finish_change(tcp, state) \
1383 (ptrace (PTRACE_SETREGS, tcp->pid, (char *) (state), 0))
1385 # define get_arg0(tcp, state, valp) (*(valp) = (state)->r_o0, 0)
1386 # define get_arg1(tcp, state, valp) (*(valp) = (state)->r_o1, 0)
1387 # define set_arg0(tcp, state, val) ((state)->r_o0 = (val), 0)
1388 # define set_arg1(tcp, state, val) ((state)->r_o1 = (val), 0)
1389 # define restore_arg0(tcp, state, val) 0
1393 # if defined S390 || defined S390X
1394 /* Note: this is only true for the `clone' system call, which handles
1395 arguments specially. We could as well say that its first two arguments
1396 are swapped relative to other architectures, but that would just be
1397 another #ifdef in the calls. */
1398 # define arg0_offset PT_GPR3
1399 # define arg1_offset PT_ORIGGPR2
1400 # define restore_arg0(tcp, state, val) ((void) (state), 0)
1401 # define restore_arg1(tcp, state, val) ((void) (state), 0)
1402 # define arg0_index 1
1403 # define arg1_index 0
1404 # elif defined (ALPHA) || defined (MIPS)
1405 # define arg0_offset REG_A0
1406 # define arg1_offset (REG_A0+1)
1407 # elif defined (POWERPC)
1408 # define arg0_offset (sizeof(unsigned long)*PT_R3)
1409 # define arg1_offset (sizeof(unsigned long)*PT_R4)
1410 # define restore_arg0(tcp, state, val) ((void) (state), 0)
1411 # elif defined (HPPA)
1412 # define arg0_offset PT_GR26
1413 # define arg1_offset (PT_GR26-4)
1414 # elif defined (X86_64)
1415 # define arg0_offset ((long)(8*(current_personality ? RBX : RDI)))
1416 # define arg1_offset ((long)(8*(current_personality ? RCX : RSI)))
1418 # define arg0_offset (4*(REG_REG0+4))
1419 # define arg1_offset (4*(REG_REG0+5))
1420 # elif defined (SH64)
1421 /* ABI defines arg0 & 1 in r2 & r3 */
1422 # define arg0_offset (REG_OFFSET+16)
1423 # define arg1_offset (REG_OFFSET+24)
1424 # define restore_arg0(tcp, state, val) 0
1426 # define arg0_offset 0
1427 # define arg1_offset 4
1429 # define restore_arg0(tcp, state, val) 0
1433 typedef int arg_setup_state;
1435 # define arg_setup(tcp, state) (0)
1436 # define arg_finish_change(tcp, state) 0
1437 # define get_arg0(tcp, cookie, valp) \
1438 (upeek ((tcp)->pid, arg0_offset, (valp)))
1439 # define get_arg1(tcp, cookie, valp) \
1440 (upeek ((tcp)->pid, arg1_offset, (valp)))
1443 set_arg0 (struct tcb *tcp, void *cookie, long val)
1445 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg0_offset, val);
1449 set_arg1 (struct tcb *tcp, void *cookie, long val)
1451 return ptrace (PTRACE_POKEUSER, tcp->pid, (char*)arg1_offset, val);
1456 #ifndef restore_arg0
1457 # define restore_arg0(tcp, state, val) set_arg0((tcp), (state), (val))
1459 #ifndef restore_arg1
1460 # define restore_arg1(tcp, state, val) set_arg1((tcp), (state), (val))
1464 # define arg0_index 0
1465 # define arg1_index 1
1472 extern int change_syscall(struct tcb *, int);
1473 arg_setup_state state;
1475 if (tcp->flags & TCB_BPTSET) {
1476 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1480 switch (known_scno(tcp)) {
1487 #if defined SYS_fork || defined SYS_vfork
1488 if (arg_setup (tcp, &state) < 0
1489 || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
1490 || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
1491 || change_syscall(tcp, SYS_clone) < 0
1492 || set_arg0 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
1493 || set_arg1 (tcp, &state, 0) < 0
1494 || arg_finish_change (tcp, &state) < 0)
1496 tcp->u_arg[arg0_index] = CLONE_PTRACE|SIGCHLD;
1497 tcp->u_arg[arg1_index] = 0;
1498 tcp->flags |= TCB_BPTSET;
1506 if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0
1507 && (arg_setup (tcp, &state) < 0
1508 || set_arg0 (tcp, &state,
1509 tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0
1510 || arg_finish_change (tcp, &state) < 0))
1512 tcp->flags |= TCB_BPTSET;
1513 tcp->inst[0] = tcp->u_arg[arg0_index];
1514 tcp->inst[1] = tcp->u_arg[arg1_index];
1518 fprintf(stderr, "PANIC: setbpt for syscall %ld on %u???\n",
1519 tcp->scno, tcp->pid);
1530 arg_setup_state state;
1531 if (arg_setup (tcp, &state) < 0
1532 || restore_arg0 (tcp, &state, tcp->inst[0]) < 0
1533 || restore_arg1 (tcp, &state, tcp->inst[1]) < 0
1534 || arg_finish_change (tcp, &state))
1536 tcp->flags &= ~TCB_BPTSET;
1548 #if defined (SPARC) || defined (SPARC64)
1549 /* We simply use the SunOS breakpoint code. */
1553 #define LOOPA 0x30800000 /* ba,a 0 */
1555 if (tcp->flags & TCB_BPTSET) {
1556 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1559 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
1560 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1563 tcp->baddr = regs.r_o7 + 8;
1565 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
1567 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1572 * XXX - BRUTAL MODE ON
1573 * We cannot set a real BPT in the child, since it will not be
1574 * traced at the moment it will reach the trap and would probably
1575 * die with a core dump.
1576 * Thus, we are force our way in by taking out two instructions
1577 * and insert an eternal loop instead, in expectance of the SIGSTOP
1578 * generated by out PTRACE_ATTACH.
1579 * Of cause, if we evaporate ourselves in the middle of all this...
1583 #if defined (SPARC64)
1585 inst |= (tcp->inst[0] & 0xffffffffUL);
1587 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, inst);
1589 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1592 tcp->flags |= TCB_BPTSET;
1594 #else /* !SPARC && !SPARC64 */
1597 # define LOOP 0x0000feeb
1598 if (tcp->flags & TCB_BPTSET) {
1599 fprintf(stderr, "PANIC: bpt already set in pid %u\n",
1603 if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0)
1606 fprintf(stderr, "[%d] setting bpt at %lx\n",
1607 tcp->pid, tcp->baddr);
1608 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid,
1609 (char *) tcp->baddr, 0);
1611 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1614 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1616 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1619 tcp->flags |= TCB_BPTSET;
1622 * Our strategy here is to replace the bundle that
1623 * contained the clone() syscall with a bundle of the
1626 * { 1: br 1b; br 1b; br 1b }
1628 * This ensures that the newly forked child will loop
1629 * endlessly until we've got a chance to attach to it.
1631 # define LOOP0 0x0000100000000017
1632 # define LOOP1 0x4000000000200000
1633 unsigned long addr, ipsr;
1637 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1639 if (upeek(pid, PT_CR_IIP, &addr) < 0)
1641 /* store "ri" in low two bits */
1642 tcp->baddr = addr | ((ipsr >> 41) & 0x3);
1645 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 0,
1647 tcp->inst[1] = ptrace(PTRACE_PEEKTEXT, pid, (char *) addr + 8,
1650 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1655 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, LOOP0);
1656 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, LOOP1);
1658 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1661 tcp->flags |= TCB_BPTSET;
1665 #if defined (I386) || defined(X86_64)
1666 #define LOOP 0x0000feeb
1667 #elif defined (M68K)
1668 #define LOOP 0x60fe0000
1669 #elif defined (ALPHA)
1670 #define LOOP 0xc3ffffff
1671 #elif defined (POWERPC)
1672 #define LOOP 0x48000000
1674 #define LOOP 0xEAFFFFFE
1676 #define LOOP 0x1000ffff
1678 #define LOOP 0xa7f40000 /* BRC 15,0 */
1679 #elif defined(S390X)
1680 #define LOOP 0xa7f4000000000000UL /* BRC 15,0 */
1682 #define LOOP 0xe81f1ff7 /* b,l,n <loc>,r0 */
1684 #ifdef __LITTLE_ENDIAN__
1685 #define LOOP 0x0000affe
1687 #define LOOP 0xfeaf0000
1690 #error unknown architecture
1693 if (tcp->flags & TCB_BPTSET) {
1694 fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid);
1698 if (upeek(tcp->pid, 4*EIP, &tcp->baddr) < 0)
1700 #elif defined (X86_64)
1701 if (upeek(tcp->pid, 8*RIP, &tcp->baddr) < 0)
1703 #elif defined (M68K)
1704 if (upeek(tcp->pid, 4*PT_PC, &tcp->baddr) < 0)
1706 #elif defined (ALPHA)
1710 #elif defined (MIPS)
1711 return -1; /* FIXME: I do not know what i do - Flo */
1712 #elif defined (POWERPC)
1713 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &tcp->baddr) < 0)
1715 #elif defined(S390) || defined(S390X)
1716 if (upeek(tcp->pid,PT_PSWADDR, &tcp->baddr) < 0)
1719 if (upeek(tcp->pid, PT_IAOQ0, &tcp->baddr) < 0)
1721 tcp->baddr &= ~0x03;
1723 if (upeek(tcp->pid, 4*REG_PC, &tcp->baddr) < 0)
1726 #error unknown architecture
1729 fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr);
1730 tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0);
1732 perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)");
1735 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP);
1737 perror("setbpt: ptrace(PTRACE_POKETEXT, ...)");
1740 tcp->flags |= TCB_BPTSET;
1743 #endif /* SPARC || SPARC64 */
1747 #ifdef SPARC /* This code is slightly sparc specific */
1750 #define BPT 0x91d02001 /* ta 1 */
1751 #define LOOP 0x10800000 /* ba 0 */
1752 #define LOOPA 0x30800000 /* ba,a 0 */
1753 #define NOP 0x01000000
1755 static int loopdeloop[1] = {LOOPA};
1757 static int loopdeloop[2] = {LOOP, NOP};
1760 if (tcp->flags & TCB_BPTSET) {
1761 fprintf(stderr, "PANIC: TCB already set in pid %u\n", tcp->pid);
1764 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
1765 perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
1768 tcp->baddr = regs.r_o7 + 8;
1769 if (ptrace(PTRACE_READTEXT, tcp->pid, (char *)tcp->baddr,
1770 sizeof tcp->inst, (char *)tcp->inst) < 0) {
1771 perror("setbpt: ptrace(PTRACE_READTEXT, ...)");
1776 * XXX - BRUTAL MODE ON
1777 * We cannot set a real BPT in the child, since it will not be
1778 * traced at the moment it will reach the trap and would probably
1779 * die with a core dump.
1780 * Thus, we are force our way in by taking out two instructions
1781 * and insert an eternal loop in stead, in expectance of the SIGSTOP
1782 * generated by out PTRACE_ATTACH.
1783 * Of cause, if we evaporate ourselves in the middle of all this...
1785 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
1786 sizeof loopdeloop, (char *) loopdeloop) < 0) {
1787 perror("setbpt: ptrace(PTRACE_WRITETEXT, ...)");
1790 tcp->flags |= TCB_BPTSET;
1804 #if defined(I386) || defined(X86_64)
1806 #elif defined(POWERPC)
1810 #elif defined(ALPHA)
1816 #endif /* architecture */
1818 #if defined (SPARC) || defined (SPARC64)
1819 /* Again, we borrow the SunOS breakpoint code. */
1820 if (!(tcp->flags & TCB_BPTSET)) {
1821 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1825 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1827 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1830 tcp->flags &= ~TCB_BPTSET;
1836 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1837 if (!(tcp->flags & TCB_BPTSET)) {
1838 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1842 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1844 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1847 tcp->flags &= ~TCB_BPTSET;
1849 if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0)
1851 if (addr != tcp->baddr) {
1852 /* The breakpoint has not been reached yet. */
1855 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1860 unsigned long addr, ipsr;
1865 if (upeek(pid, PT_CR_IPSR, &ipsr) < 0)
1867 if (upeek(pid, PT_CR_IIP, &addr) < 0)
1870 /* restore original bundle: */
1872 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 0, tcp->inst[0]);
1873 ptrace(PTRACE_POKETEXT, pid, (char *) addr + 8, tcp->inst[1]);
1875 perror("clearbpt: ptrace(PTRACE_POKETEXT, ...)");
1879 /* restore original "ri" in ipsr: */
1880 ipsr = (ipsr & ~(0x3ul << 41)) | ((tcp->baddr & 0x3) << 41);
1882 ptrace(PTRACE_POKEUSER, pid, (char *) PT_CR_IPSR, ipsr);
1884 perror("clrbpt: ptrace(PTRACE_POKEUSER, ...)");
1888 tcp->flags &= ~TCB_BPTSET;
1890 if (addr != (tcp->baddr & ~0x3)) {
1891 /* the breakpoint has not been reached yet. */
1893 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1898 #else /* !IA64 && !SPARC && !SPARC64 */
1901 fprintf(stderr, "[%d] clearing bpt\n", tcp->pid);
1902 if (!(tcp->flags & TCB_BPTSET)) {
1903 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
1907 ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]);
1909 perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)");
1912 tcp->flags &= ~TCB_BPTSET;
1915 if (upeek(tcp->pid, 4*EIP, &eip) < 0)
1917 if (eip != tcp->baddr) {
1918 /* The breakpoint has not been reached yet. */
1921 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1925 #elif defined(X86_64)
1926 if (upeek(tcp->pid, 8*RIP, &eip) < 0)
1928 if (eip != tcp->baddr) {
1929 /* The breakpoint has not been reached yet. */
1932 "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1936 #elif defined(POWERPC)
1937 if (upeek(tcp->pid, sizeof(unsigned long)*PT_NIP, &pc) < 0)
1939 if (pc != tcp->baddr) {
1940 /* The breakpoint has not been reached yet. */
1942 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1947 if (upeek(tcp->pid, 4*PT_PC, &pc) < 0)
1949 if (pc != tcp->baddr) {
1950 /* The breakpoint has not been reached yet. */
1952 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1956 #elif defined(ALPHA)
1957 if (upeek(tcp->pid, REG_PC, &pc) < 0)
1959 if (pc != tcp->baddr) {
1960 /* The breakpoint has not been reached yet. */
1962 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1967 if (upeek(tcp->pid, PT_IAOQ0, &iaoq) < 0)
1970 if (iaoq != tcp->baddr && iaoq != tcp->baddr + 4) {
1971 /* The breakpoint has not been reached yet. */
1973 fprintf(stderr, "NOTE: PC not at bpt (iaoq %#lx baddr %#lx)\n",
1977 iaoq = tcp->baddr | 3;
1978 /* We should be pointing at a 'ldi -1000,r1' in glibc, so it is
1979 * safe to set both IAOQ0 and IAOQ1 to that so the PSW N bit
1980 * has no significant effect.
1982 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ0, iaoq);
1983 ptrace(PTRACE_POKEUSER, tcp->pid, (void *)PT_IAOQ1, iaoq);
1985 if (upeek(tcp->pid, 4*REG_PC, &pc) < 0)
1987 if (pc != tcp->baddr) {
1988 /* The breakpoint has not been reached yet. */
1990 fprintf(stderr, "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n",
1996 #endif /* !SPARC && !SPARC64 && !IA64 */
2006 if (!(tcp->flags & TCB_BPTSET)) {
2007 fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid);
2010 if (ptrace(PTRACE_WRITETEXT, tcp->pid, (char *) tcp->baddr,
2011 sizeof tcp->inst, (char *) tcp->inst) < 0) {
2012 perror("clearbtp: ptrace(PTRACE_WRITETEXT, ...)");
2015 tcp->flags &= ~TCB_BPTSET;
2019 * Since we don't have a single instruction breakpoint, we may have
2020 * to adjust the program counter after removing the our `breakpoint'.
2022 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) {
2023 perror("clearbpt: ptrace(PTRACE_GETREGS, ...)");
2026 if ((regs.r_pc < tcp->baddr) ||
2027 (regs.r_pc > tcp->baddr + 4)) {
2028 /* The breakpoint has not been reached yet */
2031 "NOTE: PC not at bpt (pc %#x baddr %#x)\n",
2032 regs.r_pc, tcp->parent->baddr);
2035 if (regs.r_pc != tcp->baddr)
2037 fprintf(stderr, "NOTE: PC adjusted (%#x -> %#x\n",
2038 regs.r_pc, tcp->baddr);
2040 regs.r_pc = tcp->baddr;
2041 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) {
2042 perror("clearbpt: ptrace(PTRACE_SETREGS, ...)");
2054 #endif /* !USE_PROCFS */
2065 for (n = 0; n < sizeof *hdr; n += 4) {
2067 if (upeek(pid, uoff(u_exdata) + n, &res) < 0)
2069 memcpy(((char *) hdr) + n, &res, 4);
2072 fprintf(stderr, "[struct exec: magic: %o version %u Mach %o\n",
2073 hdr->a_magic, hdr->a_toolversion, hdr->a_machtype);
2074 fprintf(stderr, "Text %lu Data %lu Bss %lu Syms %lu Entry %#lx]\n",
2075 hdr->a_text, hdr->a_data, hdr->a_bss, hdr->a_syms, hdr->a_entry);
2086 * Change `vfork' in a freshly exec'ed dynamically linked
2087 * executable's (internal) symbol table to plain old `fork'
2091 struct link_dynamic dyn;
2092 struct link_dynamic_2 ld;
2095 if (getex(pid, &hdr) < 0)
2100 if (umove(tcp, (int) N_DATADDR(hdr), &dyn) < 0) {
2101 fprintf(stderr, "Cannot read DYNAMIC\n");
2104 if (umove(tcp, (int) dyn.ld_un.ld_2, &ld) < 0) {
2105 fprintf(stderr, "Cannot read link_dynamic_2\n");
2108 if ((strtab = malloc((unsigned)ld.ld_symb_size)) == NULL) {
2109 fprintf(stderr, "out of memory\n");
2112 if (umoven(tcp, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2113 (int)ld.ld_symb_size, strtab) < 0)
2117 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2118 fprintf(stderr, "[symbol: %s]\n", cp);
2123 for (cp = strtab; cp < strtab + ld.ld_symb_size; ) {
2124 if (strcmp(cp, "_vfork") == 0) {
2126 fprintf(stderr, "fixvfork: FOUND _vfork\n");
2127 strcpy(cp, "_fork");
2132 if (cp < strtab + ld.ld_symb_size)
2134 * Write entire symbol table back to avoid
2135 * memory alignment bugs in ptrace
2137 if (tload(pid, (int)ld.ld_symbols+(int)N_TXTADDR(hdr),
2138 (int)ld.ld_symb_size, strtab) < 0)