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