]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - gnu/usr.bin/gdb/gdbserver/fbsd-amd64-low.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / gnu / usr.bin / gdb / gdbserver / fbsd-amd64-low.c
1 /* GNU/FreeBSD/amd64 specific low level interface, for the remote server for GDB.
2    Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24
25 #include "server.h"
26 #include "fbsd-low.h"
27 #include "i387-fp.h"
28
29 #include <sys/stddef.h>
30 #include <sys/types.h>
31 #include <sys/ptrace.h>
32 #include <machine/reg.h>
33
34 /* Mapping between the general-purpose registers in `struct user'
35    format and GDB's register array layout.  */
36 static int amd64_regmap[] = {
37         offsetof(struct reg, r_rax),
38         offsetof(struct reg, r_rbx),
39         offsetof(struct reg, r_rcx),
40         offsetof(struct reg, r_rdx),
41         offsetof(struct reg, r_rsi),
42         offsetof(struct reg, r_rdi),
43         offsetof(struct reg, r_rbp),
44         offsetof(struct reg, r_rsp),
45         offsetof(struct reg, r_r8),
46         offsetof(struct reg, r_r9),
47         offsetof(struct reg, r_r10),
48         offsetof(struct reg, r_r11),
49         offsetof(struct reg, r_r12),
50         offsetof(struct reg, r_r13),
51         offsetof(struct reg, r_r14),
52         offsetof(struct reg, r_r15),
53         offsetof(struct reg, r_rip),
54         offsetof(struct reg, r_rflags), /* XXX 64-bit */
55         offsetof(struct reg, r_cs),
56         offsetof(struct reg, r_ss),
57         offsetof(struct reg, r_ds),
58         offsetof(struct reg, r_es),
59         offsetof(struct reg, r_fs),
60         offsetof(struct reg, r_gs),
61 };
62 #define AMD64_NUM_REGS  (sizeof(amd64_regmap) / sizeof(amd64_regmap[0]))
63
64 static const char amd64_breakpoint[] = { 0xCC };
65 #define AMD64_BP_LEN    1
66
67 extern int debug_threads;
68
69 static int
70 amd64_cannot_store_register(int regno)
71 {
72
73         return (regno >= AMD64_NUM_REGS);
74 }
75
76 static int
77 amd64_cannot_fetch_register(int regno)
78 {
79
80         return (regno >= AMD64_NUM_REGS);
81 }
82
83 static void
84 amd64_fill_gregset(void *buf)
85 {
86         int i;
87
88         for (i = 0; i < AMD64_NUM_REGS; i++)
89                 collect_register(i, ((char *)buf) + amd64_regmap[i]);
90 }
91
92 static void
93 amd64_store_gregset(const void *buf)
94 {
95         int i;
96
97         for (i = 0; i < AMD64_NUM_REGS; i++)
98                 supply_register(i, ((char *)buf) + amd64_regmap[i]);
99 }
100
101 static void
102 amd64_fill_fpregset(void *buf)
103 {
104
105         i387_cache_to_fsave(buf);
106 }
107
108 static void
109 amd64_store_fpregset(const void *buf)
110 {
111
112         i387_fsave_to_cache(buf);
113 }
114
115 static void
116 amd64_fill_fpxregset(void *buf)
117 {  
118
119         i387_cache_to_fxsave(buf);
120 }
121
122 static void
123 amd64_store_fpxregset(const void *buf)
124 {
125
126         i387_fxsave_to_cache(buf);
127 }
128
129
130 struct regset_info target_regsets[] = {
131         {
132                 PT_GETREGS,
133                 PT_SETREGS,
134                 sizeof(struct reg),
135                 GENERAL_REGS,
136                 amd64_fill_gregset,
137                 amd64_store_gregset,
138         },
139 #ifdef HAVE_PTRACE_GETFPXREGS
140         {
141                 PTRACE_GETFPXREGS,
142                 PTRACE_SETFPXREGS,
143                 sizeof(elf_fpxregset_t),
144                 EXTENDED_REGS,
145                 amd64_fill_fpxregset,
146                 amd64_store_fpxregset,
147         },
148 #endif
149         {
150                 PT_GETFPREGS,
151                 PT_SETFPREGS,
152                 sizeof(struct fpreg),
153                 FP_REGS,
154                 amd64_fill_fpregset,
155                 amd64_store_fpregset,
156         },
157         {
158                 0,
159                 0,
160                 -1,
161                 -1,
162                 NULL,
163                 NULL,
164         }
165 };
166
167 static CORE_ADDR
168 amd64_get_pc(void)
169 {
170         unsigned long pc;
171
172         collect_register_by_name("rip", &pc);
173
174         if (debug_threads)
175                 fprintf(stderr, "stop pc (before any decrement) is %016lx\n", pc);
176
177         return (pc);
178 }
179
180 static void
181 amd64_set_pc(CORE_ADDR newpc)
182 {
183
184         if (debug_threads)
185                 fprintf(stderr, "set pc to %016lx\n", (long)newpc);
186         supply_register_by_name("rip", &newpc);
187 }
188
189 static int
190 amd64_breakpoint_at(CORE_ADDR pc)
191 {
192         unsigned char c;
193
194         read_inferior_memory(pc, &c, 1);
195         if (c == 0xCC)
196                 return (1);
197
198         return (0);
199 }
200
201 struct fbsd_target_ops the_low_target = {
202         AMD64_NUM_REGS,
203         amd64_regmap,
204         amd64_cannot_fetch_register,
205         amd64_cannot_store_register,
206         amd64_get_pc,
207         amd64_set_pc,
208         amd64_breakpoint,
209         AMD64_BP_LEN,
210         NULL,
211         1,
212         amd64_breakpoint_at,
213 };