GDBserver
amd64-linux-siginfo.c
Go to the documentation of this file.
1 /* Low-level siginfo manipulation for amd64.
2 
3  Copyright (C) 2002-2018 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-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 {
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  {
74  int _overrun;
76  } _timer;
77 
78  /* POSIX.1b signals */
79  struct
80  {
81  unsigned int _pid;
82  unsigned int _uid;
84  } _rt;
85 
86  /* SIGCHLD */
87  struct
88  {
89  unsigned int _pid;
90  unsigned int _uid;
91  int _status;
94  } _sigchld;
95 
96  /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
97  struct
98  {
100  short int _addr_lsb;
101  struct
102  {
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 {
133  int tv_usec;
134 };
135 
136 typedef union compat_sigval
137 {
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  {
163  int _overrun;
165  } _timer;
166 
167  /* POSIX.1b signals */
168  struct
169  {
170  unsigned int _pid;
171  unsigned int _uid;
173  } _rt;
174 
175  /* SIGCHLD */
176  struct
177  {
178  unsigned int _pid;
179  unsigned int _uid;
180  int _status;
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;
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
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
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
562  int direction,
563  enum amd64_siginfo_fixup_mode mode)
564 {
565  if (mode == FIXUP_32)
566  {
567  if (direction == 0)
569  else
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
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__
593 #endif
594 gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
struct nat_siginfo::@21::@25 _sigchld
int nat_time_t
struct compat_siginfo::@14::@16 _timer
int compat_time_t
Definition: aarch64-linux.h:30
struct compat_siginfo compat_siginfo_t
unsigned int _pid
nat_clock_t _stime
gdb_static_assert(sizeof(siginfo_t)==GDB_SI_SIZE)
int nat_int_t
nat_uptr_t _addr
void * memset(T *s, int c, size_t n)=delete
int compat_int_t
Definition: aarch64-linux.h:27
nat_clock_t _utime
unsigned int _addr
Definition: aarch64-linux.h:92
struct nat_siginfo::@21::@26::@28 si_addr_bnd
nat_uptr_t sival_ptr
nat_sigval_t _sigval
PTRACE_TYPE_RET ptrace()
int compat_time_t
static void compat_siginfo_from_siginfo(compat_siginfo_t *to, const siginfo_t *from)
compat_uptr_t sival_ptr
Definition: aarch64-linux.h:43
union compat_siginfo::@14 _sifields
unsigned int _pid
Definition: aarch64-linux.h:59
int amd64_linux_siginfo_fixup_common(siginfo_t *ptrace, gdb_byte *inf, int direction, enum amd64_siginfo_fixup_mode mode)
int nat_timer_t
nat_siginfo_t ptrace_siginfo_t
int _pad[((128/sizeof(int)) - 3)]
Definition: aarch64-linux.h:54
compat_int_t sival_int
Definition: aarch64-linux.h:42
amd64_siginfo_fixup_mode
struct compat_siginfo::@14::@15 _kill
struct nat_siginfo::@21::@22 _kill
struct compat_siginfo::@14::@19 _sigfault
compat_sigval_t _sigval
Definition: aarch64-linux.h:68
unsigned int _uid
struct nat_siginfo::@21::@26 _sigfault
unsigned int _uid
Definition: aarch64-linux.h:60
nat_timer_t _tid
long __attribute__((__aligned__(4)))
int compat_int_t
int compat_clock_t
Definition: aarch64-linux.h:32
struct nat_siginfo::@21::@23 _timer
unsigned int compat_uptr_t
struct nat_siginfo::@21::@24 _rt
compat_clock_t _stime
Definition: aarch64-linux.h:86
int compat_timer_t
Definition: aarch64-linux.h:31
struct compat_siginfo::@14::@17 _rt
bfd_byte gdb_byte
Definition: common-types.h:38
struct compat_siginfo::@14::@20 _sigpoll
static void compat_x32_siginfo_from_siginfo(compat_x32_siginfo_t *to, const siginfo_t *from)
compat_clock_t _utime
Definition: aarch64-linux.h:85
static void siginfo_from_compat_x32_siginfo(siginfo_t *to, const compat_x32_siginfo_t *from)
compat_timer_t _tid
Definition: aarch64-linux.h:66
compat_time_t tv_sec
Definition: aarch64-linux.h:36
union nat_sigval nat_sigval_t
unsigned long nat_uptr_t
struct nat_siginfo::@21::@27 _sigpoll
struct compat_siginfo::@29::@34::@36 si_addr_bnd
nat_int_t sival_int
int compat_clock_t
union compat_sigval compat_sigval_t
int compat_timer_t
long nat_clock_t
struct nat_siginfo nat_siginfo_t
int _pad[((128/sizeof(int)) - 4)]
union nat_siginfo::@21 _sifields
#define GDB_SI_SIZE
unsigned int compat_uptr_t
Definition: aarch64-linux.h:28
struct compat_siginfo::@14::@18 _sigchld
static void siginfo_from_compat_siginfo(siginfo_t *to, const compat_siginfo_t *from)