Commit | Line | Data |
---|---|---|
93813b37 WT |
1 | /* Low-level siginfo manipulation for amd64. |
2 | ||
3666a048 | 3 | Copyright (C) 2002-2021 Free Software Foundation, Inc. |
93813b37 WT |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
268a13a5 | 20 | #include "gdbsupport/common-defs.h" |
8488c357 | 21 | #include <signal.h> |
93813b37 WT |
22 | #include "amd64-linux-siginfo.h" |
23 | ||
9cf12d57 PA |
24 | #define GDB_SI_SIZE 128 |
25 | ||
26 | /* The types below define the most complete kernel siginfo types known | |
27 | for the architecture, independent of the system/libc headers. They | |
28 | are named from a 64-bit kernel's perspective: | |
29 | ||
30 | | layout | type | | |
31 | |--------+----------------------| | |
32 | | 64-bit | nat_siginfo_t | | |
33 | | 32-bit | compat_siginfo_t | | |
34 | | x32 | compat_x32_siginfo_t | | |
35 | */ | |
36 | ||
37 | #ifndef __ILP32__ | |
3f2f6cb5 WT |
38 | |
39 | typedef int nat_int_t; | |
9cf12d57 | 40 | typedef unsigned long nat_uptr_t; |
3f2f6cb5 WT |
41 | |
42 | typedef int nat_time_t; | |
43 | typedef int nat_timer_t; | |
44 | ||
9cf12d57 PA |
45 | /* For native 64-bit, clock_t in _sigchld is 64-bit. */ |
46 | typedef long nat_clock_t; | |
3f2f6cb5 WT |
47 | |
48 | typedef union nat_sigval | |
49 | { | |
50 | nat_int_t sival_int; | |
51 | nat_uptr_t sival_ptr; | |
52 | } nat_sigval_t; | |
53 | ||
54 | typedef struct nat_siginfo | |
55 | { | |
56 | int si_signo; | |
57 | int si_errno; | |
58 | int si_code; | |
59 | ||
60 | union | |
61 | { | |
62 | int _pad[((128 / sizeof (int)) - 4)]; | |
63 | /* kill() */ | |
64 | struct | |
65 | { | |
66 | unsigned int _pid; | |
67 | unsigned int _uid; | |
68 | } _kill; | |
69 | ||
70 | /* POSIX.1b timers */ | |
71 | struct | |
72 | { | |
73 | nat_timer_t _tid; | |
74 | int _overrun; | |
75 | nat_sigval_t _sigval; | |
76 | } _timer; | |
77 | ||
78 | /* POSIX.1b signals */ | |
79 | struct | |
80 | { | |
81 | unsigned int _pid; | |
82 | unsigned int _uid; | |
83 | nat_sigval_t _sigval; | |
84 | } _rt; | |
85 | ||
86 | /* SIGCHLD */ | |
87 | struct | |
88 | { | |
89 | unsigned int _pid; | |
90 | unsigned int _uid; | |
91 | int _status; | |
92 | nat_clock_t _utime; | |
93 | nat_clock_t _stime; | |
94 | } _sigchld; | |
95 | ||
96 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
97 | struct | |
98 | { | |
99 | nat_uptr_t _addr; | |
100 | short int _addr_lsb; | |
101 | struct | |
102 | { | |
103 | nat_uptr_t _lower; | |
104 | nat_uptr_t _upper; | |
105 | } si_addr_bnd; | |
106 | } _sigfault; | |
107 | ||
108 | /* SIGPOLL */ | |
109 | struct | |
110 | { | |
111 | int _band; | |
112 | int _fd; | |
113 | } _sigpoll; | |
114 | } _sifields; | |
9cf12d57 | 115 | } nat_siginfo_t; |
3f2f6cb5 | 116 | |
9cf12d57 | 117 | #endif /* __ILP32__ */ |
3f2f6cb5 | 118 | |
93813b37 WT |
119 | /* These types below (compat_*) define a siginfo type that is layout |
120 | compatible with the siginfo type exported by the 32-bit userspace | |
121 | support. */ | |
122 | ||
123 | typedef int compat_int_t; | |
124 | typedef unsigned int compat_uptr_t; | |
125 | ||
126 | typedef int compat_time_t; | |
127 | typedef int compat_timer_t; | |
128 | typedef int compat_clock_t; | |
129 | ||
130 | struct compat_timeval | |
131 | { | |
132 | compat_time_t tv_sec; | |
133 | int tv_usec; | |
134 | }; | |
135 | ||
136 | typedef union compat_sigval | |
137 | { | |
138 | compat_int_t sival_int; | |
139 | compat_uptr_t sival_ptr; | |
140 | } compat_sigval_t; | |
141 | ||
142 | typedef struct compat_siginfo | |
143 | { | |
144 | int si_signo; | |
145 | int si_errno; | |
146 | int si_code; | |
147 | ||
148 | union | |
149 | { | |
150 | int _pad[((128 / sizeof (int)) - 3)]; | |
151 | ||
152 | /* kill() */ | |
153 | struct | |
154 | { | |
155 | unsigned int _pid; | |
156 | unsigned int _uid; | |
157 | } _kill; | |
158 | ||
159 | /* POSIX.1b timers */ | |
160 | struct | |
161 | { | |
162 | compat_timer_t _tid; | |
163 | int _overrun; | |
164 | compat_sigval_t _sigval; | |
165 | } _timer; | |
166 | ||
167 | /* POSIX.1b signals */ | |
168 | struct | |
169 | { | |
170 | unsigned int _pid; | |
171 | unsigned int _uid; | |
172 | compat_sigval_t _sigval; | |
173 | } _rt; | |
174 | ||
175 | /* SIGCHLD */ | |
176 | struct | |
177 | { | |
178 | unsigned int _pid; | |
179 | unsigned int _uid; | |
180 | int _status; | |
181 | compat_clock_t _utime; | |
182 | compat_clock_t _stime; | |
183 | } _sigchld; | |
184 | ||
185 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
186 | struct | |
187 | { | |
188 | unsigned int _addr; | |
3f2f6cb5 WT |
189 | short int _addr_lsb; |
190 | struct | |
191 | { | |
192 | unsigned int _lower; | |
193 | unsigned int _upper; | |
194 | } si_addr_bnd; | |
93813b37 WT |
195 | } _sigfault; |
196 | ||
197 | /* SIGPOLL */ | |
198 | struct | |
199 | { | |
200 | int _band; | |
201 | int _fd; | |
202 | } _sigpoll; | |
203 | } _sifields; | |
204 | } compat_siginfo_t; | |
205 | ||
206 | /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */ | |
207 | typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t; | |
208 | ||
209 | typedef struct compat_x32_siginfo | |
210 | { | |
211 | int si_signo; | |
212 | int si_errno; | |
213 | int si_code; | |
214 | ||
215 | union | |
216 | { | |
217 | int _pad[((128 / sizeof (int)) - 3)]; | |
218 | ||
219 | /* kill() */ | |
220 | struct | |
221 | { | |
222 | unsigned int _pid; | |
223 | unsigned int _uid; | |
224 | } _kill; | |
225 | ||
226 | /* POSIX.1b timers */ | |
227 | struct | |
228 | { | |
229 | compat_timer_t _tid; | |
230 | int _overrun; | |
231 | compat_sigval_t _sigval; | |
232 | } _timer; | |
233 | ||
234 | /* POSIX.1b signals */ | |
235 | struct | |
236 | { | |
237 | unsigned int _pid; | |
238 | unsigned int _uid; | |
239 | compat_sigval_t _sigval; | |
240 | } _rt; | |
241 | ||
242 | /* SIGCHLD */ | |
243 | struct | |
244 | { | |
245 | unsigned int _pid; | |
246 | unsigned int _uid; | |
247 | int _status; | |
248 | compat_x32_clock_t _utime; | |
249 | compat_x32_clock_t _stime; | |
250 | } _sigchld; | |
251 | ||
252 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
253 | struct | |
254 | { | |
255 | unsigned int _addr; | |
3f2f6cb5 | 256 | unsigned int _addr_lsb; |
93813b37 WT |
257 | } _sigfault; |
258 | ||
259 | /* SIGPOLL */ | |
260 | struct | |
261 | { | |
262 | int _band; | |
263 | int _fd; | |
264 | } _sigpoll; | |
265 | } _sifields; | |
266 | } compat_x32_siginfo_t __attribute__ ((__aligned__ (8))); | |
267 | ||
268 | /* To simplify usage of siginfo fields. */ | |
269 | ||
270 | #define cpt_si_pid _sifields._kill._pid | |
271 | #define cpt_si_uid _sifields._kill._uid | |
272 | #define cpt_si_timerid _sifields._timer._tid | |
273 | #define cpt_si_overrun _sifields._timer._overrun | |
274 | #define cpt_si_status _sifields._sigchld._status | |
275 | #define cpt_si_utime _sifields._sigchld._utime | |
276 | #define cpt_si_stime _sifields._sigchld._stime | |
277 | #define cpt_si_ptr _sifields._rt._sigval.sival_ptr | |
278 | #define cpt_si_addr _sifields._sigfault._addr | |
3f2f6cb5 | 279 | #define cpt_si_addr_lsb _sifields._sigfault._addr_lsb |
d3d7d1ba TV |
280 | #define cpt_si_lower _sifields._sigfault.si_addr_bnd._lower |
281 | #define cpt_si_upper _sifields._sigfault.si_addr_bnd._upper | |
93813b37 WT |
282 | #define cpt_si_band _sifields._sigpoll._band |
283 | #define cpt_si_fd _sifields._sigpoll._fd | |
284 | ||
285 | /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun. | |
286 | In their place is si_timer1,si_timer2. */ | |
287 | ||
288 | #ifndef si_timerid | |
289 | #define si_timerid si_timer1 | |
290 | #endif | |
291 | #ifndef si_overrun | |
292 | #define si_overrun si_timer2 | |
293 | #endif | |
294 | ||
d3d7d1ba TV |
295 | #ifndef SEGV_BNDERR |
296 | #define SEGV_BNDERR 3 | |
297 | #endif | |
298 | ||
9cf12d57 PA |
299 | /* The type of the siginfo object the kernel returns in |
300 | PTRACE_GETSIGINFO. If gdb is built as a x32 program, we get a x32 | |
301 | siginfo. */ | |
302 | #ifdef __ILP32__ | |
303 | typedef compat_x32_siginfo_t ptrace_siginfo_t; | |
304 | #else | |
305 | typedef nat_siginfo_t ptrace_siginfo_t; | |
306 | #endif | |
307 | ||
93813b37 WT |
308 | /* Convert the system provided siginfo into compatible siginfo. */ |
309 | ||
310 | static void | |
9cf12d57 | 311 | compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from) |
93813b37 | 312 | { |
9cf12d57 | 313 | ptrace_siginfo_t from_ptrace; |
3f2f6cb5 | 314 | |
9cf12d57 | 315 | memcpy (&from_ptrace, from, sizeof (from_ptrace)); |
93813b37 WT |
316 | memset (to, 0, sizeof (*to)); |
317 | ||
9cf12d57 PA |
318 | to->si_signo = from_ptrace.si_signo; |
319 | to->si_errno = from_ptrace.si_errno; | |
320 | to->si_code = from_ptrace.si_code; | |
93813b37 WT |
321 | |
322 | if (to->si_code == SI_TIMER) | |
323 | { | |
9cf12d57 PA |
324 | to->cpt_si_timerid = from_ptrace.cpt_si_timerid; |
325 | to->cpt_si_overrun = from_ptrace.cpt_si_overrun; | |
326 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
327 | } |
328 | else if (to->si_code == SI_USER) | |
329 | { | |
9cf12d57 PA |
330 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
331 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
93813b37 | 332 | } |
d3d7d1ba TV |
333 | else if (to->si_code == SEGV_BNDERR |
334 | && to->si_signo == SIGSEGV) | |
335 | { | |
336 | to->cpt_si_addr = from_ptrace.cpt_si_addr; | |
337 | to->cpt_si_lower = from_ptrace.cpt_si_lower; | |
338 | to->cpt_si_upper = from_ptrace.cpt_si_upper; | |
339 | } | |
93813b37 WT |
340 | else if (to->si_code < 0) |
341 | { | |
9cf12d57 PA |
342 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
343 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
344 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
345 | } |
346 | else | |
347 | { | |
348 | switch (to->si_signo) | |
349 | { | |
350 | case SIGCHLD: | |
9cf12d57 PA |
351 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
352 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
353 | to->cpt_si_status = from_ptrace.cpt_si_status; | |
354 | to->cpt_si_utime = from_ptrace.cpt_si_utime; | |
355 | to->cpt_si_stime = from_ptrace.cpt_si_stime; | |
93813b37 WT |
356 | break; |
357 | case SIGILL: | |
358 | case SIGFPE: | |
359 | case SIGSEGV: | |
360 | case SIGBUS: | |
9cf12d57 | 361 | to->cpt_si_addr = from_ptrace.cpt_si_addr; |
93813b37 WT |
362 | break; |
363 | case SIGPOLL: | |
9cf12d57 PA |
364 | to->cpt_si_band = from_ptrace.cpt_si_band; |
365 | to->cpt_si_fd = from_ptrace.cpt_si_fd; | |
93813b37 WT |
366 | break; |
367 | default: | |
9cf12d57 PA |
368 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
369 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
370 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
371 | break; |
372 | } | |
373 | } | |
374 | } | |
375 | ||
376 | /* Convert the compatible siginfo into system siginfo. */ | |
377 | ||
378 | static void | |
9cf12d57 | 379 | siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from) |
93813b37 | 380 | { |
9cf12d57 | 381 | ptrace_siginfo_t to_ptrace; |
93813b37 | 382 | |
9cf12d57 | 383 | memset (&to_ptrace, 0, sizeof (to_ptrace)); |
93813b37 | 384 | |
9cf12d57 PA |
385 | to_ptrace.si_signo = from->si_signo; |
386 | to_ptrace.si_errno = from->si_errno; | |
387 | to_ptrace.si_code = from->si_code; | |
3f2f6cb5 | 388 | |
9cf12d57 | 389 | if (to_ptrace.si_code == SI_TIMER) |
93813b37 | 390 | { |
9cf12d57 PA |
391 | to_ptrace.cpt_si_timerid = from->cpt_si_timerid; |
392 | to_ptrace.cpt_si_overrun = from->cpt_si_overrun; | |
393 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 | 394 | } |
9cf12d57 | 395 | else if (to_ptrace.si_code == SI_USER) |
93813b37 | 396 | { |
9cf12d57 PA |
397 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
398 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
93813b37 | 399 | } |
9cf12d57 | 400 | if (to_ptrace.si_code < 0) |
93813b37 | 401 | { |
9cf12d57 PA |
402 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
403 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
404 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
405 | } |
406 | else | |
407 | { | |
9cf12d57 | 408 | switch (to_ptrace.si_signo) |
93813b37 WT |
409 | { |
410 | case SIGCHLD: | |
9cf12d57 PA |
411 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
412 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
413 | to_ptrace.cpt_si_status = from->cpt_si_status; | |
414 | to_ptrace.cpt_si_utime = from->cpt_si_utime; | |
415 | to_ptrace.cpt_si_stime = from->cpt_si_stime; | |
93813b37 WT |
416 | break; |
417 | case SIGILL: | |
418 | case SIGFPE: | |
419 | case SIGSEGV: | |
420 | case SIGBUS: | |
9cf12d57 PA |
421 | to_ptrace.cpt_si_addr = from->cpt_si_addr; |
422 | to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb; | |
93813b37 WT |
423 | break; |
424 | case SIGPOLL: | |
9cf12d57 PA |
425 | to_ptrace.cpt_si_band = from->cpt_si_band; |
426 | to_ptrace.cpt_si_fd = from->cpt_si_fd; | |
93813b37 WT |
427 | break; |
428 | default: | |
9cf12d57 PA |
429 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
430 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
431 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
432 | break; |
433 | } | |
434 | } | |
9cf12d57 | 435 | memcpy (to, &to_ptrace, sizeof (to_ptrace)); |
93813b37 WT |
436 | } |
437 | ||
438 | /* Convert the system provided siginfo into compatible x32 siginfo. */ | |
439 | ||
440 | static void | |
441 | compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to, | |
9cf12d57 | 442 | const siginfo_t *from) |
93813b37 | 443 | { |
9cf12d57 | 444 | ptrace_siginfo_t from_ptrace; |
3f2f6cb5 | 445 | |
9cf12d57 | 446 | memcpy (&from_ptrace, from, sizeof (from_ptrace)); |
93813b37 WT |
447 | memset (to, 0, sizeof (*to)); |
448 | ||
9cf12d57 PA |
449 | to->si_signo = from_ptrace.si_signo; |
450 | to->si_errno = from_ptrace.si_errno; | |
451 | to->si_code = from_ptrace.si_code; | |
93813b37 WT |
452 | |
453 | if (to->si_code == SI_TIMER) | |
454 | { | |
9cf12d57 PA |
455 | to->cpt_si_timerid = from_ptrace.cpt_si_timerid; |
456 | to->cpt_si_overrun = from_ptrace.cpt_si_overrun; | |
457 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
458 | } |
459 | else if (to->si_code == SI_USER) | |
460 | { | |
9cf12d57 PA |
461 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
462 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
93813b37 WT |
463 | } |
464 | else if (to->si_code < 0) | |
465 | { | |
9cf12d57 PA |
466 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
467 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
468 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
469 | } |
470 | else | |
471 | { | |
472 | switch (to->si_signo) | |
473 | { | |
474 | case SIGCHLD: | |
9cf12d57 PA |
475 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
476 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
477 | to->cpt_si_status = from_ptrace.cpt_si_status; | |
478 | memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime, | |
93813b37 | 479 | sizeof (to->cpt_si_utime)); |
9cf12d57 | 480 | memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime, |
93813b37 WT |
481 | sizeof (to->cpt_si_stime)); |
482 | break; | |
483 | case SIGILL: | |
484 | case SIGFPE: | |
485 | case SIGSEGV: | |
486 | case SIGBUS: | |
9cf12d57 | 487 | to->cpt_si_addr = from_ptrace.cpt_si_addr; |
93813b37 WT |
488 | break; |
489 | case SIGPOLL: | |
9cf12d57 PA |
490 | to->cpt_si_band = from_ptrace.cpt_si_band; |
491 | to->cpt_si_fd = from_ptrace.cpt_si_fd; | |
93813b37 WT |
492 | break; |
493 | default: | |
9cf12d57 PA |
494 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
495 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
496 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
497 | break; |
498 | } | |
499 | } | |
500 | } | |
501 | ||
3f2f6cb5 WT |
502 | |
503 | ||
504 | ||
93813b37 WT |
505 | /* Convert the compatible x32 siginfo into system siginfo. */ |
506 | static void | |
507 | siginfo_from_compat_x32_siginfo (siginfo_t *to, | |
9cf12d57 | 508 | const compat_x32_siginfo_t *from) |
93813b37 | 509 | { |
9cf12d57 | 510 | ptrace_siginfo_t to_ptrace; |
93813b37 | 511 | |
9cf12d57 PA |
512 | memset (&to_ptrace, 0, sizeof (to_ptrace)); |
513 | to_ptrace.si_signo = from->si_signo; | |
514 | to_ptrace.si_errno = from->si_errno; | |
515 | to_ptrace.si_code = from->si_code; | |
93813b37 | 516 | |
9cf12d57 | 517 | if (to_ptrace.si_code == SI_TIMER) |
93813b37 | 518 | { |
9cf12d57 PA |
519 | to_ptrace.cpt_si_timerid = from->cpt_si_timerid; |
520 | to_ptrace.cpt_si_overrun = from->cpt_si_overrun; | |
521 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 | 522 | } |
9cf12d57 | 523 | else if (to_ptrace.si_code == SI_USER) |
93813b37 | 524 | { |
9cf12d57 PA |
525 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
526 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
93813b37 | 527 | } |
9cf12d57 | 528 | if (to_ptrace.si_code < 0) |
93813b37 | 529 | { |
9cf12d57 PA |
530 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
531 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
532 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
533 | } |
534 | else | |
535 | { | |
9cf12d57 | 536 | switch (to_ptrace.si_signo) |
93813b37 WT |
537 | { |
538 | case SIGCHLD: | |
9cf12d57 PA |
539 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
540 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
541 | to_ptrace.cpt_si_status = from->cpt_si_status; | |
542 | memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime, | |
543 | sizeof (to_ptrace.cpt_si_utime)); | |
544 | memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime, | |
545 | sizeof (to_ptrace.cpt_si_stime)); | |
93813b37 WT |
546 | break; |
547 | case SIGILL: | |
548 | case SIGFPE: | |
549 | case SIGSEGV: | |
550 | case SIGBUS: | |
9cf12d57 | 551 | to_ptrace.cpt_si_addr = from->cpt_si_addr; |
93813b37 WT |
552 | break; |
553 | case SIGPOLL: | |
9cf12d57 PA |
554 | to_ptrace.cpt_si_band = from->cpt_si_band; |
555 | to_ptrace.cpt_si_fd = from->cpt_si_fd; | |
93813b37 WT |
556 | break; |
557 | default: | |
9cf12d57 PA |
558 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
559 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
560 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
561 | break; |
562 | } | |
563 | } | |
9cf12d57 | 564 | memcpy (to, &to_ptrace, sizeof (to_ptrace)); |
93813b37 WT |
565 | } |
566 | ||
9cf12d57 | 567 | /* Convert a ptrace siginfo object, into/from the siginfo in the |
93813b37 WT |
568 | layout of the inferiors' architecture. Returns true if any |
569 | conversion was done; false otherwise. If DIRECTION is 1, then copy | |
9cf12d57 PA |
570 | from INF to PTRACE. If DIRECTION is 0, then copy from NATIVE to |
571 | INF. */ | |
93813b37 WT |
572 | |
573 | int | |
9cf12d57 | 574 | amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf, |
93813b37 WT |
575 | int direction, |
576 | enum amd64_siginfo_fixup_mode mode) | |
577 | { | |
578 | if (mode == FIXUP_32) | |
579 | { | |
93813b37 | 580 | if (direction == 0) |
9cf12d57 | 581 | compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, ptrace); |
93813b37 | 582 | else |
9cf12d57 | 583 | siginfo_from_compat_siginfo (ptrace, (struct compat_siginfo *) inf); |
93813b37 WT |
584 | |
585 | return 1; | |
586 | } | |
587 | else if (mode == FIXUP_X32) | |
588 | { | |
93813b37 WT |
589 | if (direction == 0) |
590 | compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf, | |
9cf12d57 | 591 | ptrace); |
93813b37 | 592 | else |
9cf12d57 | 593 | siginfo_from_compat_x32_siginfo (ptrace, |
93813b37 WT |
594 | (struct compat_x32_siginfo *) inf); |
595 | ||
596 | return 1; | |
597 | } | |
598 | return 0; | |
599 | } | |
9cf12d57 PA |
600 | |
601 | /* Sanity check for the siginfo structure sizes. */ | |
602 | ||
603 | gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE); | |
604 | #ifndef __ILP32__ | |
605 | gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE); | |
606 | #endif | |
607 | gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE); | |
608 | gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE); | |
609 | gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE); |