1 /* Low-level siginfo manipulation for amd64.
3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
21 #include "common-defs.h"
22 #include "amd64-linux-siginfo.h"
24 /* These types below (compat_*) define a siginfo type that is layout
25 compatible with the siginfo type exported by the 32-bit userspace
28 typedef int compat_int_t
;
29 typedef unsigned int compat_uptr_t
;
31 typedef int compat_time_t
;
32 typedef int compat_timer_t
;
33 typedef int compat_clock_t
;
41 typedef union compat_sigval
43 compat_int_t sival_int
;
44 compat_uptr_t sival_ptr
;
47 typedef struct compat_siginfo
55 int _pad
[((128 / sizeof (int)) - 3)];
69 compat_sigval_t _sigval
;
72 /* POSIX.1b signals */
77 compat_sigval_t _sigval
;
86 compat_clock_t _utime
;
87 compat_clock_t _stime
;
90 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
105 /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */
106 typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t
;
108 typedef struct compat_x32_siginfo
116 int _pad
[((128 / sizeof (int)) - 3)];
125 /* POSIX.1b timers */
130 compat_sigval_t _sigval
;
133 /* POSIX.1b signals */
138 compat_sigval_t _sigval
;
147 compat_x32_clock_t _utime
;
148 compat_x32_clock_t _stime
;
151 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
164 } compat_x32_siginfo_t
__attribute__ ((__aligned__ (8)));
166 /* To simplify usage of siginfo fields. */
168 #define cpt_si_pid _sifields._kill._pid
169 #define cpt_si_uid _sifields._kill._uid
170 #define cpt_si_timerid _sifields._timer._tid
171 #define cpt_si_overrun _sifields._timer._overrun
172 #define cpt_si_status _sifields._sigchld._status
173 #define cpt_si_utime _sifields._sigchld._utime
174 #define cpt_si_stime _sifields._sigchld._stime
175 #define cpt_si_ptr _sifields._rt._sigval.sival_ptr
176 #define cpt_si_addr _sifields._sigfault._addr
177 #define cpt_si_band _sifields._sigpoll._band
178 #define cpt_si_fd _sifields._sigpoll._fd
180 /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
181 In their place is si_timer1,si_timer2. */
184 #define si_timerid si_timer1
187 #define si_overrun si_timer2
190 /* Convert the system provided siginfo into compatible siginfo. */
193 compat_siginfo_from_siginfo (compat_siginfo_t
*to
, siginfo_t
*from
)
195 memset (to
, 0, sizeof (*to
));
197 to
->si_signo
= from
->si_signo
;
198 to
->si_errno
= from
->si_errno
;
199 to
->si_code
= from
->si_code
;
201 if (to
->si_code
== SI_TIMER
)
203 to
->cpt_si_timerid
= from
->si_timerid
;
204 to
->cpt_si_overrun
= from
->si_overrun
;
205 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
207 else if (to
->si_code
== SI_USER
)
209 to
->cpt_si_pid
= from
->si_pid
;
210 to
->cpt_si_uid
= from
->si_uid
;
212 else if (to
->si_code
< 0)
214 to
->cpt_si_pid
= from
->si_pid
;
215 to
->cpt_si_uid
= from
->si_uid
;
216 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
220 switch (to
->si_signo
)
223 to
->cpt_si_pid
= from
->si_pid
;
224 to
->cpt_si_uid
= from
->si_uid
;
225 to
->cpt_si_status
= from
->si_status
;
226 to
->cpt_si_utime
= from
->si_utime
;
227 to
->cpt_si_stime
= from
->si_stime
;
233 to
->cpt_si_addr
= (intptr_t) from
->si_addr
;
236 to
->cpt_si_band
= from
->si_band
;
237 to
->cpt_si_fd
= from
->si_fd
;
240 to
->cpt_si_pid
= from
->si_pid
;
241 to
->cpt_si_uid
= from
->si_uid
;
242 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
248 /* Convert the compatible siginfo into system siginfo. */
251 siginfo_from_compat_siginfo (siginfo_t
*to
, compat_siginfo_t
*from
)
253 memset (to
, 0, sizeof (*to
));
255 to
->si_signo
= from
->si_signo
;
256 to
->si_errno
= from
->si_errno
;
257 to
->si_code
= from
->si_code
;
259 if (to
->si_code
== SI_TIMER
)
261 to
->si_timerid
= from
->cpt_si_timerid
;
262 to
->si_overrun
= from
->cpt_si_overrun
;
263 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
265 else if (to
->si_code
== SI_USER
)
267 to
->si_pid
= from
->cpt_si_pid
;
268 to
->si_uid
= from
->cpt_si_uid
;
272 to
->si_pid
= from
->cpt_si_pid
;
273 to
->si_uid
= from
->cpt_si_uid
;
274 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
278 switch (to
->si_signo
)
281 to
->si_pid
= from
->cpt_si_pid
;
282 to
->si_uid
= from
->cpt_si_uid
;
283 to
->si_status
= from
->cpt_si_status
;
284 to
->si_utime
= from
->cpt_si_utime
;
285 to
->si_stime
= from
->cpt_si_stime
;
291 to
->si_addr
= (void *) (intptr_t) from
->cpt_si_addr
;
294 to
->si_band
= from
->cpt_si_band
;
295 to
->si_fd
= from
->cpt_si_fd
;
298 to
->si_pid
= from
->cpt_si_pid
;
299 to
->si_uid
= from
->cpt_si_uid
;
300 to
->si_ptr
= (void* ) (intptr_t) from
->cpt_si_ptr
;
306 /* Convert the system provided siginfo into compatible x32 siginfo. */
309 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t
*to
,
312 memset (to
, 0, sizeof (*to
));
314 to
->si_signo
= from
->si_signo
;
315 to
->si_errno
= from
->si_errno
;
316 to
->si_code
= from
->si_code
;
318 if (to
->si_code
== SI_TIMER
)
320 to
->cpt_si_timerid
= from
->si_timerid
;
321 to
->cpt_si_overrun
= from
->si_overrun
;
322 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
324 else if (to
->si_code
== SI_USER
)
326 to
->cpt_si_pid
= from
->si_pid
;
327 to
->cpt_si_uid
= from
->si_uid
;
329 else if (to
->si_code
< 0)
331 to
->cpt_si_pid
= from
->si_pid
;
332 to
->cpt_si_uid
= from
->si_uid
;
333 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
337 switch (to
->si_signo
)
340 to
->cpt_si_pid
= from
->si_pid
;
341 to
->cpt_si_uid
= from
->si_uid
;
342 to
->cpt_si_status
= from
->si_status
;
343 memcpy (&to
->cpt_si_utime
, &from
->si_utime
,
344 sizeof (to
->cpt_si_utime
));
345 memcpy (&to
->cpt_si_stime
, &from
->si_stime
,
346 sizeof (to
->cpt_si_stime
));
352 to
->cpt_si_addr
= (intptr_t) from
->si_addr
;
355 to
->cpt_si_band
= from
->si_band
;
356 to
->cpt_si_fd
= from
->si_fd
;
359 to
->cpt_si_pid
= from
->si_pid
;
360 to
->cpt_si_uid
= from
->si_uid
;
361 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
367 /* Convert the compatible x32 siginfo into system siginfo. */
369 siginfo_from_compat_x32_siginfo (siginfo_t
*to
,
370 compat_x32_siginfo_t
*from
)
372 memset (to
, 0, sizeof (*to
));
374 to
->si_signo
= from
->si_signo
;
375 to
->si_errno
= from
->si_errno
;
376 to
->si_code
= from
->si_code
;
378 if (to
->si_code
== SI_TIMER
)
380 to
->si_timerid
= from
->cpt_si_timerid
;
381 to
->si_overrun
= from
->cpt_si_overrun
;
382 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
384 else if (to
->si_code
== SI_USER
)
386 to
->si_pid
= from
->cpt_si_pid
;
387 to
->si_uid
= from
->cpt_si_uid
;
391 to
->si_pid
= from
->cpt_si_pid
;
392 to
->si_uid
= from
->cpt_si_uid
;
393 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
397 switch (to
->si_signo
)
400 to
->si_pid
= from
->cpt_si_pid
;
401 to
->si_uid
= from
->cpt_si_uid
;
402 to
->si_status
= from
->cpt_si_status
;
403 memcpy (&to
->si_utime
, &from
->cpt_si_utime
,
404 sizeof (to
->si_utime
));
405 memcpy (&to
->si_stime
, &from
->cpt_si_stime
,
406 sizeof (to
->si_stime
));
412 to
->si_addr
= (void *) (intptr_t) from
->cpt_si_addr
;
415 to
->si_band
= from
->cpt_si_band
;
416 to
->si_fd
= from
->cpt_si_fd
;
419 to
->si_pid
= from
->cpt_si_pid
;
420 to
->si_uid
= from
->cpt_si_uid
;
421 to
->si_ptr
= (void* ) (intptr_t) from
->cpt_si_ptr
;
427 /* Convert a native/host siginfo object, into/from the siginfo in the
428 layout of the inferiors' architecture. Returns true if any
429 conversion was done; false otherwise. If DIRECTION is 1, then copy
430 from INF to NATIVE. If DIRECTION is 0, then copy from NATIVE to INF. */
433 amd64_linux_siginfo_fixup_common (siginfo_t
*native
, gdb_byte
*inf
,
435 enum amd64_siginfo_fixup_mode mode
)
437 if (mode
== FIXUP_32
)
439 gdb_assert (sizeof (siginfo_t
) == sizeof (compat_siginfo_t
));
442 compat_siginfo_from_siginfo ((struct compat_siginfo
*) inf
, native
);
444 siginfo_from_compat_siginfo (native
, (struct compat_siginfo
*) inf
);
448 else if (mode
== FIXUP_X32
)
450 gdb_assert (sizeof (siginfo_t
) == sizeof (compat_x32_siginfo_t
));
453 compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo
*) inf
,
456 siginfo_from_compat_x32_siginfo (native
,
457 (struct compat_x32_siginfo
*) inf
);