pkgsrc/sysutils/strace/patches/patch-au
spz dda134763b compile fixes for a leaf package for non-x86 NetBSD
(note that there are no claims of making it actually work)
2009-12-29 22:03:41 +00:00

306 lines
6.6 KiB
Text

$NetBSD: patch-au,v 1.4 2009/12/29 22:03:41 spz Exp $
--- syscall.c.orig 2006-12-21 23:13:33.000000000 +0100
+++ syscall.c 2009-12-29 21:45:24.000000000 +0100
@@ -38,9 +38,9 @@
#include <signal.h>
#include <time.h>
#include <errno.h>
+#include <sys/param.h>
#include <sys/user.h>
#include <sys/syscall.h>
-#include <sys/param.h>
#if HAVE_ASM_REG_H
#if defined (SPARC) || defined (SPARC64)
@@ -56,6 +56,10 @@
#endif
#endif
+#ifdef NETBSD
+#include <machine/reg.h>
+#include <machine/psl.h>
+#endif
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#ifndef PTRACE_PEEKUSR
@@ -624,6 +628,7 @@
}
#endif
+#ifndef NETBSD
static void
decode_subcall(tcp, subcall, nsubcalls, style)
struct tcb *tcp;
@@ -709,6 +714,7 @@
#endif /* FREEBSD */
}
}
+#endif /* !NETBSD */
#endif
struct tcb *tcp_last = NULL;
@@ -747,7 +753,7 @@
#endif
if ( sys_execve == func
-#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
+#if !defined(NETBSD) && (defined(SPARC) || defined(SPARC64) || defined(SUNOS4))
|| sys_execv == func
#endif
#if UNIXWARE > 2
@@ -756,9 +762,12 @@
)
return internal_exec(tcp);
- if ( sys_waitpid == func
- || sys_wait4 == func
-#if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
+ if (
+ sys_wait4 == func
+#ifndef NETBSD
+ || sys_waitpid == func
+#endif
+#if defined(SVR4) || defined(ALLBSD) || defined(SUNOS4)
|| sys_wait == func
#endif
#ifdef ALPHA
@@ -811,9 +820,9 @@
static long rax;
#endif
#endif /* LINUX */
-#ifdef FREEBSD
- struct reg regs;
-#endif /* FREEBSD */
+#ifdef ALLBSD
+ static struct reg regs;
+#endif /* ALLBSD */
int
get_scno(tcp)
@@ -1283,9 +1292,9 @@
#ifdef HAVE_PR_SYSCALL
scno = tcp->status.PR_SYSCALL;
#else /* !HAVE_PR_SYSCALL */
-#ifndef FREEBSD
+#ifndef ALLBSD
scno = tcp->status.PR_WHAT;
-#else /* FREEBSD */
+#else /* ALLBSD */
if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
perror("pread");
return -1;
@@ -1299,8 +1308,41 @@
scno = regs.r_eax;
break;
}
-#endif /* FREEBSD */
+#endif /* ALLBSD */
#endif /* !HAVE_PR_SYSCALL */
+#else /* !USE_PROCFS */
+#ifdef NETBSD
+ if (ptrace(PTRACE_GETREGS,pid,(char *)&regs, 0) < 0) {
+ perror("GETREGS");
+ return -1;
+ }
+#ifdef __i386__
+ switch (regs.r_eax) {
+ case SYS_syscall:
+ case SYS___syscall:
+ if ((scno = ptrace(PTRACE_PEEKUSER, pid,
+ (char *)regs.r_esp + sizeof(int), sizeof(int))) == -1) {
+ perror("PEEKUSER __syscall");
+ return -1;
+ }
+ break;
+ default:
+ scno = regs.r_eax;
+ break;
+ }
+#endif
+#ifdef __x86_64__
+ switch (regs.regs[_REG_RAX]) {
+ case SYS_syscall:
+ case SYS___syscall:
+ scno = regs.regs[_REG_RDI];
+ break;
+ default:
+ scno = regs.regs[_REG_RAX];
+ break;
+ }
+#endif
+#endif /* NETBSD */
#endif /* USE_PROCFS */
if (!(tcp->flags & TCB_INSYSCALL))
tcp->scno = scno;
@@ -1325,7 +1367,9 @@
struct tcb *tcp;
{
#ifndef USE_PROCFS
+#ifndef NETBSD
int pid = tcp->pid;
+#endif
#else /* USE_PROCFS */
int scno = known_scno(tcp);
@@ -1698,17 +1742,36 @@
}
#endif /* MIPS */
#endif /* SVR4 */
-#ifdef FREEBSD
+#ifdef ALLBSD
+#ifdef __i386__
if (regs.r_eflags & PSL_C) {
tcp->u_rval = -1;
u_error = regs.r_eax;
} else {
tcp->u_rval = regs.r_eax;
+#if 0
+ /* XXX Linux only */
tcp->u_lrval =
((unsigned long long) regs.r_edx << 32) + regs.r_eax;
+#endif
u_error = 0;
}
-#endif /* FREEBSD */
+#endif
+#ifdef __x86_64__
+ if (regs.regs[_REG_RFL] & PSL_C) {
+ tcp->u_rval = -1;
+ u_error = regs.regs[_REG_RAX];
+ } else {
+ tcp->u_rval = regs.regs[_REG_RAX];
+#if 0
+ /* XXX Linux only */
+ tcp->u_lrval =
+ ((unsigned long long) regs.regs[_REG_RDX] << 64) + regs.regs[_REG_RAX];
+#endif
+ u_error = 0;
+ }
+#endif
+#endif /* ALLBSD */
tcp->u_error = u_error;
return 1;
}
@@ -1891,6 +1954,32 @@
return -1;
}
#endif /* FREEBSD */
+#ifdef NETBSD
+ if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
+ return -1;
+#ifdef __i386__
+ if (error) {
+ regs.r_eflags |= PSL_C;
+ regs.r_eax = error;
+ }
+ else {
+ regs.r_eflags &= ~PSL_C;
+ regs.r_eax = rval;
+ }
+#endif
+#ifdef __x86_64__
+ if (error) {
+ regs.regs[_REG_RFL] |= PSL_C;
+ regs.regs[_REG_RAX] = error;
+ }
+ else {
+ regs.regs[_REG_RFL] &= ~PSL_C;
+ regs.regs[_REG_RAX] = rval;
+ }
+#endif
+ if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
+ return -1;
+#endif /* NETBSD */
/* All branches reach here on success (only). */
tcp->u_error = error;
@@ -1903,7 +1992,9 @@
struct tcb *tcp;
{
#ifndef USE_PROCFS
+#ifndef NETBSD
int pid = tcp->pid;
+#endif
#endif /* !USE_PROCFS */
#ifdef LINUX
#if defined(S390) || defined(S390X)
@@ -2201,6 +2292,58 @@
I DONT KNOW WHAT TO DO
#endif /* !HAVE_PR_SYSCALL */
#endif /* SVR4 */
+#ifdef NETBSD
+ if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+ tcp->u_nargs = sysent[tcp->scno].nargs;
+ else
+ tcp->u_nargs = 5;
+#ifdef __i386__
+ switch(regs.r_eax) {
+ case SYS___syscall:
+ umoven(tcp, regs.r_esp + sizeof(int) + sizeof(quad_t),
+ tcp->u_nargs * sizeof(unsigned long),
+ (char *) tcp->u_arg);
+ break;
+ case SYS_syscall:
+ umoven(tcp, regs.r_esp + 2 * sizeof(int),
+ tcp->u_nargs * sizeof(unsigned long),
+ (char *) tcp->u_arg);
+ break;
+ default:
+ umoven(tcp, regs.r_esp + sizeof(int),
+ tcp->u_nargs * sizeof(unsigned long),
+ (char *) tcp->u_arg);
+ break;
+ }
+#endif
+#ifdef __x86_64__
+{
+ int bias, i;
+ static int ar[2][6] = {
+ { _REG_RDI, _REG_RSI, _REG_RDX,
+ _REG_R10, _REG_R8, _REG_R9 }, /* x86-64 ABI */
+ { _REG_RBX, _REG_RCX, _REG_RDX,
+ _REG_RSI, _REG_RDI, _REG_RBP } /* i386 ABI */
+ };
+ switch(regs.regs[_REG_RAX]) {
+ case SYS___syscall:
+ case SYS_syscall:
+ bias = 1;
+ break;
+ default:
+ bias = 0;
+ break;
+ }
+ for (i = 0; i < tcp->u_nargs; i++) {
+ tcp->u_arg[i] = regs.regs[ar[0][i + bias]];
+#if 0
+ if (upeek(tcp->pid, ar[0][i + bias] * 8, &tcp->u_arg[i]) < 0)
+ return -1;
+#endif
+ }
+}
+#endif
+#endif /* NETBSD */
#ifdef FREEBSD
if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
sysent[tcp->scno].nargs > tcp->status.val)
@@ -2570,6 +2713,19 @@
pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
val = regs.r_edx;
#endif
+#ifdef NETBSD
+ struct reg regs;
+ if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, sizeof(regs)) < 0) {
+ perror("PTRACE_GETREGS get edx");
+ return -1;
+ }
+#ifdef __i386__
+ val = regs.r_edx;
+#endif
+#ifdef __x86_64__
+ val = regs.regs[_REG_RDX];
+#endif
+#endif /* NETBSD */
return val;
}