Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / nat / amd64-linux-siginfo.c
CommitLineData
93813b37
WT
1/* Low-level siginfo manipulation for amd64.
2
88b9d363 3 Copyright (C) 2002-2022 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
39typedef int nat_int_t;
9cf12d57 40typedef unsigned long nat_uptr_t;
3f2f6cb5
WT
41
42typedef int nat_time_t;
43typedef int nat_timer_t;
44
9cf12d57
PA
45/* For native 64-bit, clock_t in _sigchld is 64-bit. */
46typedef long nat_clock_t;
3f2f6cb5 47
c57eb1a2 48union nat_sigval_t
3f2f6cb5
WT
49{
50 nat_int_t sival_int;
51 nat_uptr_t sival_ptr;
c57eb1a2 52};
3f2f6cb5 53
c57eb1a2 54struct nat_siginfo_t
3f2f6cb5
WT
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;
c57eb1a2 115};
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
123typedef int compat_int_t;
124typedef unsigned int compat_uptr_t;
125
126typedef int compat_time_t;
127typedef int compat_timer_t;
128typedef int compat_clock_t;
129
130struct compat_timeval
131{
132 compat_time_t tv_sec;
133 int tv_usec;
134};
135
c57eb1a2 136union compat_sigval_t
93813b37
WT
137{
138 compat_int_t sival_int;
139 compat_uptr_t sival_ptr;
c57eb1a2 140};
93813b37 141
c57eb1a2 142struct compat_siginfo_t
93813b37
WT
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;
c57eb1a2 204};
93813b37
WT
205
206/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */
207typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t;
208
c57eb1a2 209struct __attribute__ ((__aligned__ (8))) compat_x32_siginfo_t
93813b37
WT
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;
c57eb1a2 266};
93813b37
WT
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__
303typedef compat_x32_siginfo_t ptrace_siginfo_t;
304#else
305typedef nat_siginfo_t ptrace_siginfo_t;
306#endif
307
93813b37
WT
308/* Convert the system provided siginfo into compatible siginfo. */
309
310static void
9cf12d57 311compat_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
378static void
9cf12d57 379siginfo_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
440static void
441compat_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. */
506static void
507siginfo_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
573int
9cf12d57 574amd64_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)
c57eb1a2 581 compat_siginfo_from_siginfo ((compat_siginfo_t *) inf, ptrace);
93813b37 582 else
c57eb1a2 583 siginfo_from_compat_siginfo (ptrace, (compat_siginfo_t *) inf);
93813b37
WT
584
585 return 1;
586 }
587 else if (mode == FIXUP_X32)
588 {
93813b37 589 if (direction == 0)
c57eb1a2 590 compat_x32_siginfo_from_siginfo ((compat_x32_siginfo_t *) inf,
9cf12d57 591 ptrace);
93813b37 592 else
9cf12d57 593 siginfo_from_compat_x32_siginfo (ptrace,
c57eb1a2 594 (compat_x32_siginfo_t *) inf);
93813b37
WT
595
596 return 1;
597 }
598 return 0;
599}
9cf12d57
PA
600
601/* Sanity check for the siginfo structure sizes. */
602
603gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
604#ifndef __ILP32__
605gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
606#endif
607gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
608gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE);
609gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE);
This page took 0.633568 seconds and 4 git commands to generate.