# endif
#endif
-/* configuration section */
+/* Configuration section */
#ifndef MAX_QUALS
#if defined(LINUX) && defined(MIPS)
#define MAX_QUALS 7000 /* maximum number of syscalls, signals, etc. */
#ifndef DEFAULT_ACOLUMN
#define DEFAULT_ACOLUMN 40 /* default alignment column for results */
#endif
+
+/* Maximum number of args to a syscall.
+ *
+ * Make sure that all entries in all syscallent.h files
+ * have nargs <= MAX_ARGS!
+ * linux/<ARCH>/syscallent.h: ia64 has many syscalls with
+ * nargs = 8, mips has two with nargs = 7 (both are printargs),
+ * all others are <= 6.
+ * freebsd/i386/syscallent.h: one syscall with nargs = 8
+ * (sys_sendfile, looks legitimate)
+ * and one with nargs = 7 (sys_mmap, maybe it should have 6?).
+ * sunos4/syscallent.h: all are <= 6.
+ * svr4/syscallent.h: all are -1.
+ */
#ifndef MAX_ARGS
# ifdef HPPA
-# define MAX_ARGS 6 /* maximum number of args to a syscall */
+# define MAX_ARGS 6
+# elif defined X86_64 || defined I386
+# ifdef FREEBSD
+# define MAX_ARGS 8
+# else
+# define MAX_ARGS 6
+# endif
# else
/* Way too big. Switch your arch to saner size after you tested that it works */
-# define MAX_ARGS 32 /* maximum number of args to a syscall */
+# define MAX_ARGS 32
# endif
#endif
+
#ifndef DEFAULT_SORTBY
#define DEFAULT_SORTBY "time" /* default sorting method for call profiling */
#endif
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
{ 0, 0, printargs, "SYS_3999" }, /* 3999 */ /* end of POSIX */
#if !defined (LINUX_MIPSN32) && !defined (LINUX_MIPSN64)
/* For an O32 strace, decode the o32 syscalls. */
- { 8, 0, printargs, "syscall" }, /* 4000 */ /* start of Linux o32 */
+ { 7, 0, printargs, "syscall" }, /* 4000 */ /* start of Linux o32 */
{ 1, TP, sys_exit, "exit" }, /* 4001 */
{ 0, TP, sys_fork, "fork" }, /* 4002 */
{ 3, TD, sys_read, "read" }, /* 4003 */
{ 5, 0, printargs, "pciconfig_read" }, /* 198 */
{ 5, 0, printargs, "pciconfig_write" }, /* 199 */
{ 3, 0, printargs, "pciconfig_iobase" }, /* 200 */
- { 8, 0, printargs, "MOL" }, /* 201 */
+ { 6, 0, printargs, "MOL" }, /* 201 */
{ 3, TD, sys_getdents64, "getdents64" }, /* 202 */
{ 2, TF, sys_pivotroot, "pivot_root" }, /* 203 */
{ 3, TD, sys_fcntl, "fcntl64" }, /* 204 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 400
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 400 */
+ { 6, 0, printargs, "socket_subcall"}, /* 400 */
{ 3, TN, sys_socket, "socket" }, /* 401 */
{ 3, TN, sys_bind, "bind" }, /* 402 */
{ 3, TN, sys_connect, "connect" }, /* 403 */
#if SYS_socket_subcall != 353
#error fix me
#endif
- { 8, 0, printargs, "socket_subcall"}, /* 353 */
+ { 6, 0, printargs, "socket_subcall"}, /* 353 */
{ 3, TN, sys_socket, "socket" }, /* 354 */
{ 3, TN, sys_bind, "bind" }, /* 355 */
{ 3, TN, sys_connect, "connect" }, /* 356 */
#endif
#endif
+/* Note on the size of sigset_t:
+ *
+ * In glibc, sigset_t is an array with space for 1024 bits (!),
+ * even though all arches supported by Linux have only 64 signals
+ * except MIPS, which has 128. IOW, it is 128 bytes long.
+ *
+ * In-kernel sigset_t is sized correctly (it is either 64 or 128 bit long).
+ * However, some old syscall return only 32 lower bits (one word).
+ * Example: sys_sigpending vs sys_rt_sigpending.
+ *
+ * Be aware of this fact when you try to
+ * memcpy(&tcp->u_arg[1], &something, sizeof(sigset_t))
+ * - sizeof(sigset_t) is much bigger than you think,
+ * it may overflow tcp->u_arg[] array, and it may try to copy more data
+ * than is really available in <something>.
+ * Similarly,
+ * umoven(tcp, addr, sizeof(sigset_t), &sigset)
+ * may be a bad idea: it'll try to read much more data than needed
+ * to fetch a sigset_t.
+ * Use (NSIG / 8) as a size instead.
+ */
+
const char *
signame(int sig)
{
sprintsigmask(const char *str, sigset_t *mask, int rt)
/* set might include realtime sigs */
{
+ /* Was [8 * sizeof(sigset_t) * 8], but
+ * glibc sigset_t is huge (1024 bits = 128 *bytes*),
+ * and we were ending up with 8k (!) buffer here.
+ *
+ * No Unix system can have sig > 255
+ * (waitpid API won't be able to indicate death from one)
+ * and sig 0 doesn't exist either.
+ * Therefore max possible no of sigs is 255: 1..255
+ */
+ static char outstr[8 * 255];
+
int i, nsigs;
int maxsigs;
const char *format;
char *s;
- static char outstr[8 * sizeof(sigset_t) * 8];
strcpy(outstr, str);
s = outstr + strlen(outstr);
if (umove(tcp, usp+__SIGNAL_FRAMESIZE, &sc) < 0)
return 0;
tcp->u_arg[0] = 1;
- memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t));
+ memcpy(&tcp->u_arg[1], &sc.oldmask[0], NSIG / 8);
} else {
tcp->u_rval = tcp->u_error = 0;
if (tcp->u_arg[0] == 0)
if (umove(tcp, sp + 16 + SIGFRAME_SC_OFFSET, &sc) < 0)
return 0;
tcp->u_arg[0] = 1;
- memcpy(tcp->u_arg + 1, &sc.sc_mask, sizeof(sc.sc_mask));
+ memcpy(tcp->u_arg + 1, &sc.sc_mask, NSIG / 8);
}
else {
sigset_t sigm;
tcp->u_rval = tcp->u_error = 0;
if (tcp->u_arg[0] == 0)
return 0;
- memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm));
+ sigemptyset(&sigm);
+ memcpy(&sigm, tcp->u_arg + 1, NSIG / 8);
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
return RVAL_NONE | RVAL_STR;
}
if (umove(tcp, sp + SIGFRAME_UC_OFFSET, &uc) < 0)
return 0;
tcp->u_arg[0] = 1;
- memcpy(tcp->u_arg + 1, &uc.uc_sigmask, sizeof(uc.uc_sigmask));
+ memcpy(tcp->u_arg + 1, &uc.uc_sigmask, NSIG / 8);
}
else {
sigset_t sigm;
tcp->u_rval = tcp->u_error = 0;
if (tcp->u_arg[0] == 0)
return 0;
- memcpy(&sigm, tcp->u_arg + 1, sizeof(sigm));
+ sigemptyset(&sigm);
+ memcpy(&sigm, tcp->u_arg + 1, NSIG / 8);
tcp->auxstr = sprintsigmask("mask now ", &sigm, 0);
return RVAL_NONE | RVAL_STR;
}