*** empty log message ***
[deliverable/binutils-gdb.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 }
This page took 0.1011 seconds and 4 git commands to generate.