1 /* Native-dependent code for GNU/Linux x86-64.
3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Jiri Smid, SuSE Labs.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include "linux-nat.h"
28 #include "amd64-linux-tdep.h"
30 #include "gdb_assert.h"
31 #include "gdb_string.h"
32 #include "elf/common.h"
34 #include <sys/ptrace.h>
35 #include <sys/debugreg.h>
36 #include <sys/syscall.h>
37 #include <sys/procfs.h>
38 #include <asm/prctl.h>
39 /* FIXME ezannoni-2003-07-09: we need <sys/reg.h> to be included after
40 <asm/ptrace.h> because the latter redefines FS and GS for no apparent
41 reason, and those definitions don't match the ones that libpthread_db
42 uses, which come from <sys/reg.h>. */
43 /* ezannoni-2003-07-09: I think this is fixed. The extraneous defs have
44 been removed from ptrace.h in the kernel. However, better safe than
46 #include <asm/ptrace.h>
48 #include "gdb_proc_service.h"
50 /* Prototypes for supply_gregset etc. */
53 #include "amd64-tdep.h"
54 #include "i386-linux-tdep.h"
55 #include "amd64-nat.h"
57 #include "i386-xstate.h"
59 #ifndef PTRACE_GETREGSET
60 #define PTRACE_GETREGSET 0x4204
63 #ifndef PTRACE_SETREGSET
64 #define PTRACE_SETREGSET 0x4205
67 /* Does the current host support PTRACE_GETREGSET? */
68 static int have_ptrace_getregset
= -1;
70 /* Mapping between the general-purpose registers in GNU/Linux x86-64
71 `struct user' format and GDB's register cache layout. */
73 static int amd64_linux_gregset64_reg_offset
[] =
75 RAX
* 8, RBX
* 8, /* %rax, %rbx */
76 RCX
* 8, RDX
* 8, /* %rcx, %rdx */
77 RSI
* 8, RDI
* 8, /* %rsi, %rdi */
78 RBP
* 8, RSP
* 8, /* %rbp, %rsp */
79 R8
* 8, R9
* 8, /* %r8 ... */
82 R14
* 8, R15
* 8, /* ... %r15 */
83 RIP
* 8, EFLAGS
* 8, /* %rip, %eflags */
84 CS
* 8, SS
* 8, /* %cs, %ss */
85 DS
* 8, ES
* 8, /* %ds, %es */
86 FS
* 8, GS
* 8, /* %fs, %gs */
87 -1, -1, -1, -1, -1, -1, -1, -1,
88 -1, -1, -1, -1, -1, -1, -1, -1,
89 -1, -1, -1, -1, -1, -1, -1, -1,
90 -1, -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1,
92 -1, -1, -1, -1, -1, -1, -1, -1,
97 /* Mapping between the general-purpose registers in GNU/Linux x86-64
98 `struct user' format and GDB's register cache layout for GNU/Linux
101 Note that most GNU/Linux x86-64 registers are 64-bit, while the
102 GNU/Linux i386 registers are all 32-bit, but since we're
103 little-endian we get away with that. */
105 /* From <sys/reg.h> on GNU/Linux i386. */
106 static int amd64_linux_gregset32_reg_offset
[] =
108 RAX
* 8, RCX
* 8, /* %eax, %ecx */
109 RDX
* 8, RBX
* 8, /* %edx, %ebx */
110 RSP
* 8, RBP
* 8, /* %esp, %ebp */
111 RSI
* 8, RDI
* 8, /* %esi, %edi */
112 RIP
* 8, EFLAGS
* 8, /* %eip, %eflags */
113 CS
* 8, SS
* 8, /* %cs, %ss */
114 DS
* 8, ES
* 8, /* %ds, %es */
115 FS
* 8, GS
* 8, /* %fs, %gs */
116 -1, -1, -1, -1, -1, -1, -1, -1,
117 -1, -1, -1, -1, -1, -1, -1, -1,
118 -1, -1, -1, -1, -1, -1, -1, -1, -1,
119 -1, -1, -1, -1, -1, -1, -1, -1,
120 ORIG_RAX
* 8 /* "orig_eax" */
124 /* Transfering the general-purpose registers between GDB, inferiors
127 /* Fill GDB's register cache with the general-purpose register values
131 supply_gregset (struct regcache
*regcache
, const elf_gregset_t
*gregsetp
)
133 amd64_supply_native_gregset (regcache
, gregsetp
, -1);
136 /* Fill register REGNUM (if it is a general-purpose register) in
137 *GREGSETP with the value in GDB's register cache. If REGNUM is -1,
138 do this for all registers. */
141 fill_gregset (const struct regcache
*regcache
,
142 elf_gregset_t
*gregsetp
, int regnum
)
144 amd64_collect_native_gregset (regcache
, gregsetp
, regnum
);
147 /* Transfering floating-point registers between GDB, inferiors and cores. */
149 /* Fill GDB's register cache with the floating-point and SSE register
150 values in *FPREGSETP. */
153 supply_fpregset (struct regcache
*regcache
, const elf_fpregset_t
*fpregsetp
)
155 amd64_supply_fxsave (regcache
, -1, fpregsetp
);
158 /* Fill register REGNUM (if it is a floating-point or SSE register) in
159 *FPREGSETP with the value in GDB's register cache. If REGNUM is
160 -1, do this for all registers. */
163 fill_fpregset (const struct regcache
*regcache
,
164 elf_fpregset_t
*fpregsetp
, int regnum
)
166 amd64_collect_fxsave (regcache
, regnum
, fpregsetp
);
170 /* Transferring arbitrary registers between GDB and inferior. */
172 /* Fetch register REGNUM from the child process. If REGNUM is -1, do
173 this for all registers (including the floating point and SSE
177 amd64_linux_fetch_inferior_registers (struct target_ops
*ops
,
178 struct regcache
*regcache
, int regnum
)
180 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
183 /* GNU/Linux LWP ID's are process ID's. */
184 tid
= TIDGET (inferior_ptid
);
186 tid
= PIDGET (inferior_ptid
); /* Not a threaded program. */
188 if (regnum
== -1 || amd64_native_gregset_supplies_p (gdbarch
, regnum
))
192 if (ptrace (PTRACE_GETREGS
, tid
, 0, (long) ®s
) < 0)
193 perror_with_name (_("Couldn't get registers"));
195 amd64_supply_native_gregset (regcache
, ®s
, -1);
200 if (regnum
== -1 || !amd64_native_gregset_supplies_p (gdbarch
, regnum
))
202 elf_fpregset_t fpregs
;
204 if (have_ptrace_getregset
)
206 char xstateregs
[I386_XSTATE_MAX_SIZE
];
209 iov
.iov_base
= xstateregs
;
210 iov
.iov_len
= sizeof (xstateregs
);
211 if (ptrace (PTRACE_GETREGSET
, tid
,
212 (unsigned int) NT_X86_XSTATE
, (long) &iov
) < 0)
213 perror_with_name (_("Couldn't get extended state status"));
215 amd64_supply_xsave (regcache
, -1, xstateregs
);
219 if (ptrace (PTRACE_GETFPREGS
, tid
, 0, (long) &fpregs
) < 0)
220 perror_with_name (_("Couldn't get floating point status"));
222 amd64_supply_fxsave (regcache
, -1, &fpregs
);
227 /* Store register REGNUM back into the child process. If REGNUM is
228 -1, do this for all registers (including the floating-point and SSE
232 amd64_linux_store_inferior_registers (struct target_ops
*ops
,
233 struct regcache
*regcache
, int regnum
)
235 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
238 /* GNU/Linux LWP ID's are process ID's. */
239 tid
= TIDGET (inferior_ptid
);
241 tid
= PIDGET (inferior_ptid
); /* Not a threaded program. */
243 if (regnum
== -1 || amd64_native_gregset_supplies_p (gdbarch
, regnum
))
247 if (ptrace (PTRACE_GETREGS
, tid
, 0, (long) ®s
) < 0)
248 perror_with_name (_("Couldn't get registers"));
250 amd64_collect_native_gregset (regcache
, ®s
, regnum
);
252 if (ptrace (PTRACE_SETREGS
, tid
, 0, (long) ®s
) < 0)
253 perror_with_name (_("Couldn't write registers"));
259 if (regnum
== -1 || !amd64_native_gregset_supplies_p (gdbarch
, regnum
))
261 elf_fpregset_t fpregs
;
263 if (have_ptrace_getregset
)
265 char xstateregs
[I386_XSTATE_MAX_SIZE
];
268 iov
.iov_base
= xstateregs
;
269 iov
.iov_len
= sizeof (xstateregs
);
270 if (ptrace (PTRACE_GETREGSET
, tid
,
271 (unsigned int) NT_X86_XSTATE
, (long) &iov
) < 0)
272 perror_with_name (_("Couldn't get extended state status"));
274 amd64_collect_xsave (regcache
, regnum
, xstateregs
, 0);
276 if (ptrace (PTRACE_SETREGSET
, tid
,
277 (unsigned int) NT_X86_XSTATE
, (long) &iov
) < 0)
278 perror_with_name (_("Couldn't write extended state status"));
282 if (ptrace (PTRACE_GETFPREGS
, tid
, 0, (long) &fpregs
) < 0)
283 perror_with_name (_("Couldn't get floating point status"));
285 amd64_collect_fxsave (regcache
, regnum
, &fpregs
);
287 if (ptrace (PTRACE_SETFPREGS
, tid
, 0, (long) &fpregs
) < 0)
288 perror_with_name (_("Couldn't write floating point status"));
293 /* Support for debug registers. */
295 static unsigned long amd64_linux_dr
[DR_CONTROL
+ 1];
298 amd64_linux_dr_get (ptid_t ptid
, int regnum
)
307 /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
308 ptrace call fails breaks debugging remote targets. The correct
309 way to fix this is to add the hardware breakpoint and watchpoint
310 stuff to the target vector. For now, just return zero if the
311 ptrace call fails. */
313 value
= ptrace (PTRACE_PEEKUSER
, tid
,
314 offsetof (struct user
, u_debugreg
[regnum
]), 0);
317 perror_with_name (_("Couldn't read debug register"));
325 /* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
328 amd64_linux_dr_set (ptid_t ptid
, int regnum
, unsigned long value
)
337 ptrace (PTRACE_POKEUSER
, tid
,
338 offsetof (struct user
, u_debugreg
[regnum
]), value
);
340 perror_with_name (_("Couldn't write debug register"));
343 /* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */
346 amd64_linux_dr_set_control (unsigned long control
)
351 amd64_linux_dr
[DR_CONTROL
] = control
;
353 amd64_linux_dr_set (ptid
, DR_CONTROL
, control
);
356 /* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */
359 amd64_linux_dr_set_addr (int regnum
, CORE_ADDR addr
)
364 gdb_assert (regnum
>= 0 && regnum
<= DR_LASTADDR
- DR_FIRSTADDR
);
366 amd64_linux_dr
[DR_FIRSTADDR
+ regnum
] = addr
;
368 amd64_linux_dr_set (ptid
, DR_FIRSTADDR
+ regnum
, addr
);
371 /* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */
374 amd64_linux_dr_reset_addr (int regnum
)
376 amd64_linux_dr_set_addr (regnum
, 0);
379 /* Get DR_STATUS from only the one LWP of INFERIOR_PTID. */
382 amd64_linux_dr_get_status (void)
384 return amd64_linux_dr_get (inferior_ptid
, DR_STATUS
);
387 /* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */
390 amd64_linux_dr_unset_status (unsigned long mask
)
399 value
= amd64_linux_dr_get (ptid
, DR_STATUS
);
401 amd64_linux_dr_set (ptid
, DR_STATUS
, value
);
407 amd64_linux_new_thread (ptid_t ptid
)
411 for (i
= DR_FIRSTADDR
; i
<= DR_LASTADDR
; i
++)
412 amd64_linux_dr_set (ptid
, i
, amd64_linux_dr
[i
]);
414 amd64_linux_dr_set (ptid
, DR_CONTROL
, amd64_linux_dr
[DR_CONTROL
]);
418 /* This function is called by libthread_db as part of its handling of
419 a request for a thread's local storage address. */
422 ps_get_thread_area (const struct ps_prochandle
*ph
,
423 lwpid_t lwpid
, int idx
, void **base
)
425 if (gdbarch_ptr_bit (target_gdbarch
) == 32)
427 /* The full structure is found in <asm-i386/ldt.h>. The second
428 integer is the LDT's base_address and that is used to locate
429 the thread's local storage. See i386-linux-nat.c more
431 unsigned int desc
[4];
433 /* This code assumes that "int" is 32 bits and that
434 GET_THREAD_AREA returns no more than 4 int values. */
435 gdb_assert (sizeof (int) == 4);
436 #ifndef PTRACE_GET_THREAD_AREA
437 #define PTRACE_GET_THREAD_AREA 25
439 if (ptrace (PTRACE_GET_THREAD_AREA
,
440 lwpid
, (void *) (long) idx
, (unsigned long) &desc
) < 0)
443 /* Extend the value to 64 bits. Here it's assumed that a "long"
444 and a "void *" are the same. */
445 (*base
) = (void *) (long) desc
[1];
450 /* This definition comes from prctl.h, but some kernels may not
452 #ifndef PTRACE_ARCH_PRCTL
453 #define PTRACE_ARCH_PRCTL 30
455 /* FIXME: ezannoni-2003-07-09 see comment above about include
456 file order. We could be getting bogus values for these two. */
457 gdb_assert (FS
< ELF_NGREG
);
458 gdb_assert (GS
< ELF_NGREG
);
462 if (ptrace (PTRACE_ARCH_PRCTL
, lwpid
, base
, ARCH_GET_FS
) == 0)
466 if (ptrace (PTRACE_ARCH_PRCTL
, lwpid
, base
, ARCH_GET_GS
) == 0)
469 default: /* Should not happen. */
473 return PS_ERR
; /* ptrace failed. */
477 static void (*super_post_startup_inferior
) (ptid_t ptid
);
480 amd64_linux_child_post_startup_inferior (ptid_t ptid
)
482 i386_cleanup_dregs ();
483 super_post_startup_inferior (ptid
);
487 /* When GDB is built as a 64-bit application on linux, the
488 PTRACE_GETSIGINFO data is always presented in 64-bit layout. Since
489 debugging a 32-bit inferior with a 64-bit GDB should look the same
490 as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
491 conversion in-place ourselves. */
493 /* These types below (compat_*) define a siginfo type that is layout
494 compatible with the siginfo type exported by the 32-bit userspace
497 typedef int compat_int_t
;
498 typedef unsigned int compat_uptr_t
;
500 typedef int compat_time_t
;
501 typedef int compat_timer_t
;
502 typedef int compat_clock_t
;
504 struct compat_timeval
506 compat_time_t tv_sec
;
510 typedef union compat_sigval
512 compat_int_t sival_int
;
513 compat_uptr_t sival_ptr
;
516 typedef struct compat_siginfo
524 int _pad
[((128 / sizeof (int)) - 3)];
533 /* POSIX.1b timers */
538 compat_sigval_t _sigval
;
541 /* POSIX.1b signals */
546 compat_sigval_t _sigval
;
555 compat_clock_t _utime
;
556 compat_clock_t _stime
;
559 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
574 #define cpt_si_pid _sifields._kill._pid
575 #define cpt_si_uid _sifields._kill._uid
576 #define cpt_si_timerid _sifields._timer._tid
577 #define cpt_si_overrun _sifields._timer._overrun
578 #define cpt_si_status _sifields._sigchld._status
579 #define cpt_si_utime _sifields._sigchld._utime
580 #define cpt_si_stime _sifields._sigchld._stime
581 #define cpt_si_ptr _sifields._rt._sigval.sival_ptr
582 #define cpt_si_addr _sifields._sigfault._addr
583 #define cpt_si_band _sifields._sigpoll._band
584 #define cpt_si_fd _sifields._sigpoll._fd
586 /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
587 In their place is si_timer1,si_timer2. */
589 #define si_timerid si_timer1
592 #define si_overrun si_timer2
596 compat_siginfo_from_siginfo (compat_siginfo_t
*to
, siginfo_t
*from
)
598 memset (to
, 0, sizeof (*to
));
600 to
->si_signo
= from
->si_signo
;
601 to
->si_errno
= from
->si_errno
;
602 to
->si_code
= from
->si_code
;
606 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
608 else if (to
->si_code
== SI_USER
)
610 to
->cpt_si_pid
= from
->si_pid
;
611 to
->cpt_si_uid
= from
->si_uid
;
613 else if (to
->si_code
== SI_TIMER
)
615 to
->cpt_si_timerid
= from
->si_timerid
;
616 to
->cpt_si_overrun
= from
->si_overrun
;
617 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
621 switch (to
->si_signo
)
624 to
->cpt_si_pid
= from
->si_pid
;
625 to
->cpt_si_uid
= from
->si_uid
;
626 to
->cpt_si_status
= from
->si_status
;
627 to
->cpt_si_utime
= from
->si_utime
;
628 to
->cpt_si_stime
= from
->si_stime
;
634 to
->cpt_si_addr
= (intptr_t) from
->si_addr
;
637 to
->cpt_si_band
= from
->si_band
;
638 to
->cpt_si_fd
= from
->si_fd
;
641 to
->cpt_si_pid
= from
->si_pid
;
642 to
->cpt_si_uid
= from
->si_uid
;
643 to
->cpt_si_ptr
= (intptr_t) from
->si_ptr
;
650 siginfo_from_compat_siginfo (siginfo_t
*to
, compat_siginfo_t
*from
)
652 memset (to
, 0, sizeof (*to
));
654 to
->si_signo
= from
->si_signo
;
655 to
->si_errno
= from
->si_errno
;
656 to
->si_code
= from
->si_code
;
660 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
662 else if (to
->si_code
== SI_USER
)
664 to
->si_pid
= from
->cpt_si_pid
;
665 to
->si_uid
= from
->cpt_si_uid
;
667 else if (to
->si_code
== SI_TIMER
)
669 to
->si_timerid
= from
->cpt_si_timerid
;
670 to
->si_overrun
= from
->cpt_si_overrun
;
671 to
->si_ptr
= (void *) (intptr_t) from
->cpt_si_ptr
;
675 switch (to
->si_signo
)
678 to
->si_pid
= from
->cpt_si_pid
;
679 to
->si_uid
= from
->cpt_si_uid
;
680 to
->si_status
= from
->cpt_si_status
;
681 to
->si_utime
= from
->cpt_si_utime
;
682 to
->si_stime
= from
->cpt_si_stime
;
688 to
->si_addr
= (void *) (intptr_t) from
->cpt_si_addr
;
691 to
->si_band
= from
->cpt_si_band
;
692 to
->si_fd
= from
->cpt_si_fd
;
695 to
->si_pid
= from
->cpt_si_pid
;
696 to
->si_uid
= from
->cpt_si_uid
;
697 to
->si_ptr
= (void* ) (intptr_t) from
->cpt_si_ptr
;
703 /* Convert a native/host siginfo object, into/from the siginfo in the
704 layout of the inferiors' architecture. Returns true if any
705 conversion was done; false otherwise. If DIRECTION is 1, then copy
706 from INF to NATIVE. If DIRECTION is 0, copy from NATIVE to
710 amd64_linux_siginfo_fixup (struct siginfo
*native
, gdb_byte
*inf
, int direction
)
712 /* Is the inferior 32-bit? If so, then do fixup the siginfo
714 if (gdbarch_addr_bit (get_frame_arch (get_current_frame ())) == 32)
716 gdb_assert (sizeof (struct siginfo
) == sizeof (compat_siginfo_t
));
719 compat_siginfo_from_siginfo ((struct compat_siginfo
*) inf
, native
);
721 siginfo_from_compat_siginfo (native
, (struct compat_siginfo
*) inf
);
729 /* Get Linux/x86 target description from running target.
731 Value of CS segment register:
732 1. 64bit process: 0x33.
733 2. 32bit process: 0x23.
736 #define AMD64_LINUX_USER64_CS 0x33
738 static const struct target_desc
*
739 amd64_linux_read_description (struct target_ops
*ops
)
744 static uint64_t xcr0
;
746 /* GNU/Linux LWP ID's are process ID's. */
747 tid
= TIDGET (inferior_ptid
);
749 tid
= PIDGET (inferior_ptid
); /* Not a threaded program. */
751 /* Get CS register. */
753 cs
= ptrace (PTRACE_PEEKUSER
, tid
,
754 offsetof (struct user_regs_struct
, cs
), 0);
756 perror_with_name (_("Couldn't get CS register"));
758 is_64bit
= cs
== AMD64_LINUX_USER64_CS
;
760 if (have_ptrace_getregset
== -1)
762 uint64_t xstateregs
[(I386_XSTATE_SSE_SIZE
/ sizeof (uint64_t))];
765 iov
.iov_base
= xstateregs
;
766 iov
.iov_len
= sizeof (xstateregs
);
768 /* Check if PTRACE_GETREGSET works. */
769 if (ptrace (PTRACE_GETREGSET
, tid
,
770 (unsigned int) NT_X86_XSTATE
, (long) &iov
) < 0)
771 have_ptrace_getregset
= 0;
774 have_ptrace_getregset
= 1;
776 /* Get XCR0 from XSAVE extended state. */
777 xcr0
= xstateregs
[(I386_LINUX_XSAVE_XCR0_OFFSET
778 / sizeof (uint64_t))];
782 /* Check the native XCR0 only if PTRACE_GETREGSET is available. */
783 if (have_ptrace_getregset
784 && (xcr0
& I386_XSTATE_AVX_MASK
) == I386_XSTATE_AVX_MASK
)
787 return tdesc_amd64_avx_linux
;
789 return tdesc_i386_avx_linux
;
794 return tdesc_amd64_linux
;
796 return tdesc_i386_linux
;
800 /* Provide a prototype to silence -Wmissing-prototypes. */
801 void _initialize_amd64_linux_nat (void);
804 _initialize_amd64_linux_nat (void)
806 struct target_ops
*t
;
808 amd64_native_gregset32_reg_offset
= amd64_linux_gregset32_reg_offset
;
809 amd64_native_gregset32_num_regs
= I386_LINUX_NUM_REGS
;
810 amd64_native_gregset64_reg_offset
= amd64_linux_gregset64_reg_offset
;
811 amd64_native_gregset64_num_regs
= AMD64_LINUX_NUM_REGS
;
813 gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset
)
814 == amd64_native_gregset32_num_regs
);
815 gdb_assert (ARRAY_SIZE (amd64_linux_gregset64_reg_offset
)
816 == amd64_native_gregset64_num_regs
);
818 /* Fill in the generic GNU/Linux methods. */
821 i386_use_watchpoints (t
);
823 i386_dr_low
.set_control
= amd64_linux_dr_set_control
;
824 i386_dr_low
.set_addr
= amd64_linux_dr_set_addr
;
825 i386_dr_low
.reset_addr
= amd64_linux_dr_reset_addr
;
826 i386_dr_low
.get_status
= amd64_linux_dr_get_status
;
827 i386_dr_low
.unset_status
= amd64_linux_dr_unset_status
;
828 i386_set_debug_register_length (8);
830 /* Override the GNU/Linux inferior startup hook. */
831 super_post_startup_inferior
= t
->to_post_startup_inferior
;
832 t
->to_post_startup_inferior
= amd64_linux_child_post_startup_inferior
;
834 /* Add our register access methods. */
835 t
->to_fetch_registers
= amd64_linux_fetch_inferior_registers
;
836 t
->to_store_registers
= amd64_linux_store_inferior_registers
;
838 t
->to_read_description
= amd64_linux_read_description
;
840 /* Register the target. */
841 linux_nat_add_target (t
);
842 linux_nat_set_new_thread (t
, amd64_linux_new_thread
);
843 linux_nat_set_siginfo_fixup (t
, amd64_linux_siginfo_fixup
);