Use XCNEW rather than xcalloc (1, ...) in linux-x86-low.c
[deliverable/binutils-gdb.git] / gdb / amd64-linux-nat.c
CommitLineData
a4b6fc86 1/* Native-dependent code for GNU/Linux x86-64.
0a65a603 2
ecd75fc8 3 Copyright (C) 2001-2014 Free Software Foundation, Inc.
53e95fcf
JS
4 Contributed by Jiri Smid, SuSE Labs.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
53e95fcf
JS
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
53e95fcf
JS
20
21#include "defs.h"
22#include "inferior.h"
53e95fcf 23#include "regcache.h"
a055a187 24#include "elf/common.h"
53e95fcf 25#include <sys/ptrace.h>
c43af07c 26#include <asm/prctl.h>
33a0a2ac 27#include <sys/reg.h>
c4f35dd8 28#include "gregset.h"
3116063b 29#include "gdb_proc_service.h"
c4f35dd8 30
3116063b
GB
31#include "amd64-nat.h"
32#include "linux-nat.h"
9c1488cb 33#include "amd64-tdep.h"
3116063b 34#include "amd64-linux-tdep.h"
60fac5b8 35#include "i386-linux-tdep.h"
a055a187
L
36#include "i386-xstate.h"
37
040baaf6 38#include "x86-linux-nat.h"
60fac5b8 39
60fac5b8
MK
40/* Mapping between the general-purpose registers in GNU/Linux x86-64
41 `struct user' format and GDB's register cache layout for GNU/Linux
42 i386.
43
44 Note that most GNU/Linux x86-64 registers are 64-bit, while the
45 GNU/Linux i386 registers are all 32-bit, but since we're
46 little-endian we get away with that. */
47
48/* From <sys/reg.h> on GNU/Linux i386. */
430eaf2e 49static int amd64_linux_gregset32_reg_offset[] =
60fac5b8 50{
f5859b4d
MK
51 RAX * 8, RCX * 8, /* %eax, %ecx */
52 RDX * 8, RBX * 8, /* %edx, %ebx */
53 RSP * 8, RBP * 8, /* %esp, %ebp */
54 RSI * 8, RDI * 8, /* %esi, %edi */
55 RIP * 8, EFLAGS * 8, /* %eip, %eflags */
56 CS * 8, SS * 8, /* %cs, %ss */
57 DS * 8, ES * 8, /* %ds, %es */
58 FS * 8, GS * 8, /* %fs, %gs */
60fac5b8
MK
59 -1, -1, -1, -1, -1, -1, -1, -1,
60 -1, -1, -1, -1, -1, -1, -1, -1,
61 -1, -1, -1, -1, -1, -1, -1, -1, -1,
a055a187 62 -1, -1, -1, -1, -1, -1, -1, -1,
01f9f808
MS
63 -1, -1, -1, -1, /* MPX registers BND0 ... BND3. */
64 -1, -1, /* MPX registers BNDCFGU, BNDSTATUS. */
65 -1, -1, -1, -1, -1, -1, -1, -1, /* k0 ... k7 (AVX512) */
66 -1, -1, -1, -1, -1, -1, -1, -1, /* zmm0 ... zmm7 (AVX512) */
67 ORIG_RAX * 8 /* "orig_eax" */
60fac5b8 68};
53e95fcf
JS
69\f
70
71/* Transfering the general-purpose registers between GDB, inferiors
72 and core files. */
73
60fac5b8 74/* Fill GDB's register cache with the general-purpose register values
53e95fcf
JS
75 in *GREGSETP. */
76
77void
7f7fe91e 78supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
53e95fcf 79{
7f7fe91e 80 amd64_supply_native_gregset (regcache, gregsetp, -1);
53e95fcf
JS
81}
82
60fac5b8
MK
83/* Fill register REGNUM (if it is a general-purpose register) in
84 *GREGSETP with the value in GDB's register cache. If REGNUM is -1,
53e95fcf
JS
85 do this for all registers. */
86
87void
7f7fe91e
UW
88fill_gregset (const struct regcache *regcache,
89 elf_gregset_t *gregsetp, int regnum)
53e95fcf 90{
7f7fe91e 91 amd64_collect_native_gregset (regcache, gregsetp, regnum);
53e95fcf
JS
92}
93
53e95fcf
JS
94/* Transfering floating-point registers between GDB, inferiors and cores. */
95
60fac5b8 96/* Fill GDB's register cache with the floating-point and SSE register
c4f35dd8 97 values in *FPREGSETP. */
53e95fcf
JS
98
99void
7f7fe91e 100supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
53e95fcf 101{
7f7fe91e 102 amd64_supply_fxsave (regcache, -1, fpregsetp);
53e95fcf
JS
103}
104
8dda9770 105/* Fill register REGNUM (if it is a floating-point or SSE register) in
60fac5b8 106 *FPREGSETP with the value in GDB's register cache. If REGNUM is
c4f35dd8 107 -1, do this for all registers. */
53e95fcf
JS
108
109void
7f7fe91e
UW
110fill_fpregset (const struct regcache *regcache,
111 elf_fpregset_t *fpregsetp, int regnum)
53e95fcf 112{
7f7fe91e 113 amd64_collect_fxsave (regcache, regnum, fpregsetp);
53e95fcf 114}
53e95fcf
JS
115\f
116
117/* Transferring arbitrary registers between GDB and inferior. */
118
60fac5b8 119/* Fetch register REGNUM from the child process. If REGNUM is -1, do
53e95fcf
JS
120 this for all registers (including the floating point and SSE
121 registers). */
122
10d6c8cd 123static void
28439f5e
PA
124amd64_linux_fetch_inferior_registers (struct target_ops *ops,
125 struct regcache *regcache, int regnum)
53e95fcf 126{
f8028488 127 struct gdbarch *gdbarch = get_regcache_arch (regcache);
53e95fcf
JS
128 int tid;
129
a4b6fc86 130 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 131 tid = ptid_get_lwp (inferior_ptid);
c4f35dd8 132 if (tid == 0)
dfd4cc63 133 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
53e95fcf 134
f8028488 135 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 136 {
99679982
MK
137 elf_gregset_t regs;
138
139 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 140 perror_with_name (_("Couldn't get registers"));
99679982 141
56be3814 142 amd64_supply_native_gregset (regcache, &regs, -1);
60fac5b8
MK
143 if (regnum != -1)
144 return;
53e95fcf
JS
145 }
146
f8028488 147 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 148 {
99679982 149 elf_fpregset_t fpregs;
53e95fcf 150
a055a187
L
151 if (have_ptrace_getregset)
152 {
153 char xstateregs[I386_XSTATE_MAX_SIZE];
154 struct iovec iov;
155
156 iov.iov_base = xstateregs;
157 iov.iov_len = sizeof (xstateregs);
158 if (ptrace (PTRACE_GETREGSET, tid,
159 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
160 perror_with_name (_("Couldn't get extended state status"));
99679982 161
a055a187
L
162 amd64_supply_xsave (regcache, -1, xstateregs);
163 }
164 else
165 {
166 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
167 perror_with_name (_("Couldn't get floating point status"));
168
169 amd64_supply_fxsave (regcache, -1, &fpregs);
170 }
99679982 171 }
53e95fcf
JS
172}
173
60fac5b8
MK
174/* Store register REGNUM back into the child process. If REGNUM is
175 -1, do this for all registers (including the floating-point and SSE
53e95fcf 176 registers). */
c4f35dd8 177
10d6c8cd 178static void
28439f5e
PA
179amd64_linux_store_inferior_registers (struct target_ops *ops,
180 struct regcache *regcache, int regnum)
53e95fcf 181{
f8028488 182 struct gdbarch *gdbarch = get_regcache_arch (regcache);
53e95fcf
JS
183 int tid;
184
a4b6fc86 185 /* GNU/Linux LWP ID's are process ID's. */
dfd4cc63 186 tid = ptid_get_lwp (inferior_ptid);
c4f35dd8 187 if (tid == 0)
dfd4cc63 188 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */
53e95fcf 189
f8028488 190 if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 191 {
99679982
MK
192 elf_gregset_t regs;
193
194 if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 195 perror_with_name (_("Couldn't get registers"));
99679982 196
56be3814 197 amd64_collect_native_gregset (regcache, &regs, regnum);
99679982
MK
198
199 if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
edefbb7c 200 perror_with_name (_("Couldn't write registers"));
99679982 201
60fac5b8
MK
202 if (regnum != -1)
203 return;
53e95fcf
JS
204 }
205
f8028488 206 if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
53e95fcf 207 {
99679982
MK
208 elf_fpregset_t fpregs;
209
a055a187
L
210 if (have_ptrace_getregset)
211 {
212 char xstateregs[I386_XSTATE_MAX_SIZE];
213 struct iovec iov;
214
215 iov.iov_base = xstateregs;
216 iov.iov_len = sizeof (xstateregs);
217 if (ptrace (PTRACE_GETREGSET, tid,
218 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
219 perror_with_name (_("Couldn't get extended state status"));
99679982 220
a055a187
L
221 amd64_collect_xsave (regcache, regnum, xstateregs, 0);
222
223 if (ptrace (PTRACE_SETREGSET, tid,
224 (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
225 perror_with_name (_("Couldn't write extended state status"));
226 }
227 else
228 {
229 if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
230 perror_with_name (_("Couldn't get floating point status"));
99679982 231
a055a187 232 amd64_collect_fxsave (regcache, regnum, &fpregs);
99679982 233
a055a187
L
234 if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
235 perror_with_name (_("Couldn't write floating point status"));
236 }
53e95fcf 237 }
53e95fcf
JS
238}
239\f
1aa7e42c 240
50d71875
AC
241/* This function is called by libthread_db as part of its handling of
242 a request for a thread's local storage address. */
243
5bca7895 244ps_err_e
c43af07c
EZ
245ps_get_thread_area (const struct ps_prochandle *ph,
246 lwpid_t lwpid, int idx, void **base)
247{
f5656ead 248 if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
50d71875 249 {
8c420b8d
GB
250 unsigned int base_addr;
251 ps_err_e result;
252
253 result = x86_linux_get_thread_area (lwpid, (void *) (long) idx,
254 &base_addr);
255 if (result == PS_OK)
256 {
257 /* Extend the value to 64 bits. Here it's assumed that
258 a "long" and a "void *" are the same. */
259 (*base) = (void *) (long) base_addr;
260 }
261 return result;
50d71875
AC
262 }
263 else
264 {
265 /* This definition comes from prctl.h, but some kernels may not
266 have it. */
c43af07c
EZ
267#ifndef PTRACE_ARCH_PRCTL
268#define PTRACE_ARCH_PRCTL 30
269#endif
50d71875
AC
270 /* FIXME: ezannoni-2003-07-09 see comment above about include
271 file order. We could be getting bogus values for these two. */
272 gdb_assert (FS < ELF_NGREG);
273 gdb_assert (GS < ELF_NGREG);
274 switch (idx)
275 {
276 case FS:
6fea9e18
L
277#ifdef HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE
278 {
279 /* PTRACE_ARCH_PRCTL is obsolete since 2.6.25, where the
280 fs_base and gs_base fields of user_regs_struct can be
281 used directly. */
282 unsigned long fs;
283 errno = 0;
284 fs = ptrace (PTRACE_PEEKUSER, lwpid,
285 offsetof (struct user_regs_struct, fs_base), 0);
286 if (errno == 0)
287 {
288 *base = (void *) fs;
289 return PS_OK;
290 }
291 }
292#endif
50d71875
AC
293 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
294 return PS_OK;
295 break;
296 case GS:
6fea9e18
L
297#ifdef HAVE_STRUCT_USER_REGS_STRUCT_GS_BASE
298 {
299 unsigned long gs;
300 errno = 0;
301 gs = ptrace (PTRACE_PEEKUSER, lwpid,
302 offsetof (struct user_regs_struct, gs_base), 0);
303 if (errno == 0)
304 {
305 *base = (void *) gs;
306 return PS_OK;
307 }
308 }
309#endif
50d71875
AC
310 if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
311 return PS_OK;
312 break;
313 default: /* Should not happen. */
314 return PS_BADADDR;
315 }
c43af07c 316 }
b6d42148 317 return PS_ERR; /* ptrace failed. */
c43af07c 318}
5bca7895 319\f
c43af07c 320
5b009018
PA
321/* When GDB is built as a 64-bit application on linux, the
322 PTRACE_GETSIGINFO data is always presented in 64-bit layout. Since
323 debugging a 32-bit inferior with a 64-bit GDB should look the same
324 as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
325 conversion in-place ourselves. */
326
327/* These types below (compat_*) define a siginfo type that is layout
328 compatible with the siginfo type exported by the 32-bit userspace
329 support. */
330
331typedef int compat_int_t;
332typedef unsigned int compat_uptr_t;
333
334typedef int compat_time_t;
335typedef int compat_timer_t;
336typedef int compat_clock_t;
337
338struct compat_timeval
339{
340 compat_time_t tv_sec;
341 int tv_usec;
342};
343
344typedef union compat_sigval
345{
346 compat_int_t sival_int;
347 compat_uptr_t sival_ptr;
348} compat_sigval_t;
349
350typedef struct compat_siginfo
351{
352 int si_signo;
353 int si_errno;
354 int si_code;
355
356 union
357 {
358 int _pad[((128 / sizeof (int)) - 3)];
359
360 /* kill() */
361 struct
362 {
363 unsigned int _pid;
364 unsigned int _uid;
365 } _kill;
366
367 /* POSIX.1b timers */
368 struct
369 {
370 compat_timer_t _tid;
371 int _overrun;
372 compat_sigval_t _sigval;
373 } _timer;
374
375 /* POSIX.1b signals */
376 struct
377 {
378 unsigned int _pid;
379 unsigned int _uid;
380 compat_sigval_t _sigval;
381 } _rt;
382
383 /* SIGCHLD */
384 struct
385 {
386 unsigned int _pid;
387 unsigned int _uid;
388 int _status;
389 compat_clock_t _utime;
390 compat_clock_t _stime;
391 } _sigchld;
392
393 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
394 struct
395 {
396 unsigned int _addr;
397 } _sigfault;
398
399 /* SIGPOLL */
400 struct
401 {
402 int _band;
403 int _fd;
404 } _sigpoll;
405 } _sifields;
406} compat_siginfo_t;
407
ba224c70
L
408/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */
409typedef struct compat_x32_clock
410{
411 int lower;
412 int upper;
413} compat_x32_clock_t;
414
415typedef struct compat_x32_siginfo
416{
417 int si_signo;
418 int si_errno;
419 int si_code;
420
421 union
422 {
423 int _pad[((128 / sizeof (int)) - 3)];
424
425 /* kill() */
426 struct
427 {
428 unsigned int _pid;
429 unsigned int _uid;
430 } _kill;
431
432 /* POSIX.1b timers */
433 struct
434 {
435 compat_timer_t _tid;
436 int _overrun;
437 compat_sigval_t _sigval;
438 } _timer;
439
440 /* POSIX.1b signals */
441 struct
442 {
443 unsigned int _pid;
444 unsigned int _uid;
445 compat_sigval_t _sigval;
446 } _rt;
447
448 /* SIGCHLD */
449 struct
450 {
451 unsigned int _pid;
452 unsigned int _uid;
453 int _status;
454 compat_x32_clock_t _utime;
455 compat_x32_clock_t _stime;
456 } _sigchld;
457
458 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
459 struct
460 {
461 unsigned int _addr;
462 } _sigfault;
463
464 /* SIGPOLL */
465 struct
466 {
467 int _band;
468 int _fd;
469 } _sigpoll;
470 } _sifields;
471} compat_x32_siginfo_t;
472
5b009018
PA
473#define cpt_si_pid _sifields._kill._pid
474#define cpt_si_uid _sifields._kill._uid
475#define cpt_si_timerid _sifields._timer._tid
476#define cpt_si_overrun _sifields._timer._overrun
477#define cpt_si_status _sifields._sigchld._status
478#define cpt_si_utime _sifields._sigchld._utime
479#define cpt_si_stime _sifields._sigchld._stime
480#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
481#define cpt_si_addr _sifields._sigfault._addr
482#define cpt_si_band _sifields._sigpoll._band
483#define cpt_si_fd _sifields._sigpoll._fd
484
14064aa2
DE
485/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
486 In their place is si_timer1,si_timer2. */
487#ifndef si_timerid
488#define si_timerid si_timer1
489#endif
490#ifndef si_overrun
491#define si_overrun si_timer2
492#endif
493
5b009018
PA
494static void
495compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
496{
497 memset (to, 0, sizeof (*to));
498
499 to->si_signo = from->si_signo;
500 to->si_errno = from->si_errno;
501 to->si_code = from->si_code;
502
b53a1623 503 if (to->si_code == SI_TIMER)
5b009018 504 {
b53a1623
PA
505 to->cpt_si_timerid = from->si_timerid;
506 to->cpt_si_overrun = from->si_overrun;
5b009018
PA
507 to->cpt_si_ptr = (intptr_t) from->si_ptr;
508 }
509 else if (to->si_code == SI_USER)
510 {
511 to->cpt_si_pid = from->si_pid;
512 to->cpt_si_uid = from->si_uid;
513 }
b53a1623 514 else if (to->si_code < 0)
5b009018 515 {
b53a1623
PA
516 to->cpt_si_pid = from->si_pid;
517 to->cpt_si_uid = from->si_uid;
5b009018
PA
518 to->cpt_si_ptr = (intptr_t) from->si_ptr;
519 }
520 else
521 {
522 switch (to->si_signo)
523 {
524 case SIGCHLD:
525 to->cpt_si_pid = from->si_pid;
526 to->cpt_si_uid = from->si_uid;
527 to->cpt_si_status = from->si_status;
528 to->cpt_si_utime = from->si_utime;
529 to->cpt_si_stime = from->si_stime;
530 break;
531 case SIGILL:
532 case SIGFPE:
533 case SIGSEGV:
534 case SIGBUS:
535 to->cpt_si_addr = (intptr_t) from->si_addr;
536 break;
537 case SIGPOLL:
538 to->cpt_si_band = from->si_band;
539 to->cpt_si_fd = from->si_fd;
540 break;
541 default:
542 to->cpt_si_pid = from->si_pid;
543 to->cpt_si_uid = from->si_uid;
544 to->cpt_si_ptr = (intptr_t) from->si_ptr;
545 break;
546 }
547 }
548}
549
550static void
551siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
552{
553 memset (to, 0, sizeof (*to));
554
555 to->si_signo = from->si_signo;
556 to->si_errno = from->si_errno;
557 to->si_code = from->si_code;
558
b53a1623 559 if (to->si_code == SI_TIMER)
5b009018 560 {
b53a1623
PA
561 to->si_timerid = from->cpt_si_timerid;
562 to->si_overrun = from->cpt_si_overrun;
5b009018
PA
563 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
564 }
565 else if (to->si_code == SI_USER)
566 {
567 to->si_pid = from->cpt_si_pid;
568 to->si_uid = from->cpt_si_uid;
569 }
b53a1623 570 if (to->si_code < 0)
5b009018 571 {
b53a1623
PA
572 to->si_pid = from->cpt_si_pid;
573 to->si_uid = from->cpt_si_uid;
5b009018
PA
574 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
575 }
576 else
577 {
578 switch (to->si_signo)
579 {
580 case SIGCHLD:
581 to->si_pid = from->cpt_si_pid;
582 to->si_uid = from->cpt_si_uid;
583 to->si_status = from->cpt_si_status;
584 to->si_utime = from->cpt_si_utime;
585 to->si_stime = from->cpt_si_stime;
586 break;
587 case SIGILL:
588 case SIGFPE:
589 case SIGSEGV:
590 case SIGBUS:
591 to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
592 break;
593 case SIGPOLL:
594 to->si_band = from->cpt_si_band;
595 to->si_fd = from->cpt_si_fd;
596 break;
597 default:
598 to->si_pid = from->cpt_si_pid;
599 to->si_uid = from->cpt_si_uid;
600 to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
601 break;
602 }
603 }
604}
605
ba224c70
L
606static void
607compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
608 siginfo_t *from)
609{
610 memset (to, 0, sizeof (*to));
611
612 to->si_signo = from->si_signo;
613 to->si_errno = from->si_errno;
614 to->si_code = from->si_code;
615
616 if (to->si_code == SI_TIMER)
617 {
618 to->cpt_si_timerid = from->si_timerid;
619 to->cpt_si_overrun = from->si_overrun;
620 to->cpt_si_ptr = (intptr_t) from->si_ptr;
621 }
622 else if (to->si_code == SI_USER)
623 {
624 to->cpt_si_pid = from->si_pid;
625 to->cpt_si_uid = from->si_uid;
626 }
627 else if (to->si_code < 0)
628 {
629 to->cpt_si_pid = from->si_pid;
630 to->cpt_si_uid = from->si_uid;
631 to->cpt_si_ptr = (intptr_t) from->si_ptr;
632 }
633 else
634 {
635 switch (to->si_signo)
636 {
637 case SIGCHLD:
638 to->cpt_si_pid = from->si_pid;
639 to->cpt_si_uid = from->si_uid;
640 to->cpt_si_status = from->si_status;
641 memcpy (&to->cpt_si_utime, &from->si_utime,
642 sizeof (to->cpt_si_utime));
643 memcpy (&to->cpt_si_stime, &from->si_stime,
644 sizeof (to->cpt_si_stime));
645 break;
646 case SIGILL:
647 case SIGFPE:
648 case SIGSEGV:
649 case SIGBUS:
650 to->cpt_si_addr = (intptr_t) from->si_addr;
651 break;
652 case SIGPOLL:
653 to->cpt_si_band = from->si_band;
654 to->cpt_si_fd = from->si_fd;
655 break;
656 default:
657 to->cpt_si_pid = from->si_pid;
658 to->cpt_si_uid = from->si_uid;
659 to->cpt_si_ptr = (intptr_t) from->si_ptr;
660 break;
661 }
662 }
663}
664
665static void
666siginfo_from_compat_x32_siginfo (siginfo_t *to,
667 compat_x32_siginfo_t *from)
668{
669 memset (to, 0, sizeof (*to));
670
671 to->si_signo = from->si_signo;
672 to->si_errno = from->si_errno;
673 to->si_code = from->si_code;
674
675 if (to->si_code == SI_TIMER)
676 {
677 to->si_timerid = from->cpt_si_timerid;
678 to->si_overrun = from->cpt_si_overrun;
679 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
680 }
681 else if (to->si_code == SI_USER)
682 {
683 to->si_pid = from->cpt_si_pid;
684 to->si_uid = from->cpt_si_uid;
685 }
686 if (to->si_code < 0)
687 {
688 to->si_pid = from->cpt_si_pid;
689 to->si_uid = from->cpt_si_uid;
690 to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
691 }
692 else
693 {
694 switch (to->si_signo)
695 {
696 case SIGCHLD:
697 to->si_pid = from->cpt_si_pid;
698 to->si_uid = from->cpt_si_uid;
699 to->si_status = from->cpt_si_status;
700 memcpy (&to->si_utime, &from->cpt_si_utime,
701 sizeof (to->si_utime));
702 memcpy (&to->si_stime, &from->cpt_si_stime,
703 sizeof (to->si_stime));
704 break;
705 case SIGILL:
706 case SIGFPE:
707 case SIGSEGV:
708 case SIGBUS:
709 to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
710 break;
711 case SIGPOLL:
712 to->si_band = from->cpt_si_band;
713 to->si_fd = from->cpt_si_fd;
714 break;
715 default:
716 to->si_pid = from->cpt_si_pid;
717 to->si_uid = from->cpt_si_uid;
718 to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
719 break;
720 }
721 }
722}
723
5b009018
PA
724/* Convert a native/host siginfo object, into/from the siginfo in the
725 layout of the inferiors' architecture. Returns true if any
726 conversion was done; false otherwise. If DIRECTION is 1, then copy
727 from INF to NATIVE. If DIRECTION is 0, copy from NATIVE to
728 INF. */
729
730static int
a5362b9a 731amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
5b009018 732{
ba224c70
L
733 struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
734
5b009018
PA
735 /* Is the inferior 32-bit? If so, then do fixup the siginfo
736 object. */
ba224c70 737 if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
5b009018 738 {
a5362b9a 739 gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t));
5b009018
PA
740
741 if (direction == 0)
742 compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
743 else
744 siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
745
ba224c70
L
746 return 1;
747 }
748 /* No fixup for native x32 GDB. */
749 else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
750 {
751 gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t));
752
753 if (direction == 0)
754 compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
755 native);
756 else
757 siginfo_from_compat_x32_siginfo (native,
758 (struct compat_x32_siginfo *) inf);
759
5b009018
PA
760 return 1;
761 }
762 else
763 return 0;
764}
040baaf6 765\f
c1e246a0
GB
766
767/* Provide a prototype to silence -Wmissing-prototypes. */
768void _initialize_amd64_linux_nat (void);
769
770void
771_initialize_amd64_linux_nat (void)
772{
773 struct target_ops *t;
774
775 amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
776 amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
777 amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
778 amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
779
780 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
781 == amd64_native_gregset32_num_regs);
782
783 /* Create a generic x86 GNU/Linux target. */
784 t = x86_linux_create_target ();
785
786 /* Add our register access methods. */
787 t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
788 t->to_store_registers = amd64_linux_store_inferior_registers;
789
790 /* Add the target. */
791 x86_linux_add_target (t);
792
793 /* Add our siginfo layout converter. */
794 linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
795}
This page took 0.927729 seconds and 4 git commands to generate.