summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorn0ano <n0ano>2001-03-07 01:13:25 +0000
committern0ano <n0ano>2001-03-07 01:13:25 +0000
commit86fbd54e64770f4781c8f8a1e228faca05fc8b73 (patch)
tree8b36b97b85f3fe334035ae8554f6dfd789417231
parent396902349b47077a4e98e5c0e78a6538a8e1f75c (diff)
downloadstrace-obsolete/ia64.0.tar.gz
Support for following IA32 forks.obsolete/ia64.0
-rw-r--r--linux/syscall.h15
-rw-r--r--syscall.c6
-rw-r--r--util.c56
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
diff --git a/syscall.c b/syscall.c
index 3ebe108b4..e2eb55411 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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;
}
diff --git a/util.c b/util.c
index fd67afb10..900b1c3a0 100644
--- a/util.c
+++ b/util.c
@@ -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;