* objfiles.h (gdb_bfd_close_or_warn): Declare.
[platform/upstream/binutils.git] / gdb / amd64-linux-nat.c
1 /* Native-dependent code for GNU/Linux x86-64.
2
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.
6
7    This file is part of GDB.
8
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.
13
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.
18
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/>.  */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "gdbcore.h"
25 #include "regcache.h"
26 #include "regset.h"
27 #include "linux-nat.h"
28 #include "amd64-linux-tdep.h"
29
30 #include "gdb_assert.h"
31 #include "gdb_string.h"
32 #include "elf/common.h"
33 #include <sys/uio.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
45    sorry.  */
46 #include <asm/ptrace.h>
47 #include <sys/reg.h>
48 #include "gdb_proc_service.h"
49
50 /* Prototypes for supply_gregset etc.  */
51 #include "gregset.h"
52
53 #include "amd64-tdep.h"
54 #include "i386-linux-tdep.h"
55 #include "amd64-nat.h"
56 #include "i386-nat.h"
57 #include "i386-xstate.h"
58
59 #ifndef PTRACE_GETREGSET
60 #define PTRACE_GETREGSET        0x4204
61 #endif
62
63 #ifndef PTRACE_SETREGSET
64 #define PTRACE_SETREGSET        0x4205
65 #endif
66
67 /* Does the current host support PTRACE_GETREGSET?  */
68 static int have_ptrace_getregset = -1;
69
70 /* Mapping between the general-purpose registers in GNU/Linux x86-64
71    `struct user' format and GDB's register cache layout.  */
72
73 static int amd64_linux_gregset64_reg_offset[] =
74 {
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 ... */
80   R10 * 8, R11 * 8,
81   R12 * 8, R13 * 8,
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,
93   ORIG_RAX * 8
94 };
95 \f
96
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
99    i386.
100
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.  */
104
105 /* From <sys/reg.h> on GNU/Linux i386.  */
106 static int amd64_linux_gregset32_reg_offset[] =
107 {
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" */
121 };
122 \f
123
124 /* Transfering the general-purpose registers between GDB, inferiors
125    and core files.  */
126
127 /* Fill GDB's register cache with the general-purpose register values
128    in *GREGSETP.  */
129
130 void
131 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
132 {
133   amd64_supply_native_gregset (regcache, gregsetp, -1);
134 }
135
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.  */
139
140 void
141 fill_gregset (const struct regcache *regcache,
142               elf_gregset_t *gregsetp, int regnum)
143 {
144   amd64_collect_native_gregset (regcache, gregsetp, regnum);
145 }
146
147 /* Transfering floating-point registers between GDB, inferiors and cores.  */
148
149 /* Fill GDB's register cache with the floating-point and SSE register
150    values in *FPREGSETP.  */
151
152 void
153 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
154 {
155   amd64_supply_fxsave (regcache, -1, fpregsetp);
156 }
157
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.  */
161
162 void
163 fill_fpregset (const struct regcache *regcache,
164                elf_fpregset_t *fpregsetp, int regnum)
165 {
166   amd64_collect_fxsave (regcache, regnum, fpregsetp);
167 }
168 \f
169
170 /* Transferring arbitrary registers between GDB and inferior.  */
171
172 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
173    this for all registers (including the floating point and SSE
174    registers).  */
175
176 static void
177 amd64_linux_fetch_inferior_registers (struct target_ops *ops,
178                                       struct regcache *regcache, int regnum)
179 {
180   struct gdbarch *gdbarch = get_regcache_arch (regcache);
181   int tid;
182
183   /* GNU/Linux LWP ID's are process ID's.  */
184   tid = TIDGET (inferior_ptid);
185   if (tid == 0)
186     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
187
188   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
189     {
190       elf_gregset_t regs;
191
192       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
193         perror_with_name (_("Couldn't get registers"));
194
195       amd64_supply_native_gregset (regcache, &regs, -1);
196       if (regnum != -1)
197         return;
198     }
199
200   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
201     {
202       elf_fpregset_t fpregs;
203
204       if (have_ptrace_getregset)
205         {
206           char xstateregs[I386_XSTATE_MAX_SIZE];
207           struct iovec iov;
208
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"));
214
215           amd64_supply_xsave (regcache, -1, xstateregs);
216         }
217       else
218         {
219           if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
220             perror_with_name (_("Couldn't get floating point status"));
221
222           amd64_supply_fxsave (regcache, -1, &fpregs);
223         }
224     }
225 }
226
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
229    registers).  */
230
231 static void
232 amd64_linux_store_inferior_registers (struct target_ops *ops,
233                                       struct regcache *regcache, int regnum)
234 {
235   struct gdbarch *gdbarch = get_regcache_arch (regcache);
236   int tid;
237
238   /* GNU/Linux LWP ID's are process ID's.  */
239   tid = TIDGET (inferior_ptid);
240   if (tid == 0)
241     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
242
243   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
244     {
245       elf_gregset_t regs;
246
247       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
248         perror_with_name (_("Couldn't get registers"));
249
250       amd64_collect_native_gregset (regcache, &regs, regnum);
251
252       if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
253         perror_with_name (_("Couldn't write registers"));
254
255       if (regnum != -1)
256         return;
257     }
258
259   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
260     {
261       elf_fpregset_t fpregs;
262
263       if (have_ptrace_getregset)
264         {
265           char xstateregs[I386_XSTATE_MAX_SIZE];
266           struct iovec iov;
267
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"));
273
274           amd64_collect_xsave (regcache, regnum, xstateregs, 0);
275
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"));
279         }
280       else
281         {
282           if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
283             perror_with_name (_("Couldn't get floating point status"));
284
285           amd64_collect_fxsave (regcache, regnum, &fpregs);
286
287           if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
288             perror_with_name (_("Couldn't write floating point status"));
289         }
290     }
291 }
292 \f
293 /* Support for debug registers.  */
294
295 static unsigned long amd64_linux_dr[DR_CONTROL + 1];
296
297 static unsigned long
298 amd64_linux_dr_get (ptid_t ptid, int regnum)
299 {
300   int tid;
301   unsigned long value;
302
303   tid = TIDGET (ptid);
304   if (tid == 0)
305     tid = PIDGET (ptid);
306
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.  */
312   errno = 0;
313   value = ptrace (PTRACE_PEEKUSER, tid,
314                   offsetof (struct user, u_debugreg[regnum]), 0);
315   if (errno != 0)
316 #if 0
317     perror_with_name (_("Couldn't read debug register"));
318 #else
319     return 0;
320 #endif
321
322   return value;
323 }
324
325 /* Set debug register REGNUM to VALUE in only the one LWP of PTID.  */
326
327 static void
328 amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
329 {
330   int tid;
331
332   tid = TIDGET (ptid);
333   if (tid == 0)
334     tid = PIDGET (ptid);
335
336   errno = 0;
337   ptrace (PTRACE_POKEUSER, tid,
338           offsetof (struct user, u_debugreg[regnum]), value);
339   if (errno != 0)
340     perror_with_name (_("Couldn't write debug register"));
341 }
342
343 /* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST.  */
344
345 static void
346 amd64_linux_dr_set_control (unsigned long control)
347 {
348   struct lwp_info *lp;
349   ptid_t ptid;
350
351   amd64_linux_dr[DR_CONTROL] = control;
352   ALL_LWPS (lp, ptid)
353     amd64_linux_dr_set (ptid, DR_CONTROL, control);
354 }
355
356 /* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST.  */
357
358 static void
359 amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
360 {
361   struct lwp_info *lp;
362   ptid_t ptid;
363
364   gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
365
366   amd64_linux_dr[DR_FIRSTADDR + regnum] = addr;
367   ALL_LWPS (lp, ptid)
368     amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
369 }
370
371 /* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST.  */
372
373 static void
374 amd64_linux_dr_reset_addr (int regnum)
375 {
376   amd64_linux_dr_set_addr (regnum, 0);
377 }
378
379 /* Get DR_STATUS from only the one LWP of INFERIOR_PTID.  */
380
381 static unsigned long
382 amd64_linux_dr_get_status (void)
383 {
384   return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
385 }
386
387 /* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST.  */
388
389 static void
390 amd64_linux_dr_unset_status (unsigned long mask)
391 {
392   struct lwp_info *lp;
393   ptid_t ptid;
394
395   ALL_LWPS (lp, ptid)
396     {
397       unsigned long value;
398       
399       value = amd64_linux_dr_get (ptid, DR_STATUS);
400       value &= ~mask;
401       amd64_linux_dr_set (ptid, DR_STATUS, value);
402     }
403 }
404
405
406 static void
407 amd64_linux_new_thread (ptid_t ptid)
408 {
409   int i;
410
411   for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
412     amd64_linux_dr_set (ptid, i, amd64_linux_dr[i]);
413
414   amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
415 }
416 \f
417
418 /* This function is called by libthread_db as part of its handling of
419    a request for a thread's local storage address.  */
420
421 ps_err_e
422 ps_get_thread_area (const struct ps_prochandle *ph,
423                     lwpid_t lwpid, int idx, void **base)
424 {
425   if (gdbarch_ptr_bit (target_gdbarch) == 32)
426     {
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
430          info.  */
431       unsigned int desc[4];
432
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
438 #endif
439       if  (ptrace (PTRACE_GET_THREAD_AREA, 
440                    lwpid, (void *) (long) idx, (unsigned long) &desc) < 0)
441         return PS_ERR;
442       
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];
446       return PS_OK;
447     }
448   else
449     {
450       /* This definition comes from prctl.h, but some kernels may not
451          have it.  */
452 #ifndef PTRACE_ARCH_PRCTL
453 #define PTRACE_ARCH_PRCTL      30
454 #endif
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);
459       switch (idx)
460         {
461         case FS:
462           if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
463             return PS_OK;
464           break;
465         case GS:
466           if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
467             return PS_OK;
468           break;
469         default:                   /* Should not happen.  */
470           return PS_BADADDR;
471         }
472     }
473   return PS_ERR;               /* ptrace failed.  */
474 }
475 \f
476
477 static void (*super_post_startup_inferior) (ptid_t ptid);
478
479 static void
480 amd64_linux_child_post_startup_inferior (ptid_t ptid)
481 {
482   i386_cleanup_dregs ();
483   super_post_startup_inferior (ptid);
484 }
485 \f
486
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.  */
492
493 /* These types below (compat_*) define a siginfo type that is layout
494    compatible with the siginfo type exported by the 32-bit userspace
495    support.  */
496
497 typedef int compat_int_t;
498 typedef unsigned int compat_uptr_t;
499
500 typedef int compat_time_t;
501 typedef int compat_timer_t;
502 typedef int compat_clock_t;
503
504 struct compat_timeval
505 {
506   compat_time_t tv_sec;
507   int tv_usec;
508 };
509
510 typedef union compat_sigval
511 {
512   compat_int_t sival_int;
513   compat_uptr_t sival_ptr;
514 } compat_sigval_t;
515
516 typedef struct compat_siginfo
517 {
518   int si_signo;
519   int si_errno;
520   int si_code;
521
522   union
523   {
524     int _pad[((128 / sizeof (int)) - 3)];
525
526     /* kill() */
527     struct
528     {
529       unsigned int _pid;
530       unsigned int _uid;
531     } _kill;
532
533     /* POSIX.1b timers */
534     struct
535     {
536       compat_timer_t _tid;
537       int _overrun;
538       compat_sigval_t _sigval;
539     } _timer;
540
541     /* POSIX.1b signals */
542     struct
543     {
544       unsigned int _pid;
545       unsigned int _uid;
546       compat_sigval_t _sigval;
547     } _rt;
548
549     /* SIGCHLD */
550     struct
551     {
552       unsigned int _pid;
553       unsigned int _uid;
554       int _status;
555       compat_clock_t _utime;
556       compat_clock_t _stime;
557     } _sigchld;
558
559     /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
560     struct
561     {
562       unsigned int _addr;
563     } _sigfault;
564
565     /* SIGPOLL */
566     struct
567     {
568       int _band;
569       int _fd;
570     } _sigpoll;
571   } _sifields;
572 } compat_siginfo_t;
573
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
585
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.  */
588 #ifndef si_timerid
589 #define si_timerid si_timer1
590 #endif
591 #ifndef si_overrun
592 #define si_overrun si_timer2
593 #endif
594
595 static void
596 compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
597 {
598   memset (to, 0, sizeof (*to));
599
600   to->si_signo = from->si_signo;
601   to->si_errno = from->si_errno;
602   to->si_code = from->si_code;
603
604   if (to->si_code < 0)
605     {
606       to->cpt_si_ptr = (intptr_t) from->si_ptr;
607     }
608   else if (to->si_code == SI_USER)
609     {
610       to->cpt_si_pid = from->si_pid;
611       to->cpt_si_uid = from->si_uid;
612     }
613   else if (to->si_code == SI_TIMER)
614     {
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;
618     }
619   else
620     {
621       switch (to->si_signo)
622         {
623         case SIGCHLD:
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;
629           break;
630         case SIGILL:
631         case SIGFPE:
632         case SIGSEGV:
633         case SIGBUS:
634           to->cpt_si_addr = (intptr_t) from->si_addr;
635           break;
636         case SIGPOLL:
637           to->cpt_si_band = from->si_band;
638           to->cpt_si_fd = from->si_fd;
639           break;
640         default:
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;
644           break;
645         }
646     }
647 }
648
649 static void
650 siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
651 {
652   memset (to, 0, sizeof (*to));
653
654   to->si_signo = from->si_signo;
655   to->si_errno = from->si_errno;
656   to->si_code = from->si_code;
657
658   if (to->si_code < 0)
659     {
660       to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
661     }
662   else if (to->si_code == SI_USER)
663     {
664       to->si_pid = from->cpt_si_pid;
665       to->si_uid = from->cpt_si_uid;
666     }
667   else if (to->si_code == SI_TIMER)
668     {
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;
672     }
673   else
674     {
675       switch (to->si_signo)
676         {
677         case SIGCHLD:
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;
683           break;
684         case SIGILL:
685         case SIGFPE:
686         case SIGSEGV:
687         case SIGBUS:
688           to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
689           break;
690         case SIGPOLL:
691           to->si_band = from->cpt_si_band;
692           to->si_fd = from->cpt_si_fd;
693           break;
694         default:
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;
698           break;
699         }
700     }
701 }
702
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
707    INF.  */
708
709 static int
710 amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction)
711 {
712   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
713      object.  */
714   if (gdbarch_addr_bit (get_frame_arch (get_current_frame ())) == 32)
715     {
716       gdb_assert (sizeof (struct siginfo) == sizeof (compat_siginfo_t));
717
718       if (direction == 0)
719         compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
720       else
721         siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
722
723       return 1;
724     }
725   else
726     return 0;
727 }
728
729 /* Get Linux/x86 target description from running target.
730
731    Value of CS segment register:
732      1. 64bit process: 0x33.
733      2. 32bit process: 0x23.
734  */
735
736 #define AMD64_LINUX_USER64_CS   0x33
737
738 static const struct target_desc *
739 amd64_linux_read_description (struct target_ops *ops)
740 {
741   unsigned long cs;
742   int tid;
743   int is_64bit;
744   static uint64_t xcr0;
745
746   /* GNU/Linux LWP ID's are process ID's.  */
747   tid = TIDGET (inferior_ptid);
748   if (tid == 0)
749     tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
750
751   /* Get CS register.  */
752   errno = 0;
753   cs = ptrace (PTRACE_PEEKUSER, tid,
754                offsetof (struct user_regs_struct, cs), 0);
755   if (errno != 0)
756     perror_with_name (_("Couldn't get CS register"));
757
758   is_64bit = cs == AMD64_LINUX_USER64_CS;
759
760   if (have_ptrace_getregset == -1)
761     {
762       uint64_t xstateregs[(I386_XSTATE_SSE_SIZE / sizeof (uint64_t))];
763       struct iovec iov;
764
765       iov.iov_base = xstateregs;
766       iov.iov_len = sizeof (xstateregs);
767
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;
772       else
773         {
774           have_ptrace_getregset = 1;
775
776           /* Get XCR0 from XSAVE extended state.  */
777           xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
778                              / sizeof (uint64_t))];
779         }
780     }
781
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)
785     {
786       if (is_64bit)
787         return tdesc_amd64_avx_linux;
788       else
789         return tdesc_i386_avx_linux;
790     }
791   else
792     {
793       if (is_64bit)
794         return tdesc_amd64_linux;
795       else
796         return tdesc_i386_linux;
797     }
798 }
799
800 /* Provide a prototype to silence -Wmissing-prototypes.  */
801 void _initialize_amd64_linux_nat (void);
802
803 void
804 _initialize_amd64_linux_nat (void)
805 {
806   struct target_ops *t;
807
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;
812
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);
817
818   /* Fill in the generic GNU/Linux methods.  */
819   t = linux_target ();
820
821   i386_use_watchpoints (t);
822
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);
829
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;
833
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;
837
838   t->to_read_description = amd64_linux_read_description;
839
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);
844 }