]> granicus.if.org Git - strace/commitdiff
Add FreeBSD support
authorWichert Akkerman <wichert@deephackmode.org>
Fri, 1 Sep 2000 21:03:06 +0000 (21:03 +0000)
committerWichert Akkerman <wichert@deephackmode.org>
Fri, 1 Sep 2000 21:03:06 +0000 (21:03 +0000)
27 files changed:
CREDITS
ChangeLog
Makefile.in
acconfig.h
configure.in
defs.h
file.c
freebsd/.cvsignore [new file with mode: 0644]
freebsd/ioctlent.sh [new file with mode: 0644]
freebsd/syscalls.cat [new file with mode: 0644]
freebsd/syscalls.pl [new file with mode: 0644]
freebsd/syscalls.print [new file with mode: 0644]
io.c
ioctl.c
ipc.c
mem.c
net.c
proc.c
process.c
resource.c
signal.c
strace.c
stream.c
syscall.c
system.c
term.c
util.c

diff --git a/CREDITS b/CREDITS
index 4ff1bc87aea8aa6a05a76a576331b0ea0d392a78..ed03b50094e8fe46a98a1dadb28e41b2261157c8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -39,3 +39,4 @@ porting to new systems:
        Florian Lohoff <flo@rfc822.org>
        D.J. Barrow <djbarrow@de.ibm.com>
        Topi Miettinen <Topi.Miettinen@nic.fi>
+       Gaël Roualland <gael.roualland@dial.oleane.com>
index 12050bd2db91356d7b4631903ef4b5d901fd0be9..7f6d438198e6bbc48819cc7f5a36dada2dc3a4f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2000-09-01  Wichert Akkerman <wakkerma@debian.org>
+
+  *  lots of files: merge patch from Gaël Roualland to add
+     support for FreeBSD.
+
 2000-08-09  Wichert Akkerman <wakkerma@debian.org>
 
   * file.c: update to reflect that st_ino suddenly became a long long
index 8b070f94b26af1c44d853359698afae518be24d3..ca72d1da97804542546096d411b708164f5df256 100644 (file)
@@ -20,7 +20,7 @@ CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 WARNFLAGS = @WARNFLAGS@
 
-# OS is one of `linux', `sunos4', or `svr4'.
+# OS is one of `linux', `sunos4', `svr4', or `freebsd'.
 OS = @opsys@
 # ARCH is one of `i386', `m68k', `sparc', `arm', `mips' or `ia64'.
 ARCH = @arch@
@@ -47,7 +47,7 @@ SHELL = /bin/sh
 
 INCLUDES = -I. -I$(OS)/$(ARCH) -I$(srcdir)/$(OS)/$(ARCH) -I$(OS) -I$(srcdir)/$(OS)
 SUBDIRS = $(OSARCH)
-ALL_SUBDIRS = test linux linux/alpha linux/powerpc sunos4 svr4
+ALL_SUBDIRS = test linux linux/alpha linux/powerpc sunos4 svr4 freebsd/i386
 OBJ = strace.o version.o syscall.o util.o \
        desc.o file.o ipc.o io.o ioctl.o mem.o net.o process.o bjm.o \
        resource.o signal.o sock.o system.o term.o time.o proc.o stream.o
index 2a711d903c2578743f91b11c654a2f4c2e781a7b..b86ddfab7dce40caf1351e2820730a4ad4d3db53 100644 (file)
@@ -9,6 +9,9 @@
    or a derivative like Solaris 2.x or Irix 5.x.  */
 #undef SVR4
 
+/* Define if this is running the FreeBSD operating system.  */
+#undef FREEBSD
+
 /* Define for UnixWare systems. */
 #undef UNIXWARE
 
index c59e583455895161f17e7cb75fc81479c5e6740c..9f74a54a3c8232c81539adf9982a8b36f0344f20 100644 (file)
@@ -22,6 +22,9 @@ sysv5*)
 irix[56]*)
        opsys=svr4
        ;;
+freebsd*)
+       opsys=freebsd
+       ;;
 *)
        AC_MSG_ERROR(this operating system is not yet supported by strace)
        ;;
@@ -30,7 +33,7 @@ AC_MSG_RESULT($opsys)
 
 # Autoheader trick.  Heh, heh.
 opsys_list='
-@@@syms="$syms LINUX SUNOS4 SVR4"@@@
+@@@syms="$syms LINUX SUNOS4 SVR4 FREEBSD"@@@
 '
 
 AC_MSG_CHECKING(for supported architecture)
@@ -148,7 +151,7 @@ if test x$OPSYS != xLINUX; then
 AC_CHECK_LIB(nsl, main)
 fi
 AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg inet_ntop)
-AC_CHECK_HEADERS(sys/reg.h sys/filio.h sys/acl.h sys/asynch.h sys/door.h sys/stream.h sys/tiuser.h sys/sysconfig.h asm/sigcontext.h ioctls.h sys/ioctl.h sys/ptrace.h termio.h linux/ptrace.h asm/reg.h linux/icmp.h linux/in6.h sys/uio.h linux/netlink.h linux/if_packet.h sys/poll.h)
+AC_CHECK_HEADERS(sys/reg.h sys/filio.h sys/acl.h sys/asynch.h sys/door.h sys/stream.h sys/tiuser.h sys/sysconfig.h asm/sigcontext.h ioctls.h sys/ioctl.h sys/ptrace.h termio.h linux/ptrace.h asm/reg.h linux/icmp.h linux/in6.h sys/uio.h linux/netlink.h linux/if_packet.h sys/poll.h sys/vfs.h)
 AC_DECL_SYS_ERRLIST
 AC_DECL_SYS_SIGLIST
 AC_DECL__SYS_SIGLIST
diff --git a/defs.h b/defs.h
index 906d62e209afe9e0b955e1313f83953a8fab1738..4dbed044b225ed27de838e701b6d097f022bfc05 100644 (file)
--- a/defs.h
+++ b/defs.h
 #  endif
 #endif 
 
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
+#define USE_PROCFS
+#else
+#undef USE_PROCFS
+#endif
+
+#ifdef FREEBSD
+#ifndef I386
+#error "FreeBSD support is only for i386 arch right now."
+#endif
+#include <machine/psl.h>
+#include <machine/reg.h>
+#include <sys/syscall.h>
+#endif
+
+#ifdef USE_PROCFS
 #include <sys/procfs.h>
 #ifdef HAVE_MP_PROCFS
 #include <sys/uio.h>
 #endif
-#else /* !SVR4 */
+#ifdef FREEBSD
+#include <sys/pioctl.h>
+#endif /* FREEBSD */
+#else /* !USE_PROCFS */
 #if defined(LINUXSPARC) && defined(__GLIBC__)
 #include <sys/ptrace.h>
 #else
@@ -184,6 +202,22 @@ extern int mp_ioctl (int f, int c, void *a, int s);
 #define PR_FLAGS       pr_flags
 #endif
 #endif
+#ifdef FREEBSD
+#define IOCTL          ioctl
+#define IOCTL_STATUS(t)        ioctl (t->pfd, PIOCSTATUS, &t->status)
+#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWAIT, &t->status)
+#define PIOCRUN         PIOCCONT
+#define PIOCWSTOP       PIOCWAIT
+#define PR_WHY         why
+#define PR_WHAT                val
+#define PR_FLAGS       flags
+/* from /usr/src/sys/miscfs/procfs/procfs_vnops.c,
+   status.state = 0 for running, 1 for stopped */
+#define PR_SYSENTRY     S_SCE
+#define PR_SYSEXIT      S_SCX
+#define PR_SIGNALLED    S_SIG
+#define PR_FAULTED      S_CORE
+#endif
 
 /* Trace Control Block */
 struct tcb {
@@ -219,6 +253,11 @@ struct tcb {
        prstatus_t status;      /* procfs status structure */
 #endif
 #endif
+#ifdef FREEBSD
+       struct procfs_status status;
+       int pfd_reg;
+       int pfd_status;
+#endif
 };
 
 /* TCB flags */
@@ -269,8 +308,10 @@ struct xlat {
 #define RVAL_HEX       001     /* hex format */
 #define RVAL_OCTAL     002     /* octal format */
 #define RVAL_UDECIMAL  003     /* unsigned decimal format */
-#define RVAL_LDECIMAL  004     /* long long format */
-                               /* Maybe add long long hex, octal, unsigned */
+#define RVAL_LDECIMAL  004     /* long decimal format */
+#define RVAL_LHEX      005     /* long hex format */
+#define RVAL_LOCTAL    006     /* long octal format */
+#define RVAL_LUDECIMAL 007     /* long unsigned decimal format */
 #define RVAL_MASK      007     /* mask for these values */
 
 #define RVAL_STR       010     /* Print `auxstr' field after return val */
@@ -315,6 +356,7 @@ extern void set_sortby P((char *));
 extern void set_overhead P((int));
 extern void qualify P((char *));
 extern void newoutf P((struct tcb *));
+extern int get_scno P((struct tcb *));
 extern int trace_syscall P((struct tcb *));
 extern void printxval P((struct xlat *, int, char *));
 extern int printargs P((struct tcb *));
@@ -375,7 +417,7 @@ extern int fixvfork P((struct tcb *));
 #if !(defined(LINUX) && !defined(SPARC))
 extern long getrval2 P((struct tcb *));
 #endif
-#ifdef SVR4
+#ifdef USE_PROCFS
 extern int proc_open P((struct tcb *tcp, int attaching));
 #endif
 
diff --git a/file.c b/file.c
index a53d229b204a5ad67db84e367c306f5e7c7cfbdc..a74beda9c47dfbff08c4e3ce9ce2c17e9b617e66 100644 (file)
--- a/file.c
+++ b/file.c
@@ -120,7 +120,15 @@ struct stat {
 #  include <sys/cred.h>
 #endif /* SVR4 */
 
+#ifdef HAVE_SYS_VFS_H
 #include <sys/vfs.h>
+#endif
+
+#ifdef FREEBSD
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#endif
 
 #ifdef MAJOR_IN_SYSMACROS
 #include <sys/sysmacros.h>
@@ -222,6 +230,12 @@ struct xlat openmodes[] = {
 #endif
 #ifdef FNOCTTY
        { FNOCTTY,      "FNOCTTY"       },
+#endif 
+#ifdef O_SHLOCK
+       { O_SHLOCK,     "O_SHLOCK"      },
+#endif
+#ifdef O_EXLOCK
+       { O_EXLOCK,     "O_EXLOCK"      },
 #endif
        { 0,            NULL            },
 };
@@ -339,14 +353,33 @@ int
 sys_lseek(tcp)
 struct tcb *tcp;
 {
+       off_t offset;
+       int _whence;
+
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
-               if (tcp->u_arg[2] == SEEK_SET)
-                       tprintf("%lu, ", tcp->u_arg[1]);
+#ifndef FREEBSD
+               offset = tcp->u_arg[1];
+               _whence = tcp->u_arg[2];
+               if (_whence == SEEK_SET)
+                       tprintf("%lu, ", offset);
                else
-                       tprintf("%ld, ", tcp->u_arg[1]);
-               printxval(whence, tcp->u_arg[2], "SEEK_???");
-       }
+                       tprintf("%ld, ", offset);               
+#else /* FREEBSD */
+               offset = ((off_t) tcp->u_arg[1] << 32) +  tcp->u_arg[2];
+               _whence = tcp->u_arg[4];
+               if (_whence == SEEK_SET)
+                       tprintf("%llu, ", offset);
+               else
+                       tprintf("%lld, ", offset);              
+#endif         
+               printxval(whence, _whence, "SEEK_???");
+       } 
+#ifdef FREEBSD
+       else
+               if (!syserror(tcp))
+                       return RVAL_LUDECIMAL;
+#endif /* FREEBSD */
        return RVAL_UDECIMAL;
 }
 
@@ -383,7 +416,11 @@ struct tcb *tcp;
 {
        if (entering(tcp)) {
                printpath(tcp, tcp->u_arg[0]);
+#ifndef FREEBSD
                tprintf(", %lu", tcp->u_arg[1]);
+#else
+               tprintf(", %llu", ((off_t) tcp->u_arg[1] << 32) + tcp->u_arg[2]);
+#endif         
        }
        return 0;
 }
@@ -393,7 +430,12 @@ sys_ftruncate(tcp)
 struct tcb *tcp;
 {
        if (entering(tcp)) {
+#ifndef FREEBSD
                tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
+#else
+               tprintf("%ld, %llu", tcp->u_arg[0],
+                       ((off_t) tcp->u_arg[1] << 32) + tcp->u_arg[2]);
+#endif         
        }
        return 0;
 }
@@ -534,6 +576,50 @@ long addr;
 }
 #endif /* LINUXSPARC */
 
+#ifdef FREEBSD
+static struct xlat fileflags[] = {
+       { UF_NODUMP,    "UF_NODUMP"     },
+       { UF_IMMUTABLE, "UF_IMMUTABLE"  },
+       { UF_APPEND,    "UF_APPEND"     },
+       { UF_OPAQUE,    "UF_OPAQUE"     },
+       { UF_NOUNLINK,  "UF_NOUNLINK"   },
+       { SF_ARCHIVED,  "SF_ARCHIVED"   },
+       { SF_IMMUTABLE, "SF_IMMUTABLE"  },
+       { SF_APPEND,    "SF_APPEND"     },
+       { SF_NOUNLINK,  "SF_NOUNLINK"   },
+       { 0,            NULL            },
+};
+
+int
+sys_chflags(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               printpath(tcp, tcp->u_arg[0]);
+               tprintf(", ");
+               if (tcp->u_arg[1])
+                       printflags(fileflags, tcp->u_arg[1]);
+               else
+                       tprintf("0");
+       }
+       return 0;
+}
+
+int
+sys_fchflags(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               tprintf("%ld, ", tcp->u_arg[0]);
+               if (tcp->u_arg[1])
+                       printflags(fileflags, tcp->u_arg[1]);
+               else
+                       tprintf("0");
+       }
+       return 0;
+}
+#endif
+
 static void
 realprintstat(tcp, statbuf)
 struct tcb *tcp;
@@ -577,7 +663,17 @@ struct stat *statbuf;
     if (!abbrev(tcp)) {
            tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
            tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
+#ifndef FREEBSD
            tprintf("st_ctime=%s}", sprinttime(statbuf->st_ctime));
+#else /* FREEBSD */
+           tprintf("st_ctime=%s, ", sprinttime(statbuf->st_ctime));
+           tprintf("st_flags=");
+           if (statbuf->st_flags) {
+                   printflags(fileflags, statbuf->st_flags);
+           } else
+                   tprintf("0");
+           tprintf(", st_gen=%u}", statbuf->st_gen);
+#endif /* FREEBSD */
     }
     else
            tprintf("...}");
@@ -1581,6 +1677,21 @@ struct tcb *tcp;
 
 #endif /* linux */
 
+#ifdef FREEBSD
+struct xlat direnttypes[] = {
+       { DT_FIFO,      "DT_FIFO"       },
+       { DT_CHR,       "DT_CHR"        },
+       { DT_DIR,       "DT_DIR"        },
+       { DT_BLK,       "DT_BLK"        },
+       { DT_REG,       "DT_REG"        },
+       { DT_LNK,       "DT_LNK"        },
+       { DT_SOCK,      "DT_SOCK"       },
+       { DT_WHT,       "DT_WHT"        },
+       { 0,            NULL            },
+};
+
+#endif
+
 int
 sys_getdents(tcp)
 struct tcb *tcp;
@@ -1635,6 +1746,15 @@ struct tcb *tcp;
                                d->d_namlen, d->d_namlen, d->d_name);
                }
 #endif /* SUNOS4 */
+#ifdef FREEBSD
+               if (!abbrev(tcp)) {
+                       tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
+                               i ? " " : "", d->d_fileno, d->d_reclen);
+                       printxval(direnttypes, d->d_type, "DT_???");
+                       tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
+                               d->d_namlen, d->d_namlen, d->d_name);
+               }
+#endif /* FREEBSD */           
                if (!d->d_reclen) {
                        tprintf("/* d_reclen == 0, problem here */");
                        break;
@@ -1651,8 +1771,62 @@ struct tcb *tcp;
        return 0;
 }
 
-#ifdef linux
+#ifdef FREEBSD
+int
+sys_getdirentries(tcp)
+struct tcb * tcp;
+{
+       int i, len, dents = 0;
+       long basep;
+       char *buf;
+
+       if (entering(tcp)) {
+               tprintf("%lu, ", tcp->u_arg[0]);
+               return 0;
+       }
+       if (syserror(tcp) || !verbose(tcp)) {
+               tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
+               return 0;
+       }
+       len = tcp->u_rval;
+       if ((buf = malloc(len)) == NULL) {
+               tprintf("out of memory\n");
+               return 0;
+       }
+       if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
+               tprintf("{...}, %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
+               free(buf);
+               return 0;
+       }
+       if (!abbrev(tcp))
+               tprintf("{");
+       for (i = 0; i < len;) {
+               struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
+               if (!abbrev(tcp)) {
+                       tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
+                               i ? " " : "", d->d_fileno, d->d_reclen);
+                       printxval(direnttypes, d->d_type, "DT_???");
+                       tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
+                               d->d_namlen, d->d_namlen, d->d_name);
+               }
+               i += d->d_reclen;
+               dents++;
+       }
+       if (!abbrev(tcp))
+               tprintf("}");
+       else
+               tprintf("/* %u entries */", dents);
+       free(buf);
+       tprintf(", %lu", tcp->u_arg[2]);
+       if (umove(tcp, tcp->u_arg[3], &basep) < 0)
+               tprintf(", %#lx", tcp->u_arg[3]);
+       else
+               tprintf(", [%lu]", basep);
+       return 0;
+}
+#endif
 
+#ifdef linux
 int
 sys_getcwd(tcp)
 struct tcb *tcp;
@@ -1668,6 +1842,22 @@ struct tcb *tcp;
 }
 #endif /* linux */
 
+#ifdef FREEBSD
+int
+sys___getcwd(tcp)
+struct tcb *tcp;
+{
+    if (exiting(tcp)) {
+       if (syserror(tcp))
+           tprintf("%#lx", tcp->u_arg[0]);
+       else
+           printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
+       tprintf(", %lu", tcp->u_arg[1]);
+    }
+    return 0;
+}
+#endif
+
 #ifdef HAVE_SYS_ASYNCH_H
 
 int
diff --git a/freebsd/.cvsignore b/freebsd/.cvsignore
new file mode 100644 (file)
index 0000000..f3c7a7c
--- /dev/null
@@ -0,0 +1 @@
+Makefile
diff --git a/freebsd/ioctlent.sh b/freebsd/ioctlent.sh
new file mode 100644 (file)
index 0000000..7d8a21c
--- /dev/null
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# initialy from $FreeBSD: src/usr.bin/kdump/mkioctls,v 1.18 2000/08/02 07:37:44 ru Exp $
+# changed by Gaël Roualland.
+
+# Validate arg count.
+if [ $# -ne 1 ]
+then
+        echo "usage: $0 include-directory" >&2
+        exit 1
+fi
+
+# build a list of files with ioctls
+ioctl_includes=`
+       cd $1
+       find * -name '*.h' -follow |
+               egrep -v '^(netns)/' |
+               xargs egrep -l \
+'^#[   ]*define[       ]+[A-Za-z_][A-Za-z0-9_]*[       ]+_IO[^a-z0-9_]'`
+
+# Generate the output file.
+echo '/* This file is automatically generated by ioctlent.sh */'
+echo
+echo '/* XXX obnoxious prerequisites. */'
+echo '#define COMPAT_43'
+echo
+echo '#include <sys/types.h>'
+echo '#include <sys/param.h>'
+echo '#include <sys/devicestat.h>'
+echo '#include <sys/disklabel.h>'
+echo '#include <sys/socket.h>'
+echo '#include <sys/time.h>'
+echo '#include <sys/tty.h>'
+echo '#include <net/ethernet.h>'
+echo '#include <net/if.h>'
+echo '#include <net/if_var.h>'
+echo '#include <net/route.h>'
+echo '#include <netatm/atm.h>'
+echo '#include <netatm/atm_if.h>'
+echo '#include <netatm/atm_sap.h>'
+echo '#include <netatm/atm_sys.h>'
+echo '#include <netinet/in.h>'
+echo '#include <netinet/ip_compat.h>'
+echo '#include <netinet/ip_fil.h>'
+echo '#include <netinet/ip_auth.h>'
+echo '#include <netinet/ip_nat.h>'
+echo '#include <netinet/ip_frag.h>'
+echo '#include <netinet/ip_state.h>'
+echo '#include <netinet/ip_mroute.h>'
+echo '#include <netinet6/in6_var.h>'
+echo '#include <netinet6/nd6.h>'
+echo '#include <netinet6/ip6_mroute.h>'
+echo '#include <cam/cam.h>'
+echo '#include <stdio.h>'
+echo
+echo "$ioctl_includes" | sed -e 's/^/#include </' -e s'/$/>/'
+echo
+echo 'struct ioctlent ioctlent [] ='
+echo '{'
+(cd $1 && for i in $ioctl_includes ; do echo "#include <$i>" | gcc -I$1 -E -dM - | egrep '^#[  ]*define[       ]+[A-Za-z_][A-Za-z0-9_]*[       ]+_IO[^a-z0-9_]' | sed -n -e 's|^#[     ]*define[       ]*\([A-Za-z_][A-Za-z0-9_]*\).*| { "'$i'", "\1", \1 },|p' ; done )
+
+echo '};'
diff --git a/freebsd/syscalls.cat b/freebsd/syscalls.cat
new file mode 100644 (file)
index 0000000..0dde7b6
--- /dev/null
@@ -0,0 +1,177 @@
+#
+# Copyright (c) 2000, Gaël Roualland <gael.roualland@iname.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#      $Id$
+#
+# Syscalls categories
+# syntax: syscall catmask
+#
+# mostly built from other archs/os syscallent.h
+
+# file calls
+access TF
+acct   TF
+acl    TF
+chdir  TF
+chmod  TF
+chown  TF
+chroot TF
+creat  TF
+close  TF
+chflags        TF
+fstat64        TF
+fstat  TF
+fchdir TF
+fchflags       TF
+lchown TF
+link   TF
+lstat  TF
+lstat64        TF
+lxstat TF
+mkdir  TF
+mknod  TF
+mount  TF
+oldlstat       TF
+oldstat        TF
+oldumount      TF
+open   TF
+outime TF
+pathconf       TF
+pread  TF
+pwrite TF
+readlink       TF
+rename TF
+rmdir  TF
+sendfile       TF
+stat   TF
+stat64 TF
+statfs TF
+statvfs        TF
+swapon TF
+symlink        TF
+truncate       TF
+umount TF
+unlink TF
+unmount        TF
+uselib TF
+utime  TF
+utimes TF
+xmknod TF
+xstat  TF
+
+# file/process calls
+exec   TF|TP
+execv  TF|TP
+execve TF|TP
+
+# IPC calls
+msgctl TI
+msgget TI
+msgrcv TI
+msgsnd TI
+msgsys TI
+semctl TI
+semget TI
+semop  TI
+semsys TI
+shmat  TI
+shmctl TI
+shmdt  TI
+shmget TI
+shmsys TI
+
+# network calls
+accept TN
+bind   TN
+connect        TN
+getmsg TN
+getpeername    TN
+getpmsg        TN
+getsockname    TN
+getsockopt     TN
+listen TN
+poll   TN
+putmsg TN
+putpmsg        TN
+recv   TN
+recvfrom       TN
+recvmsg        TN
+send   TN
+sendmsg        TN
+sendto TN
+setsockopt     TN
+shutdown       TN
+socket TN
+socketpair     TN
+
+# process calls
+_exit  TP
+clone  TP
+fork   TP
+fork1  TP
+owait  TP
+owait3 TP
+vfork  TP
+wait   TP
+wait4  TP
+waitid TP
+waitpid        TP
+waitsys        TP
+
+# signal calls
+kill   TS
+killpg TS
+ksigqueue      TS
+pause  TS
+rt_sigaction   TS
+rt_sigpending  TS
+rt_sigprocmask TS
+rt_sigqueueinfo        TS
+rt_sigreturn   TS
+rt_sigsuspend  TS
+rt_sigtimedwait        TS
+sigaction      TS
+sigaltstack    TS
+sigblock       TS
+sigcleanup     TS
+sigfillset     TS
+siggetmask     TS
+sighold        TS
+sigignore      TS
+signal TS
+sigpause       TS
+sigpending     TS
+sigpoll        TS
+sigprocmask    TS
+sigrelse       TS
+sigreturn      TS
+sigsendset     TS
+sigset TS
+sigsetmask     TS
+sigstack       TS
+sigsuspend     TS
+sigtimedwait   TS
+sigvec TS
diff --git a/freebsd/syscalls.pl b/freebsd/syscalls.pl
new file mode 100644 (file)
index 0000000..0b072a9
--- /dev/null
@@ -0,0 +1,151 @@
+#!/usr/bin/perl -w
+#
+# Copyright (c) 2000, Gaël Roualland <gael.roualland@iname.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#      $Id$
+#/
+
+# Buils syscall.h and syscallent.h from:
+# - syscalls.cat containing lines of format: syscall catmask
+# - syscalls.print containing lines of format: syscall [printfunction]
+#   if no printfunction is provided, sys_<call> is used.
+# - syscalls.master in the FreeBSD kernel source tree (/usr/src/sys/kern)
+
+use strict;
+use POSIX;
+
+use vars qw(%sysprint %syscat);
+
+sub usage() {
+    print STDERR 
+       "usage: $0 syscalls.master [<syscalls.print>] [<syscalls.cat>]\n";
+    exit 1;
+}
+
+sub readprint ($) {
+    my($fprint) = @_;
+    
+    open (PRINT, "< $fprint") || die "can't open $fprint: $!";
+    while(<PRINT>) {
+       chomp;
+       s/^\s*//;
+       s/\s+$//;
+       s/#.*$//;
+       my($sys, $func) = split(/\s+/);
+       if (defined($sys)) {
+           if (defined($func)) {
+               $sysprint{$sys} = $func;
+           } else {
+               $sysprint{$sys} = "sys_$sys";
+           }
+       }
+    }
+    close(PRINT);
+}
+
+sub readcat ($) {
+    my($fcat) = @_;
+    
+    open (CAT, "< $fcat") || die "can't open $fcat: $!";
+    while(<CAT>) {
+       chomp;
+       s/^\s*//;
+       s/\s+$//;
+       s/#.*$//;
+       my($sys, $cat) = split(/\s+/);
+       $syscat{$sys} = $cat if (defined($sys) && defined($cat));
+    }
+    close(CAT);
+}
+
+
+usage if (!defined($ARGV[0]) || defined($ARGV[3]));
+
+%sysprint = ();
+readprint $ARGV[1] if defined $ARGV[1];
+
+%syscat = ();
+readcat $ARGV[2] if defined $ARGV[2];
+
+open(MASTER, "< $ARGV[0]") || die "can't open $ARGV[0]: $!";
+
+open(SYSCALL, "> syscall.h") || die "can't create syscall.h: $!";
+
+print SYSCALL "/*\n * Automatically generated by $0 on " . ctime(time()) . " */\n\n";
+print "/*\n * Automatically generated by $0 on " . ctime(time()) . " */\n\n";
+
+my $sysnum = 0;
+
+while (<MASTER>) {
+    chomp;
+    # join broken lines
+    while (/\\$/) {
+       my $line;
+       s/\\$//;
+       $line = <MASTER>;
+       chomp($line);
+       $_ = "$_$line";
+    }
+
+    if (/^(\d+)\s+\w+\s+\w+\s+\{\s*([^}]+)\s*\}([^}]*)$/) {
+       my($proto, $ext, $name, $nargs, @args, $pfunc, $cat);
+       
+       $proto = $2;
+       $ext = $3;
+       
+       if ($1 > $sysnum) { # syscall gap
+           while($sysnum < $1) {
+               print "  { -1,\t0,\tprintargs,\t\"SYS_$sysnum\"\t}, /* $sysnum */\n";
+               $sysnum++;
+           }
+       } elsif ($1 < $sysnum) {
+           warn "error in master file: syscall $1 found, expecting $sysnum.";
+       }
+       
+       if ($proto =~ /^[^\s]+\s+([^\s]+)\s*\(([^)]*)\);/) {
+           my @args = split(/,/, $2);
+           $nargs = @args;
+           $name = $1;
+           $name = $1 if ($ext =~ /^\s*([^\s]+)\s+[^\s]+\s+[^\s]+$/);
+           if (defined($sysprint{$name})) {
+               $pfunc = $sysprint{$name};
+               print SYSCALL "int $pfunc();\n";
+           } else {
+               $pfunc = "sys_$name";
+               print SYSCALL "#define $pfunc printargs\n";
+           }
+           if (defined($syscat{$name})) {
+               $cat = $syscat{$name};
+           } else {
+               $cat = "0";
+           }
+           print "  { $nargs,\t$cat,\t$pfunc,\t\"$name\"\t}, /* $sysnum */\n";
+           $sysnum++;
+       } else {
+           warn "bad syscall specification for $sysnum: $proto";
+       }
+    }
+}
diff --git a/freebsd/syscalls.print b/freebsd/syscalls.print
new file mode 100644 (file)
index 0000000..bc59a6f
--- /dev/null
@@ -0,0 +1,192 @@
+#
+# Copyright (c) 2000, Gaël Roualland <gael.roualland@iname.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#      $Id$
+#
+# Printable syscalls
+# syntax: syscall [printfunc]
+#
+# mostly built from sys_* functions in source code
+
+__getcwd
+__sysctl
+accept
+access
+adjtime
+alarm
+bind
+brk
+capget
+capset
+chdir
+chflags
+chmod
+chown
+chroot
+close
+connect
+creat
+dup
+dup2
+errlist
+execv
+execve
+exit
+fchdir
+fchflags
+fchmod
+fchown
+fchroot
+fcntl
+flock
+fork
+fpathconf
+fstat
+fstatfs
+fsync
+ftruncate
+getdents
+getdirentries
+getdomainname
+getdtablesize
+getgid
+getgroups
+gethostid
+gethostname
+getitimer
+getpagesize
+getpeername
+getpgid
+getpgrp
+getpid
+getpriority
+getrlimit
+getrusage
+getsid
+getsockname
+getsockopt
+gettimeofday
+getuid
+indir
+ioctl
+kill
+killpg
+link
+listen
+lseek
+lstat
+mincore
+mkdir
+mkfifo
+mknod
+mmap
+mprotect
+msgctl
+msgget
+msgrcv
+msgsnd
+msync
+munmap
+nerr
+nice
+open
+pathconf
+pipe
+poll
+pread
+ptrace
+pwrite
+quotactl
+read
+readlink
+readv
+recv
+recvfrom
+recvmsg
+rename
+rmdir
+sbrk
+select
+semctl
+semget
+semop
+send
+sendfile
+sendmsg
+sendto
+setdomainname
+setgroups
+sethostname
+setitimer
+setpgid
+setpgrp
+setpriority
+setregid
+setresgid
+setresuid
+setreuid
+setrlimit
+setsid
+setsockopt
+settimeofday
+shmat
+shmctl
+shmdt
+shmget
+shutdown
+sigaction
+sigaltstack
+sigblock
+sigcleanup
+signal
+sigpause
+sigpending
+sigprocmask
+sigsetmask
+sigstack
+sigsuspend
+sigvec
+socket
+socketpair
+stat
+statfs
+stime
+symlink
+sysctl
+time
+times
+truncate
+umask
+uname
+unlink
+utime
+utimes
+vfork
+wait
+wait4
+waitpid
+write
+writev
diff --git a/io.c b/io.c
index 45c34135fc5529eb5d2f653118b75f370f98eab8..a819c1113d850d7f6e56495325418c2a75467ec1 100644 (file)
--- a/io.c
+++ b/io.c
@@ -63,13 +63,47 @@ struct tcb *tcp;
        return 0;
 }
 
+void
+tprint_iov(tcp, len, addr)
+struct tcb * tcp;
+int len;
+char * addr;
+{
+       struct iovec *iov;
+       int i;
+
+
+       if (!len) {
+               tprintf("[]");
+               return;
+       }
+         
+       if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
+               fprintf(stderr, "No memory");
+               return;
+       }
+       if (umoven(tcp, (int) addr,
+                  len * sizeof *iov, (char *) iov) < 0) {
+               tprintf("%#lx", tcp->u_arg[1]);
+       } else {
+               tprintf("[");
+               for (i = 0; i < len; i++) {
+                       if (i)
+                               tprintf(", ");
+                       tprintf("{");
+                       printstr(tcp, (long) iov[i].iov_base,
+                               iov[i].iov_len);
+                       tprintf(", %lu}", (unsigned long)iov[i].iov_len);
+               }
+               tprintf("]");
+       }
+       free((char *) iov);
+}
+
 int
 sys_readv(tcp)
 struct tcb *tcp;
 {
-       struct iovec *iov;
-       int i, len;
-
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
        } else {
@@ -78,27 +112,7 @@ struct tcb *tcp;
                                        tcp->u_arg[1], tcp->u_arg[2]);
                        return 0;
                }
-               len = tcp->u_arg[2];
-               if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
-                       fprintf(stderr, "No memory");
-                       return 0;
-               }
-               if (umoven(tcp, tcp->u_arg[1],
-                               len * sizeof *iov, (char *) iov) < 0) {
-                       tprintf("%#lx", tcp->u_arg[1]);
-               } else {
-                       tprintf("[");
-                       for (i = 0; i < len; i++) {
-                               if (i)
-                                       tprintf(", ");
-                               tprintf("{");
-                               printstr(tcp, (long) iov[i].iov_base,
-                                       iov[i].iov_len);
-                               tprintf(", %lu}", (unsigned long)iov[i].iov_len);
-                       }
-                       tprintf("]");
-               }
-               free((char *) iov);
+               tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
                tprintf(", %lu", tcp->u_arg[2]);
        }
        return 0;
@@ -108,39 +122,15 @@ int
 sys_writev(tcp)
 struct tcb *tcp;
 {
-       struct iovec *iov;
-       int i, len;
-
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
-               len = tcp->u_arg[2];
-               iov = (struct iovec *) malloc(len * sizeof *iov);
-               if (iov == NULL) {
-                       fprintf(stderr, "No memory");
-                       return 0;
-               }
-               if (umoven(tcp, tcp->u_arg[1],
-                               len * sizeof *iov, (char *) iov) < 0) {
-                       tprintf("%#lx", tcp->u_arg[1]);
-               } else {
-                       tprintf("[");
-                       for (i = 0; i < len; i++) {
-                               if (i)
-                                       tprintf(", ");
-                               tprintf("{");
-                               printstr(tcp, (long) iov[i].iov_base,
-                                       iov[i].iov_len);
-                               tprintf(", %lu}", (unsigned long)iov[i].iov_len);
-                       }
-                       tprintf("]");
-               }
-               free((char *) iov);
+               tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
                tprintf(", %lu", tcp->u_arg[2]);
        }
        return 0;
 }
 
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
 
 int
 sys_pread(tcp)
@@ -157,9 +147,14 @@ struct tcb *tcp;
                /* off_t is signed int */
                tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
 #else
+#ifndef FREEBSD
                tprintf(", %lu, %llu", tcp->u_arg[2],
                                (((unsigned long long) tcp->u_arg[4]) << 32
                                 | tcp->u_arg[3]));
+#else
+               tprintf(", %lu, %llu", tcp->u_arg[2], 
+                               (((off_t) tcp->u_arg[3]) << 32) +  tcp->u_arg[4]);
+#endif
 #endif
        }
        return 0;
@@ -176,14 +171,61 @@ struct tcb *tcp;
                /* off_t is signed int */
                tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
 #else
+#ifndef FREEBSD
                tprintf(", %lu, %llu", tcp->u_arg[2],
                                (((unsigned long long) tcp->u_arg[4]) << 32
                                 | tcp->u_arg[3]));
+#else
+               tprintf(", %lu, %llu", tcp->u_arg[2],
+                               (((off_t) tcp->u_arg[3]) << 32) + tcp->u_arg[4]);
+#endif
 #endif
        }
        return 0;
 }
-#endif /* SVR4 */
+#endif /* SVR4 || FREEBSD */
+
+#ifdef FREEBSD
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+sys_sendfile(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               tprintf("%ld, %ld, %llu, %lu", tcp->u_arg[0], tcp->u_arg[1],
+                       (((unsigned long long) tcp->u_arg[3]) << 32 |
+                        tcp->u_arg[2]), tcp->u_arg[4]);
+       } else {
+               off_t offset;
+
+               if (!tcp->u_arg[5])
+                       tprintf(", NULL");
+               else {
+                       struct sf_hdtr hdtr;
+
+                       if (umove(tcp, tcp->u_arg[5], &hdtr) < 0)
+                               tprintf(", %#lx", tcp->u_arg[5]);
+                       else {
+                               tprintf(", { ");
+                               tprint_iov(tcp, hdtr.hdr_cnt, hdtr.headers);
+                               tprintf(", %u, ", hdtr.hdr_cnt);
+                               tprint_iov(tcp, hdtr.trl_cnt, hdtr.trailers);
+                               tprintf(", %u }", hdtr.hdr_cnt);
+                       }
+               }
+               if (!tcp->u_arg[6])
+                       tprintf(", NULL");
+               else if (umove(tcp, tcp->u_arg[6], &offset) < 0)
+                       tprintf(", %#lx", tcp->u_arg[6]);
+               else
+                       tprintf(", [%llu]", offset);
+               tprintf(", %lu", tcp->u_arg[7]);
+       }
+       return 0;
+}
+#endif /* FREEBSD */
 
 #ifdef LINUX
 int
diff --git a/ioctl.c b/ioctl.c
index f4bb784eff7cc69dff831b06e6df8946e52e0dce..ed2a32bcca4476e13e9084962e1dded7516dcc1f 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -105,15 +105,22 @@ long code, arg;
 #ifdef LINUX
        case 0x89:
 #else /* !LINUX */
-       case 'r': case 's': case 'i': case 'p':
+       case 'r': case 's': case 'i':
+#ifndef FREEBSD                
+       case 'p':
+#endif         
 #endif /* !LINUX */
                return sock_ioctl(tcp, code, arg);
-#ifdef SVR4
+#ifdef USE_PROCFS
 #ifndef HAVE_MP_PROCFS
+#ifndef FREEBSD
        case 'q':
+#else
+       case 'p':
+#endif         
                return proc_ioctl(tcp, code, arg);
 #endif
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 #ifdef HAVE_SYS_STREAM_H
        case 'S':
                return stream_ioctl(tcp, code, arg);
diff --git a/ipc.c b/ipc.c
index e4dacabdbed039e4fa7e76585e6b6a1b38da6b00..06688f0a5133fc3f58ce668391808c14b71095a1 100644 (file)
--- a/ipc.c
+++ b/ipc.c
@@ -32,7 +32,7 @@
 
 #include "defs.h"
 
-#if defined(LINUX) || defined(SUNOS4)
+#if defined(LINUX) || defined(SUNOS4) || defined(FREEBSD)
 
 #include <sys/ipc.h>
 #include <sys/sem.h>
@@ -98,8 +98,12 @@ static struct xlat shmctl_flags[] = {
        { SHM_STAT,     "SHM_STAT"      },
        { SHM_INFO,     "SHM_INFO"      },
 #endif /* LINUX */
+#ifdef SHM_LOCK        
        { SHM_LOCK,     "SHM_LOCK"      },
+#endif
+#ifdef SHM_UNLOCK      
        { SHM_UNLOCK,   "SHM_UNLOCK"    },
+#endif 
        { 0,            NULL            },
 };
 
@@ -352,4 +356,4 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* defined(LINUX) || defined(SUNOS4) */
+#endif /* defined(LINUX) || defined(SUNOS4) || defined(FREEBSD) */
diff --git a/mem.c b/mem.c
index 73a72fcc2a140ccf06fd6185ea50448d34f966a4..0d728703db99fd925023cd56646f0cef46469fb1 100644 (file)
--- a/mem.c
+++ b/mem.c
@@ -133,6 +133,22 @@ static struct xlat mmap_flags[] = {
 #endif
 #ifdef MAP_LOCKED
        { MAP_LOCKED,"MAP_LOCKED"},
+#endif
+       /* FreeBSD ones */
+#ifdef MAP_ANON
+       { MAP_ANON,             "MAP_ANON"      },
+#endif
+#ifdef MAP_HASSEMAPHORE
+       { MAP_HASSEMAPHORE,     "MAP_HASSEMAPHORE"      },
+#endif
+#ifdef MAP_STACK
+       { MAP_STACK,            "MAP_STACK"     },
+#endif
+#ifdef MAP_NOSYNC
+       { MAP_NOSYNC,           "MAP_NOSYNC"    },
+#endif
+#ifdef MAP_NOCORE
+       { MAP_NOCORE,           "MAP_NOCORE"    },
 #endif
        { 0,            NULL            },
 };
@@ -155,8 +171,12 @@ long *u_arg;
                printflags(mmap_prot, u_arg[2]);
                tprintf(", ");
                /* flags */
+#ifdef MAP_TYPE
                printxval(mmap_flags, u_arg[3] & MAP_TYPE, "MAP_???");
                addflags(mmap_flags, u_arg[3] & ~MAP_TYPE);
+#else
+               printflags(mmap_flags, u_arg[3]);
+#endif
                /* fd */
                tprintf(", %ld, ", u_arg[4]);
                /* offset */
diff --git a/net.c b/net.c
index db88c6d6df91a62ca463007e7cc62953b4438d5c..da061c87cefc91021a80e398115fd7cc76b27c20 100644 (file)
--- a/net.c
+++ b/net.c
@@ -36,6 +36,9 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <netinet/in.h>
+#ifdef FREEBSD
+#include <netinet/tcp.h>
+#endif
 #include <arpa/inet.h>
 #if defined(LINUX)
 #include <asm/types.h>
diff --git a/proc.c b/proc.c
index d4969a6cbff2f8bcb2c3f7498a9dd315487142d0..854657d4193951d40ea44a2f041393c05b08c7d7 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -186,3 +186,88 @@ int code, arg;
 #endif /* HAVE_MP_PROCFS */
 #endif /* SVR4 */
 
+#ifdef FREEBSD
+#include <sys/pioctl.h>
+
+static struct xlat proc_status_why[] = {
+       { S_EXEC,       "S_EXEC"        },
+       { S_SIG,        "S_SIG"         },
+       { S_SCE,        "S_SCE"         },
+       { S_SCX,        "S_SCX"         },
+       { S_CORE,       "S_CORE"        },
+       { S_EXIT,       "S_EXIT"        },
+       { 0,            NULL            }
+};
+
+static struct xlat proc_status_flags[] = {
+       { PF_LINGER,    "PF_LINGER"     },
+       { PF_ISUGID,    "PF_ISUGID"     },
+       { 0,            NULL            }
+};
+
+int
+proc_ioctl(tcp, code, arg)
+struct tcb *tcp;
+int code, arg;
+{
+       int val;
+       struct procfs_status status;
+
+       if (entering(tcp))
+               return 0;
+
+       switch (code) {
+       case PIOCSTATUS:
+       case PIOCWAIT:
+               if (arg == 0)
+                       tprintf(", NULL");
+               else if (syserror(tcp))
+                       tprintf(", %x", arg);
+               else if (umove(tcp, arg, &status) < 0)
+                       tprintf(", {...}");
+               else {
+                       tprintf(", {state=%d, flags=", status.state);
+                       if (!printflags(proc_status_flags, status.flags))
+                               tprintf("0");
+                       tprintf(", events=");
+                       printflags(proc_status_why, status.events);
+                       tprintf(", why=");
+                       printxval(proc_status_why, status.why, "S_???");
+                       tprintf(", val=%lu}", status.val);
+               }
+               return 1;
+       case PIOCBIS:
+               if (arg) {
+                       tprintf(", ");
+                       printflags(proc_status_why, arg);
+               } else
+                       tprintf(", 0");
+               return 1;
+               return 1;
+       case PIOCSFL:
+               if (arg) {
+                       tprintf(", ");
+                       printflags(proc_status_flags, arg);
+               } else
+                       tprintf(", 0");
+               return 1;
+       case PIOCGFL:
+               if (syserror(tcp))
+                       tprintf(", %#x", arg);
+               else if (umove(tcp, arg, &val) < 0)
+                       tprintf(", {...}");
+               else {
+                       tprintf(", [");
+                       if (val)
+                               printflags(proc_status_flags, val);
+                       else
+                               tprintf("0");
+                       tprintf("]");
+               }
+               return 1;
+       default:
+               /* ad naseum */
+               return 0;
+       }
+}
+#endif
index b409fa1f87e4f9e200e8bd6e7d60d2bbf9476147..dda3b9eef61fb6abdd4a08bf069816f65f363c88 100644 (file)
--- a/process.c
+++ b/process.c
 #include <machine/reg.h>
 #endif /* SUNOS4 */
 
+#ifdef FREEBSD
+#include <sys/ptrace.h>
+#endif
+
 #ifdef HAVE_SYS_REG_H
 # include <sys/reg.h>
 #ifndef PTRACE_PEEKUSR
@@ -333,7 +337,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 
 int
 sys_fork(tcp)
@@ -372,12 +376,13 @@ struct tcb *tcp;
                        fprintf(stderr, "sys_fork: tcb table full\n");
                        return 0;
                }
-               proc_open(tcpchild, 1);
+               if (proc_open(tcpchild, 1) < 0)
+                       droptcb(tcpchild);
        }
        return 0;
 }
 
-#else /* !SVR4 */
+#else /* !USE_PROCFS */
 
 #ifdef LINUX
 
@@ -673,9 +678,9 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
-#if defined(SUNOS4) || defined(LINUX)
+#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
 
 int
 sys_vfork(tcp)
@@ -686,7 +691,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* SUNOS4 || LINUX */
+#endif /* SUNOS4 || LINUX || FREEBSD */
 
 #ifndef LINUX
 
@@ -832,7 +837,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#ifdef LINUX
+#if defined(LINUX) || defined(FREEBSD)
 int
 sys_setresuid(tcp)
      struct tcb *tcp;
@@ -858,7 +863,7 @@ sys_setresgid(tcp)
        return 0;
 }
 
-#endif /* LINUX */
+#endif /* LINUX || FREEBSD */
 
 int
 sys_setgroups(tcp)
@@ -1280,6 +1285,25 @@ struct tcb *tcp;
 
 #endif /* SVR4 */
 
+#ifdef FREEBSD
+int
+sys_wait(tcp)
+struct tcb *tcp;
+{
+       int status;
+       
+       if (exiting(tcp)) {
+               if (!syserror(tcp)) {
+                       if (umove(tcp, tcp->u_arg[0], &status) < 0)
+                               tprintf("%#lx", tcp->u_arg[0]);
+                       else
+                               printstatus(status);
+               }
+       }
+       return 0;
+}
+#endif
+
 int
 sys_waitpid(tcp)
 struct tcb *tcp;
@@ -1608,6 +1632,7 @@ struct tcb *tcp;
 #ifndef SVR4
 
 static struct xlat ptrace_cmds[] = {
+#ifndef FREEBSD        
        { PTRACE_TRACEME,       "PTRACE_TRACEME"        },
        { PTRACE_PEEKTEXT,      "PTRACE_PEEKTEXT",      },
        { PTRACE_PEEKDATA,      "PTRACE_PEEKDATA",      },
@@ -1653,9 +1678,29 @@ static struct xlat ptrace_cmds[] = {
 #endif /* !I386 */
        { PTRACE_GETUCODE,      "PTRACE_GETUCODE"       },
 #endif /* SUNOS4 */
+#else /* FREEBSD */
+       { PT_TRACE_ME,          "PT_TRACE_ME"           },
+       { PT_READ_I,            "PT_READ_I"             },
+       { PT_READ_D,            "PT_READ_D"             },
+       { PT_WRITE_I,           "PT_WRITE_I"            },
+       { PT_WRITE_D,           "PT_WRITE_D"            },
+       { PT_READ_U,            "PT_WRITE_U"            },
+       { PT_CONTINUE,          "PT_CONTINUE"           },
+       { PT_KILL,              "PT_KILL"               },
+       { PT_STEP,              "PT_STEP"               },
+       { PT_ATTACH,            "PT_ATTACH"             },
+       { PT_DETACH,            "PT_DETACH"             },
+       { PT_GETREGS,           "PT_GETREGS"            },
+       { PT_SETREGS,           "PT_SETREGS"            },
+       { PT_GETFPREGS,         "PT_GETFPREGS"          },
+       { PT_SETFPREGS,         "PT_SETFPREGS"          },
+       { PT_GETDBREGS,         "PT_GETDBREGS"          },
+       { PT_SETDBREGS,         "PT_SETDBREGS"          },
+#endif /* FREEBSD */
        { 0,                    NULL                    },
 };
 
+#ifndef FREEBSD
 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
 static
 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
@@ -2038,6 +2083,7 @@ struct xlat struct_user_offsets[] = {
        { sizeof(struct user),  "sizeof(struct user)"                   },
        { 0,                    NULL                                    },
 };
+#endif
 
 int
 sys_ptrace(tcp)
@@ -2049,10 +2095,15 @@ struct tcb *tcp;
 
        cmd = xlookup(ptrace_cmds, tcp->u_arg[0]);
        if (!cmd)
+#ifndef FREEBSD
                cmd = "PTRACE_???";
+#else
+               cmd = "PT_???";
+#endif         
        if (entering(tcp)) {
                tprintf("%s, %lu, ", cmd, tcp->u_arg[1]);
                addr = tcp->u_arg[2];
+#ifndef FREEBSD
                if (tcp->u_arg[0] == PTRACE_PEEKUSER
                        || tcp->u_arg[0] == PTRACE_POKEUSER) {
                        for (x = struct_user_offsets; x->str; x++) {
@@ -2069,6 +2120,7 @@ struct tcb *tcp;
                                tprintf("%s, ", x->str);
                }
                else
+#endif
                        tprintf("%#lx, ", tcp->u_arg[2]);
 #ifdef LINUX
                switch (tcp->u_arg[0]) {
@@ -2113,6 +2165,10 @@ struct tcb *tcp;
                }
        }
 #endif /* SUNOS4 */
+#ifdef FREEBSD
+               tprintf("%lu", tcp->u_arg[3]);
+       }
+#endif /* FREEBSD */
        return 0;
 }
 
index 74222f4d3e6aedcb950f9a45f2c7a2f22100bb18..be776cec718e1f6709909d8317795f322dd64821 100644 (file)
@@ -41,7 +41,7 @@
 #ifdef SUNOS4
 #include <ufs/quota.h>
 #endif /* SUNOS4 */
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
 #include <sys/times.h>
 #include <sys/time.h>
 #endif
@@ -439,14 +439,23 @@ struct tcb *tcp;
 
 #endif /* Linux */
 
-#ifdef SUNOS4
+#if defined(SUNOS4) || defined(FREEBSD)
+
+#ifdef FREEBSD
+#include <ufs/ufs/quota.h>
+#endif
 
 static struct xlat quotacmds[] = {
        { Q_QUOTAON,    "Q_QUOTAON"     },
        { Q_QUOTAOFF,   "Q_QUOTAOFF"    },
        { Q_GETQUOTA,   "Q_GETQUOTA"    },
        { Q_SETQUOTA,   "Q_SETQUOTA"    },
+#ifdef Q_SETQLIM
        { Q_SETQLIM,    "Q_SETQLIM"     },
+#endif
+#ifdef Q_SETUSE
+       { Q_SETUSE,     "Q_SETUSE"      },
+#endif
        { Q_SYNC,       "Q_SYNC"        },
        { 0,            NULL            },
 };
@@ -457,12 +466,19 @@ struct tcb *tcp;
 {
        /* fourth arg (addr) not interpreted here */
        if (entering(tcp)) {
+#ifdef SUNOS4
                printxval(quotacmds, tcp->u_arg[0], "Q_???");
                tprintf(", ");
                printstr(tcp, tcp->u_arg[1], -1);
+#endif
+#ifdef FREEBSD
+               printpath(tcp, tcp->u_arg[0]);
+               tprintf(", ");
+               printxval(quotacmds, tcp->u_arg[1], "Q_???");
+#endif         
                tprintf(", %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
        }
        return 0;
 }
 
-#endif /* SUNOS4 */
+#endif /* SUNOS4 || FREEBSD */
index 90ac5fe8896cf1cad4a66950afb3b610addfa723..1b807d886df7f839bfa56282056d735b7a63192c 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -146,7 +146,7 @@ int nsignals2 = sizeof signalent2 / sizeof signalent2[0];
 char **signalent;
 int nsignals;
 
-#ifdef SUNOS4
+#if defined(SUNOS4) || defined(FREEBSD)
 
 static struct xlat sigvec_flags[] = {
        { SV_ONSTACK,   "SV_ONSTACK"    },
@@ -156,7 +156,7 @@ static struct xlat sigvec_flags[] = {
        { 0,            NULL            },
 };
 
-#endif /* SUNOS4 */
+#endif /* SUNOS4 || FREEBSD */
 
 #ifdef HAVE_SIGACTION
 
@@ -429,7 +429,7 @@ int sig;
 #endif /* !SVR4 */
 }
 
-#if defined(SUNOS4)
+#if defined(SUNOS4) || defined(FREEBSD)
 
 int
 sys_sigvec(tcp)
@@ -534,7 +534,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* SUNOS4 */
+#endif /* SUNOS4 || FREEBSD */
 
 #ifndef SVR4
 
@@ -546,12 +546,14 @@ struct tcb *tcp;
                sigset_t sigm;
                long_to_sigset(tcp->u_arg[0], &sigm);
                printsigmask(&sigm, 0);
+#ifndef USE_PROCFS
                if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
                        /* Mark attempt to block SIGTRAP */
                        tcp->flags |= TCB_SIGTRAPPED;
                        /* Send unblockable signal */
                        kill(tcp->pid, SIGSTOP);
                }
+#endif /* !USE_PROCFS */               
        }
        else if (!syserror(tcp)) {
                sigset_t sigm;
@@ -622,21 +624,21 @@ struct tcb *tcp;
                        tprintf("{SIG_DFL}");
                        break;
                case (long) SIG_IGN:
-#ifndef SVR4
+#ifndef USE_PROCFS
                        if (tcp->u_arg[0] == SIGTRAP) {
                                tcp->flags |= TCB_SIGTRAPPED;
                                kill(tcp->pid, SIGSTOP);
                        }
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
                        tprintf("{SIG_IGN}");
                        break;
                default:
-#ifndef SVR4
+#ifndef USE_PROCFS
                        if (tcp->u_arg[0] == SIGTRAP) {
                                tcp->flags |= TCB_SIGTRAPPED;
                                kill(tcp->pid, SIGSTOP);
                        }
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
                        tprintf("{%#lx, ", (long) sa.SA_HANDLER);
 #ifndef LINUX
                        printsigmask (&sa.sa_mask, 0);
@@ -674,21 +676,21 @@ struct tcb *tcp;
                        tprintf("SIG_DFL");
                        break;
                case (int) SIG_IGN:
-#ifndef SVR4
+#ifndef USE_PROCFS
                        if (tcp->u_arg[0] == SIGTRAP) {
                                tcp->flags |= TCB_SIGTRAPPED;
                                kill(tcp->pid, SIGSTOP);
                        }
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
                        tprintf("SIG_IGN");
                        break;
                default:
-#ifndef SVR4
+#ifndef USE_PROCFS
                        if (tcp->u_arg[0] == SIGTRAP) {
                                tcp->flags |= TCB_SIGTRAPPED;
                                kill(tcp->pid, SIGSTOP);
                        }
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
                        tprintf("%#lx", tcp->u_arg[1]);
                }
                return 0;
@@ -960,7 +962,7 @@ struct tcb *tcp;
 
 #endif /* LINUX */
 
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
 
 int
 sys_sigsuspend(tcp)
@@ -976,6 +978,7 @@ struct tcb *tcp;
        }
        return 0;
 }
+#ifndef FREEBSD
 static struct xlat ucontext_flags[] = {
        { UC_SIGMASK,   "UC_SIGMASK"    },
        { UC_STACK,     "UC_STACK"      },
@@ -988,10 +991,10 @@ static struct xlat ucontext_flags[] = {
 #endif
        { 0,            NULL            },
 };
+#endif /* !FREEBSD */
+#endif /* SVR4 || FREEBSD */
 
-#endif
-
-#if defined SVR4 || defined LINUX
+#if defined SVR4 || defined LINUX || defined FREEBSD
 #if defined LINUX && !defined SS_ONSTACK
 #define SS_ONSTACK      1
 #define SS_DISABLE      2
@@ -1004,6 +1007,9 @@ typedef struct
 } stack_t;
 #endif
 #endif
+#ifdef FREEBSD
+#define stack_t struct sigaltstack
+#endif
 
 static struct xlat sigaltstack_flags[] = {
        { SS_ONSTACK,   "SS_ONSTACK"    },
@@ -1082,7 +1088,7 @@ struct tcb *tcp;
 
 #endif /* SVR4 */
 
-#ifdef LINUX
+#if defined(LINUX) || defined(FREEBSD)
 
 static int
 print_stack_t(tcp, addr)
index f96eaa04d88c45fd2132078972343445f33feab4..3e4b4a610c3b31851ba37a1151a639d8afbaa84b 100644 (file)
--- a/strace.c
+++ b/strace.c
 #include <grp.h>
 #include <string.h>
 
+#ifdef USE_PROCFS
+#include <poll.h>
+#endif
+
 #ifdef SVR4
 #include <sys/stropts.h>
-#include <poll.h>
 #ifdef HAVE_MP_PROCFS
 #include <sys/uio.h>
 #endif
@@ -87,7 +90,7 @@ static int interrupted;
 #endif /* !__STDC__ */
 #endif /* !HAVE_SIG_ATOMIC_T */
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 
 static struct tcb *pfd2tcb P((int pfd));
 static void reaper P((int sig));
@@ -115,7 +118,7 @@ static int proc_poll_pipe[2] = { -1, -1 };
 #else
 #define POLLWANT       POLLPRI
 #endif
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
 static void
 usage(ofp, exitval)
@@ -334,19 +337,19 @@ char *argv[];
                tcp->outf = outf;
                if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED))
                        continue;
-#ifdef SVR4
+#ifdef USE_PROCFS
                if (proc_open(tcp, 1) < 0) {
                        fprintf(stderr, "trouble opening proc file\n");
                        droptcb(tcp);
                        continue;
                }
-#else /* !SVR4 */
+#else /* !USE_PROCFS */
                if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) {
                        perror("attach: ptrace(PTRACE_ATTACH, ...)");
                        droptcb(tcp);
                        continue;
                }
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
                if (!qflag)
                        fprintf(stderr,
                                "Process %u attached - interrupt to quit\n",
@@ -408,8 +411,8 @@ char *argv[];
                        exit(1);
                        break;
                case 0: {
-#ifdef SVR4
-                       if (outf != stderr) close (fileno (outf));
+#ifdef USE_PROCFS
+                       if (outf != stderr) close (fileno (outf));
 #ifdef MIPS
                        /* Kludge for SGI, see proc_open for details. */
                        sa.sa_handler = foobar;
@@ -417,8 +420,12 @@ char *argv[];
                        sigemptyset(&sa.sa_mask);
                        sigaction(SIGINT, &sa, NULL);
 #endif /* MIPS */
+#ifndef FREEBSD
                        pause();
-#else /* !SVR4 */
+#else /* FREEBSD */
+                       kill(getpid(), SIGSTOP); /* stop HERE */
+#endif /* FREEBSD */                   
+#else /* !USE_PROCFS */
                        if (outf!=stderr)       
                                close(fileno (outf));
 
@@ -459,7 +466,7 @@ char *argv[];
                        }
                        else
                                setreuid(run_uid, run_uid);
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
                        execv(pathname, &argv[optind]);
                        perror("strace: exec");
@@ -472,16 +479,16 @@ char *argv[];
                                cleanup();
                                exit(1);
                        }
-#ifdef SVR4
+#ifdef USE_PROCFS
                        if (proc_open(tcp, 0) < 0) {
                                fprintf(stderr, "trouble opening proc file\n");
                                cleanup();
                                exit(1);
                        }
-#endif /* SVR4 */
-#ifndef SVR4
+#endif /* USE_PROCFS */
+#ifndef USE_PROCFS
                        fake_execve(tcp, pathname, &argv[optind], environ);
-#endif
+#endif /* !USE_PROCFS */
                        break;
                }
        }
@@ -512,10 +519,10 @@ char *argv[];
        sigaction(SIGQUIT, &sa, NULL);
        sigaction(SIGPIPE, &sa, NULL);
        sigaction(SIGTERM, &sa, NULL);
-#ifdef SVR4
+#ifdef USE_PROCFS
        sa.sa_handler = reaper;
        sigaction(SIGCHLD, &sa, NULL);
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
        if (trace() < 0)
                exit(1);
@@ -572,7 +579,7 @@ int pid;
        return NULL;
 }
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 int
 proc_open(tcp, attaching)
 struct tcb *tcp;
@@ -580,9 +587,11 @@ int attaching;
 {
        char proc[32];
        long arg;
+#ifdef SVR4
        sysset_t sc_enter, sc_exit;
        sigset_t signals;
        fltset_t faults;
+#endif
 #ifndef HAVE_POLLABLE_PROCFS
        static int last_pfd;
 #endif
@@ -630,8 +639,13 @@ int attaching;
        }
 #else
        /* Open the process pseudo-file in /proc. */
+#ifndef FREEBSD
        sprintf(proc, "/proc/%d", tcp->pid);
        if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
+#else /* FREEBSD */
+       sprintf(proc, "/proc/%d/mem", tcp->pid);
+       if ((tcp->pfd = open(proc, O_RDWR)) < 0) {
+#endif /* FREEBSD */
                perror("strace: open(\"/proc/...\", ...)");
                return -1;
        }
@@ -644,6 +658,21 @@ int attaching;
                return -1;
        }
 #endif
+#ifdef FREEBSD
+       sprintf(proc, "/proc/%d/regs", tcp->pid);
+       if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) {
+               perror("strace: open(\"/proc/.../regs\", ...)");
+               return -1;
+       }
+       if (cflag) {
+               sprintf(proc, "/proc/%d/status", tcp->pid);
+               if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) {
+                       perror("strace: open(\"/proc/.../status\", ...)");
+                       return -1;
+               }
+       } else
+               tcp->pfd_status = -1;
+#endif /* FREEBSD */
        rebuild_pollv();
        if (!attaching) {
                /*
@@ -655,15 +684,21 @@ int attaching;
                                perror("strace: PIOCSTATUS");
                                return -1;
                        }
+#ifndef FREEBSD                        
                        if (tcp->status.PR_FLAGS & PR_ASLEEP)
-                               break;
+#else
+                       if (tcp->status.state == 1)
+#endif
+                           break;
                }
        }
+#ifndef FREEBSD
        /* Stop the process so that we own the stop. */
        if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) {
                perror("strace: PIOCSTOP");
                return -1;
        }
+#endif 
 #ifdef PIOCSET
        /* Set Run-on-Last-Close. */
        arg = PR_RLC;
@@ -678,6 +713,7 @@ int attaching;
                return -1;
        }
 #else  /* !PIOCSET */
+#ifndef FREEBSD        
        if (ioctl(tcp->pfd, PIOCSRLC) < 0) {
                perror("PIOCSRLC");
                return -1;
@@ -686,7 +722,20 @@ int attaching;
                perror("PIOC{S,R}FORK");
                return -1;
        }
+#else /* FREEBSD */
+       /* just unset the PF_LINGER flag for the Run-on-Last-Close. */
+       if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) {
+               perror("PIOCGFL");
+               return -1;
+       }
+       arg &= ~PF_LINGER;
+       if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) {
+               perror("PIOCSFL");
+               return -1;
+       }
+#endif /* FREEBSD */
 #endif /* !PIOCSET */
+#ifndef FREEBSD
        /* Enable all syscall entries. */
        prfillset(&sc_enter);
        if (IOCTL(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
@@ -711,6 +760,14 @@ int attaching;
                perror("PIOCSFAULT");
                return -1;
        }
+#else /* FREEBSD */
+       /* set events flags. */
+       arg = S_SIG | S_SCE | S_SCX ;
+       if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) {
+               perror("PIOCBIS");
+               return -1;
+       }
+#endif /* FREEBSD */
        if (!attaching) {
 #ifdef MIPS
                /*
@@ -719,13 +776,19 @@ int attaching;
                 */
                kill(tcp->pid, SIGINT);
 #else /* !MIPS */
+#ifdef PRSABORT        
                /* The child is in a pause(), abort it. */
                arg = PRSABORT;
                if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
                        perror("PIOCRUN");
                        return -1;
                }
-#endif /* !MIPS */
+#endif         
+#endif /* !MIPS*/
+#ifdef FREEBSD
+               /* wake up the child if it received the SIGSTOP */
+               kill(tcp->pid, SIGCONT);
+#endif         
                for (;;) {
                        /* Wait for the child to do something. */
                        if (IOCTL_WSTOP (tcp) < 0) {
@@ -733,22 +796,40 @@ int attaching;
                                return -1;
                        }
                        if (tcp->status.PR_WHY == PR_SYSENTRY) {
-#ifdef HAVE_PR_SYSCALL
-                               int scno = tcp->status.pr_syscall;
-#else /* !HAVE_PR_SYSCALL */
-                               int scno = tcp->status.PR_WHAT;
-#endif /* !HAVE_PR_SYSCALL */
-                               if (scno == SYS_execve)
+                               tcp->flags &= ~TCB_INSYSCALL;
+                               get_scno(tcp);
+                               if (tcp->scno == SYS_execve)
                                        break;
                        }
                        /* Set it running: maybe execve will be next. */
+#ifndef FREEBSD
                        arg = 0;
                        if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
+#else /* FREEBSD */
+                       if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) {
+#endif /* FREEBSD */                     
                                perror("PIOCRUN");
                                return -1;
                        }
+#ifdef FREEBSD
+                       /* handle the case where we "opened" the child before
+                          it did the kill -STOP */
+                       if (tcp->status.PR_WHY == PR_SIGNALLED &&
+                           tcp->status.PR_WHAT == SIGSTOP)
+                               kill(tcp->pid, SIGCONT);
+#endif                 
                }
+#ifndef FREEBSD
        }
+#else /* FREEBSD */
+       } else {
+              /* little hack to show the current syscall */
+              IOCTL_STATUS(tcp);
+              tcp->flags &= ~TCB_INSYSCALL;
+              tcp->status.why = PR_SYSENTRY;
+              trace_syscall(tcp);
+       }
+#endif /* FREEBSD */
 #ifndef HAVE_POLLABLE_PROCFS
        if (proc_poll_pipe[0] != -1)
                proc_poller(tcp->pfd);
@@ -762,7 +843,7 @@ int attaching;
        return 0;
 }
 
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
 static struct tcb *
 pid2tcb(pid)
@@ -780,7 +861,7 @@ int pid;
        return NULL;
 }
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 
 static struct tcb *
 pfd2tcb(pfd)
@@ -798,7 +879,7 @@ int pfd;
        return NULL;
 }
 
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
 void
 droptcb(tcp)
@@ -812,7 +893,17 @@ struct tcb *tcp;
        if (tcp->pfd != -1) {
                close(tcp->pfd);
                tcp->pfd = -1;
-#ifdef SVR4
+#ifdef FREEBSD
+               if (tcp->pfd_reg != -1) {
+                       close(tcp->pfd_reg);
+                       tcp->pfd_reg = -1;
+               }
+               if (tcp->pfd_status != -1) {
+                       close(tcp->pfd_status);
+                       tcp->pfd_status = -1;
+               }
+#endif /* !FREEBSD */          
+#ifdef USE_PROCFS
                rebuild_pollv();
 #endif
        }
@@ -827,7 +918,7 @@ struct tcb *tcp;
        tcp->outf = 0;
 }
 
-#ifndef SVR4
+#ifndef USE_PROCFS
 
 static int
 resume(tcp)
@@ -852,7 +943,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
 /* detach traced process; continue with sig */
 
@@ -934,10 +1025,10 @@ int sig;
                perror("detach: ptrace(PTRACE_DETACH, ...)");
 #endif /* SUNOS4 */
 
-#ifndef SVR4
+#ifndef USE_PROCFS
        if (waiting_parent(tcp))
                error = resume(tcp->parent);
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
        if (!qflag)
                fprintf(stderr, "Process %u detached\n", tcp->pid);
@@ -946,7 +1037,7 @@ int sig;
        return error;
 }
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 
 static void
 reaper(sig)
@@ -966,7 +1057,7 @@ int sig;
        }
 }
 
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
 static void
 cleanup()
@@ -1054,7 +1145,7 @@ int sig;
 
 #endif /* HAVE_STRSIGNAL */
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 
 static void
 rebuild_pollv()
@@ -1141,6 +1232,9 @@ int pfd;
        int i;
        int n;
        struct rlimit rl;
+#ifdef FREEBSD
+       struct procfs_status pfs;
+#endif /* FREEBSD */
 
        switch (fork()) {
        case -1:
@@ -1180,7 +1274,11 @@ int pfd;
        pollinfo.fd = pfd;
        pollinfo.pid = getpid();
        for (;;) {
-               if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
+#ifndef FREEBSD
+               if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
+#else /* FREEBSD */
+               if (ioctl(pfd, PIOCWSTOP, &pfs) < 0)
+#endif /* FREEBSD */
                {
                        switch (errno) {
                        case EINTR:
@@ -1331,7 +1429,17 @@ trace()
        FOUND:
                /* Get the status of the process. */
                if (!interrupted) {
+#ifndef FREEBSD
                        ioctl_result = IOCTL_WSTOP (tcp);
+#else /* FREEBSD */
+                       /* Thanks to some scheduling mystery, the first poller
+                          sometimes waits for the already processed end of fork
+                          event. Doing a non blocking poll here solves the problem. */
+                       if (proc_poll_pipe[0] != -1)
+                               ioctl_result = IOCTL_STATUS (tcp);
+                       else
+                               ioctl_result = IOCTL_WSTOP (tcp);
+#endif /* FREEBSD */                     
                        ioctl_errno = errno;
 #ifndef HAVE_POLLABLE_PROCFS
                        if (proc_poll_pipe[0] != -1) {
@@ -1354,6 +1462,9 @@ trace()
                        case EINTR:
                        case EBADF:
                                continue;
+#ifdef FREEBSD
+                       case ENOTTY:
+#endif                   
                        case ENOENT:
                                droptcb(tcp);
                                continue;
@@ -1371,15 +1482,27 @@ trace()
 
                if (cflag) {
                        struct timeval stime;
-
+#ifdef FREEBSD
+                       char buf[1024];
+                       int len;
+
+                       if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) {
+                               buf[len] = '\0';
+                               sscanf(buf,
+                                      "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld",
+                                      &stime.tv_sec, &stime.tv_usec);
+                       } else
+                               stime.tv_sec = stime.tv_usec = 0;
+#else /* !FREEBSD */                   
                        stime.tv_sec = tcp->status.pr_stime.tv_sec;
                        stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000;
+#endif /* !FREEBSD */
                        tv_sub(&tcp->dtime, &stime, &tcp->stime);
                        tcp->stime = stime;
                }
-
                what = tcp->status.PR_WHAT;
                switch (tcp->status.PR_WHY) {
+#ifndef FREEBSD
                case PR_REQUESTED:
                        if (tcp->status.PR_FLAGS & PR_ASLEEP) {
                                tcp->status.PR_WHY = PR_SYSENTRY;
@@ -1389,6 +1512,7 @@ trace()
                                }
                        }
                        break;
+#endif /* !FREEBSD */
                case PR_SYSENTRY:
 #ifdef POLL_HACK
                        in_syscall = tcp;
@@ -1414,13 +1538,21 @@ trace()
                                printtrailer(tcp);
                        }
                        break;
+#ifdef FREEBSD
+               case 0: /* handle case we polled for nothing */
+                       continue;
+#endif                 
                default:
                        fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
                        exit(1);
                        break;
                }
                arg = 0;
+#ifndef FREEBSD                
                if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
+#else            
+               if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) {
+#endif           
                        perror("PIOCRUN");
                        exit(1);
                }
@@ -1428,7 +1560,7 @@ trace()
        return 0;
 }
 
-#else /* !SVR4 */
+#else /* !USE_PROCFS */
 
 static int
 trace()
@@ -1667,7 +1799,7 @@ trace()
        return 0;
 }
 
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
 static int curcol;
 
index 0cc14a037be657f2721fa310cef414c15c628528..4abf861b684b16bdb742b174505444660c0c913e 100644 (file)
--- a/stream.c
+++ b/stream.c
@@ -30,7 +30,7 @@
 
 #include "defs.h"
 
-#if defined(HAVE_SYS_STREAM_H) || defined(linux)
+#if defined(HAVE_SYS_STREAM_H) || defined(linux) || defined(FREEBSD)
 
 #if defined(linux)
 #ifdef HAVE_SYS_POLL_H
@@ -48,11 +48,15 @@ struct strbuf {
 
 #else /* linux */
 
+#ifndef FREEBSD
 #include <stropts.h>
 #include <poll.h>
 #include <sys/conf.h>
 #include <sys/stream.h>
 #include <sys/tihdr.h>
+#else /* FREEBSD */
+#include <poll.h>
+#endif /* FREEBSD */
 
 #endif /* linux */
 
@@ -62,6 +66,7 @@ struct strbuf {
 #include <sys/timod.h>
 #endif /* HAVE_SYS_TIUSER_H */
 
+#ifndef FREEBSD
 static struct xlat msgflags[] = {
        { RS_HIPRI,     "RS_HIPRI"      },
        { 0,            NULL            },
@@ -252,6 +257,7 @@ struct tcb *tcp;
 }
 
 #endif /* HAVE_PUTPMSG */
+#endif /* !FREEBSD */
 
 
 #ifdef HAVE_SYS_POLL_H
@@ -349,7 +355,7 @@ struct tcb *tcp;
 }
 #endif
 
-#ifndef linux
+#if !defined(linux) && !defined(FREEBSD)
 
 static struct xlat stream_flush_options[] = {
        { FLUSHR,       "FLUSHR"        },
@@ -824,7 +830,7 @@ int code, arg;
        }
 }
 
-#endif /* linux */
+#endif /* !linux && !FREEBSD */ 
 
-#endif /* LINUXSPARC && linux */
+#endif /* HAVE_SYS_STREAM_H || linux || FREEBSD */
 
index 96424460de3368595c1f1d3d8cfc4df850cd43f3..e59b16fb210409a9056520ff12c9235eef4e2b9d 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -410,7 +410,23 @@ struct tcb *tcp;
        }
 }
 
+#ifndef FREEBSD
 enum subcall_style { shift_style, deref_style, mask_style, door_style };
+#else /* FREEBSD */
+enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
+
+struct subcall {
+  int call;
+  int nsubcalls;
+  int subcalls[5];
+};
+
+const struct subcall subcalls_table[] = {
+  { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
+  { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
+  { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
+};
+#endif /* FREEBSD */
 
 #if !(defined(LINUX) && ( defined(ALPHA) || defined(IA64) || defined(MIPS) ))
 
@@ -464,6 +480,11 @@ int nsubcalls;
 enum subcall_style style;
 {
        int i, addr, mask, arg;
+
+#ifndef FREEBSD
+       if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
+               return;
+#endif 
        switch (style) {
        case shift_style:
                if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
@@ -513,6 +534,18 @@ enum subcall_style style;
                else
                        tcp->u_nargs--;
                break;
+#ifdef FREEBSD
+       case table_style:
+               for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
+                       if (subcalls_table[i].call == tcp->scno) break;
+               if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
+                   tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
+                       tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
+                       for (i = 0; i < tcp->u_nargs; i++)
+                               tcp->u_arg[i] = tcp->u_arg[i + 1];
+               }
+               break;
+#endif /* FREEBSD */
        }
 }
 #endif
@@ -602,13 +635,18 @@ struct tcb *tcp;
        static long pc;
 #endif 
 #endif /* LINUX */
+#ifdef FREEBSD
+       struct reg regs;
+#endif /* FREEBSD */   
 
 int
 get_scno(tcp)
 struct tcb *tcp;
 {
        long scno = 0;
+#ifndef USE_PROCFS
        int pid = tcp->pid;
+#endif /* !PROCFS */   
 
 #ifdef LINUX
 #if defined(S390)
@@ -774,13 +812,29 @@ struct tcb *tcp;
        if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
                return -1;
 #endif
-#ifdef SVR4
+#ifdef USE_PROCFS
 #ifdef HAVE_PR_SYSCALL
        scno = tcp->status.pr_syscall;
 #else /* !HAVE_PR_SYSCALL */
+#ifndef FREEBSD
        scno = tcp->status.PR_WHAT;
+#else /* FREEBSD */
+       if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
+               perror("pread");
+                return -1;
+        }
+       switch (regs.r_eax) {
+       case SYS_syscall:
+       case SYS___syscall:
+               pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
+               break;
+       default:
+               scno = regs.r_eax;
+               break;
+       }
+#endif /* FREEBSD */
 #endif /* !HAVE_PR_SYSCALL */
-#endif
+#endif /* USE_PROCFS */
        if (!(tcp->flags & TCB_INSYSCALL))
                tcp->scno = scno;
        return 1;
@@ -791,9 +845,11 @@ int
 syscall_fixup(tcp)
 struct tcb *tcp;
 {
+#ifndef USE_PROCFS
        int pid = tcp->pid;
+#else /* USE_PROCFS */ 
+       int scno = tcp->scno;
 
-#ifdef SVR4
        if (!(tcp->flags & TCB_INSYSCALL)) {
                if (tcp->status.PR_WHY != PR_SYSENTRY) {
                        if (
@@ -819,7 +875,7 @@ struct tcb *tcp;
                        tcp->flags &= ~TCB_INSYSCALL;
                }
        }
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 #ifdef SUNOS4
        if (!(tcp->flags & TCB_INSYSCALL)) {
                if (scno == 0) {
@@ -1054,6 +1110,17 @@ struct tcb *tcp;
                }
 #endif /* MIPS */
 #endif /* SVR4 */
+#ifdef FREEBSD
+               if (regs.r_eflags & PSL_C) {
+                       tcp->u_rval = -1;
+                       u_error = regs.r_eax;
+               } else {
+                       tcp->u_rval = regs.r_eax;
+                       tcp->u_lrval =
+                         ((unsigned long long) regs.r_edx << 32) +  regs.r_eax;
+                       u_error = 0;
+               }
+#endif /* FREEBSD */   
        tcp->u_error = u_error;
        return 1;
 }
@@ -1061,12 +1128,17 @@ struct tcb *tcp;
 int syscall_enter(tcp)
 struct tcb *tcp;
 {
+#ifndef USE_PROCFS
        int pid = tcp->pid;
+#endif /* !USE_PROCFS */       
 #ifdef LINUX
 #if defined(S390)
        {
                int i;
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++) {
                        if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+(i<<2), &tcp->u_arg[i]) < 0)
                                return -1;
@@ -1075,7 +1147,10 @@ struct tcb *tcp;
 #elif defined (ALPHA)
        {
                int i;
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++) {
                        /* WTA: if scno is out-of-bounds this will bomb. Add range-check
                         * for scno somewhere above here!
@@ -1095,7 +1170,10 @@ struct tcb *tcp;
 
                bsp = ia64_rse_skip_regs(bsp, -(cfm & 0x7f));
 
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; ++i) {
                        if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(bsp, i), sizeof(long),
                                   (char *) &tcp->u_arg[i])
@@ -1108,7 +1186,10 @@ struct tcb *tcp;
                long sp;
                int i, nargs;
 
-               nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       nargs = tcp->u_nargs = MAX_ARGS;
                if(nargs > 4) {
                        if(upeek(pid, REG_SP, &sp) < 0)
                                return -1;
@@ -1128,7 +1209,10 @@ struct tcb *tcp;
 #elif defined (POWERPC)
        {
                int i;
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++) {
                        if (upeek(pid, (i==0) ? (4*PT_ORIG_R3) : ((i+PT_R3)*4), &tcp->u_arg[i]) < 0)
                                return -1;
@@ -1137,15 +1221,21 @@ struct tcb *tcp;
 #elif defined (SPARC)
        {
                int i;
-                
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++)
                        tcp->u_arg[i] = *((&regs.r_o0) + i);
        }
 #else /* Other architecture (like i386) (32bits specific) */
        {
                int i;
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++) {
                        if (upeek(pid, i*4, &tcp->u_arg[i]) < 0)
                                return -1;
@@ -1156,7 +1246,10 @@ struct tcb *tcp;
 #ifdef SUNOS4
        {
                int i;
-               tcp->u_nargs = sysent[tcp->scno].nargs;
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
+                       tcp->u_nargs = sysent[tcp->scno].nargs;
+               else 
+                       tcp->u_nargs = MAX_ARGS;
                for (i = 0; i < tcp->u_nargs; i++) {
                        struct user *u;
 
@@ -1172,7 +1265,7 @@ struct tcb *tcp;
         * SGI is broken: even though it has pr_sysarg, it doesn't
         * set them on system call entry.  Get a clue.
         */
-       if (sysent[tcp->scno].nargs != -1)
+       if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
                tcp->u_nargs = sysent[tcp->scno].nargs;
        else
                tcp->u_nargs = tcp->status.pr_nsysarg;
@@ -1188,7 +1281,7 @@ struct tcb *tcp;
        }
 #else /* !MIPS */
 #ifdef HAVE_PR_SYSCALL
-       if (sysent[tcp->scno].nargs != -1)
+       if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
                tcp->u_nargs = sysent[tcp->scno].nargs;
        else
                tcp->u_nargs = tcp->status.pr_nsysarg;
@@ -1199,7 +1292,7 @@ struct tcb *tcp;
        }
 #else /* !HAVE_PR_SYSCALL */
 #ifdef I386
-       if (sysent[tcp->scno].nargs != -1)
+       if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
                tcp->u_nargs = sysent[tcp->scno].nargs;
        else
 #if UNIXWARE >= 2
@@ -1213,6 +1306,31 @@ struct tcb *tcp;
 #endif /* !HAVE_PR_SYSCALL */
 #endif /* !MIPS */
 #endif /* SVR4 */
+#ifdef FREEBSD
+       if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
+           sysent[tcp->scno].nargs > tcp->status.val)
+               tcp->u_nargs = sysent[tcp->scno].nargs;
+       else 
+               tcp->u_nargs = tcp->status.val;
+       if (tcp->u_nargs < 0)
+               tcp->u_nargs = 0;
+       if (tcp->u_nargs > MAX_ARGS)
+               tcp->u_nargs = MAX_ARGS;
+       switch(regs.r_eax) {
+       case SYS___syscall:
+               pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
+                     regs.r_esp + sizeof(int) + sizeof(quad_t));
+         break;
+        case SYS_syscall:
+               pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
+                     regs.r_esp + 2 * sizeof(int));
+         break;
+        default:
+               pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
+                     regs.r_esp + sizeof(int));
+         break;
+       }
+#endif /* FREEBSD */
        return 1;
 }
 
@@ -1245,7 +1363,8 @@ struct tcb *tcp;
 
 
                internal_syscall(tcp);
-               if (!(qual_flags[tcp->scno] & QUAL_TRACE)) {
+               if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
+                   !(qual_flags[tcp->scno] & QUAL_TRACE)) {
                        tcp->flags &= ~TCB_INSYSCALL;
                        return 0;
                }
@@ -1253,14 +1372,14 @@ struct tcb *tcp;
                if (tcp->flags & TCB_REPRINT) {
                        printleader(tcp);
                        tprintf("<... ");
-                       if (tcp->scno >= nsyscalls)
+                       if (tcp->scno >= nsyscalls || tcp->scno < 0)
                                tprintf("syscall_%lu", tcp->scno);
                        else
                                tprintf("%s", sysent[tcp->scno].sys_name);
                        tprintf(" resumed> ");
                }
 
-               if (cflag) {
+               if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) {
                        call_count[tcp->scno]++;
                        if (tcp->u_error)
                                error_count[tcp->scno]++;
@@ -1288,7 +1407,7 @@ struct tcb *tcp;
                        return 0;
                }
 
-               if (tcp->scno >= nsyscalls
+               if (tcp->scno >= nsyscalls || tcp->scno < 0
                    || (qual_flags[tcp->scno] & QUAL_RAW))
                        sys_res = printargs(tcp);
                else
@@ -1296,7 +1415,8 @@ struct tcb *tcp;
                u_error = tcp->u_error;
                tprintf(") ");
                tabto(acolumn);
-               if (qual_flags[tcp->scno] & QUAL_RAW) {
+               if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
+                   qual_flags[tcp->scno] & QUAL_RAW) {
                        if (u_error)
                                tprintf("= -1 (errno %ld)", u_error);
                        else
@@ -1349,10 +1469,18 @@ struct tcb *tcp;
                                        tprintf("= %ld", tcp->u_rval);
                                        break;
 #ifdef HAVE_LONG_LONG
+                               case RVAL_LHEX:
+                                       tprintf("= %#llx", tcp->u_lrval);
+                                       break;
+                               case RVAL_LOCTAL:
+                                       tprintf("= %#llo", tcp->u_lrval);
+                                       break;
+                               case RVAL_LUDECIMAL:
+                                       tprintf("= %llu", tcp->u_lrval);
+                                       break;
                                case RVAL_LDECIMAL:
-                                       tprintf ("= %lld", tcp->u_lrval);
+                                       tprintf("= %lld", tcp->u_lrval);
                                        break;
-                                       /* LHEX, LOCTAL, LUDECIMAL... */
 #endif
                                default:
                                        fprintf(stderr,
@@ -1452,6 +1580,13 @@ struct tcb *tcp;
                break;
 #endif /* SYS_door_subcall */
 #endif /* SVR4 */
+#ifdef FREEBSD
+       case SYS_msgsys:
+       case SYS_shmsys:
+       case SYS_semsys:
+               decode_subcall(tcp, 0, 0, table_style);
+               break;
+#endif         
 #ifdef SUNOS4
        case SYS_semsys:
                decode_subcall(tcp, SYS_semsys_subcall,
@@ -1469,7 +1604,7 @@ struct tcb *tcp;
        }
 
        internal_syscall(tcp);
-       if (!(qual_flags[tcp->scno] & QUAL_TRACE)) {
+       if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
                tcp->flags |= TCB_INSYSCALL;
                return 0;
        }
@@ -1483,11 +1618,11 @@ struct tcb *tcp;
        printleader(tcp);
        tcp->flags &= ~TCB_REPRINT;
        tcp_last = tcp;
-       if (tcp->scno >= nsyscalls)
+       if (tcp->scno >= nsyscalls || tcp->scno < 0)
                tprintf("syscall_%lu(", tcp->scno);
        else
                tprintf("%s(", sysent[tcp->scno].sys_name);
-       if (tcp->scno >= nsyscalls ||
+       if (tcp->scno >= nsyscalls || tcp->scno < 0 || 
            ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
                sys_res = printargs(tcp);
        else
@@ -1545,7 +1680,11 @@ struct tcb *tcp;
        val = tcp->status.PR_REG[CTX_V1];
 #endif /* MIPS */
 #endif /* SVR4 */
-
+#ifdef FREEBSD
+       struct reg regs;
+       pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
+       val = regs.r_edx;
+#endif 
        return val;
 }
 
index f16b711c6ef91b50fd87a1dfb8d00a0af929265c..39930b571821bb0d25ed13f99684cd18e12bb546 100644 (file)
--- a/system.c
+++ b/system.c
@@ -543,6 +543,19 @@ static struct xlat sysconflimits[] = {
        { 0,            NULL            },
 };
 
+int
+sys_sysconf(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               printxval(sysconflimits, tcp->u_arg[0], "_SC_???");
+       }
+       return 0;
+}
+
+#endif /* SUNOS4 */
+
+#if defined(SUNOS4) || defined(FREEBSD)
 static struct xlat pathconflimits[] = {
 #ifdef _PC_LINK_MAX
        { _PC_LINK_MAX, "_PC_LINK_MAX"  },      /* max links to file/dir */
@@ -574,15 +587,6 @@ static struct xlat pathconflimits[] = {
        { 0,            NULL            },
 };
 
-int
-sys_sysconf(tcp)
-struct tcb *tcp;
-{
-       if (entering(tcp)) {
-               printxval(sysconflimits, tcp->u_arg[0], "_SC_???");
-       }
-       return 0;
-}
 
 int
 sys_pathconf(tcp)
@@ -591,7 +595,7 @@ struct tcb *tcp;
        if (entering(tcp)) {
                printstr(tcp, tcp->u_arg[0], -1);
                tprintf(", ");
-               printxval(pathconflimits, tcp->u_arg[1], "_SC_???");
+               printxval(pathconflimits, tcp->u_arg[1], "_PC_???");
        }
        return 0;
 }
@@ -602,12 +606,12 @@ struct tcb *tcp;
 {
        if (entering(tcp)) {
                tprintf("%lu, ", tcp->u_arg[0]);
-               printxval(pathconflimits, tcp->u_arg[1], "_SC_???");
+               printxval(pathconflimits, tcp->u_arg[1], "_PC_???");
        }
        return 0;
 }
 
-#endif /* SUNOS4 */
+#endif /* SUNOS4 || FREEBSD */
 
 #ifdef SVR4
 
@@ -1903,6 +1907,55 @@ struct tcb *tcp;
 }
 #endif
 
+#ifdef FREEBSD
+#include <sys/sysctl.h>
+
+int sys___sysctl(tcp)
+struct tcb *tcp;
+{
+       int qoid[CTL_MAXNAME+2];
+       char ctl[1024];
+       size_t len;
+       int i, numeric;
+       
+       if (entering(tcp)) {
+               if (tcp->u_arg[1] < 0 || tcp->u_arg[1] > CTL_MAXNAME ||
+                   (umoven(tcp, tcp->u_arg[0], tcp->u_arg[1] * sizeof(int),
+                           (char *) (qoid + 2)) < 0))
+                       tprintf("[...], ");
+               else {
+                       /* Use sysctl to ask the name of the current MIB
+                          This uses the undocumented "Staff-functions" used
+                          by the sysctl program. See kern_sysctl.c for
+                          details. */
+                       qoid[0] = 0; /* sysctl */
+                       qoid[1] = 1; /* name */
+                       i = sizeof(ctl);
+                       tprintf("[");
+                       if (sysctl(qoid, tcp->u_arg[1] + 2, ctl, &i, 0, 0) >= 0) {
+                               numeric = !abbrev(tcp);
+                               tprintf("%s%s", ctl, numeric ? ", " : "");
+                       } else
+                               numeric = 1;
+                       if (numeric) {
+                               for (i = 0; i < tcp->u_arg[1]; i++)
+                                       tprintf("%s%d", i ? "." : "", qoid[i + 2]);
+                       }
+                       tprintf("], ");
+                       tprintf("%lu, ", tcp->u_arg[1]);
+               }
+       } else {
+               if (!syserror(tcp) && (umove(tcp, tcp->u_arg[3], &len) >= 0)) {
+                       printstr(tcp, tcp->u_arg[2], len);
+                       tprintf(", [%u], ", len);
+               } else 
+                       tprintf("%#lx, %#lx, ", tcp->u_arg[2], tcp->u_arg[3]);
+               printstr(tcp, tcp->u_arg[4], tcp->u_arg[5]);
+               tprintf(", %lu", tcp->u_arg[5]);
+       }
+       return 0;
+}
+#endif
 
 #if UNIXWARE >= 2
 
diff --git a/term.c b/term.c
index 4cf10a925c3be890128d7ec7c1f155a1dfcb2c67..db15ef9b112eb8e2658cd01a26b30b0ef95525ec 100644 (file)
--- a/term.c
+++ b/term.c
@@ -47,12 +47,14 @@ static struct xlat tcxonc_options[] = {
        { 0,            NULL            },
 };
 
+#ifdef TCLFLSH
 static struct xlat tcflsh_options[] = {
        { TCIFLUSH,     "TCIFLUSH"      },
        { TCOFLUSH,     "TCOFLUSH"      },
        { TCIOFLUSH,    "TCIOFLUSH"     },
        { 0,            NULL            },
 };
+#endif
 
 static struct xlat baud_options[] = {
        { B0,           "B0"            },
@@ -173,7 +175,11 @@ struct tcb *tcp;
 long code, arg;
 {
        struct termios tios;
+#ifndef FREEBSD
        struct termio tio;
+#else
+       struct termios tio;
+#endif 
        struct winsize ws;
 #ifdef TIOCGSIZE
        struct  ttysize ts;
@@ -290,15 +296,18 @@ long code, arg;
 #endif
 
        /* ioctls with a direct decodable arg */
-
+#ifdef TCXONC
        case TCXONC:
                tprintf(", ");
                printxval(tcxonc_options, arg, "TC???");
                return 1;
+#endif
+#ifdef TCLFLSH
        case TCFLSH:
                tprintf(", ");
                printxval(tcflsh_options, arg, "TC???");
                return 1;
+#endif
 
        /* ioctls with an indirect parameter displayed as modem flags */
 
diff --git a/util.c b/util.c
index f0810b41a43a5d813449687e4b4a7931ed402cb2..c0b7cc0ceb2db633bb7dec40e4d19d51b1030c89 100644 (file)
--- a/util.c
+++ b/util.c
@@ -630,7 +630,7 @@ char *laddr;
 #endif /* !oldway */
 #endif /* SUNOS4 */
 
-#ifdef SVR4
+#ifdef USE_PROCFS
 #ifdef HAVE_MP_PROCFS
        if (pread(tcp->pfd_as, laddr, len, addr) == -1)
                return -1;
@@ -651,7 +651,7 @@ char *laddr;
                return -1;
 #endif /* !HAVE_PREAD */
 #endif /* HAVE_MP_PROCFS */
-#endif /* SVR4 */
+#endif /* USE_PROCFS */
 
        return 0;
 }
@@ -667,9 +667,9 @@ long addr;
 int len;
 char *laddr;
 {
-#ifdef SVR4
+#ifdef USE_PROCFS
        return umoven(tcp, addr, len, laddr);
-#else /* !SVR4 */
+#else /* !USE_PROCFS */
        int started = 0;
        int pid = tcp->pid;
        int i, n, m;
@@ -719,7 +719,7 @@ char *laddr;
                addr += sizeof(long), laddr += m, len -= m;
        }
        return 0;
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 }
 
 #ifdef LINUX
@@ -821,7 +821,7 @@ char *laddr;
 
 #endif /* SUNOS4 */
 
-#ifndef SVR4
+#ifndef USE_PROCFS
 
 int
 upeek(pid, off, res)
@@ -865,7 +865,7 @@ long *res;
        return 0;
 }
 
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
 long
 getpc(tcp)
@@ -925,6 +925,11 @@ struct tcb *tcp;
        return 0;
 #endif /* SVR4 */
 
+#ifdef FREEBSD
+       struct reg regs;
+       pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
+       return regs.r_eip;
+#endif /* FREEBSD */
 }
 
 void
@@ -999,9 +1004,14 @@ struct tcb *tcp;
        tprintf("[????????] ");
 #endif
 
+#ifdef FREEBSD
+       struct reg regs;
+       pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
+       tprintf("[%08x] ", regs.r_eip);
+#endif /* FREEBSD */
 }
 
-#ifndef SVR4
+#ifndef USE_PROCFS
 
 int
 setbpt(tcp)
@@ -1388,7 +1398,7 @@ struct tcb *tcp;
        return 0;
 }
 
-#endif /* !SVR4 */
+#endif /* !USE_PROCFS */
 
 #ifdef SUNOS4