]> Git Repo - binutils.git/blob - gdb/nat/amd64-linux-siginfo.c
Automatic date update in version.in
[binutils.git] / gdb / nat / amd64-linux-siginfo.c
1 /* Low-level siginfo manipulation for amd64.
2
3    Copyright (C) 2002-2022 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);
This page took 0.057573 seconds and 4 git commands to generate.