1 /* Low-level siginfo manipulation for amd64.
3 Copyright (C) 2002-2021 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "gdbsupport/common-defs.h"
22 #include "amd64-linux-siginfo.h"
24 #define GDB_SI_SIZE 128
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:
31 |--------+----------------------|
32 | 64-bit | nat_siginfo_t |
33 | 32-bit | compat_siginfo_t |
34 | x32 | compat_x32_siginfo_t |
39 typedef int nat_int_t
;
40 typedef unsigned long nat_uptr_t
;
42 typedef int nat_time_t
;
43 typedef int nat_timer_t
;
45 /* For native 64-bit, clock_t in _sigchld is 64-bit. */
46 typedef long nat_clock_t
;
48 typedef union nat_sigval
54 typedef struct nat_siginfo
62 int _pad
[((128 / sizeof (int)) - 4)];
78 /* POSIX.1b signals */
96 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
117 #endif /* __ILP32__ */
119 /* These types below (compat_*) define a siginfo type that is layout
120 compatible with the siginfo type exported by the 32-bit userspace
123 typedef int compat_int_t
;
124 typedef unsigned int compat_uptr_t
;
126 typedef int compat_time_t
;
127 typedef int compat_timer_t
;
128 typedef int compat_clock_t
;
130 struct compat_timeval
132 compat_time_t tv_sec
;
136 typedef union compat_sigval
138 compat_int_t sival_int
;
139 compat_uptr_t sival_ptr
;
142 typedef struct compat_siginfo
150 int _pad
[((128 / sizeof (int)) - 3)];
159 /* POSIX.1b timers */
164 compat_sigval_t _sigval
;
167 /* POSIX.1b signals */
172 compat_sigval_t _sigval
;
181 compat_clock_t _utime
;
182 compat_clock_t _stime
;
185 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
206 /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */
207 typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t
;
209 typedef struct compat_x32_siginfo
217 int _pad
[((128 / sizeof (int)) - 3)];
226 /* POSIX.1b timers */
231 compat_sigval_t _sigval
;
234 /* POSIX.1b signals */
239 compat_sigval_t _sigval
;
248 compat_x32_clock_t _utime
;
249 compat_x32_clock_t _stime
;
252 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
256 unsigned int _addr_lsb
;
266 } compat_x32_siginfo_t
__attribute__ ((__aligned__ (8)));
268 /* To simplify usage of siginfo fields. */
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
279 #define cpt_si_addr_lsb _sifields._sigfault._addr_lsb
280 #define cpt_si_lower _sifields._sigfault.si_addr_bnd._lower
281 #define cpt_si_upper _sifields._sigfault.si_addr_bnd._upper
282 #define cpt_si_band _sifields._sigpoll._band
283 #define cpt_si_fd _sifields._sigpoll._fd
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. */
289 #define si_timerid si_timer1
292 #define si_overrun si_timer2
296 #define SEGV_BNDERR 3
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
303 typedef compat_x32_siginfo_t ptrace_siginfo_t
;
305 typedef nat_siginfo_t ptrace_siginfo_t
;
308 /* Convert the system provided siginfo into compatible siginfo. */
311 compat_siginfo_from_siginfo (compat_siginfo_t
*to
, const siginfo_t
*from
)
313 ptrace_siginfo_t from_ptrace
;
315 memcpy (&from_ptrace
, from
, sizeof (from_ptrace
));
316 memset (to
, 0, sizeof (*to
));
318 to
->si_signo
= from_ptrace
.si_signo
;
319 to
->si_errno
= from_ptrace
.si_errno
;
320 to
->si_code
= from_ptrace
.si_code
;
322 if (to
->si_code
== SI_TIMER
)
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
;
328 else if (to
->si_code
== SI_USER
)
330 to
->cpt_si_pid
= from_ptrace
.cpt_si_pid
;
331 to
->cpt_si_uid
= from_ptrace
.cpt_si_uid
;
333 else if (to
->si_code
== SEGV_BNDERR
334 && to
->si_signo
== SIGSEGV
)
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
;
340 else if (to
->si_code
< 0)
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
;
348 switch (to
->si_signo
)
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
;
361 to
->cpt_si_addr
= from_ptrace
.cpt_si_addr
;
364 to
->cpt_si_band
= from_ptrace
.cpt_si_band
;
365 to
->cpt_si_fd
= from_ptrace
.cpt_si_fd
;
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
;
376 /* Convert the compatible siginfo into system siginfo. */
379 siginfo_from_compat_siginfo (siginfo_t
*to
, const compat_siginfo_t
*from
)
381 ptrace_siginfo_t to_ptrace
;
383 memset (&to_ptrace
, 0, sizeof (to_ptrace
));
385 to_ptrace
.si_signo
= from
->si_signo
;
386 to_ptrace
.si_errno
= from
->si_errno
;
387 to_ptrace
.si_code
= from
->si_code
;
389 if (to_ptrace
.si_code
== SI_TIMER
)
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
;
395 else if (to_ptrace
.si_code
== SI_USER
)
397 to_ptrace
.cpt_si_pid
= from
->cpt_si_pid
;
398 to_ptrace
.cpt_si_uid
= from
->cpt_si_uid
;
400 if (to_ptrace
.si_code
< 0)
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
;
408 switch (to_ptrace
.si_signo
)
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
;
421 to_ptrace
.cpt_si_addr
= from
->cpt_si_addr
;
422 to_ptrace
.cpt_si_addr_lsb
= from
->cpt_si_addr_lsb
;
425 to_ptrace
.cpt_si_band
= from
->cpt_si_band
;
426 to_ptrace
.cpt_si_fd
= from
->cpt_si_fd
;
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
;
435 memcpy (to
, &to_ptrace
, sizeof (to_ptrace
));
438 /* Convert the system provided siginfo into compatible x32 siginfo. */
441 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t
*to
,
442 const siginfo_t
*from
)
444 ptrace_siginfo_t from_ptrace
;
446 memcpy (&from_ptrace
, from
, sizeof (from_ptrace
));
447 memset (to
, 0, sizeof (*to
));
449 to
->si_signo
= from_ptrace
.si_signo
;
450 to
->si_errno
= from_ptrace
.si_errno
;
451 to
->si_code
= from_ptrace
.si_code
;
453 if (to
->si_code
== SI_TIMER
)
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
;
459 else if (to
->si_code
== SI_USER
)
461 to
->cpt_si_pid
= from_ptrace
.cpt_si_pid
;
462 to
->cpt_si_uid
= from_ptrace
.cpt_si_uid
;
464 else if (to
->si_code
< 0)
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
;
472 switch (to
->si_signo
)
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
,
479 sizeof (to
->cpt_si_utime
));
480 memcpy (&to
->cpt_si_stime
, &from_ptrace
.cpt_si_stime
,
481 sizeof (to
->cpt_si_stime
));
487 to
->cpt_si_addr
= from_ptrace
.cpt_si_addr
;
490 to
->cpt_si_band
= from_ptrace
.cpt_si_band
;
491 to
->cpt_si_fd
= from_ptrace
.cpt_si_fd
;
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
;
505 /* Convert the compatible x32 siginfo into system siginfo. */
507 siginfo_from_compat_x32_siginfo (siginfo_t
*to
,
508 const compat_x32_siginfo_t
*from
)
510 ptrace_siginfo_t to_ptrace
;
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
;
517 if (to_ptrace
.si_code
== SI_TIMER
)
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
;
523 else if (to_ptrace
.si_code
== SI_USER
)
525 to_ptrace
.cpt_si_pid
= from
->cpt_si_pid
;
526 to_ptrace
.cpt_si_uid
= from
->cpt_si_uid
;
528 if (to_ptrace
.si_code
< 0)
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
;
536 switch (to_ptrace
.si_signo
)
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
));
551 to_ptrace
.cpt_si_addr
= from
->cpt_si_addr
;
554 to_ptrace
.cpt_si_band
= from
->cpt_si_band
;
555 to_ptrace
.cpt_si_fd
= from
->cpt_si_fd
;
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
;
564 memcpy (to
, &to_ptrace
, sizeof (to_ptrace
));
567 /* Convert a ptrace siginfo object, into/from the siginfo in the
568 layout of the inferiors' architecture. Returns true if any
569 conversion was done; false otherwise. If DIRECTION is 1, then copy
570 from INF to PTRACE. If DIRECTION is 0, then copy from NATIVE to
574 amd64_linux_siginfo_fixup_common (siginfo_t
*ptrace
, gdb_byte
*inf
,
576 enum amd64_siginfo_fixup_mode mode
)
578 if (mode
== FIXUP_32
)
581 compat_siginfo_from_siginfo ((struct compat_siginfo
*) inf
, ptrace
);
583 siginfo_from_compat_siginfo (ptrace
, (struct compat_siginfo
*) inf
);
587 else if (mode
== FIXUP_X32
)
590 compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo
*) inf
,
593 siginfo_from_compat_x32_siginfo (ptrace
,
594 (struct compat_x32_siginfo
*) inf
);
601 /* Sanity check for the siginfo structure sizes. */
603 gdb_static_assert (sizeof (siginfo_t
) == GDB_SI_SIZE
);
605 gdb_static_assert (sizeof (nat_siginfo_t
) == GDB_SI_SIZE
);
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
);