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