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