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