+/*
+ * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
+ * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
+ * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
+ * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
+ * Copyright (c) 2001 John Hughes <john@Calva.COM>
+ * Copyright (c) 2013 Denys Vlasenko <vda.linux@googlemail.com>
+ * Copyright (c) 2011-2015 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
+ * Copyright (c) 2015-2018 The strace developers.
+ * 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.
+ */
+
#include "defs.h"
+#include DEF_MPERS_TYPE(siginfo_t)
+
#include <signal.h>
#include <linux/audit.h>
+#include MPERS_DEFS
+
+#include "nr_prefix.c"
+
+#ifndef IN_MPERS
#include "printsiginfo.h"
+#endif
#include "xlat/audit_arch.h"
#include "xlat/sigbus_codes.h"
}
static void
-printsigval(const siginfo_t *sip, bool verbose)
+printsigval(const siginfo_t *sip)
{
- if (!verbose)
- tprints(", ...");
- else
- tprintf(", si_value={int=%d, ptr=%#lx}",
- sip->si_int,
- (unsigned long) sip->si_ptr);
+ tprintf(", si_value={int=%d, ptr=", sip->si_int);
+ printaddr(ptr_to_kulong(sip->si_ptr));
+ tprints("}");
}
static void
-print_si_code(int si_signo, int si_code)
+print_si_code(int si_signo, unsigned int si_code)
{
const char *code = xlookup(siginfo_codes, si_code);
}
}
- if (code)
- tprints(code);
- else
- tprintf("%#x", si_code);
+ print_xlat_ex(si_code, code, XLAT_STYLE_DEFAULT);
}
static void
-print_si_info(const siginfo_t *sip, bool verbose)
+print_si_info(const siginfo_t *sip)
{
if (sip->si_errno) {
tprints(", si_errno=");
case SI_TIMER:
tprintf(", si_timerid=%#x, si_overrun=%d",
sip->si_timerid, sip->si_overrun);
- printsigval(sip, verbose);
+ printsigval(sip);
break;
#endif
default:
printsigsource(sip);
if (sip->si_ptr)
- printsigval(sip, verbose);
+ printsigval(sip);
break;
}
} else {
tprintf("%d", sip->si_status);
else
printsignal(sip->si_status);
- if (!verbose)
- tprints(", ...");
- else
- tprintf(", si_utime=%llu, si_stime=%llu",
- (unsigned long long) sip->si_utime,
- (unsigned long long) sip->si_stime);
+ tprintf(", si_utime=%llu, si_stime=%llu",
+ zero_extend_signed_to_ull(sip->si_utime),
+ zero_extend_signed_to_ull(sip->si_stime));
break;
case SIGILL: case SIGFPE:
case SIGSEGV: case SIGBUS:
- tprintf(", si_addr=%#lx",
- (unsigned long) sip->si_addr);
+ tprints(", si_addr=");
+ printaddr(ptr_to_kulong(sip->si_addr));
break;
case SIGPOLL:
switch (sip->si_code) {
}
break;
#ifdef HAVE_SIGINFO_T_SI_SYSCALL
- case SIGSYS:
- tprintf(", si_call_addr=%#lx, si_syscall=__NR_%s, si_arch=",
- (unsigned long) sip->si_call_addr,
- syscall_name(sip->si_syscall));
+ case SIGSYS: {
+ /*
+ * Note that we can safely use the personlity set in
+ * current_personality here (and don't have to guess it
+ * based on X32_SYSCALL_BIT and si_arch, for example):
+ * - The signal is delivered as a result of seccomp
+ * filtering to the process executing forbidden
+ * syscall.
+ * - We have set the personality for the tracee during
+ * the syscall entering.
+ * - The current_personality is reliably switched in
+ * the next_event routine, it is set to the
+ * personality of the last call made (the one that
+ * triggered the signal delivery).
+ * - Looks like there are no other cases where SIGSYS
+ * is delivered from the kernel so far.
+ */
+ const char *scname = syscall_name(shuffle_scno(
+ (unsigned) sip->si_syscall));
+
+ tprints(", si_call_addr=");
+ printaddr(ptr_to_kulong(sip->si_call_addr));
+ tprints(", si_syscall=");
+ if (scname)
+ tprintf("%s%s",
+ nr_prefix(sip->si_syscall), scname);
+ else
+ tprintf("%u", (unsigned) sip->si_syscall);
+ tprints(", si_arch=");
printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
break;
+ }
#endif
default:
if (sip->si_pid || sip->si_uid)
printsigsource(sip);
if (sip->si_ptr)
- printsigval(sip, verbose);
+ printsigval(sip);
}
}
}
+#ifdef IN_MPERS
+static
+#endif
void
-printsiginfo(const siginfo_t *sip, bool verbose)
+printsiginfo(const siginfo_t *sip)
{
if (sip->si_signo == 0) {
tprints("{}");
#ifdef SI_NOINFO
if (sip->si_code != SI_NOINFO)
#endif
- print_si_info(sip, verbose);
+ print_si_info(sip);
tprints("}");
}
-void
-printsiginfo_at(struct tcb *tcp, long addr)
+MPERS_PRINTER_DECL(void, printsiginfo_at,
+ struct tcb *const tcp, const kernel_ulong_t addr)
{
siginfo_t si;
if (!umove_or_printaddr(tcp, addr, &si))
- printsiginfo(&si, verbose(tcp));
+ printsiginfo(&si);
+}
+
+static bool
+print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
+{
+ printsiginfo((const siginfo_t *) elem_buf);
+ return true;
+}
+
+MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
+ const kernel_ulong_t addr, const kernel_ulong_t len)
+{
+ siginfo_t si;
+
+ print_array(tcp, addr, len, &si, sizeof(si),
+ tfetch_mem, print_siginfo_t, 0);
}