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