diff options
author | n0ano <n0ano> | 2001-03-07 01:13:25 +0000 |
---|---|---|
committer | n0ano <n0ano> | 2001-03-07 01:13:25 +0000 |
commit | 86fbd54e64770f4781c8f8a1e228faca05fc8b73 (patch) | |
tree | 8b36b97b85f3fe334035ae8554f6dfd789417231 | |
parent | 396902349b47077a4e98e5c0e78a6538a8e1f75c (diff) | |
download | strace-obsolete/ia64.0.tar.gz |
Support for following IA32 forks.obsolete/ia64.0
-rw-r--r-- | linux/syscall.h | 15 | ||||
-rw-r--r-- | syscall.c | 6 | ||||
-rw-r--r-- | util.c | 56 |
3 files changed, 75 insertions, 2 deletions
diff --git a/linux/syscall.h b/linux/syscall.h index e64512102..5919221c3 100644 --- a/linux/syscall.h +++ b/linux/syscall.h @@ -214,6 +214,21 @@ int sys_shmat(), sys_shmdt(), sys_shmget(), sys_shmctl(); #define SYS_ipc_nsubcalls 25 #endif /* !(ALPHA || MIPS) */ +#if !defined(ALPHA) && !defined(MIPS) && !defined(SPARC) +#ifdef IA64 +/* + * IA64 syscall numbers (the only ones available from standard + * header files) are disjoint from IA32 syscall numbers. We + * need to define some IA32 specific syscalls here. + */ +#define SYS_fork 2 +#define SYS_vfork 190 +#define SYS32_exit 1 +#define SYS_waitpid 7 +#define SYS32_wait4 114 +#endif /* IA64 */ +#endif /* !(ALPHA || MIPS) */ + #if defined(ALPHA) || defined(IA64) int sys_getpagesize(); #endif @@ -597,6 +597,9 @@ struct tcb *tcp; #ifdef SYS_wait4 case SYS_wait4: #endif +#ifdef SYS32_wait4 + case SYS32_wait4: +#endif #ifdef SYS_waitpid case SYS_waitpid: #endif @@ -609,6 +612,9 @@ struct tcb *tcp; #ifdef SYS_exit case SYS_exit: #endif +#ifdef SYS32_exit + case SYS32_exit: +#endif internal_exit(tcp); break; } @@ -108,6 +108,10 @@ static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data, #endif +#ifdef IA64 +extern long ia32; +#endif // IA64 + /* macros */ #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) @@ -1061,6 +1065,28 @@ struct tcb *tcp; #else /* !SPARC */ #ifdef IA64 + if (ia32) { +#define LOOP 0x0000feeb + if (tcp->flags & TCB_BPTSET) { + fprintf(stderr, "PANIC: bpt already set in pid %u\n", tcp->pid); + return -1; + } + if (upeek(tcp->pid, PT_CR_IIP, &tcp->baddr) < 0) + return -1; + if (debug) + fprintf(stderr, "[%d] setting bpt at %lx\n", tcp->pid, tcp->baddr); + tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *) tcp->baddr, 0); + if (errno) { + perror("setbpt: ptrace(PTRACE_PEEKTEXT, ...)"); + return -1; + } + ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, LOOP); + if (errno) { + perror("setbpt: ptrace(PTRACE_POKETEXT, ...)"); + return -1; + } + tcp->flags |= TCB_BPTSET; + } else { /* * Our strategy here is to replace the bundle that contained * the clone() syscall with a bundle of the form: @@ -1070,7 +1096,6 @@ struct tcb *tcp; * This ensures that the newly forked child will loop * endlessly until we've got a chance to attach to it. */ - { # define LOOP0 0x0000100000000017 # define LOOP1 0x4000000000200000 unsigned long addr, ipsr; @@ -1245,7 +1270,34 @@ struct tcb *tcp; } tcp->flags &= ~TCB_BPTSET; #elif defined(IA64) - { + if (ia32) { + unsigned long addr; + + if (debug) + fprintf(stderr, "[%d] clearing bpt\n", tcp->pid); + if (!(tcp->flags & TCB_BPTSET)) { + fprintf(stderr, "PANIC: TCB not set in pid %u\n", tcp->pid); + return -1; + } + errno = 0; + ptrace(PTRACE_POKETEXT, tcp->pid, (char *) tcp->baddr, tcp->inst[0]); + if (errno) { + perror("clearbtp: ptrace(PTRACE_POKETEXT, ...)"); + return -1; + } + tcp->flags &= ~TCB_BPTSET; + + if (upeek(tcp->pid, PT_CR_IIP, &addr) < 0) + return -1; + if (addr != tcp->baddr) { + /* The breakpoint has not been reached yet. */ + if (debug) + fprintf(stderr, + "NOTE: PC not at bpt (pc %#lx baddr %#lx)\n", + addr, tcp->baddr); + return 0; + } + } else { unsigned long addr, ipsr; pid_t pid; |