1 /* Low-level siginfo manipulation for amd64.
3 Copyright (C) 2002-2019 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/>. */
21 #include "common/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_band _sifields._sigpoll._band
281 #define cpt_si_fd _sifields._sigpoll._fd
283 /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
284 In their place is si_timer1,si_timer2. */
287 #define si_timerid si_timer1
290 #define si_overrun si_timer2
293 /* The type of the siginfo object the kernel returns in
294 PTRACE_GETSIGINFO. If gdb is built as a x32 program, we get a x32
297 typedef compat_x32_siginfo_t ptrace_siginfo_t;
299 typedef nat_siginfo_t ptrace_siginfo_t;
302 /* Convert the system provided siginfo into compatible siginfo. */
305 compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from)
307 ptrace_siginfo_t from_ptrace;
309 memcpy (&from_ptrace, from, sizeof (from_ptrace));
310 memset (to, 0, sizeof (*to));
312 to->si_signo = from_ptrace.si_signo;
313 to->si_errno = from_ptrace.si_errno;
314 to->si_code = from_ptrace.si_code;
316 if (to->si_code == SI_TIMER)
318 to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
319 to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
320 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
322 else if (to->si_code == SI_USER)
324 to->cpt_si_pid = from_ptrace.cpt_si_pid;
325 to->cpt_si_uid = from_ptrace.cpt_si_uid;
327 else if (to->si_code < 0)
329 to->cpt_si_pid = from_ptrace.cpt_si_pid;
330 to->cpt_si_uid = from_ptrace.cpt_si_uid;
331 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
335 switch (to->si_signo)
338 to->cpt_si_pid = from_ptrace.cpt_si_pid;
339 to->cpt_si_uid = from_ptrace.cpt_si_uid;
340 to->cpt_si_status = from_ptrace.cpt_si_status;
341 to->cpt_si_utime = from_ptrace.cpt_si_utime;
342 to->cpt_si_stime = from_ptrace.cpt_si_stime;
348 to->cpt_si_addr = from_ptrace.cpt_si_addr;
351 to->cpt_si_band = from_ptrace.cpt_si_band;
352 to->cpt_si_fd = from_ptrace.cpt_si_fd;
355 to->cpt_si_pid = from_ptrace.cpt_si_pid;
356 to->cpt_si_uid = from_ptrace.cpt_si_uid;
357 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
363 /* Convert the compatible siginfo into system siginfo. */
366 siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from)
368 ptrace_siginfo_t to_ptrace;
370 memset (&to_ptrace, 0, sizeof (to_ptrace));
372 to_ptrace.si_signo = from->si_signo;
373 to_ptrace.si_errno = from->si_errno;
374 to_ptrace.si_code = from->si_code;
376 if (to_ptrace.si_code == SI_TIMER)
378 to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
379 to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
380 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
382 else if (to_ptrace.si_code == SI_USER)
384 to_ptrace.cpt_si_pid = from->cpt_si_pid;
385 to_ptrace.cpt_si_uid = from->cpt_si_uid;
387 if (to_ptrace.si_code < 0)
389 to_ptrace.cpt_si_pid = from->cpt_si_pid;
390 to_ptrace.cpt_si_uid = from->cpt_si_uid;
391 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
395 switch (to_ptrace.si_signo)
398 to_ptrace.cpt_si_pid = from->cpt_si_pid;
399 to_ptrace.cpt_si_uid = from->cpt_si_uid;
400 to_ptrace.cpt_si_status = from->cpt_si_status;
401 to_ptrace.cpt_si_utime = from->cpt_si_utime;
402 to_ptrace.cpt_si_stime = from->cpt_si_stime;
408 to_ptrace.cpt_si_addr = from->cpt_si_addr;
409 to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb;
412 to_ptrace.cpt_si_band = from->cpt_si_band;
413 to_ptrace.cpt_si_fd = from->cpt_si_fd;
416 to_ptrace.cpt_si_pid = from->cpt_si_pid;
417 to_ptrace.cpt_si_uid = from->cpt_si_uid;
418 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
422 memcpy (to, &to_ptrace, sizeof (to_ptrace));
425 /* Convert the system provided siginfo into compatible x32 siginfo. */
428 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
429 const siginfo_t *from)
431 ptrace_siginfo_t from_ptrace;
433 memcpy (&from_ptrace, from, sizeof (from_ptrace));
434 memset (to, 0, sizeof (*to));
436 to->si_signo = from_ptrace.si_signo;
437 to->si_errno = from_ptrace.si_errno;
438 to->si_code = from_ptrace.si_code;
440 if (to->si_code == SI_TIMER)
442 to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
443 to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
444 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
446 else if (to->si_code == SI_USER)
448 to->cpt_si_pid = from_ptrace.cpt_si_pid;
449 to->cpt_si_uid = from_ptrace.cpt_si_uid;
451 else if (to->si_code < 0)
453 to->cpt_si_pid = from_ptrace.cpt_si_pid;
454 to->cpt_si_uid = from_ptrace.cpt_si_uid;
455 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
459 switch (to->si_signo)
462 to->cpt_si_pid = from_ptrace.cpt_si_pid;
463 to->cpt_si_uid = from_ptrace.cpt_si_uid;
464 to->cpt_si_status = from_ptrace.cpt_si_status;
465 memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime,
466 sizeof (to->cpt_si_utime));
467 memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime,
468 sizeof (to->cpt_si_stime));
474 to->cpt_si_addr = from_ptrace.cpt_si_addr;
477 to->cpt_si_band = from_ptrace.cpt_si_band;
478 to->cpt_si_fd = from_ptrace.cpt_si_fd;
481 to->cpt_si_pid = from_ptrace.cpt_si_pid;
482 to->cpt_si_uid = from_ptrace.cpt_si_uid;
483 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
492 /* Convert the compatible x32 siginfo into system siginfo. */
494 siginfo_from_compat_x32_siginfo (siginfo_t *to,
495 const compat_x32_siginfo_t *from)
497 ptrace_siginfo_t to_ptrace;
499 memset (&to_ptrace, 0, sizeof (to_ptrace));
500 to_ptrace.si_signo = from->si_signo;
501 to_ptrace.si_errno = from->si_errno;
502 to_ptrace.si_code = from->si_code;
504 if (to_ptrace.si_code == SI_TIMER)
506 to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
507 to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
508 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
510 else if (to_ptrace.si_code == SI_USER)
512 to_ptrace.cpt_si_pid = from->cpt_si_pid;
513 to_ptrace.cpt_si_uid = from->cpt_si_uid;
515 if (to_ptrace.si_code < 0)
517 to_ptrace.cpt_si_pid = from->cpt_si_pid;
518 to_ptrace.cpt_si_uid = from->cpt_si_uid;
519 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
523 switch (to_ptrace.si_signo)
526 to_ptrace.cpt_si_pid = from->cpt_si_pid;
527 to_ptrace.cpt_si_uid = from->cpt_si_uid;
528 to_ptrace.cpt_si_status = from->cpt_si_status;
529 memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime,
530 sizeof (to_ptrace.cpt_si_utime));
531 memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime,
532 sizeof (to_ptrace.cpt_si_stime));
538 to_ptrace.cpt_si_addr = from->cpt_si_addr;
541 to_ptrace.cpt_si_band = from->cpt_si_band;
542 to_ptrace.cpt_si_fd = from->cpt_si_fd;
545 to_ptrace.cpt_si_pid = from->cpt_si_pid;
546 to_ptrace.cpt_si_uid = from->cpt_si_uid;
547 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
551 memcpy (to, &to_ptrace, sizeof (to_ptrace));
554 /* Convert a ptrace siginfo object, into/from the siginfo in the
555 layout of the inferiors' architecture. Returns true if any
556 conversion was done; false otherwise. If DIRECTION is 1, then copy
557 from INF to PTRACE. If DIRECTION is 0, then copy from NATIVE to
561 amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf,
563 enum amd64_siginfo_fixup_mode mode)
565 if (mode == FIXUP_32)
568 compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, ptrace);
570 siginfo_from_compat_siginfo (ptrace, (struct compat_siginfo *) inf);
574 else if (mode == FIXUP_X32)
577 compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
580 siginfo_from_compat_x32_siginfo (ptrace,
581 (struct compat_x32_siginfo *) inf);
588 /* Sanity check for the siginfo structure sizes. */
590 gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
592 gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
594 gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
595 gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE);
596 gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE);