opcodes: fix Werror=format build breaker in opcodes/riscv-dis.c
[binutils-gdb.git] / gdb / nat / amd64-linux-siginfo.c
blobf5e99941b5c1dab59ba59e5e5adfdb5bf9ba2f36
1 /* Low-level siginfo manipulation for amd64.
3 Copyright (C) 2002-2024 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 <signal.h>
21 #include "amd64-linux-siginfo.h"
23 #define GDB_SI_SIZE 128
25 /* The types below define the most complete kernel siginfo types known
26 for the architecture, independent of the system/libc headers. They
27 are named from a 64-bit kernel's perspective:
29 | layout | type |
30 |--------+----------------------|
31 | 64-bit | nat_siginfo_t |
32 | 32-bit | compat_siginfo_t |
33 | x32 | compat_x32_siginfo_t |
36 #ifndef __ILP32__
38 typedef int nat_int_t;
39 typedef unsigned long nat_uptr_t;
41 typedef int nat_time_t;
42 typedef int nat_timer_t;
44 /* For native 64-bit, clock_t in _sigchld is 64-bit. */
45 typedef long nat_clock_t;
47 union nat_sigval_t
49 nat_int_t sival_int;
50 nat_uptr_t sival_ptr;
53 struct nat_siginfo_t
55 int si_signo;
56 int si_errno;
57 int si_code;
59 union
61 int _pad[((128 / sizeof (int)) - 4)];
62 /* kill() */
63 struct
65 unsigned int _pid;
66 unsigned int _uid;
67 } _kill;
69 /* POSIX.1b timers */
70 struct
72 nat_timer_t _tid;
73 int _overrun;
74 nat_sigval_t _sigval;
75 } _timer;
77 /* POSIX.1b signals */
78 struct
80 unsigned int _pid;
81 unsigned int _uid;
82 nat_sigval_t _sigval;
83 } _rt;
85 /* SIGCHLD */
86 struct
88 unsigned int _pid;
89 unsigned int _uid;
90 int _status;
91 nat_clock_t _utime;
92 nat_clock_t _stime;
93 } _sigchld;
95 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
96 struct
98 nat_uptr_t _addr;
99 short int _addr_lsb;
100 struct
102 nat_uptr_t _lower;
103 nat_uptr_t _upper;
104 } si_addr_bnd;
105 } _sigfault;
107 /* SIGPOLL */
108 struct
110 int _band;
111 int _fd;
112 } _sigpoll;
113 } _sifields;
116 #endif /* __ILP32__ */
118 /* These types below (compat_*) define a siginfo type that is layout
119 compatible with the siginfo type exported by the 32-bit userspace
120 support. */
122 typedef int compat_int_t;
123 typedef unsigned int compat_uptr_t;
125 typedef int compat_time_t;
126 typedef int compat_timer_t;
127 typedef int compat_clock_t;
129 struct compat_timeval
131 compat_time_t tv_sec;
132 int tv_usec;
135 union compat_sigval_t
137 compat_int_t sival_int;
138 compat_uptr_t sival_ptr;
141 struct compat_siginfo_t
143 int si_signo;
144 int si_errno;
145 int si_code;
147 union
149 int _pad[((128 / sizeof (int)) - 3)];
151 /* kill() */
152 struct
154 unsigned int _pid;
155 unsigned int _uid;
156 } _kill;
158 /* POSIX.1b timers */
159 struct
161 compat_timer_t _tid;
162 int _overrun;
163 compat_sigval_t _sigval;
164 } _timer;
166 /* POSIX.1b signals */
167 struct
169 unsigned int _pid;
170 unsigned int _uid;
171 compat_sigval_t _sigval;
172 } _rt;
174 /* SIGCHLD */
175 struct
177 unsigned int _pid;
178 unsigned int _uid;
179 int _status;
180 compat_clock_t _utime;
181 compat_clock_t _stime;
182 } _sigchld;
184 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
185 struct
187 unsigned int _addr;
188 short int _addr_lsb;
189 struct
191 unsigned int _lower;
192 unsigned int _upper;
193 } si_addr_bnd;
194 } _sigfault;
196 /* SIGPOLL */
197 struct
199 int _band;
200 int _fd;
201 } _sigpoll;
202 } _sifields;
205 /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */
206 typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t;
208 struct __attribute__ ((__aligned__ (8))) compat_x32_siginfo_t
210 int si_signo;
211 int si_errno;
212 int si_code;
214 union
216 int _pad[((128 / sizeof (int)) - 3)];
218 /* kill() */
219 struct
221 unsigned int _pid;
222 unsigned int _uid;
223 } _kill;
225 /* POSIX.1b timers */
226 struct
228 compat_timer_t _tid;
229 int _overrun;
230 compat_sigval_t _sigval;
231 } _timer;
233 /* POSIX.1b signals */
234 struct
236 unsigned int _pid;
237 unsigned int _uid;
238 compat_sigval_t _sigval;
239 } _rt;
241 /* SIGCHLD */
242 struct
244 unsigned int _pid;
245 unsigned int _uid;
246 int _status;
247 compat_x32_clock_t _utime;
248 compat_x32_clock_t _stime;
249 } _sigchld;
251 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
252 struct
254 unsigned int _addr;
255 unsigned int _addr_lsb;
256 } _sigfault;
258 /* SIGPOLL */
259 struct
261 int _band;
262 int _fd;
263 } _sigpoll;
264 } _sifields;
267 /* To simplify usage of siginfo fields. */
269 #define cpt_si_pid _sifields._kill._pid
270 #define cpt_si_uid _sifields._kill._uid
271 #define cpt_si_timerid _sifields._timer._tid
272 #define cpt_si_overrun _sifields._timer._overrun
273 #define cpt_si_status _sifields._sigchld._status
274 #define cpt_si_utime _sifields._sigchld._utime
275 #define cpt_si_stime _sifields._sigchld._stime
276 #define cpt_si_ptr _sifields._rt._sigval.sival_ptr
277 #define cpt_si_addr _sifields._sigfault._addr
278 #define cpt_si_addr_lsb _sifields._sigfault._addr_lsb
279 #define cpt_si_lower _sifields._sigfault.si_addr_bnd._lower
280 #define cpt_si_upper _sifields._sigfault.si_addr_bnd._upper
281 #define cpt_si_band _sifields._sigpoll._band
282 #define cpt_si_fd _sifields._sigpoll._fd
284 /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
285 In their place is si_timer1,si_timer2. */
287 #ifndef si_timerid
288 #define si_timerid si_timer1
289 #endif
290 #ifndef si_overrun
291 #define si_overrun si_timer2
292 #endif
294 #ifndef SEGV_BNDERR
295 #define SEGV_BNDERR 3
296 #endif
298 /* The type of the siginfo object the kernel returns in
299 PTRACE_GETSIGINFO. If gdb is built as a x32 program, we get a x32
300 siginfo. */
301 #ifdef __ILP32__
302 typedef compat_x32_siginfo_t ptrace_siginfo_t;
303 #else
304 typedef nat_siginfo_t ptrace_siginfo_t;
305 #endif
307 /* Convert the system provided siginfo into compatible siginfo. */
309 static void
310 compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from)
312 ptrace_siginfo_t from_ptrace;
314 memcpy (&from_ptrace, from, sizeof (from_ptrace));
315 memset (to, 0, sizeof (*to));
317 to->si_signo = from_ptrace.si_signo;
318 to->si_errno = from_ptrace.si_errno;
319 to->si_code = from_ptrace.si_code;
321 if (to->si_code == SI_TIMER)
323 to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
324 to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
325 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
327 else if (to->si_code == SI_USER)
329 to->cpt_si_pid = from_ptrace.cpt_si_pid;
330 to->cpt_si_uid = from_ptrace.cpt_si_uid;
332 #ifndef __ILP32__
333 /* The struct compat_x32_siginfo_t doesn't contain
334 cpt_si_lower/cpt_si_upper. */
335 else if (to->si_code == SEGV_BNDERR
336 && to->si_signo == SIGSEGV)
338 to->cpt_si_addr = from_ptrace.cpt_si_addr;
339 to->cpt_si_lower = from_ptrace.cpt_si_lower;
340 to->cpt_si_upper = from_ptrace.cpt_si_upper;
342 #endif
343 else if (to->si_code < 0)
345 to->cpt_si_pid = from_ptrace.cpt_si_pid;
346 to->cpt_si_uid = from_ptrace.cpt_si_uid;
347 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
349 else
351 switch (to->si_signo)
353 case SIGCHLD:
354 to->cpt_si_pid = from_ptrace.cpt_si_pid;
355 to->cpt_si_uid = from_ptrace.cpt_si_uid;
356 to->cpt_si_status = from_ptrace.cpt_si_status;
357 to->cpt_si_utime = from_ptrace.cpt_si_utime;
358 to->cpt_si_stime = from_ptrace.cpt_si_stime;
359 break;
360 case SIGILL:
361 case SIGFPE:
362 case SIGSEGV:
363 case SIGBUS:
364 to->cpt_si_addr = from_ptrace.cpt_si_addr;
365 break;
366 case SIGPOLL:
367 to->cpt_si_band = from_ptrace.cpt_si_band;
368 to->cpt_si_fd = from_ptrace.cpt_si_fd;
369 break;
370 default:
371 to->cpt_si_pid = from_ptrace.cpt_si_pid;
372 to->cpt_si_uid = from_ptrace.cpt_si_uid;
373 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
374 break;
379 /* Convert the compatible siginfo into system siginfo. */
381 static void
382 siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from)
384 ptrace_siginfo_t to_ptrace;
386 memset (&to_ptrace, 0, sizeof (to_ptrace));
388 to_ptrace.si_signo = from->si_signo;
389 to_ptrace.si_errno = from->si_errno;
390 to_ptrace.si_code = from->si_code;
392 if (to_ptrace.si_code == SI_TIMER)
394 to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
395 to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
396 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
398 else if (to_ptrace.si_code == SI_USER)
400 to_ptrace.cpt_si_pid = from->cpt_si_pid;
401 to_ptrace.cpt_si_uid = from->cpt_si_uid;
403 if (to_ptrace.si_code < 0)
405 to_ptrace.cpt_si_pid = from->cpt_si_pid;
406 to_ptrace.cpt_si_uid = from->cpt_si_uid;
407 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
409 else
411 switch (to_ptrace.si_signo)
413 case SIGCHLD:
414 to_ptrace.cpt_si_pid = from->cpt_si_pid;
415 to_ptrace.cpt_si_uid = from->cpt_si_uid;
416 to_ptrace.cpt_si_status = from->cpt_si_status;
417 to_ptrace.cpt_si_utime = from->cpt_si_utime;
418 to_ptrace.cpt_si_stime = from->cpt_si_stime;
419 break;
420 case SIGILL:
421 case SIGFPE:
422 case SIGSEGV:
423 case SIGBUS:
424 to_ptrace.cpt_si_addr = from->cpt_si_addr;
425 to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb;
426 break;
427 case SIGPOLL:
428 to_ptrace.cpt_si_band = from->cpt_si_band;
429 to_ptrace.cpt_si_fd = from->cpt_si_fd;
430 break;
431 default:
432 to_ptrace.cpt_si_pid = from->cpt_si_pid;
433 to_ptrace.cpt_si_uid = from->cpt_si_uid;
434 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
435 break;
438 memcpy (to, &to_ptrace, sizeof (to_ptrace));
441 /* Convert the system provided siginfo into compatible x32 siginfo. */
443 static void
444 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
445 const siginfo_t *from)
447 ptrace_siginfo_t from_ptrace;
449 memcpy (&from_ptrace, from, sizeof (from_ptrace));
450 memset (to, 0, sizeof (*to));
452 to->si_signo = from_ptrace.si_signo;
453 to->si_errno = from_ptrace.si_errno;
454 to->si_code = from_ptrace.si_code;
456 if (to->si_code == SI_TIMER)
458 to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
459 to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
460 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
462 else if (to->si_code == SI_USER)
464 to->cpt_si_pid = from_ptrace.cpt_si_pid;
465 to->cpt_si_uid = from_ptrace.cpt_si_uid;
467 else if (to->si_code < 0)
469 to->cpt_si_pid = from_ptrace.cpt_si_pid;
470 to->cpt_si_uid = from_ptrace.cpt_si_uid;
471 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
473 else
475 switch (to->si_signo)
477 case SIGCHLD:
478 to->cpt_si_pid = from_ptrace.cpt_si_pid;
479 to->cpt_si_uid = from_ptrace.cpt_si_uid;
480 to->cpt_si_status = from_ptrace.cpt_si_status;
481 memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime,
482 sizeof (to->cpt_si_utime));
483 memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime,
484 sizeof (to->cpt_si_stime));
485 break;
486 case SIGILL:
487 case SIGFPE:
488 case SIGSEGV:
489 case SIGBUS:
490 to->cpt_si_addr = from_ptrace.cpt_si_addr;
491 break;
492 case SIGPOLL:
493 to->cpt_si_band = from_ptrace.cpt_si_band;
494 to->cpt_si_fd = from_ptrace.cpt_si_fd;
495 break;
496 default:
497 to->cpt_si_pid = from_ptrace.cpt_si_pid;
498 to->cpt_si_uid = from_ptrace.cpt_si_uid;
499 to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
500 break;
508 /* Convert the compatible x32 siginfo into system siginfo. */
509 static void
510 siginfo_from_compat_x32_siginfo (siginfo_t *to,
511 const compat_x32_siginfo_t *from)
513 ptrace_siginfo_t to_ptrace;
515 memset (&to_ptrace, 0, sizeof (to_ptrace));
516 to_ptrace.si_signo = from->si_signo;
517 to_ptrace.si_errno = from->si_errno;
518 to_ptrace.si_code = from->si_code;
520 if (to_ptrace.si_code == SI_TIMER)
522 to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
523 to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
524 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
526 else if (to_ptrace.si_code == SI_USER)
528 to_ptrace.cpt_si_pid = from->cpt_si_pid;
529 to_ptrace.cpt_si_uid = from->cpt_si_uid;
531 if (to_ptrace.si_code < 0)
533 to_ptrace.cpt_si_pid = from->cpt_si_pid;
534 to_ptrace.cpt_si_uid = from->cpt_si_uid;
535 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
537 else
539 switch (to_ptrace.si_signo)
541 case SIGCHLD:
542 to_ptrace.cpt_si_pid = from->cpt_si_pid;
543 to_ptrace.cpt_si_uid = from->cpt_si_uid;
544 to_ptrace.cpt_si_status = from->cpt_si_status;
545 memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime,
546 sizeof (to_ptrace.cpt_si_utime));
547 memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime,
548 sizeof (to_ptrace.cpt_si_stime));
549 break;
550 case SIGILL:
551 case SIGFPE:
552 case SIGSEGV:
553 case SIGBUS:
554 to_ptrace.cpt_si_addr = from->cpt_si_addr;
555 break;
556 case SIGPOLL:
557 to_ptrace.cpt_si_band = from->cpt_si_band;
558 to_ptrace.cpt_si_fd = from->cpt_si_fd;
559 break;
560 default:
561 to_ptrace.cpt_si_pid = from->cpt_si_pid;
562 to_ptrace.cpt_si_uid = from->cpt_si_uid;
563 to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
564 break;
567 memcpy (to, &to_ptrace, sizeof (to_ptrace));
570 /* Convert a ptrace siginfo object, into/from the siginfo in the
571 layout of the inferiors' architecture. Returns true if any
572 conversion was done; false otherwise. If DIRECTION is 1, then copy
573 from INF to PTRACE. If DIRECTION is 0, then copy from NATIVE to
574 INF. */
577 amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf,
578 int direction,
579 enum amd64_siginfo_fixup_mode mode)
581 if (mode == FIXUP_32)
583 if (direction == 0)
584 compat_siginfo_from_siginfo ((compat_siginfo_t *) inf, ptrace);
585 else
586 siginfo_from_compat_siginfo (ptrace, (compat_siginfo_t *) inf);
588 return 1;
590 else if (mode == FIXUP_X32)
592 if (direction == 0)
593 compat_x32_siginfo_from_siginfo ((compat_x32_siginfo_t *) inf,
594 ptrace);
595 else
596 siginfo_from_compat_x32_siginfo (ptrace,
597 (compat_x32_siginfo_t *) inf);
599 return 1;
601 return 0;
604 /* Sanity check for the siginfo structure sizes. */
606 static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
607 #ifndef __ILP32__
608 static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
609 #endif
610 static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
611 static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE);
612 static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE);