Fixes for ptrace() argument parsing.
* process.c: Add parsing of PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG,
PTRACE_GETSIGINFO, PTRACE_SETSIGINFO.
* strace.c (handle_stopped_tcbs): Make PTRACE_SETOPTIONS
define check more robust.
* defs.h: Declare several "extern const struct xlat" arrays here.
* desc.c: Remove open_mode_flags[] and open_access_modes[]
extern declarations.
* net.c: Remove open_mode_flags[] extern declaration.
* sock.c: Remove addrfams[] extern declaration.
* util.c: Remove struct_user_offsets[] extern declaration.
* signal.c: Remove open_mode_flags[] extern declaration.
diff --git a/ChangeLog b/ChangeLog
index ac67497..5a3d0fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-01-13 Denys Vlasenko <dvlasenk@redhat.com>
+
+ Fixes for ptrace() argument parsing.
+ * process.c: Add parsing of PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG,
+ PTRACE_GETSIGINFO, PTRACE_SETSIGINFO.
+ * strace.c (handle_stopped_tcbs): Make PTRACE_SETOPTIONS
+ define check more robust.
+ * defs.h: Declare several "extern const struct xlat" arrays here.
+ * desc.c: Remove open_mode_flags[] and open_access_modes[]
+ extern declarations.
+ * net.c: Remove open_mode_flags[] extern declaration.
+ * sock.c: Remove addrfams[] extern declaration.
+ * util.c: Remove struct_user_offsets[] extern declaration.
+ * signal.c: Remove open_mode_flags[] extern declaration.
+
2009-01-09 Denys Vlasenko <dvlasenk@redhat.com>
* defs.h: Add new struct tcb fields: wait_status, next_need_service.
diff --git a/defs.h b/defs.h
index f9e4ecc..1366a6e 100644
--- a/defs.h
+++ b/defs.h
@@ -417,6 +417,11 @@
char *str;
};
+extern const struct xlat open_mode_flags[];
+extern const struct xlat addrfams[];
+extern const struct xlat struct_user_offsets[];
+extern const struct xlat open_access_modes[];
+
/* Format of syscall return values */
#define RVAL_DECIMAL 000 /* decimal format */
#define RVAL_HEX 001 /* hex format */
diff --git a/desc.c b/desc.c
index db1084d..c4c5a69 100644
--- a/desc.c
+++ b/desc.c
@@ -261,8 +261,6 @@
}
#endif
-extern const struct xlat open_mode_flags[];
-
/*
* low bits of the open(2) flags define access mode,
* other bits are real flags.
@@ -270,7 +268,6 @@
static const char *
sprint_open_modes(mode_t flags)
{
- extern const struct xlat open_access_modes[];
static char outstr[1024];
const char *str = xlookup(open_access_modes, flags & 3);
const char *sep = "";
diff --git a/net.c b/net.c
index be88969..b5cf81c 100644
--- a/net.c
+++ b/net.c
@@ -1499,8 +1499,6 @@
return sys_accept(tcp);
}
-extern const struct xlat open_mode_flags[];
-
static int
do_pipe(struct tcb *tcp, int flags_arg)
{
diff --git a/process.c b/process.c
index 95c47e1..03cd251 100644
--- a/process.c
+++ b/process.c
@@ -2231,7 +2231,7 @@
else if (umove(tcp, tcp->u_arg[2], &si) < 0)
tprintf("{???}");
else
- printsiginfo(&si, verbose (tcp));
+ printsiginfo(&si, verbose(tcp));
/* options */
tprintf(", ");
printflags(wait4_options, tcp->u_arg[3], "W???");
@@ -2332,6 +2332,18 @@
#ifdef PTRACE_SETVRREGS
{ PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
#endif
+#ifdef PTRACE_SETOPTIONS
+ { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
+#endif
+#ifdef PTRACE_GETEVENTMSG
+ { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
+#endif
+#ifdef PTRACE_GETSIGINFO
+ { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
+#endif
+#ifdef PTRACE_SETSIGINFO
+ { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
+#endif
#ifdef SUNOS4
{ PTRACE_READDATA, "PTRACE_READDATA" },
{ PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
@@ -2361,7 +2373,9 @@
#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" },
@@ -2386,9 +2400,35 @@
};
#ifndef FREEBSD
-#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
-static
-#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
+#ifdef PTRACE_SETOPTIONS
+static const struct xlat ptrace_setoptions_flags[] = {
+#ifdef PTRACE_O_TRACESYSGOOD
+ { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
+#endif
+#ifdef PTRACE_O_TRACEFORK
+ { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
+#endif
+#ifdef PTRACE_O_TRACEVFORK
+ { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
+#endif
+#ifdef PTRACE_O_TRACECLONE
+ { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
+#endif
+#ifdef PTRACE_O_TRACEEXEC
+ { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
+#endif
+#ifdef PTRACE_O_TRACEVFORKDONE
+ { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
+#endif
+#ifdef PTRACE_O_TRACEEXIT
+ { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
+#endif
+ { 0, NULL },
+};
+#endif
+#endif
+
+#ifndef FREEBSD
const struct xlat struct_user_offsets[] = {
#ifdef LINUX
#if defined(S390) || defined(S390X)
@@ -3192,6 +3232,30 @@
case PTRACE_DETACH:
printsignal(tcp->u_arg[3]);
break;
+#ifdef PTRACE_SETOPTIONS
+ case PTRACE_SETOPTIONS:
+ printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
+ break;
+#endif
+#ifdef PTRACE_SETSIGINFO
+ case PTRACE_SETSIGINFO: {
+ siginfo_t si;
+ if (!tcp->u_arg[3])
+ tprintf("NULL");
+ else if (syserror(tcp))
+ tprintf("%#lx", tcp->u_arg[3]);
+ else if (umove(tcp, tcp->u_arg[3], &si) < 0)
+ tprintf("{???}");
+ else
+ printsiginfo(&si, verbose(tcp));
+ break;
+ }
+#endif
+#ifdef PTRACE_GETSIGINFO
+ case PTRACE_GETSIGINFO:
+ /* Don't print anything, do it at syscall return. */
+ break;
+#endif
default:
tprintf("%#lx", tcp->u_arg[3]);
break;
@@ -3207,6 +3271,20 @@
printnum(tcp, tcp->u_arg[3], "%#lx");
break;
#endif
+#ifdef PTRACE_GETSIGINFO
+ case PTRACE_GETSIGINFO: {
+ siginfo_t si;
+ if (!tcp->u_arg[3])
+ tprintf("NULL");
+ else if (syserror(tcp))
+ tprintf("%#lx", tcp->u_arg[3]);
+ else if (umove(tcp, tcp->u_arg[3], &si) < 0)
+ tprintf("{???}");
+ else
+ printsiginfo(&si, verbose(tcp));
+ break;
+ }
+#endif
}
}
#endif /* LINUX */
diff --git a/signal.c b/signal.c
index 05ab30a..963bf0f 100644
--- a/signal.c
+++ b/signal.c
@@ -1967,7 +1967,7 @@
if (umove(tcp, tcp->u_arg[2], &si) < 0)
tprintf("%#lx", tcp->u_arg[2]);
else
- printsiginfo(&si, verbose (tcp));
+ printsiginfo(&si, verbose(tcp));
}
return 0;
}
@@ -1993,7 +1993,7 @@
if (umove(tcp, tcp->u_arg[1], &si) < 0)
tprintf("%#lx", tcp->u_arg[1]);
else
- printsiginfo(&si, verbose (tcp));
+ printsiginfo(&si, verbose(tcp));
/* XXX For now */
tprintf(", %#lx", tcp->u_arg[2]);
tprintf(", %d", (int) tcp->u_arg[3]);
@@ -2011,8 +2011,6 @@
return 0;
}
-extern const struct xlat open_mode_flags[];
-
static int
do_signalfd(struct tcb *tcp, int flags_arg)
{
diff --git a/sock.c b/sock.c
index 5303fa9..670f72b 100644
--- a/sock.c
+++ b/sock.c
@@ -47,8 +47,6 @@
#endif
#include <net/if.h>
-extern const struct xlat addrfams[];
-
static const struct xlat iffflags[] = {
{ IFF_UP, "IFF_UP" },
{ IFF_BROADCAST, "IFF_BROADCAST" },
diff --git a/strace.c b/strace.c
index 989db1a..57945db 100644
--- a/strace.c
+++ b/strace.c
@@ -2525,8 +2525,10 @@
}
}
/* Add more OSes after you verified it works for them. */
-/* PTRACE_SETOPTIONS is not a #define. PT_SETOPTIONS is. */
-#if defined LINUX && defined PT_SETOPTIONS
+/* PTRACE_SETOPTIONS may be an enum, not a #define.
+ * But sometimes we can test for it by checking PT_SETOPTIONS.
+ */
+#if defined LINUX && (defined PTRACE_SETOPTIONS || defined PT_SETOPTIONS)
# ifndef PTRACE_O_TRACESYSGOOD
# define PTRACE_O_TRACESYSGOOD 0x00000001
# endif
@@ -2557,7 +2559,7 @@
goto tracing;
}
-#if defined LINUX && defined PT_SETOPTIONS
+#if defined LINUX && (defined PTRACE_SETOPTIONS || defined PT_SETOPTIONS)
if (ptrace_stop_sig != SIGTRAP && WSTOPSIG(status) == SIGTRAP) {
/*
* We told ptrace to report SIGTRAP | 0x80 on this process
diff --git a/util.c b/util.c
index f9e2b1d..763ae84 100644
--- a/util.c
+++ b/util.c
@@ -1116,7 +1116,6 @@
}
is_sun4m = strcmp(name.machine, "sun4m") == 0;
if (is_sun4m) {
- extern const struct xlat struct_user_offsets[];
const struct xlat *x;
for (x = struct_user_offsets; x->str; x++)