xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/amd64-linux-nat.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /* Native-dependent code for GNU/Linux x86-64.
2 
3    Copyright (C) 2001-2015 Free Software Foundation, Inc.
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
10    the Free Software Foundation; either version 3 of the License, or
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
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #include "defs.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 #include "elf/common.h"
25 #include <sys/uio.h>
26 #include <sys/ptrace.h>
27 #include <asm/prctl.h>
28 #include <sys/reg.h>
29 #include "gregset.h"
30 #include "gdb_proc_service.h"
31 
32 #include "amd64-nat.h"
33 #include "linux-nat.h"
34 #include "amd64-tdep.h"
35 #include "amd64-linux-tdep.h"
36 #include "i386-linux-tdep.h"
37 #include "x86-xstate.h"
38 
39 #include "x86-linux-nat.h"
40 #include "nat/linux-ptrace.h"
41 
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.  */
51 static int amd64_linux_gregset32_reg_offset[] =
52 {
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 */
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,
64   -1, -1, -1, -1, -1, -1, -1, -1,
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"  */
70 };
71 
72 
73 /* Transfering the general-purpose registers between GDB, inferiors
74    and core files.  */
75 
76 /* Fill GDB's register cache with the general-purpose register values
77    in *GREGSETP.  */
78 
79 void
80 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
81 {
82   amd64_supply_native_gregset (regcache, gregsetp, -1);
83 }
84 
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,
87    do this for all registers.  */
88 
89 void
90 fill_gregset (const struct regcache *regcache,
91 	      elf_gregset_t *gregsetp, int regnum)
92 {
93   amd64_collect_native_gregset (regcache, gregsetp, regnum);
94 }
95 
96 /* Transfering floating-point registers between GDB, inferiors and cores.  */
97 
98 /* Fill GDB's register cache with the floating-point and SSE register
99    values in *FPREGSETP.  */
100 
101 void
102 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
103 {
104   amd64_supply_fxsave (regcache, -1, fpregsetp);
105 }
106 
107 /* Fill register REGNUM (if it is a floating-point or SSE register) in
108    *FPREGSETP with the value in GDB's register cache.  If REGNUM is
109    -1, do this for all registers.  */
110 
111 void
112 fill_fpregset (const struct regcache *regcache,
113 	       elf_fpregset_t *fpregsetp, int regnum)
114 {
115   amd64_collect_fxsave (regcache, regnum, fpregsetp);
116 }
117 
118 
119 /* Transferring arbitrary registers between GDB and inferior.  */
120 
121 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
122    this for all registers (including the floating point and SSE
123    registers).  */
124 
125 static void
126 amd64_linux_fetch_inferior_registers (struct target_ops *ops,
127 				      struct regcache *regcache, int regnum)
128 {
129   struct gdbarch *gdbarch = get_regcache_arch (regcache);
130   int tid;
131 
132   /* GNU/Linux LWP ID's are process ID's.  */
133   tid = ptid_get_lwp (inferior_ptid);
134   if (tid == 0)
135     tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
136 
137   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
138     {
139       elf_gregset_t regs;
140 
141       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
142 	perror_with_name (_("Couldn't get registers"));
143 
144       amd64_supply_native_gregset (regcache, &regs, -1);
145       if (regnum != -1)
146 	return;
147     }
148 
149   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
150     {
151       elf_fpregset_t fpregs;
152 
153       if (have_ptrace_getregset == TRIBOOL_TRUE)
154 	{
155 	  char xstateregs[X86_XSTATE_MAX_SIZE];
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"));
163 
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 	}
173     }
174 }
175 
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
178    registers).  */
179 
180 static void
181 amd64_linux_store_inferior_registers (struct target_ops *ops,
182 				      struct regcache *regcache, int regnum)
183 {
184   struct gdbarch *gdbarch = get_regcache_arch (regcache);
185   int tid;
186 
187   /* GNU/Linux LWP ID's are process ID's.  */
188   tid = ptid_get_lwp (inferior_ptid);
189   if (tid == 0)
190     tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */
191 
192   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
193     {
194       elf_gregset_t regs;
195 
196       if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
197 	perror_with_name (_("Couldn't get registers"));
198 
199       amd64_collect_native_gregset (regcache, &regs, regnum);
200 
201       if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
202 	perror_with_name (_("Couldn't write registers"));
203 
204       if (regnum != -1)
205 	return;
206     }
207 
208   if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
209     {
210       elf_fpregset_t fpregs;
211 
212       if (have_ptrace_getregset == TRIBOOL_TRUE)
213 	{
214 	  char xstateregs[X86_XSTATE_MAX_SIZE];
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"));
222 
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"));
233 
234 	  amd64_collect_fxsave (regcache, regnum, &fpregs);
235 
236 	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
237 	    perror_with_name (_("Couldn't write floating point status"));
238 	}
239     }
240 }
241 
242 
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 
246 ps_err_e
247 ps_get_thread_area (const struct ps_prochandle *ph,
248                     lwpid_t lwpid, int idx, void **base)
249 {
250   if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
251     {
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;
264     }
265   else
266     {
267       /* This definition comes from prctl.h, but some kernels may not
268          have it.  */
269 #ifndef PTRACE_ARCH_PRCTL
270 #define PTRACE_ARCH_PRCTL      30
271 #endif
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:
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
295 	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
296 	    return PS_OK;
297 	  break;
298 	case GS:
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
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 	}
318     }
319   return PS_ERR;               /* ptrace failed.  */
320 }
321 
322 
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 
333 typedef int compat_int_t;
334 typedef unsigned int compat_uptr_t;
335 
336 typedef int compat_time_t;
337 typedef int compat_timer_t;
338 typedef int compat_clock_t;
339 
340 struct compat_timeval
341 {
342   compat_time_t tv_sec;
343   int tv_usec;
344 };
345 
346 typedef union compat_sigval
347 {
348   compat_int_t sival_int;
349   compat_uptr_t sival_ptr;
350 } compat_sigval_t;
351 
352 typedef 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 
410 /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
411 typedef struct compat_x32_clock
412 {
413   int lower;
414   int upper;
415 } compat_x32_clock_t;
416 
417 typedef 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 
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 
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 
496 static void
497 compat_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 
505   if (to->si_code == SI_TIMER)
506     {
507       to->cpt_si_timerid = from->si_timerid;
508       to->cpt_si_overrun = from->si_overrun;
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     }
516   else if (to->si_code < 0)
517     {
518       to->cpt_si_pid = from->si_pid;
519       to->cpt_si_uid = from->si_uid;
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 
552 static void
553 siginfo_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 
561   if (to->si_code == SI_TIMER)
562     {
563       to->si_timerid = from->cpt_si_timerid;
564       to->si_overrun = from->cpt_si_overrun;
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     }
572   if (to->si_code < 0)
573     {
574       to->si_pid = from->cpt_si_pid;
575       to->si_uid = from->cpt_si_uid;
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 
608 static void
609 compat_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 
667 static void
668 siginfo_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 
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 
732 static int
733 amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
734 {
735   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
736 
737   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
738      object.  */
739   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
740     {
741       gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t));
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 
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 
762       return 1;
763     }
764   else
765     return 0;
766 }
767 
768 
769 /* Provide a prototype to silence -Wmissing-prototypes.  */
770 void _initialize_amd64_linux_nat (void);
771 
772 void
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 }
798