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