xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/nat/amd64-linux-siginfo.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* Low-level siginfo manipulation for amd64.
2 
3    Copyright (C) 2002-2019 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 <signal.h>
21 #include "common/common-defs.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 typedef union nat_sigval
49 {
50   nat_int_t sival_int;
51   nat_uptr_t sival_ptr;
52 } nat_sigval_t;
53 
54 typedef struct nat_siginfo
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 } nat_siginfo_t;
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 typedef union compat_sigval
137 {
138   compat_int_t sival_int;
139   compat_uptr_t sival_ptr;
140 } compat_sigval_t;
141 
142 typedef struct compat_siginfo
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 } compat_siginfo_t;
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 typedef struct compat_x32_siginfo
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 } compat_x32_siginfo_t __attribute__ ((__aligned__ (8)));
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_band _sifields._sigpoll._band
281 #define cpt_si_fd _sifields._sigpoll._fd
282 
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.  */
285 
286 #ifndef si_timerid
287 #define si_timerid si_timer1
288 #endif
289 #ifndef si_overrun
290 #define si_overrun si_timer2
291 #endif
292 
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
295    siginfo.  */
296 #ifdef __ILP32__
297 typedef compat_x32_siginfo_t ptrace_siginfo_t;
298 #else
299 typedef nat_siginfo_t ptrace_siginfo_t;
300 #endif
301 
302 /*  Convert the system provided siginfo into compatible siginfo.  */
303 
304 static void
305 compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from)
306 {
307   ptrace_siginfo_t from_ptrace;
308 
309   memcpy (&from_ptrace, from, sizeof (from_ptrace));
310   memset (to, 0, sizeof (*to));
311 
312   to->si_signo = from_ptrace.si_signo;
313   to->si_errno = from_ptrace.si_errno;
314   to->si_code = from_ptrace.si_code;
315 
316   if (to->si_code == SI_TIMER)
317     {
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;
321     }
322   else if (to->si_code == SI_USER)
323     {
324       to->cpt_si_pid = from_ptrace.cpt_si_pid;
325       to->cpt_si_uid = from_ptrace.cpt_si_uid;
326     }
327   else if (to->si_code < 0)
328     {
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;
332     }
333   else
334     {
335       switch (to->si_signo)
336 	{
337 	case SIGCHLD:
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;
343 	  break;
344 	case SIGILL:
345 	case SIGFPE:
346 	case SIGSEGV:
347 	case SIGBUS:
348 	  to->cpt_si_addr = from_ptrace.cpt_si_addr;
349 	  break;
350 	case SIGPOLL:
351 	  to->cpt_si_band = from_ptrace.cpt_si_band;
352 	  to->cpt_si_fd = from_ptrace.cpt_si_fd;
353 	  break;
354 	default:
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;
358 	  break;
359 	}
360     }
361 }
362 
363 /* Convert the compatible siginfo into system siginfo.  */
364 
365 static void
366 siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from)
367 {
368   ptrace_siginfo_t to_ptrace;
369 
370   memset (&to_ptrace, 0, sizeof (to_ptrace));
371 
372   to_ptrace.si_signo = from->si_signo;
373   to_ptrace.si_errno = from->si_errno;
374   to_ptrace.si_code = from->si_code;
375 
376   if (to_ptrace.si_code == SI_TIMER)
377     {
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;
381     }
382   else if (to_ptrace.si_code == SI_USER)
383     {
384       to_ptrace.cpt_si_pid = from->cpt_si_pid;
385       to_ptrace.cpt_si_uid = from->cpt_si_uid;
386     }
387   if (to_ptrace.si_code < 0)
388     {
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;
392     }
393   else
394     {
395       switch (to_ptrace.si_signo)
396 	{
397 	case SIGCHLD:
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;
403 	  break;
404 	case SIGILL:
405 	case SIGFPE:
406 	case SIGSEGV:
407 	case SIGBUS:
408 	  to_ptrace.cpt_si_addr = from->cpt_si_addr;
409 	  to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb;
410 	  break;
411 	case SIGPOLL:
412 	  to_ptrace.cpt_si_band = from->cpt_si_band;
413 	  to_ptrace.cpt_si_fd = from->cpt_si_fd;
414 	  break;
415 	default:
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;
419 	  break;
420 	}
421     }
422   memcpy (to, &to_ptrace, sizeof (to_ptrace));
423 }
424 
425 /*  Convert the system provided siginfo into compatible x32 siginfo.  */
426 
427 static void
428 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
429 				 const siginfo_t *from)
430 {
431   ptrace_siginfo_t from_ptrace;
432 
433   memcpy (&from_ptrace, from, sizeof (from_ptrace));
434   memset (to, 0, sizeof (*to));
435 
436   to->si_signo = from_ptrace.si_signo;
437   to->si_errno = from_ptrace.si_errno;
438   to->si_code = from_ptrace.si_code;
439 
440   if (to->si_code == SI_TIMER)
441     {
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;
445     }
446   else if (to->si_code == SI_USER)
447     {
448       to->cpt_si_pid = from_ptrace.cpt_si_pid;
449       to->cpt_si_uid = from_ptrace.cpt_si_uid;
450     }
451   else if (to->si_code < 0)
452     {
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;
456     }
457   else
458     {
459       switch (to->si_signo)
460 	{
461 	case SIGCHLD:
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));
469 	  break;
470 	case SIGILL:
471 	case SIGFPE:
472 	case SIGSEGV:
473 	case SIGBUS:
474 	  to->cpt_si_addr = from_ptrace.cpt_si_addr;
475 	  break;
476 	case SIGPOLL:
477 	  to->cpt_si_band = from_ptrace.cpt_si_band;
478 	  to->cpt_si_fd = from_ptrace.cpt_si_fd;
479 	  break;
480 	default:
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;
484 	  break;
485 	}
486     }
487 }
488 
489 
490 
491 
492 /* Convert the compatible x32 siginfo into system siginfo.  */
493 static void
494 siginfo_from_compat_x32_siginfo (siginfo_t *to,
495 				 const compat_x32_siginfo_t *from)
496 {
497   ptrace_siginfo_t to_ptrace;
498 
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;
503 
504   if (to_ptrace.si_code == SI_TIMER)
505     {
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;
509     }
510   else if (to_ptrace.si_code == SI_USER)
511     {
512       to_ptrace.cpt_si_pid = from->cpt_si_pid;
513       to_ptrace.cpt_si_uid = from->cpt_si_uid;
514     }
515   if (to_ptrace.si_code < 0)
516     {
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;
520     }
521   else
522     {
523       switch (to_ptrace.si_signo)
524 	{
525 	case SIGCHLD:
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));
533 	  break;
534 	case SIGILL:
535 	case SIGFPE:
536 	case SIGSEGV:
537 	case SIGBUS:
538 	  to_ptrace.cpt_si_addr = from->cpt_si_addr;
539 	  break;
540 	case SIGPOLL:
541 	  to_ptrace.cpt_si_band = from->cpt_si_band;
542 	  to_ptrace.cpt_si_fd = from->cpt_si_fd;
543 	  break;
544 	default:
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;
548 	  break;
549 	}
550     }
551   memcpy (to, &to_ptrace, sizeof (to_ptrace));
552 }
553 
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
558    INF.  */
559 
560 int
561 amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf,
562 				  int direction,
563 				  enum amd64_siginfo_fixup_mode mode)
564 {
565   if (mode == FIXUP_32)
566     {
567       if (direction == 0)
568 	compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, ptrace);
569       else
570 	siginfo_from_compat_siginfo (ptrace, (struct compat_siginfo *) inf);
571 
572       return 1;
573     }
574   else if (mode == FIXUP_X32)
575     {
576       if (direction == 0)
577 	compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
578 					 ptrace);
579       else
580 	siginfo_from_compat_x32_siginfo (ptrace,
581 					 (struct compat_x32_siginfo *) inf);
582 
583       return 1;
584     }
585   return 0;
586 }
587 
588 /* Sanity check for the siginfo structure sizes.  */
589 
590 gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
591 #ifndef __ILP32__
592 gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
593 #endif
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);
597