xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/nat/amd64-linux-siginfo.c (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1 /* Low-level siginfo manipulation for amd64.
2 
3    Copyright (C) 2002-2023 Free Software Foundation, Inc.
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 
20 #include "gdbsupport/common-defs.h"
21 #include <signal.h>
22 #include "amd64-linux-siginfo.h"
23 
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__
38 
39 typedef int nat_int_t;
40 typedef unsigned long nat_uptr_t;
41 
42 typedef int nat_time_t;
43 typedef int nat_timer_t;
44 
45 /* For native 64-bit, clock_t in _sigchld is 64-bit.  */
46 typedef long nat_clock_t;
47 
48 union nat_sigval_t
49 {
50   nat_int_t sival_int;
51   nat_uptr_t sival_ptr;
52 };
53 
54 struct nat_siginfo_t
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;
115 };
116 
117 #endif /* __ILP32__ */
118 
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 union compat_sigval_t
137 {
138   compat_int_t sival_int;
139   compat_uptr_t sival_ptr;
140 };
141 
142 struct compat_siginfo_t
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;
189       short int _addr_lsb;
190       struct
191       {
192 	unsigned int _lower;
193 	unsigned int _upper;
194       } si_addr_bnd;
195     } _sigfault;
196 
197     /* SIGPOLL */
198     struct
199     {
200       int _band;
201       int _fd;
202     } _sigpoll;
203   } _sifields;
204 };
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 struct __attribute__ ((__aligned__ (8))) compat_x32_siginfo_t
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;
256       unsigned int _addr_lsb;
257     } _sigfault;
258 
259     /* SIGPOLL */
260     struct
261     {
262       int _band;
263       int _fd;
264     } _sigpoll;
265   } _sifields;
266 };
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
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
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 
295 #ifndef SEGV_BNDERR
296 #define SEGV_BNDERR	3
297 #endif
298 
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 
308 /*  Convert the system provided siginfo into compatible siginfo.  */
309 
310 static void
311 compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from)
312 {
313   ptrace_siginfo_t from_ptrace;
314 
315   memcpy (&from_ptrace, from, sizeof (from_ptrace));
316   memset (to, 0, sizeof (*to));
317 
318   to->si_signo = from_ptrace.si_signo;
319   to->si_errno = from_ptrace.si_errno;
320   to->si_code = from_ptrace.si_code;
321 
322   if (to->si_code == SI_TIMER)
323     {
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;
327     }
328   else if (to->si_code == SI_USER)
329     {
330       to->cpt_si_pid = from_ptrace.cpt_si_pid;
331       to->cpt_si_uid = from_ptrace.cpt_si_uid;
332     }
333 #ifndef __ILP32__
334   /* The struct compat_x32_siginfo_t doesn't contain
335      cpt_si_lower/cpt_si_upper.  */
336   else if (to->si_code == SEGV_BNDERR
337 	   && to->si_signo == SIGSEGV)
338     {
339       to->cpt_si_addr = from_ptrace.cpt_si_addr;
340       to->cpt_si_lower = from_ptrace.cpt_si_lower;
341       to->cpt_si_upper = from_ptrace.cpt_si_upper;
342     }
343 #endif
344   else if (to->si_code < 0)
345     {
346       to->cpt_si_pid = from_ptrace.cpt_si_pid;
347       to->cpt_si_uid = from_ptrace.cpt_si_uid;
348       to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
349     }
350   else
351     {
352       switch (to->si_signo)
353 	{
354 	case SIGCHLD:
355 	  to->cpt_si_pid = from_ptrace.cpt_si_pid;
356 	  to->cpt_si_uid = from_ptrace.cpt_si_uid;
357 	  to->cpt_si_status = from_ptrace.cpt_si_status;
358 	  to->cpt_si_utime = from_ptrace.cpt_si_utime;
359 	  to->cpt_si_stime = from_ptrace.cpt_si_stime;
360 	  break;
361 	case SIGILL:
362 	case SIGFPE:
363 	case SIGSEGV:
364 	case SIGBUS:
365 	  to->cpt_si_addr = from_ptrace.cpt_si_addr;
366 	  break;
367 	case SIGPOLL:
368 	  to->cpt_si_band = from_ptrace.cpt_si_band;
369 	  to->cpt_si_fd = from_ptrace.cpt_si_fd;
370 	  break;
371 	default:
372 	  to->cpt_si_pid = from_ptrace.cpt_si_pid;
373 	  to->cpt_si_uid = from_ptrace.cpt_si_uid;
374 	  to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
375 	  break;
376 	}
377     }
378 }
379 
380 /* Convert the compatible siginfo into system siginfo.  */
381 
382 static void
383 siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from)
384 {
385   ptrace_siginfo_t to_ptrace;
386 
387   memset (&to_ptrace, 0, sizeof (to_ptrace));
388 
389   to_ptrace.si_signo = from->si_signo;
390   to_ptrace.si_errno = from->si_errno;
391   to_ptrace.si_code = from->si_code;
392 
393   if (to_ptrace.si_code == SI_TIMER)
394     {
395       to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
396       to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
397       to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
398     }
399   else if (to_ptrace.si_code == SI_USER)
400     {
401       to_ptrace.cpt_si_pid = from->cpt_si_pid;
402       to_ptrace.cpt_si_uid = from->cpt_si_uid;
403     }
404   if (to_ptrace.si_code < 0)
405     {
406       to_ptrace.cpt_si_pid = from->cpt_si_pid;
407       to_ptrace.cpt_si_uid = from->cpt_si_uid;
408       to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
409     }
410   else
411     {
412       switch (to_ptrace.si_signo)
413 	{
414 	case SIGCHLD:
415 	  to_ptrace.cpt_si_pid = from->cpt_si_pid;
416 	  to_ptrace.cpt_si_uid = from->cpt_si_uid;
417 	  to_ptrace.cpt_si_status = from->cpt_si_status;
418 	  to_ptrace.cpt_si_utime = from->cpt_si_utime;
419 	  to_ptrace.cpt_si_stime = from->cpt_si_stime;
420 	  break;
421 	case SIGILL:
422 	case SIGFPE:
423 	case SIGSEGV:
424 	case SIGBUS:
425 	  to_ptrace.cpt_si_addr = from->cpt_si_addr;
426 	  to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb;
427 	  break;
428 	case SIGPOLL:
429 	  to_ptrace.cpt_si_band = from->cpt_si_band;
430 	  to_ptrace.cpt_si_fd = from->cpt_si_fd;
431 	  break;
432 	default:
433 	  to_ptrace.cpt_si_pid = from->cpt_si_pid;
434 	  to_ptrace.cpt_si_uid = from->cpt_si_uid;
435 	  to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
436 	  break;
437 	}
438     }
439   memcpy (to, &to_ptrace, sizeof (to_ptrace));
440 }
441 
442 /*  Convert the system provided siginfo into compatible x32 siginfo.  */
443 
444 static void
445 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
446 				 const siginfo_t *from)
447 {
448   ptrace_siginfo_t from_ptrace;
449 
450   memcpy (&from_ptrace, from, sizeof (from_ptrace));
451   memset (to, 0, sizeof (*to));
452 
453   to->si_signo = from_ptrace.si_signo;
454   to->si_errno = from_ptrace.si_errno;
455   to->si_code = from_ptrace.si_code;
456 
457   if (to->si_code == SI_TIMER)
458     {
459       to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
460       to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
461       to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
462     }
463   else if (to->si_code == SI_USER)
464     {
465       to->cpt_si_pid = from_ptrace.cpt_si_pid;
466       to->cpt_si_uid = from_ptrace.cpt_si_uid;
467     }
468   else if (to->si_code < 0)
469     {
470       to->cpt_si_pid = from_ptrace.cpt_si_pid;
471       to->cpt_si_uid = from_ptrace.cpt_si_uid;
472       to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
473     }
474   else
475     {
476       switch (to->si_signo)
477 	{
478 	case SIGCHLD:
479 	  to->cpt_si_pid = from_ptrace.cpt_si_pid;
480 	  to->cpt_si_uid = from_ptrace.cpt_si_uid;
481 	  to->cpt_si_status = from_ptrace.cpt_si_status;
482 	  memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime,
483 		  sizeof (to->cpt_si_utime));
484 	  memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime,
485 		  sizeof (to->cpt_si_stime));
486 	  break;
487 	case SIGILL:
488 	case SIGFPE:
489 	case SIGSEGV:
490 	case SIGBUS:
491 	  to->cpt_si_addr = from_ptrace.cpt_si_addr;
492 	  break;
493 	case SIGPOLL:
494 	  to->cpt_si_band = from_ptrace.cpt_si_band;
495 	  to->cpt_si_fd = from_ptrace.cpt_si_fd;
496 	  break;
497 	default:
498 	  to->cpt_si_pid = from_ptrace.cpt_si_pid;
499 	  to->cpt_si_uid = from_ptrace.cpt_si_uid;
500 	  to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
501 	  break;
502 	}
503     }
504 }
505 
506 
507 
508 
509 /* Convert the compatible x32 siginfo into system siginfo.  */
510 static void
511 siginfo_from_compat_x32_siginfo (siginfo_t *to,
512 				 const compat_x32_siginfo_t *from)
513 {
514   ptrace_siginfo_t to_ptrace;
515 
516   memset (&to_ptrace, 0, sizeof (to_ptrace));
517   to_ptrace.si_signo = from->si_signo;
518   to_ptrace.si_errno = from->si_errno;
519   to_ptrace.si_code = from->si_code;
520 
521   if (to_ptrace.si_code == SI_TIMER)
522     {
523       to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
524       to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
525       to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
526     }
527   else if (to_ptrace.si_code == SI_USER)
528     {
529       to_ptrace.cpt_si_pid = from->cpt_si_pid;
530       to_ptrace.cpt_si_uid = from->cpt_si_uid;
531     }
532   if (to_ptrace.si_code < 0)
533     {
534       to_ptrace.cpt_si_pid = from->cpt_si_pid;
535       to_ptrace.cpt_si_uid = from->cpt_si_uid;
536       to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
537     }
538   else
539     {
540       switch (to_ptrace.si_signo)
541 	{
542 	case SIGCHLD:
543 	  to_ptrace.cpt_si_pid = from->cpt_si_pid;
544 	  to_ptrace.cpt_si_uid = from->cpt_si_uid;
545 	  to_ptrace.cpt_si_status = from->cpt_si_status;
546 	  memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime,
547 		  sizeof (to_ptrace.cpt_si_utime));
548 	  memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime,
549 		  sizeof (to_ptrace.cpt_si_stime));
550 	  break;
551 	case SIGILL:
552 	case SIGFPE:
553 	case SIGSEGV:
554 	case SIGBUS:
555 	  to_ptrace.cpt_si_addr = from->cpt_si_addr;
556 	  break;
557 	case SIGPOLL:
558 	  to_ptrace.cpt_si_band = from->cpt_si_band;
559 	  to_ptrace.cpt_si_fd = from->cpt_si_fd;
560 	  break;
561 	default:
562 	  to_ptrace.cpt_si_pid = from->cpt_si_pid;
563 	  to_ptrace.cpt_si_uid = from->cpt_si_uid;
564 	  to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
565 	  break;
566 	}
567     }
568   memcpy (to, &to_ptrace, sizeof (to_ptrace));
569 }
570 
571 /* Convert a ptrace siginfo object, into/from the siginfo in the
572    layout of the inferiors' architecture.  Returns true if any
573    conversion was done; false otherwise.  If DIRECTION is 1, then copy
574    from INF to PTRACE.  If DIRECTION is 0, then copy from NATIVE to
575    INF.  */
576 
577 int
578 amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf,
579 				  int direction,
580 				  enum amd64_siginfo_fixup_mode mode)
581 {
582   if (mode == FIXUP_32)
583     {
584       if (direction == 0)
585 	compat_siginfo_from_siginfo ((compat_siginfo_t *) inf, ptrace);
586       else
587 	siginfo_from_compat_siginfo (ptrace, (compat_siginfo_t *) inf);
588 
589       return 1;
590     }
591   else if (mode == FIXUP_X32)
592     {
593       if (direction == 0)
594 	compat_x32_siginfo_from_siginfo ((compat_x32_siginfo_t *) inf,
595 					 ptrace);
596       else
597 	siginfo_from_compat_x32_siginfo (ptrace,
598 					 (compat_x32_siginfo_t *) inf);
599 
600       return 1;
601     }
602   return 0;
603 }
604 
605 /* Sanity check for the siginfo structure sizes.  */
606 
607 gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
608 #ifndef __ILP32__
609 gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
610 #endif
611 gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
612 gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE);
613 gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE);
614