1b725ae77Skettenis /* GNU/Linux/x86-64 specific low level interface, for the remote server
2b725ae77Skettenis for GDB.
3*11efff7fSkettenis Copyright 2002, 2004
4b725ae77Skettenis Free Software Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis #include "server.h"
24b725ae77Skettenis #include "linux-low.h"
25b725ae77Skettenis #include "i387-fp.h"
26b725ae77Skettenis
27*11efff7fSkettenis /* Correct for all GNU/Linux targets (for quite some time). */
28*11efff7fSkettenis #define GDB_GREGSET_T elf_gregset_t
29*11efff7fSkettenis #define GDB_FPREGSET_T elf_fpregset_t
30*11efff7fSkettenis
31*11efff7fSkettenis #ifndef HAVE_ELF_FPREGSET_T
32*11efff7fSkettenis /* Make sure we have said types. Not all platforms bring in <linux/elf.h>
33*11efff7fSkettenis via <sys/procfs.h>. */
34*11efff7fSkettenis #ifdef HAVE_LINUX_ELF_H
35*11efff7fSkettenis #include <linux/elf.h>
36*11efff7fSkettenis #endif
37*11efff7fSkettenis #endif
38*11efff7fSkettenis
39*11efff7fSkettenis #include "../gdb_proc_service.h"
40*11efff7fSkettenis
41b725ae77Skettenis #include <sys/reg.h>
42b725ae77Skettenis #include <sys/procfs.h>
43b725ae77Skettenis #include <sys/ptrace.h>
44b725ae77Skettenis
45*11efff7fSkettenis /* This definition comes from prctl.h, but some kernels may not have it. */
46*11efff7fSkettenis #ifndef PTRACE_ARCH_PRCTL
47*11efff7fSkettenis #define PTRACE_ARCH_PRCTL 30
48*11efff7fSkettenis #endif
49*11efff7fSkettenis
50*11efff7fSkettenis /* The following definitions come from prctl.h, but may be absent
51*11efff7fSkettenis for certain configurations. */
52*11efff7fSkettenis #ifndef ARCH_GET_FS
53*11efff7fSkettenis #define ARCH_SET_GS 0x1001
54*11efff7fSkettenis #define ARCH_SET_FS 0x1002
55*11efff7fSkettenis #define ARCH_GET_FS 0x1003
56*11efff7fSkettenis #define ARCH_GET_GS 0x1004
57*11efff7fSkettenis #endif
58*11efff7fSkettenis
59b725ae77Skettenis static int x86_64_regmap[] = {
60b725ae77Skettenis RAX * 8, RBX * 8, RCX * 8, RDX * 8,
61b725ae77Skettenis RSI * 8, RDI * 8, RBP * 8, RSP * 8,
62b725ae77Skettenis R8 * 8, R9 * 8, R10 * 8, R11 * 8,
63b725ae77Skettenis R12 * 8, R13 * 8, R14 * 8, R15 * 8,
64b725ae77Skettenis RIP * 8, EFLAGS * 8, CS * 8, SS * 8,
65b725ae77Skettenis DS * 8, ES * 8, FS * 8, GS * 8
66b725ae77Skettenis };
67b725ae77Skettenis
68b725ae77Skettenis #define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int))
69b725ae77Skettenis
70*11efff7fSkettenis /* Called by libthread_db. */
71*11efff7fSkettenis
72*11efff7fSkettenis ps_err_e
ps_get_thread_area(const struct ps_prochandle * ph,lwpid_t lwpid,int idx,void ** base)73*11efff7fSkettenis ps_get_thread_area (const struct ps_prochandle *ph,
74*11efff7fSkettenis lwpid_t lwpid, int idx, void **base)
75*11efff7fSkettenis {
76*11efff7fSkettenis switch (idx)
77*11efff7fSkettenis {
78*11efff7fSkettenis case FS:
79*11efff7fSkettenis if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
80*11efff7fSkettenis return PS_OK;
81*11efff7fSkettenis break;
82*11efff7fSkettenis case GS:
83*11efff7fSkettenis if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
84*11efff7fSkettenis return PS_OK;
85*11efff7fSkettenis break;
86*11efff7fSkettenis default:
87*11efff7fSkettenis return PS_BADADDR;
88*11efff7fSkettenis }
89*11efff7fSkettenis return PS_ERR;
90*11efff7fSkettenis }
91*11efff7fSkettenis
92b725ae77Skettenis static void
x86_64_fill_gregset(void * buf)93b725ae77Skettenis x86_64_fill_gregset (void *buf)
94b725ae77Skettenis {
95b725ae77Skettenis int i;
96b725ae77Skettenis
97b725ae77Skettenis for (i = 0; i < X86_64_NUM_GREGS; i++)
98b725ae77Skettenis collect_register (i, ((char *) buf) + x86_64_regmap[i]);
99b725ae77Skettenis }
100b725ae77Skettenis
101b725ae77Skettenis static void
x86_64_store_gregset(const void * buf)102b725ae77Skettenis x86_64_store_gregset (const void *buf)
103b725ae77Skettenis {
104b725ae77Skettenis int i;
105b725ae77Skettenis
106b725ae77Skettenis for (i = 0; i < X86_64_NUM_GREGS; i++)
107b725ae77Skettenis supply_register (i, ((char *) buf) + x86_64_regmap[i]);
108b725ae77Skettenis }
109b725ae77Skettenis
110b725ae77Skettenis static void
x86_64_fill_fpregset(void * buf)111b725ae77Skettenis x86_64_fill_fpregset (void *buf)
112b725ae77Skettenis {
113b725ae77Skettenis i387_cache_to_fxsave (buf);
114b725ae77Skettenis }
115b725ae77Skettenis
116b725ae77Skettenis static void
x86_64_store_fpregset(const void * buf)117b725ae77Skettenis x86_64_store_fpregset (const void *buf)
118b725ae77Skettenis {
119b725ae77Skettenis i387_fxsave_to_cache (buf);
120b725ae77Skettenis }
121b725ae77Skettenis
122b725ae77Skettenis struct regset_info target_regsets[] = {
123b725ae77Skettenis { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
124b725ae77Skettenis GENERAL_REGS,
125b725ae77Skettenis x86_64_fill_gregset, x86_64_store_gregset },
126b725ae77Skettenis { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
127b725ae77Skettenis FP_REGS,
128b725ae77Skettenis x86_64_fill_fpregset, x86_64_store_fpregset },
129b725ae77Skettenis { 0, 0, -1, -1, NULL, NULL }
130b725ae77Skettenis };
131b725ae77Skettenis
132b725ae77Skettenis struct linux_target_ops the_low_target = {
133b725ae77Skettenis -1,
134b725ae77Skettenis NULL,
135b725ae77Skettenis NULL,
136b725ae77Skettenis NULL,
137b725ae77Skettenis };
138