printsiginfo.c revision 3595f4ae15ad50fae917fdd1871eece4e928fb3a
1#include "defs.h"
2
3#include <signal.h>
4#include <linux/audit.h>
5
6#include "printsiginfo.h"
7
8#include "xlat/audit_arch.h"
9#include "xlat/sigbus_codes.h"
10#include "xlat/sigchld_codes.h"
11#include "xlat/sigfpe_codes.h"
12#include "xlat/sigill_codes.h"
13#include "xlat/siginfo_codes.h"
14#include "xlat/sigpoll_codes.h"
15#include "xlat/sigprof_codes.h"
16#include "xlat/sigsegv_codes.h"
17#include "xlat/sigsys_codes.h"
18#include "xlat/sigtrap_codes.h"
19
20#ifdef SIGEMT
21# include "xlat/sigemt_codes.h"
22#endif
23
24#ifndef SI_FROMUSER
25# define SI_FROMUSER(sip)	((sip)->si_code <= 0)
26#endif
27
28static void
29printsigsource(const siginfo_t *sip)
30{
31	tprintf(", si_pid=%u, si_uid=%u",
32		(unsigned int) sip->si_pid,
33		(unsigned int) sip->si_uid);
34}
35
36static void
37printsigval(const siginfo_t *sip, bool verbose)
38{
39	if (!verbose)
40		tprints(", ...");
41	else
42		tprintf(", si_value={int=%d, ptr=%#lx}",
43			sip->si_int,
44			(unsigned long) sip->si_ptr);
45}
46
47static void
48print_si_code(int si_signo, int si_code)
49{
50	const char *code = xlookup(siginfo_codes, si_code);
51
52	if (!code) {
53		switch (si_signo) {
54		case SIGTRAP:
55			code = xlookup(sigtrap_codes, si_code);
56			break;
57		case SIGCHLD:
58			code = xlookup(sigchld_codes, si_code);
59			break;
60		case SIGPOLL:
61			code = xlookup(sigpoll_codes, si_code);
62			break;
63		case SIGPROF:
64			code = xlookup(sigprof_codes, si_code);
65			break;
66		case SIGILL:
67			code = xlookup(sigill_codes, si_code);
68			break;
69#ifdef SIGEMT
70		case SIGEMT:
71			code = xlookup(sigemt_codes, si_code);
72			break;
73#endif
74		case SIGFPE:
75			code = xlookup(sigfpe_codes, si_code);
76			break;
77		case SIGSEGV:
78			code = xlookup(sigsegv_codes, si_code);
79			break;
80		case SIGBUS:
81			code = xlookup(sigbus_codes, si_code);
82			break;
83		case SIGSYS:
84			code = xlookup(sigsys_codes, si_code);
85			break;
86		}
87	}
88
89	if (code)
90		tprints(code);
91	else
92		tprintf("%#x", si_code);
93}
94
95static void
96print_si_info(const siginfo_t *sip, bool verbose)
97{
98	if (sip->si_errno) {
99		tprints(", si_errno=");
100		if ((unsigned) sip->si_errno < nerrnos
101		    && errnoent[sip->si_errno])
102			tprints(errnoent[sip->si_errno]);
103		else
104			tprintf("%d", sip->si_errno);
105	}
106
107	if (SI_FROMUSER(sip)) {
108		switch (sip->si_code) {
109		case SI_USER:
110			printsigsource(sip);
111			break;
112		case SI_TKILL:
113			printsigsource(sip);
114			break;
115#if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
116		case SI_TIMER:
117			tprintf(", si_timerid=%#x, si_overrun=%d",
118				sip->si_timerid, sip->si_overrun);
119			printsigval(sip, verbose);
120			break;
121#endif
122		default:
123			printsigsource(sip);
124			if (sip->si_ptr)
125				printsigval(sip, verbose);
126			break;
127		}
128	} else {
129		switch (sip->si_signo) {
130		case SIGCHLD:
131			printsigsource(sip);
132			tprints(", si_status=");
133			if (sip->si_code == CLD_EXITED)
134				tprintf("%d", sip->si_status);
135			else
136				printsignal(sip->si_status);
137			if (!verbose)
138				tprints(", ...");
139			else
140				tprintf(", si_utime=%llu, si_stime=%llu",
141					(unsigned long long) sip->si_utime,
142					(unsigned long long) sip->si_stime);
143			break;
144		case SIGILL: case SIGFPE:
145		case SIGSEGV: case SIGBUS:
146			tprintf(", si_addr=%#lx",
147				(unsigned long) sip->si_addr);
148			break;
149		case SIGPOLL:
150			switch (sip->si_code) {
151			case POLL_IN: case POLL_OUT: case POLL_MSG:
152				tprintf(", si_band=%ld",
153					(long) sip->si_band);
154				break;
155			}
156			break;
157#ifdef HAVE_SIGINFO_T_SI_SYSCALL
158		case SIGSYS:
159			tprintf(", si_call_addr=%#lx, si_syscall=__NR_%s, si_arch=",
160				(unsigned long) sip->si_call_addr,
161				syscall_name(sip->si_syscall));
162			printxval(audit_arch, sip->si_arch, "AUDIT_ARCH_???");
163			break;
164#endif
165		default:
166			if (sip->si_pid || sip->si_uid)
167				printsigsource(sip);
168			if (sip->si_ptr)
169				printsigval(sip, verbose);
170		}
171	}
172}
173
174void
175printsiginfo(const siginfo_t *sip, bool verbose)
176{
177	if (sip->si_signo == 0) {
178		tprints("{}");
179		return;
180	}
181	tprints("{si_signo=");
182	printsignal(sip->si_signo);
183
184	tprints(", si_code=");
185	print_si_code(sip->si_signo, sip->si_code);
186
187#ifdef SI_NOINFO
188	if (sip->si_code != SI_NOINFO)
189#endif
190		print_si_info(sip, verbose);
191
192	tprints("}");
193}
194
195void
196printsiginfo_at(struct tcb *tcp, long addr)
197{
198	siginfo_t si;
199
200	if (!umove_or_printaddr(tcp, addr, &si))
201		printsiginfo(&si, verbose(tcp));
202}
203