summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWichert Akkerman <wichert@deephackmode.org>1999-08-29 23:15:07 +0000
committerWichert Akkerman <wichert@deephackmode.org>1999-08-29 23:15:07 +0000
commit9ce1a63eb20b069607c06f9645ac5a17b418a5f3 (patch)
treec44fbd1dfd23b635e8dd518ac76c20b68e923563
parent5a777663d5208fb2485d06b5a54419f0d15e7bf6 (diff)
downloadstrace-9ce1a63eb20b069607c06f9645ac5a17b418a5f3.tar.gz
strace-9ce1a63eb20b069607c06f9645ac5a17b418a5f3.tar.bz2
strace-9ce1a63eb20b069607c06f9645ac5a17b418a5f3.tar.xz
Catching up on my mail-backlog, see ChangeLog for details
-rw-r--r--CREDITS2
-rw-r--r--ChangeLog21
-rw-r--r--Makefile.in1
-rw-r--r--README-svr410
-rw-r--r--TODO1
-rw-r--r--configure.in5
-rw-r--r--defs.h44
-rw-r--r--io.c10
-rw-r--r--ioctl.c2
-rw-r--r--linux/sparc/syscall.h1
-rw-r--r--net.c17
-rw-r--r--proc.c2
-rw-r--r--signal.c11
-rwxr-xr-xstrace-graph317
-rw-r--r--strace.c150
-rw-r--r--svr4/syscallent.h78
-rw-r--r--syscall.c62
-rw-r--r--system.c15
-rw-r--r--util.c27
19 files changed, 689 insertions, 87 deletions
diff --git a/CREDITS b/CREDITS
index c9afc1c..239c676 100644
--- a/CREDITS
+++ b/CREDITS
@@ -34,3 +34,5 @@ porting to new systems:
Ulrich Drepper <drepper@cygnus.com>
Nate Eldredge <nate@cartsys.com>
Jakub Jelinek <jj@ultra.linux.cz>
+ John Hughes <john@Calva.COM>
+ Richard Braakman <dark@xs4all.nl>
diff --git a/ChangeLog b/ChangeLog
index 1d42590..33cc2ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,28 @@
+Mon Aug 30 00:53:57 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
+
+ * Merge patch from Daniel Jacobowitz: KERN_JAVA_* and KERN_SECURELVL aren't
+ defined for all kernelversions
+ * Add strace-graph
+
+Thu Aug 19 13:10:15 CEST 1999 Jakub Jelinek <jj@ultra.linux.cz>
+
+ * linux/sparc/syscall.h: Declare create_module/init_module.
+ * configure.in: Allow compilation in a different directory
+ than the source one.
+ * signal.c: Use asm/reg.h and struct regs instead of pt_regs
+ so that we don't depend on asm/ptrace.h which clashes with
+ glibc sys/ptrace.h.
+ * util.c: Likewise.
+ * syscall.c: Likewise.
+
Wed Aug 4 18:01:50 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
* Syscall 94 on Linux alpha is sys_poll
+Sun Jul 25 14:38:33 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
+
+ * Merge in UnixWare patches from John Hughes <john@Calva.COM>
+
Thu Jul 15 23:00:32 CEST 1999 Wichert Akkerman <wakkerma@debian.org>
* Merge patch from Maciej W. Rozycki <macro@ds2.pg.gda.pl>:
diff --git a/Makefile.in b/Makefile.in
index 5cf059b..c1ddde2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -59,6 +59,7 @@ strace: $(OBJ)
install: all
$(INSTALL_PROGRAM) strace $(bindir)/strace
+ $(INSTALL_PROGRAM) strace-graph $(bindir)/strace-graph
$(INSTALL_DATA) $(srcdir)/strace.1 $(man1dir)/strace$(man1ext)
clean: clean-local
diff --git a/README-svr4 b/README-svr4
index e53a393..82febf7 100644
--- a/README-svr4
+++ b/README-svr4
@@ -9,4 +9,12 @@ lot of processes at once.
There is no thread support but it wouldn't be very difficult to add it.
-Rick Sladkey <jrs@world.std.com>
+There is currently no configure-support yet for UnixWare system. To compile
+on UnixWare 2.1 you need to add the following to config.h yourself:
+
+ #define SVR4_MP 1
+ #define UNIXWARE 2
+ #define HAVE_POLLABLE_PROCFS 1
+
+Wichert Akkerman <wakkerma@debian.org>
+
diff --git a/TODO b/TODO
index ecc38fb..a8e7093 100644
--- a/TODO
+++ b/TODO
@@ -5,6 +5,7 @@ replace printargs with something that reads a configuration-file
rename functions that are used for general things:
sys_chdir -> general_1stringarg
generate syscallent.h from the kernel sources
+add IPv6 support
-- old entries from jrs
diff --git a/configure.in b/configure.in
index af1e492..41e821a 100644
--- a/configure.in
+++ b/configure.in
@@ -125,9 +125,12 @@ AC_TYPE_GETGROUPS
AC_HEADER_MAJOR
AC_SIG_ATOMIC_T
AC_CHECK_LIB(nsl, main)
-AC_CHECK_FUNCS(sigaction strerror strsignal pread sys_siglist _sys_siglist getdents mctl putpmsg prctl sendmsg)
+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)
AC_DECL_SYS_ERRLIST
AC_DECL_SYS_SIGLIST
AC_DECL__SYS_SIGLIST
+if test ! -d $osarch; then
+ mkdir -p $osarch
+fi
AC_OUTPUT(Makefile $osarch/Makefile)
diff --git a/defs.h b/defs.h
index b7a1d18..1e6c446 100644
--- a/defs.h
+++ b/defs.h
@@ -77,6 +77,9 @@
#ifdef SVR4
#include <sys/procfs.h>
+#ifdef SVR4_MP
+#include <sys/uio.h>
+#endif
#else /* !SVR4 */
#if defined(LINUXSPARC) && defined(__GLIBC__)
#include <sys/ptrace.h>
@@ -131,6 +134,41 @@ extern int ptrace();
#define SUPPORTED_PERSONALITIES 2
#endif /* LINUXSPARC */
+
+#ifdef SVR4
+#ifdef SVR4_MP
+extern int mp_ioctl (int f, int c, void *a, int s);
+#define IOCTL(f,c,a) mp_ioctl (f, c, a, sizeof *a)
+#define IOCTL_STATUS(t) \
+ pread (t->pfd_stat, &t->status, sizeof t->status, 0)
+#define IOCTL_WSTOP(t) \
+ (IOCTL (t->pfd, PCWSTOP, NULL) < 0 ? -1 : \
+ IOCTL_STATUS (t))
+#define PR_WHY pr_lwp.pr_why
+#define PR_WHAT pr_lwp.pr_what
+#define PR_REG pr_lwp.pr_context.uc_mcontext.gregs
+#define PR_FLAGS pr_lwp.pr_flags
+#define PIOCSTIP PCSTOP
+#define PIOCSET PCSET
+#define PIOCRESET PCRESET
+#define PIOCSTRACE PCSTRACE
+#define PIOCSFAULT PCSFAULT
+#define PIOCWSTOP PCWSTOP
+#define PIOCSTOP PCSTOP
+#define PIOCSENTRY PCSENTRY
+#define PIOCSEXIT PCSEXIT
+#define PIOCRUN PCRUN
+#else
+#define IOCTL ioctl
+#define IOCTL_STATUS(t) ioctl (t->pfd, PIOCSTATUS, &t->status)
+#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)
+#define PR_WHY pr_why
+#define PR_WHAT pr_what
+#define PR_REG pr_reg
+#define PR_FLAGS pr_flags
+#endif
+#endif
+
/* Trace Control Block */
struct tcb {
short flags; /* See below for TCB_ values */
@@ -154,8 +192,14 @@ struct tcb {
long inst[2]; /* Instructions on above */
int pfd; /* proc file descriptor */
#ifdef SVR4
+#ifdef SVR4_MP
+ int pfd_stat;
+ int pfd_as;
+ pstatus_t status;
+#else
prstatus_t status; /* procfs status structure */
#endif
+#endif
};
/* TCB flags */
diff --git a/io.c b/io.c
index 543772a..e42fba1 100644
--- a/io.c
+++ b/io.c
@@ -152,9 +152,14 @@ struct tcb *tcp;
tprintf("%#lx", tcp->u_arg[1]);
else
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
+#if UNIXWARE
+ /* off_t is signed int */
+ tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
+#else
tprintf(", %lu, %llu", tcp->u_arg[2],
(((unsigned long long) tcp->u_arg[4]) << 32
| tcp->u_arg[3]));
+#endif
}
return 0;
}
@@ -166,9 +171,14 @@ struct tcb *tcp;
if (entering(tcp)) {
tprintf("%ld, ", tcp->u_arg[0]);
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+#if UNIXWARE
+ /* off_t is signed int */
+ tprintf(", %lu, %ld", tcp->u_arg[2], tcp->u_arg[3]);
+#else
tprintf(", %lu, %llu", tcp->u_arg[2],
(((unsigned long long) tcp->u_arg[4]) << 32
| tcp->u_arg[3]));
+#endif
}
return 0;
}
diff --git a/ioctl.c b/ioctl.c
index 65d3f52..24e84ba 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -108,8 +108,10 @@ long code, arg;
#endif /* !LINUX */
return sock_ioctl(tcp, code, arg);
#ifdef SVR4
+#ifndef SVR4_MP
case 'q':
return proc_ioctl(tcp, code, arg);
+#endif
#endif /* SVR4 */
#ifdef HAVE_SYS_STREAM_H
case 'S':
diff --git a/linux/sparc/syscall.h b/linux/sparc/syscall.h
index 1857f90..6ee1ace 100644
--- a/linux/sparc/syscall.h
+++ b/linux/sparc/syscall.h
@@ -99,6 +99,7 @@ int sys_sigaltstack(), sys_rt_sigprocmask(), sys_rt_sigaction();
int sys_rt_sigpending(), sys_rt_sigsuspend(), sys_rt_sigqueueinfo();
int sys_rt_sigtimedwait(), sys_prctl(), sys_poll();
int sys_sendfile(), sys_query_module(), sys_capget(), sys_capset();
+int sys_create_module(), sys_init_module();
int sys_umask(); /* XXX */
diff --git a/net.c b/net.c
index a7dbc44..d8e4b15 100644
--- a/net.c
+++ b/net.c
@@ -311,6 +311,10 @@ long addr;
struct sockaddr sa;
struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
struct sockaddr_un sau;
+#ifdef HAVE_INET_NTOP
+ struct sockaddr_in6 sa6;
+ char string_addr[100];
+#endif
#ifdef LINUX
struct sockaddr_ipx sipx;
#endif
@@ -340,6 +344,19 @@ long addr;
tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
break;
+#ifdef HAVE_INET_NTOP
+ case AF_INET6:
+ if (umove(tcp, addr, &sa6) < 0)
+ tprintf("{sin6_family=AF_INET6, ...}");
+ else
+ {
+ tprintf("{sin6_family=AF_INET6, ");
+ inet_ntop(AF_INET6, &sa6.sin6_addr, string_addr, sizeof(string_addr));
+ tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)",
+ ntohs(sa6.sin6_port), string_addr, ntohl(sa6.sin6_flowinfo));
+ }
+ break;
+#endif
#if defined(AF_IPX) && defined(linux)
case AF_IPX:
if (umove(tcp, addr, &sipx)<0)
diff --git a/proc.c b/proc.c
index 1bafa5e..a6008f9 100644
--- a/proc.c
+++ b/proc.c
@@ -30,6 +30,7 @@
#include "defs.h"
#ifdef SVR4
+#ifndef SVR4_MP
static struct xlat proc_status_flags[] = {
{ PR_STOPPED, "PR_STOPPED" },
@@ -182,5 +183,6 @@ int code, arg;
}
}
+#endif /* SVR4_MP */
#endif /* SVR4 */
diff --git a/signal.c b/signal.c
index e295c50..d5f2336 100644
--- a/signal.c
+++ b/signal.c
@@ -54,8 +54,9 @@
#ifdef HAVE_ASM_SIGCONTEXT_H
#include <asm/sigcontext.h>
#ifdef SPARC
+#include <asm/reg.h>
typedef struct {
- struct pt_regs si_regs;
+ struct regs si_regs;
int si_mask;
} m_siginfo_t;
#endif
@@ -227,6 +228,7 @@ int sig;
}
}
+#ifndef UNIXWARE
static void
long_to_sigset(l, s)
long l;
@@ -235,6 +237,7 @@ sigset_t *s;
sigemptyset(s);
*(long *)s = l;
}
+#endif
static int
copy_sigset_len(tcp, addr, s, len)
@@ -778,18 +781,16 @@ struct tcb *tcp;
#else
#ifdef SPARC
long i1;
- struct pt_regs regs;
+ struct regs regs;
m_siginfo_t si;
if(ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0) {
perror("sigreturn: PTRACE_GETREGS ");
return 0;
}
- memmove (&regs.u_regs [1], &regs.u_regs [0],
- sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
if(entering(tcp)) {
tcp->u_arg[0] = 0;
- i1 = regs.u_regs[UREG_I1];
+ i1 = regs.r_o1;
if(umove(tcp, i1, &si) < 0) {
perror("sigreturn: umove ");
return 0;
diff --git a/strace-graph b/strace-graph
new file mode 100755
index 0000000..a157a54
--- /dev/null
+++ b/strace-graph
@@ -0,0 +1,317 @@
+#!/usr/bin/perl
+
+# This script processes strace -f output. It displays a graph of invoked
+# subprocesses, and is useful for finding out what complex commands do.
+
+# You will probably want to invoke strace with -q as well, and with
+# -s 100 to get complete filenames.
+
+# The script can also handle the output with strace -t, -tt, or -ttt.
+# It will add elapsed time for each process in that case.
+
+# This script is Copyright (C) 1998 by Richard Braakman <dark@xs4all.nl>.
+# It is distributed under the GNU General Public License version 2 or,
+# at your option, any later version published by the Free Software Foundation.
+
+my %unfinished;
+
+# Scales for strace slowdown. Make configurable!
+my $scale_factor = 3.5;
+
+while (<>) {
+ my ($pid, $call, $args, $result, $time);
+ chop;
+
+ s/^(\d+)\s+//;
+ $pid = $1;
+
+ if (s/^(\d\d):(\d\d):(\d\d)(?:\.(\d\d\d\d\d\d))? //) {
+ $time = $1 * 3600 + $2 * 60 + $3;
+ if (defined $4) {
+ $time = $time + $4 / 1000000;
+ $floatform = 1;
+ }
+ } elsif (s/^(\d+)\.(\d\d\d\d\d\d) //) {
+ $time = $1 + ($2 / 1000000);
+ $floatform = 1;
+ }
+
+ if (s/ <unfinished ...>$//) {
+ $unfinished{$pid} = $_;
+ next;
+ }
+
+ if (s/^<... \S+ resumed> //) {
+ unless (exists $unfinished{$pid}) {
+ print STDERR "$0: $ARGV: cannot find start of resumed call on line $.";
+ next;
+ }
+ $_ = $unfinished{$pid} . $_;
+ delete $unfinished{$pid};
+ }
+
+ if (/^--- SIG(\S+) \(.*\) ---$/) {
+ # $pid received signal $1
+ # currently we don't do anything with this
+ next;
+ }
+
+ if (/^\+\+\+ killed by SIG(\S+) \+\+\+$/) {
+ # $pid received signal $1
+ handle_killed($pid, $time);
+ next;
+ }
+
+ ($call, $args, $result) = /(\S+)\((.*)\)\s+= (.*)$/;
+ unless (defined $result) {
+ print STDERR "$0: $ARGV: $.: cannot parse line.\n";
+ next;
+ }
+
+ handle_trace($pid, $call, $args, $result, $time);
+}
+
+display_trace();
+
+exit 0;
+
+sub parse_str {
+ my ($in) = @_;
+ my $result = "";
+
+ while (1) {
+ if ($in =~ s/^\\(.)//) {
+ $result .= $1;
+ } elsif ($in =~ s/^\"//) {
+ if ($in =~ s/^\.\.\.//) {
+ return ("$result...", $in);
+ }
+ return ($result, $in);
+ } elsif ($in =~ s/([^\\\"]*)//) {
+ $result .= $1;
+ } else {
+ return (undef, $in);
+ }
+ }
+}
+
+sub parse_one {
+ my ($in) = @_;
+
+ if ($in =~ s/^\"//) {
+ ($tmp, $in) = parse_str($in);
+ if (not defined $tmp) {
+ print STDERR "$0: $ARGV: $.: cannot parse string.\n";
+ return (undef, $in);
+ }
+ return ($tmp, $in);
+ } elsif ($in =~ s/^0x(\x+)//) {
+ return (hex $1, $in);
+ } elsif ($in =~ s/^(\d+)//) {
+ return (int $1, $in);
+ } else {
+ print STDERR "$0: $ARGV: $.: unrecognized element.\n";
+ return (undef, $in);
+ }
+}
+
+sub parseargs {
+ my ($in) = @_;
+ my @args = ();
+ my $tmp;
+
+ while (length $in) {
+ if ($in =~ s/^\[//) {
+ my @subarr = ();
+ if ($in =~ s,^/\* (\d+) vars \*/\],,) {
+ push @args, $1;
+ } else {
+ while ($in !~ s/^\]//) {
+ ($tmp, $in) = parse_one($in);
+ defined $tmp or return undef;
+ push @subarr, $tmp;
+ unless ($in =~ /^\]/ or $in =~ s/^, //) {
+ print STDERR "$0: $ARGV: $.: missing comma in array.\n";
+ return undef;
+ }
+ if ($in =~ s/^\.\.\.//) {
+ push @subarr, "...";
+ }
+ }
+ push @args, \@subarr;
+ }
+ } elsif ($in =~ s/^\{//) {
+ my %subhash = ();
+ while ($in !~ s/^\}//) {
+ my $key;
+ unless ($in =~ s/^(\w+)=//) {
+ print STDERR "$0: $ARGV: $.: struct field expected.\n";
+ return undef;
+ }
+ $key = $1;
+ ($tmp, $in) = parse_one($in);
+ defined $tmp or return undef;
+ $subhash{$key} = $tmp;
+ unless ($in =~ s/, //) {
+ print STDERR "$0: $ARGV: $.: missing comma in struct.\n";
+ return undef;
+ }
+ }
+ push @args, \%subhash;
+ } else {
+ ($tmp, $in) = parse_one($in);
+ defined $tmp or return undef;
+ push @args, $tmp;
+ }
+ unless (length($in) == 0 or $in =~ s/^, //) {
+ print STDERR "$0: $ARGV: $.: missing comma.\n";
+ return undef;
+ }
+ }
+ return @args;
+}
+
+
+my $depth = "";
+
+# process info, indexed by pid.
+# fields:
+# parent pid number
+# seq forks and execs for this pid, in sequence (array)
+
+# filename and argv (from latest exec)
+# basename (derived from filename)
+# argv[0] is modified to add the basename if it differs from the 0th argument.
+
+my %pr;
+
+sub handle_trace {
+ my ($pid, $call, $args, $result, $time) = @_;
+ my $p;
+
+ if (defined $time and not defined $pr{$pid}{start}) {
+ $pr{$pid}{start} = $time;
+ }
+
+ if ($call eq 'execve') {
+ return if $result != 0;
+
+ my ($filename, $argv) = parseargs($args);
+ ($basename) = $filename =~ m/([^\/]*)$/;
+ if ($basename ne $$argv[0]) {
+ $$argv[0] = "$basename($$argv[0])";
+ }
+ my $seq = $pr{$pid}{seq};
+ $seq = [] if not defined $seq;
+
+ push @$seq, ['EXEC', $filename, $argv];
+
+ $pr{$pid}{seq} = $seq;
+ } elsif ($call eq 'fork') {
+ return if $result == 0;
+
+ my $seq = $pr{$pid}{seq};
+ $seq = [] if not defined $seq;
+ push @$seq, ['FORK', $result];
+ $pr{$pid}{seq} = $seq;
+ $pr{$result}{parent} = $pid;
+ } elsif ($call eq '_exit') {
+ $pr{$pid}{end} = $time if defined $time;
+ }
+}
+
+sub handle_killed {
+ my ($pid, $time) = @_;
+ $pr{$pid}{end} = $time if defined $time;
+}
+
+sub straight_seq {
+ my ($pid) = @_;
+ my $seq = $pr{$pid}{seq};
+
+ for $elem (@$seq) {
+ if ($$elem[0] eq 'EXEC') {
+ my $argv = $$elem[2];
+ print "$$elem[0] $$elem[1] @$argv\n";
+ } elsif ($$elem[0] eq 'FORK') {
+ print "$$elem[0] $$elem[1]\n";
+ } else {
+ print "$$elem[0]\n";
+ }
+ }
+}
+
+sub first_exec {
+ my ($pid) = @_;
+ my $seq = $pr{$pid}{seq};
+
+ for $elem (@$seq) {
+ if ($$elem[0] eq 'EXEC') {
+ return $elem;
+ }
+ }
+ return undef;
+}
+
+sub display_pid_trace {
+ my ($pid, $lead) = @_;
+ my $i = 0;
+ my @seq = @{$pr{$pid}{seq}};
+ my $elapsed;
+
+ if (not defined first_exec($pid)) {
+ unshift @seq, ['EXEC', '', ['(anon)'] ];
+ }
+
+ if (defined $pr{$pid}{start} and defined $pr{$pid}{end}) {
+ $elapsed = $pr{$pid}{end} - $pr{$pid}{start};
+ $elapsed /= $scale_factor;
+ if ($floatform) {
+ $elapsed = sprintf("%0.02f", $elapsed);
+ } else {
+ $elapsed = int $elapsed;
+ }
+ }
+
+ for $elem (@seq) {
+ $i++;
+ if ($$elem[0] eq 'EXEC') {
+ my $argv = $$elem[2];
+ if (defined $elapsed) {
+ print "$lead [$elapsed] @$argv\n";
+ undef $elapsed;
+ } else {
+ print "$lead @$argv\n";
+ }
+ } elsif ($$elem[0] eq 'FORK') {
+ if ($i == 1) {
+ if ($lead =~ /-$/) {
+ display_pid_trace($$elem[1], "$lead--+--");
+ } else {
+ display_pid_trace($$elem[1], "$lead +--");
+ }
+ } elsif ($i == @seq) {
+ display_pid_trace($$elem[1], "$lead `--");
+ } else {
+ display_pid_trace($$elem[1], "$lead +--");
+ }
+ }
+ if ($i == 1) {
+ $lead =~ s/\`--/ /g;
+ $lead =~ s/-/ /g;
+ $lead =~ s/\+/|/g;
+ }
+ }
+}
+
+sub display_trace {
+ my ($startpid) = @_;
+
+ $startpid = (keys %pr)[0];
+ while ($pr{$startpid}{parent}) {
+ $startpid = $pr{$startpid}{parent};
+ }
+
+ display_pid_trace($startpid, "");
+}
+
diff --git a/strace.c b/strace.c
index 75ab84a..c96fbb7 100644
--- a/strace.c
+++ b/strace.c
@@ -45,6 +45,9 @@
#ifdef SVR4
#include <sys/stropts.h>
#include <poll.h>
+#ifdef SVR4_MP
+#include <sys/uio.h>
+#endif
#endif
int debug = 0, followfork = 0, followvfork = 0, interactive = 0;
@@ -105,6 +108,11 @@ static int proc_poll_pipe[2] = { -1, -1 };
#endif /* !HAVE_POLLABLE_PROCFS */
+#ifdef SVR4_MP
+#define POLLWANT POLLWRNORM
+#else
+#define POLLWANT POLLPRI
+#endif
#endif /* SVR4 */
static void
@@ -559,7 +567,6 @@ int pid;
}
#ifdef SVR4
-
int
proc_open(tcp, attaching)
struct tcb *tcp;
@@ -570,19 +577,67 @@ int attaching;
sysset_t sc_enter, sc_exit;
sigset_t signals;
fltset_t faults;
-#ifndef MIPS
- prrun_t run;
-#endif
#ifndef HAVE_POLLABLE_PROCFS
static int last_pfd;
#endif
+#ifdef SVR4_MP
+ /* Open the process pseudo-files in /proc. */
+ sprintf(proc, "/proc/%d/ctl", tcp->pid);
+ if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) {
+ perror("strace: open(\"/proc/...\", ...)");
+ return -1;
+ }
+ if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
+ perror("F_GETFD");
+ return -1;
+ }
+ if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
+ perror("F_SETFD");
+ return -1;
+ }
+ sprintf(proc, "/proc/%d/status", tcp->pid);
+ if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) {
+ perror("strace: open(\"/proc/...\", ...)");
+ return -1;
+ }
+ if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) {
+ perror("F_GETFD");
+ return -1;
+ }
+ if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) {
+ perror("F_SETFD");
+ return -1;
+ }
+ sprintf(proc, "/proc/%d/as", tcp->pid);
+ if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) {
+ perror("strace: open(\"/proc/...\", ...)");
+ return -1;
+ }
+ if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) {
+ perror("F_GETFD");
+ return -1;
+ }
+ if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) {
+ perror("F_SETFD");
+ return -1;
+ }
+#else
/* Open the process pseudo-file in /proc. */
sprintf(proc, "/proc/%d", tcp->pid);
if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) {
perror("strace: open(\"/proc/...\", ...)");
return -1;
}
+ if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
+ perror("F_GETFD");
+ return -1;
+ }
+ if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
+ perror("F_SETFD");
+ return -1;
+ }
+#endif
rebuild_pollv();
if (!attaching) {
/*
@@ -590,37 +645,29 @@ int attaching;
* condition we have to poll for the event.
*/
for (;;) {
- if (ioctl(tcp->pfd, PIOCSTATUS, &tcp->status) < 0) {
+ if (IOCTL_STATUS (tcp) < 0) {
perror("strace: PIOCSTATUS");
return -1;
}
- if (tcp->status.pr_flags & PR_ASLEEP)
+ if (tcp->status.PR_FLAGS & PR_ASLEEP)
break;
}
}
/* Stop the process so that we own the stop. */
- if (ioctl(tcp->pfd, PIOCSTOP, &tcp->status) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSTOP, NULL) < 0) {
perror("strace: PIOCSTOP");
return -1;
}
- if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) {
- perror("F_GETFD");
- return -1;
- }
- if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) {
- perror("F_SETFD");
- return -1;
- }
#ifdef PIOCSET
/* Set Run-on-Last-Close. */
arg = PR_RLC;
- if (ioctl(tcp->pfd, PIOCSET, &arg) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) {
perror("PIOCSET PR_RLC");
return -1;
}
/* Set or Reset Inherit-on-Fork. */
arg = PR_FORK;
- if (ioctl(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
+ if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) {
perror("PIOC{SET,RESET} PR_FORK");
return -1;
}
@@ -636,25 +683,25 @@ int attaching;
#endif /* !PIOCSET */
/* Enable all syscall entries. */
prfillset(&sc_enter);
- if (ioctl(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSENTRY, &sc_enter) < 0) {
perror("PIOCSENTRY");
return -1;
}
/* Enable all syscall exits. */
prfillset(&sc_exit);
- if (ioctl(tcp->pfd, PIOCSEXIT, &sc_exit) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSEXIT, &sc_exit) < 0) {
perror("PIOSEXIT");
return -1;
}
/* Enable all signals. */
prfillset(&signals);
- if (ioctl(tcp->pfd, PIOCSTRACE, &signals) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) {
perror("PIOCSTRACE");
return -1;
}
/* Enable all faults. */
prfillset(&faults);
- if (ioctl(tcp->pfd, PIOCSFAULT, &faults) < 0) {
+ if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) {
perror("PIOCSFAULT");
return -1;
}
@@ -667,29 +714,30 @@ int attaching;
kill(tcp->pid, SIGINT);
#else /* !MIPS */
/* The child is in a pause(), abort it. */
- run.pr_flags = PRSABORT;
- if (ioctl(tcp->pfd, PIOCRUN, &run) < 0) {
+ arg = PRSABORT;
+ if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
perror("PIOCRUN");
return -1;
}
#endif /* !MIPS */
for (;;) {
/* Wait for the child to do something. */
- if (ioctl(tcp->pfd, PIOCWSTOP, &tcp->status) < 0) {
+ if (IOCTL_WSTOP (tcp) < 0) {
perror("PIOCWSTOP");
return -1;
}
- if (tcp->status.pr_why == PR_SYSENTRY) {
+ 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;
+ int scno = tcp->status.PR_WHAT;
#endif /* !HAVE_PR_SYSCALL */
if (scno == SYS_execve)
break;
}
/* Set it running: maybe execve will be next. */
- if (ioctl(tcp->pfd, PIOCRUN, NULL) < 0) {
+ arg = 0;
+ if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) {
perror("PIOCRUN");
return -1;
}
@@ -1012,7 +1060,7 @@ rebuild_pollv()
if (!(tcp->flags & TCB_INUSE))
continue;
pollv[j].fd = tcp->pfd;
- pollv[j].events = POLLPRI;
+ pollv[j].events = POLLWANT;
j++;
}
if (j != nprocs) {
@@ -1126,7 +1174,8 @@ int pfd;
pollinfo.fd = pfd;
pollinfo.pid = getpid();
for (;;) {
- if (ioctl(pfd, PIOCWSTOP, NULL) < 0) {
+ if (ioctl(pfd, PIOCWSTOP, NULL) < 0)
+ {
switch (errno) {
case EINTR:
continue;
@@ -1142,7 +1191,7 @@ int pfd;
write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
_exit(0);
}
- pollinfo.revents = POLLPRI;
+ pollinfo.revents = POLLWANT;
write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo));
sigsuspend(&empty_set);
}
@@ -1159,7 +1208,7 @@ choose_pfd()
static int last;
if (followfork < 2 &&
- last < nprocs && (pollv[last].revents & POLLPRI)) {
+ last < nprocs && (pollv[last].revents & POLLWANT)) {
/*
* The previous process is ready to run again. We'll
* let it do so if it is currently in a syscall. This
@@ -1182,7 +1231,7 @@ choose_pfd()
droptcb(tcp);
return -1;
}
- if (pollv[j].revents & POLLPRI) {
+ if (pollv[j].revents & POLLWANT) {
last = j;
return pollv[j].fd;
}
@@ -1198,6 +1247,7 @@ trace()
int pfd;
int what;
int ioctl_result = 0, ioctl_errno = 0;
+ long arg;
for (;;) {
if (interactive)
@@ -1249,8 +1299,7 @@ trace()
}
/* Get the status of the process. */
if (!interrupted) {
- ioctl_result = ioctl(tcp->pfd, PIOCWSTOP,
- &tcp->status);
+ ioctl_result = IOCTL_WSTOP (tcp);
ioctl_errno = errno;
#ifndef HAVE_POLLABLE_PROCFS
if (proc_poll_pipe[0] != -1) {
@@ -1297,11 +1346,11 @@ trace()
tcp->stime = stime;
}
- what = tcp->status.pr_what;
- switch (tcp->status.pr_why) {
+ what = tcp->status.PR_WHAT;
+ switch (tcp->status.PR_WHY) {
case PR_REQUESTED:
- if (tcp->status.pr_flags & PR_ASLEEP) {
- tcp->status.pr_why = PR_SYSENTRY;
+ if (tcp->status.PR_FLAGS & PR_ASLEEP) {
+ tcp->status.PR_WHY = PR_SYSENTRY;
if (trace_syscall(tcp) < 0) {
fprintf(stderr, "syscall trouble\n");
exit(1);
@@ -1331,11 +1380,12 @@ trace()
}
break;
default:
- fprintf(stderr, "odd stop %d\n", tcp->status.pr_why);
+ fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY);
exit(1);
break;
}
- if (ioctl(tcp->pfd, PIOCRUN, NULL) < 0) {
+ arg = 0;
+ if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) {
perror("PIOCRUN");
exit(1);
}
@@ -1656,3 +1706,23 @@ struct tcb *tcp;
tprintf("\n");
tcp_last = NULL;
}
+
+#ifdef SVR4_MP
+
+int mp_ioctl (int fd, int cmd, void *arg, int size) {
+
+ struct iovec iov[2];
+ int n = 1;
+
+ iov[0].iov_base = &cmd;
+ iov[0].iov_len = sizeof cmd;
+ if (arg) {
+ ++n;
+ iov[1].iov_base = arg;
+ iov[1].iov_len = size;
+ }
+
+ return writev (fd, iov, n);
+}
+
+#endif
diff --git a/svr4/syscallent.h b/svr4/syscallent.h
index 4f69b1e..818b596 100644
--- a/svr4/syscallent.h
+++ b/svr4/syscallent.h
@@ -221,7 +221,7 @@
{ -1, 0, sys_swapctl, "swapctl" }, /* 167 */
{ -1, 0, sys_getcontext, "getcontext" }, /* 168 */
{ -1, 0, sys_setcontext, "setcontext" }, /* 169 */
- { -1, TP, sys_waitsys, "waitid" }, /* 170 */
+ { -1, TP, sys_waitid, "waitid" }, /* 170 */
{ -1, TS, sys_sigstack, "sigstack" }, /* 171 */
{ -1, TS, sys_sigaltstack, "sigaltstack" }, /* 172 */
{ -1, TS, sys_sigsendset, "sigsendset" }, /* 173 */
@@ -322,7 +322,11 @@
{ -1, 0, sys_fstatvfs, "fstatvfs" }, /* 104 */
{ -1, 0, printargs, "SYS_105" }, /* 105 */
{ -1, 0, sys_nfssys, "nfssys" }, /* 106 */
+#if UNIXWARE
+ { -1, TP, sys_waitsys, "waitsys" }, /* 107 */
+#else
{ -1, TP, sys_waitid, "waitid" }, /* 107 */
+#endif
{ -1, 0, sys_sigsendsys, "sigsendsys" }, /* 108 */
{ -1, 0, sys_hrtsys, "hrtsys" }, /* 109 */
{ -1, 0, sys_acancel, "acancel" }, /* 110 */
@@ -356,6 +360,77 @@
{ -1, 0, sys_adjtime, "adjtime" }, /* 138 */
{ -1, 0, sys_sysinfo, "sysinfo" }, /* 139 */
{ -1, 0, printargs, "SYS_140" }, /* 140 */
+#if UNIXWARE >= 2
+ { -1, 0, sys_seteuid, "seteuid" }, /* 141 */
+ { -1, 0, printargs, "SYS_142" }, /* 142 */
+ { -1, 0, printargs, "keyctl" }, /* 143 */
+ { -1, 0, printargs, "secsys" }, /* 144 */
+ { -1, 0, printargs, "filepriv" }, /* 145 */
+ { -1, 0, printargs, "procpriv" }, /* 146 */
+ { -1, 0, printargs, "devstat" }, /* 147 */
+ { -1, 0, printargs, "aclipc" }, /* 148 */
+ { -1, 0, printargs, "fdevstat" }, /* 149 */
+ { -1, 0, printargs, "flvlfile" }, /* 150 */
+ { -1, 0, printargs, "lvlfile" }, /* 151 */
+ { -1, 0, printargs, "SYS_152" }, /* 152 */
+ { -1, 0, printargs, "lvlequal" }, /* 153 */
+ { -1, 0, printargs, "lvlproc" }, /* 154 */
+ { -1, 0, printargs, "SYS_155" }, /* 155 */
+ { -1, 0, printargs, "lvlipc" }, /* 156 */
+ { -1, 0, printargs, "acl" }, /* 157 */
+ { -1, 0, printargs, "auditevt" }, /* 158 */
+ { -1, 0, printargs, "auditctl" }, /* 159 */
+ { -1, 0, printargs, "auditdmp" }, /* 160 */
+ { -1, 0, printargs, "auditlog" }, /* 161 */
+ { -1, 0, printargs, "auditbuf" }, /* 162 */
+ { -1, 0, printargs, "lvldom" }, /* 163 */
+ { -1, 0, printargs, "lvlvfs" }, /* 164 */
+ { -1, 0, printargs, "mkmld" }, /* 165 */
+ { -1, 0, printargs, "mldmode" }, /* 166 */
+ { -1, 0, printargs, "secadvise" }, /* 167 */
+ { -1, 0, printargs, "online" }, /* 168 */
+ { -1, 0, sys_setitimer, "setitimer" }, /* 169 */
+ { -1, 0, sys_getitimer, "getitimer" }, /* 170 */
+ { -1, 0, sys_gettimeofday, "gettimeofday" }, /* 171 */
+ { -1, 0, printargs, "settimeofday" }, /* 172 */
+ { -1, 0, sys_lwp_create, "lwpcreate" }, /* 173 */
+ { -1, 0, sys_lwp_exit, "lwpexit" }, /* 174 */
+ { -1, 0, sys_lwp_wait, "lwpwait" }, /* 175 */
+ { -1, 0, sys_lwp_self, "lwpself" }, /* 176 */
+ { -1, 0, printargs, "lwpinfo" }, /* 177 */
+ { -1, 0, printargs, "lwpprivate" }, /* 178 */
+ { -1, 0, sys_processor_bind, "processor_bind"}, /* 179 */
+ { -1, 0, printargs, "processor_exbind"}, /* 180 */
+ { -1, 0, printargs, "SYS_181" }, /* 181 */
+ { -1, 0, printargs, "SYS_182" }, /* 182 */
+ { -1, 0, printargs, "prepblock" }, /* 183 */
+ { -1, 0, printargs, "block" }, /* 184 */
+ { -1, 0, printargs, "rdblock" }, /* 185 */
+ { -1, 0, printargs, "unblock" }, /* 186 */
+ { -1, 0, printargs, "cancelblock" }, /* 187 */
+ { -1, 0, printargs, "SYS_188" }, /* 188 */
+ { -1, 0, sys_pread, "pread" }, /* 189 */
+ { -1, 0, sys_pwrite, "pwrite" }, /* 190 */
+ { -1, 0, printargs, "truncate" }, /* 191 */
+ { -1, 0, printargs, "ftruncate" }, /* 192 */
+ { -1, 0, printargs, "lwpkill" }, /* 193 */
+ { -1, 0, printargs, "sigwait" }, /* 194 */
+ { -1, 0, printargs, "fork1" }, /* 195 */
+ { -1, 0, printargs, "forkall" }, /* 196 */
+ { -1, 0, printargs, "modload" }, /* 197 */
+ { -1, 0, printargs, "moduload" }, /* 198 */
+ { -1, 0, printargs, "modpath" }, /* 199 */
+ { -1, 0, printargs, "modstat" }, /* 200 */
+ { -1, 0, printargs, "modadm" }, /* 201 */
+ { -1, 0, printargs, "getksym" }, /* 202 */
+ { -1, 0, printargs, "lwpsuspend" }, /* 203 */
+ { -1, 0, printargs, "lwpcontinue" }, /* 204 */
+ { -1, 0, printargs, "priocntllst" }, /* 205 */
+ { -1, 0, printargs, "sleep" }, /* 206 */
+ { -1, 0, printargs, "lwp_sema_wait" }, /* 207 */
+ { -1, 0, printargs, "lwp_sema_post" }, /* 208 */
+ { -1, 0, printargs, "lwp_sema_trywait"}, /* 209 */
+#else
{ -1, 0, sys_seteuid, "seteuid" }, /* 141 */
{ -1, 0, sys_vtrace, "vtrace" }, /* 142 */
{ -1, TP, sys_fork1, "fork1" }, /* 143 */
@@ -437,6 +512,7 @@
{ -1, 0, printargs, "SYS_207" }, /* 207 */
{ -1, 0, printargs, "SYS_208" }, /* 208 */
{ -1, 0, printargs, "SYS_209" }, /* 209 */
+#endif
{ -1, 0, printargs, "SYS_210" }, /* 210 */
{ -1, 0, printargs, "SYS_211" }, /* 211 */
{ -1, 0, printargs, "SYS_212" }, /* 212 */
diff --git a/syscall.c b/syscall.c
index ea57544..912a273 100644
--- a/syscall.c
+++ b/syscall.c
@@ -38,6 +38,10 @@
#include <sys/syscall.h>
#include <sys/param.h>
+#if defined(LINUX) && defined(SPARC)
+#include <asm/reg.h>
+#endif
+
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
@@ -579,7 +583,7 @@ struct tcb *tcp;
long r0;
long a3;
#elif defined (SPARC)
- struct pt_regs regs;
+ struct regs regs;
unsigned long trap;
#endif
#endif /* LINUX */
@@ -650,14 +654,11 @@ struct tcb *tcp;
if (ptrace(PTRACE_GETREGS,pid,(char *)&regs,0) < 0)
return -1;
- memmove (&regs.u_regs [1], &regs.u_regs [0],
- sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
-
/* If we are entering, then disassemble the syscall trap. */
if (!(tcp->flags & TCB_INSYSCALL)) {
/* Retrieve the syscall trap instruction. */
errno = 0;
- trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.pc,0);
+ trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
if (errno)
return -1;
@@ -693,7 +694,7 @@ struct tcb *tcp;
tcp->flags &= ~TCB_WAITEXECVE;
return 0;
}
- fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.pc);
+ fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
return -1;
}
@@ -701,10 +702,10 @@ struct tcb *tcp;
if (trap == 0x91d02027)
scno = 156;
else
- scno = regs.u_regs[UREG_G1];
+ scno = regs.r_g1;
if (scno == 0) {
- scno = regs.u_regs[UREG_I0];
- memmove (&regs.u_regs[UREG_I0], &regs.u_regs[UREG_I1], 7*sizeof(regs.u_regs[0]));
+ scno = regs.r_o0;
+ memmove (&regs.r_o0, &regs.r_o1, 7*sizeof(regs.r_o0));
}
}
#endif
@@ -717,10 +718,10 @@ struct tcb *tcp;
#ifdef HAVE_PR_SYSCALL
scno = tcp->status.pr_syscall;
#else /* !HAVE_PR_SYSCALL */
- scno = tcp->status.pr_what;
+ scno = tcp->status.PR_WHAT;
#endif /* !HAVE_PR_SYSCALL */
if (!(tcp->flags & TCB_INSYSCALL)) {
- if (tcp->status.pr_why != PR_SYSENTRY) {
+ if (tcp->status.PR_WHY != PR_SYSENTRY) {
if (
scno == SYS_fork
#ifdef SYS_vfork
@@ -728,9 +729,9 @@ struct tcb *tcp;
#endif /* SYS_vfork */
) {
/* We are returning in the child, fake it. */
- tcp->status.pr_why = PR_SYSENTRY;
+ tcp->status.PR_WHY = PR_SYSENTRY;
trace_syscall(tcp);
- tcp->status.pr_why = PR_SYSEXIT;
+ tcp->status.PR_WHY = PR_SYSEXIT;
}
else {
fprintf(stderr, "syscall: missing entry\n");
@@ -739,7 +740,7 @@ struct tcb *tcp;
}
}
else {
- if (tcp->status.pr_why != PR_SYSEXIT) {
+ if (tcp->status.PR_WHY != PR_SYSEXIT) {
fprintf(stderr, "syscall: missing exit\n");
tcp->flags &= ~TCB_INSYSCALL;
}
@@ -858,12 +859,12 @@ struct tcb *tcp;
}
#else /* !ALPHA */
#ifdef SPARC
- if (regs.psr & PSR_C) {
+ if (regs.r_psr & PSR_C) {
tcp->u_rval = -1;
- u_error = regs.u_regs[UREG_I0];
+ u_error = regs.r_o0;
}
else {
- tcp->u_rval = regs.u_regs[UREG_I0];
+ tcp->u_rval = regs.r_o0;
u_error = 0;
}
#endif /* SPARC */
@@ -897,12 +898,12 @@ struct tcb *tcp;
#endif /* SPARC */
#ifdef I386
/* Wanna know how to kill an hour single-stepping? */
- if (tcp->status.pr_reg[EFL] & 0x1) {
+ if (tcp->status.PR_REG[EFL] & 0x1) {
tcp->u_rval = -1;
- u_error = tcp->status.pr_reg[EAX];
+ u_error = tcp->status.PR_REG[EAX];
}
else {
- tcp->u_rval = tcp->status.pr_reg[EAX];
+ tcp->u_rval = tcp->status.PR_REG[EAX];
u_error = 0;
}
#endif /* I386 */
@@ -1074,12 +1075,11 @@ struct tcb *tcp;
}
#elif defined (SPARC)
{
- int i, offset;
+ int i;
- offset = UREG_I0;
tcp->u_nargs = sysent[tcp->scno].nargs;
for (i = 0; i < tcp->u_nargs; i++)
- tcp->u_arg[i] = regs.u_regs[offset + i];
+ tcp->u_arg[i] = *((&regs.r_o0) + i);
}
#else
{
@@ -1141,8 +1141,12 @@ struct tcb *tcp;
if (sysent[tcp->scno].nargs != -1)
tcp->u_nargs = sysent[tcp->scno].nargs;
else
+#if UNIXWARE >= 2
+ tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
+#else
tcp->u_nargs = 5;
- umoven(tcp, tcp->status.pr_reg[UESP] + 4,
+#endif
+ umoven(tcp, tcp->status.PR_REG[UESP] + 4,
tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
#endif /* I386 */
#endif /* !HAVE_PR_SYSCALL */
@@ -1292,10 +1296,10 @@ struct tcb *tcp;
#ifdef LINUX
#ifdef SPARC
- struct pt_regs regs;
+ struct regs regs;
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
return -1;
- val = regs.u_regs[UREG_I1];
+ val = regs.r_o1;
#endif /* SPARC */
#endif /* LINUX */
@@ -1306,13 +1310,13 @@ struct tcb *tcp;
#ifdef SVR4
#ifdef SPARC
- val = tcp->status.pr_reg[R_O1];
+ val = tcp->status.PR_REG[R_O1];
#endif /* SPARC */
#ifdef I386
- val = tcp->status.pr_reg[EDX];
+ val = tcp->status.PR_REG[EDX];
#endif /* I386 */
#ifdef MIPS
- val = tcp->status.pr_reg[CTX_V1];
+ val = tcp->status.PR_REG[CTX_V1];
#endif /* MIPS */
#endif /* SVR4 */
diff --git a/system.c b/system.c
index f1f1fbe..361e6e4 100644
--- a/system.c
+++ b/system.c
@@ -1279,11 +1279,19 @@ static struct xlat sysctl_kern[] = {
{ KERN_PROF, "KERN_PROF" },
{ KERN_NODENAME, "KERN_NODENAME" },
{ KERN_DOMAINNAME, "KERN_DOMAINNAME" },
+#ifdef KERN_SECURELVL
{ KERN_SECURELVL, "KERN_SECURELVL" },
+#endif
{ KERN_PANIC, "KERN_PANIC" },
+#ifdef KERN_REALROOTDEV
{ KERN_REALROOTDEV, "KERN_REALROOTDEV" },
+#endif
+#ifdef KERN_JAVA_INTERPRETER
{ KERN_JAVA_INTERPRETER, "KERN_JAVA_INTERPRETER" },
+#endif
+#ifdef KERN_JAVA_APPLETVIEWER
{ KERN_JAVA_APPLETVIEWER, "KERN_JAVA_APPLETVIEWER" },
+#endif
{ KERN_SPARC_REBOOT, "KERN_SPARC_REBOOT" },
{ KERN_CTLALTDEL, "KERN_CTLALTDEL" },
{ KERN_PRINTK, "KERN_PRINTK" },
@@ -1562,8 +1570,13 @@ struct tcb *tcp;
&& ((name[0] == CTL_KERN
&& (name[1] == KERN_OSRELEASE
|| name[1] == KERN_OSTYPE
+#ifdef KERN_JAVA_INTERPRETER
|| name[1] == KERN_JAVA_INTERPRETER
- || name[1] == KERN_JAVA_APPLETVIEWER)))) {
+#endif
+#ifdef KERN_JAVA_APPLETVIEWER
+ || name[1] == KERN_JAVA_APPLETVIEWER
+#endif
+ )))) {
printpath(tcp, (size_t)info.oldval);
tprintf(", %d, ", oldlen);
if (info.newval == 0)
diff --git a/util.c b/util.c
index b6beb1b..7d9c5fa 100644
--- a/util.c
+++ b/util.c
@@ -57,7 +57,11 @@
#include <sys/utsname.h>
#endif /* SUNOS4_KERNEL_ARCH_KLUDGE */
-#if defined(LINUX) && defined(SPARC) && !defined(__GLIBC__)
+#if defined(LINUX) && defined(SPARC)
+
+#include <asm/reg.h>
+
+#if !defined(__GLIBC__)
#include <linux/unistd.h>
@@ -95,6 +99,8 @@ static _hack_syscall5(int,_ptrace,int,__request,int,__pid,int,__addr,int,__data,
#endif
+#endif
+
/* macros */
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -618,6 +624,10 @@ char *laddr;
#endif /* SUNOS4 */
#ifdef SVR4
+#ifdef SVR4_MP
+ if (pread(tcp->pfd_as, laddr, len, addr) == -1)
+ return -1;
+#else
/*
* We would like to use pread preferentially for speed
* but even though SGI has it in their library, it no longer works.
@@ -633,6 +643,7 @@ char *laddr;
if (read(tcp->pfd, laddr, len) == -1)
return -1;
#endif /* !HAVE_PREAD */
+#endif /* SVR4_MP */
#endif /* SVR4 */
return 0;
@@ -878,10 +889,10 @@ struct tcb *tcp;
return -1;
#else /* !ALPHA */
#ifdef SPARC
- struct pt_regs regs;
+ struct regs regs;
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
return -1;
- pc = regs.pc;
+ pc = regs.r_pc;
#endif /* SPARC */
#endif /* ALPHA */
#endif /* !M68K */
@@ -955,12 +966,12 @@ struct tcb *tcp;
tprintf("[%08lx] ", pc);
#else /* !ALPHA */
#ifdef SPARC
- struct pt_regs regs;
+ struct regs regs;
if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0) {
tprintf("[????????] ");
return;
}
- tprintf("[%08lx] ", regs.pc);
+ tprintf("[%08lx] ", regs.r_pc);
#endif /* SPARC */
#endif /* ALPHA */
#endif /* !M68K */
@@ -997,7 +1008,7 @@ struct tcb *tcp;
#ifdef SPARC
/* We simply use the SunOS breakpoint code. */
- struct pt_regs regs;
+ struct regs regs;
#define LOOPA 0x30800000 /* ba,a 0 */
if (tcp->flags & TCB_BPTSET) {
@@ -1008,9 +1019,7 @@ struct tcb *tcp;
perror("setbpt: ptrace(PTRACE_GETREGS, ...)");
return -1;
}
- memmove (&regs.u_regs [1], &regs.u_regs [0],
- sizeof (regs.u_regs) - sizeof (regs.u_regs [0]));
- tcp->baddr = regs.u_regs[UREG_I7] + 8;
+ tcp->baddr = regs.r_o7 + 8;
errno = 0;
tcp->inst[0] = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)tcp->baddr, 0);
if(errno) {