i386-gnu-nat.c revision 1.1.1.1 1 1.1 christos /* Low level interface to i386 running the GNU Hurd.
2 1.1 christos
3 1.1 christos Copyright (C) 1992-2017 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos /* Mach/Hurd headers are not yet ready for C++ compilation. */
21 1.1 christos extern "C"
22 1.1 christos {
23 1.1 christos #include <mach.h>
24 1.1 christos #include <mach_error.h>
25 1.1 christos #include <mach/message.h>
26 1.1 christos #include <mach/exception.h>
27 1.1 christos }
28 1.1 christos
29 1.1 christos #include "defs.h"
30 1.1 christos #include "x86-nat.h"
31 1.1 christos #include "inferior.h"
32 1.1 christos #include "floatformat.h"
33 1.1 christos #include "regcache.h"
34 1.1 christos
35 1.1 christos #include "i386-tdep.h"
36 1.1 christos
37 1.1 christos #include "gnu-nat.h"
38 1.1 christos #include "inf-child.h"
39 1.1 christos #include "i387-tdep.h"
40 1.1 christos
41 1.1 christos /* Offset to the thread_state_t location where REG is stored. */
42 1.1 christos #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
43 1.1 christos
44 1.1 christos /* At REG_OFFSET[N] is the offset to the thread_state_t location where
45 1.1 christos the GDB register N is stored. */
46 1.1 christos static int reg_offset[] =
47 1.1 christos {
48 1.1 christos REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
49 1.1 christos REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
50 1.1 christos REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
51 1.1 christos REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
52 1.1 christos };
53 1.1 christos
54 1.1 christos #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
55 1.1 christos
56 1.1 christos
57 1.1 christos /* Get the whole floating-point state of THREAD and record the values
59 1.1 christos of the corresponding (pseudo) registers. */
60 1.1 christos
61 1.1 christos static void
62 1.1 christos fetch_fpregs (struct regcache *regcache, struct proc *thread)
63 1.1 christos {
64 1.1 christos mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
65 1.1 christos struct i386_float_state state;
66 1.1 christos kern_return_t err;
67 1.1 christos
68 1.1 christos err = thread_get_state (thread->port, i386_FLOAT_STATE,
69 1.1 christos (thread_state_t) &state, &count);
70 1.1 christos if (err)
71 1.1 christos {
72 1.1 christos warning (_("Couldn't fetch floating-point state from %s"),
73 1.1 christos proc_string (thread));
74 1.1 christos return;
75 1.1 christos }
76 1.1 christos
77 1.1 christos if (!state.initialized)
78 1.1 christos {
79 1.1 christos /* The floating-point state isn't initialized. */
80 1.1 christos i387_supply_fsave (regcache, -1, NULL);
81 1.1 christos }
82 1.1 christos else
83 1.1 christos {
84 1.1 christos /* Supply the floating-point registers. */
85 1.1 christos i387_supply_fsave (regcache, -1, state.hw_state);
86 1.1 christos }
87 1.1 christos }
88 1.1 christos
89 1.1 christos /* Fetch register REGNO, or all regs if REGNO is -1. */
90 1.1 christos static void
91 1.1 christos gnu_fetch_registers (struct target_ops *ops,
92 1.1 christos struct regcache *regcache, int regno)
93 1.1 christos {
94 1.1 christos struct proc *thread;
95 1.1 christos ptid_t ptid = regcache_get_ptid (regcache);
96 1.1 christos
97 1.1 christos /* Make sure we know about new threads. */
98 1.1 christos inf_update_procs (gnu_current_inf);
99 1.1 christos
100 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid));
101 1.1 christos if (!thread)
102 1.1 christos error (_("Can't fetch registers from thread %s: No such thread"),
103 1.1 christos target_pid_to_str (ptid));
104 1.1 christos
105 1.1 christos if (regno < I386_NUM_GREGS || regno == -1)
106 1.1 christos {
107 1.1 christos thread_state_t state;
108 1.1 christos
109 1.1 christos /* This does the dirty work for us. */
110 1.1 christos state = proc_get_state (thread, 0);
111 1.1 christos if (!state)
112 1.1 christos {
113 1.1 christos warning (_("Couldn't fetch registers from %s"),
114 1.1 christos proc_string (thread));
115 1.1 christos return;
116 1.1 christos }
117 1.1 christos
118 1.1 christos if (regno == -1)
119 1.1 christos {
120 1.1 christos int i;
121 1.1 christos
122 1.1 christos proc_debug (thread, "fetching all register");
123 1.1 christos
124 1.1 christos for (i = 0; i < I386_NUM_GREGS; i++)
125 1.1 christos regcache_raw_supply (regcache, i, REG_ADDR (state, i));
126 1.1 christos thread->fetched_regs = ~0;
127 1.1 christos }
128 1.1 christos else
129 1.1 christos {
130 1.1 christos proc_debug (thread, "fetching register %s",
131 1.1 christos gdbarch_register_name (get_regcache_arch (regcache),
132 1.1 christos regno));
133 1.1 christos
134 1.1 christos regcache_raw_supply (regcache, regno,
135 1.1 christos REG_ADDR (state, regno));
136 1.1 christos thread->fetched_regs |= (1 << regno);
137 1.1 christos }
138 1.1 christos }
139 1.1 christos
140 1.1 christos if (regno >= I386_NUM_GREGS || regno == -1)
141 1.1 christos {
142 1.1 christos proc_debug (thread, "fetching floating-point registers");
143 1.1 christos
144 1.1 christos fetch_fpregs (regcache, thread);
145 1.1 christos }
146 1.1 christos }
147 1.1 christos
148 1.1 christos
150 1.1 christos /* Store the whole floating-point state into THREAD using information
151 1.1 christos from the corresponding (pseudo) registers. */
152 1.1 christos static void
153 1.1 christos store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
154 1.1 christos {
155 1.1 christos mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
156 1.1 christos struct i386_float_state state;
157 1.1 christos kern_return_t err;
158 1.1 christos
159 1.1 christos err = thread_get_state (thread->port, i386_FLOAT_STATE,
160 1.1 christos (thread_state_t) &state, &count);
161 1.1 christos if (err)
162 1.1 christos {
163 1.1 christos warning (_("Couldn't fetch floating-point state from %s"),
164 1.1 christos proc_string (thread));
165 1.1 christos return;
166 1.1 christos }
167 1.1 christos
168 1.1 christos /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
169 1.1 christos take into account DEPRECATED_REGISTER_VALID like the old code did? */
170 1.1 christos i387_collect_fsave (regcache, regno, state.hw_state);
171 1.1 christos
172 1.1 christos err = thread_set_state (thread->port, i386_FLOAT_STATE,
173 1.1 christos (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
174 1.1 christos if (err)
175 1.1 christos {
176 1.1 christos warning (_("Couldn't store floating-point state into %s"),
177 1.1 christos proc_string (thread));
178 1.1 christos return;
179 1.1 christos }
180 1.1 christos }
181 1.1 christos
182 1.1 christos /* Store at least register REGNO, or all regs if REGNO == -1. */
183 1.1 christos static void
184 1.1 christos gnu_store_registers (struct target_ops *ops,
185 1.1 christos struct regcache *regcache, int regno)
186 1.1 christos {
187 1.1 christos struct proc *thread;
188 1.1 christos struct gdbarch *gdbarch = get_regcache_arch (regcache);
189 1.1 christos ptid_t ptid = regcache_get_ptid (regcache);
190 1.1 christos
191 1.1 christos /* Make sure we know about new threads. */
192 1.1 christos inf_update_procs (gnu_current_inf);
193 1.1 christos
194 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid));
195 1.1 christos if (!thread)
196 1.1 christos error (_("Couldn't store registers into thread %s: No such thread"),
197 1.1 christos target_pid_to_str (ptid));
198 1.1 christos
199 1.1 christos if (regno < I386_NUM_GREGS || regno == -1)
200 1.1 christos {
201 1.1 christos thread_state_t state;
202 1.1 christos thread_state_data_t old_state;
203 1.1 christos int was_aborted = thread->aborted;
204 1.1 christos int was_valid = thread->state_valid;
205 1.1 christos int trace;
206 1.1 christos
207 1.1 christos if (!was_aborted && was_valid)
208 1.1 christos memcpy (&old_state, &thread->state, sizeof (old_state));
209 1.1 christos
210 1.1 christos state = proc_get_state (thread, 1);
211 1.1 christos if (!state)
212 1.1 christos {
213 1.1 christos warning (_("Couldn't store registers into %s"),
214 1.1 christos proc_string (thread));
215 1.1 christos return;
216 1.1 christos }
217 1.1 christos
218 1.1 christos /* Save the T bit. We might try to restore the %eflags register
219 1.1 christos below, but changing the T bit would seriously confuse GDB. */
220 1.1 christos trace = ((struct i386_thread_state *)state)->efl & 0x100;
221 1.1 christos
222 1.1 christos if (!was_aborted && was_valid)
223 1.1 christos /* See which registers have changed after aborting the thread. */
224 1.1 christos {
225 1.1 christos int check_regno;
226 1.1 christos
227 1.1 christos for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
228 1.1 christos if ((thread->fetched_regs & (1 << check_regno))
229 1.1 christos && memcpy (REG_ADDR (&old_state, check_regno),
230 1.1 christos REG_ADDR (state, check_regno),
231 1.1 christos register_size (gdbarch, check_regno)))
232 1.1 christos /* Register CHECK_REGNO has changed! Ack! */
233 1.1 christos {
234 1.1 christos warning (_("Register %s changed after the thread was aborted"),
235 1.1 christos gdbarch_register_name (gdbarch, check_regno));
236 1.1 christos if (regno >= 0 && regno != check_regno)
237 1.1 christos /* Update GDB's copy of the register. */
238 1.1 christos regcache_raw_supply (regcache, check_regno,
239 1.1 christos REG_ADDR (state, check_regno));
240 1.1 christos else
241 1.1 christos warning (_("... also writing this register! "
242 1.1 christos "Suspicious..."));
243 1.1 christos }
244 1.1 christos }
245 1.1 christos
246 1.1 christos if (regno == -1)
247 1.1 christos {
248 1.1 christos int i;
249 1.1 christos
250 1.1 christos proc_debug (thread, "storing all registers");
251 1.1 christos
252 1.1 christos for (i = 0; i < I386_NUM_GREGS; i++)
253 1.1 christos if (REG_VALID == regcache_register_status (regcache, i))
254 1.1 christos regcache_raw_collect (regcache, i, REG_ADDR (state, i));
255 1.1 christos }
256 1.1 christos else
257 1.1 christos {
258 1.1 christos proc_debug (thread, "storing register %s",
259 1.1 christos gdbarch_register_name (gdbarch, regno));
260 1.1 christos
261 1.1 christos gdb_assert (REG_VALID == regcache_register_status (regcache, regno));
262 1.1 christos regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
263 1.1 christos }
264 1.1 christos
265 1.1 christos /* Restore the T bit. */
266 1.1 christos ((struct i386_thread_state *)state)->efl &= ~0x100;
267 1.1 christos ((struct i386_thread_state *)state)->efl |= trace;
268 1.1 christos }
269 1.1 christos
270 1.1 christos if (regno >= I386_NUM_GREGS || regno == -1)
271 1.1 christos {
272 1.1 christos proc_debug (thread, "storing floating-point registers");
273 1.1 christos
274 1.1 christos store_fpregs (regcache, thread, regno);
275 1.1 christos }
276 1.1 christos }
277 1.1 christos
278 1.1 christos
279 1.1 christos /* Support for debug registers. */
281 1.1 christos
282 1.1 christos #ifdef i386_DEBUG_STATE
283 1.1 christos /* Get debug registers for thread THREAD. */
284 1.1 christos
285 1.1 christos static void
286 1.1 christos i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
287 1.1 christos {
288 1.1 christos mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
289 1.1 christos kern_return_t err;
290 1.1 christos
291 1.1 christos err = thread_get_state (thread->port, i386_DEBUG_STATE,
292 1.1 christos (thread_state_t) regs, &count);
293 1.1 christos if (err != 0 || count != i386_DEBUG_STATE_COUNT)
294 1.1 christos warning (_("Couldn't fetch debug state from %s"),
295 1.1 christos proc_string (thread));
296 1.1 christos }
297 1.1 christos
298 1.1 christos /* Set debug registers for thread THREAD. */
299 1.1 christos
300 1.1 christos static void
301 1.1 christos i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
302 1.1 christos {
303 1.1 christos kern_return_t err;
304 1.1 christos
305 1.1 christos err = thread_set_state (thread->port, i386_DEBUG_STATE,
306 1.1 christos (thread_state_t) regs, i386_DEBUG_STATE_COUNT);
307 1.1 christos if (err != 0)
308 1.1 christos warning (_("Couldn't store debug state into %s"),
309 1.1 christos proc_string (thread));
310 1.1 christos }
311 1.1 christos
312 1.1 christos /* Set DR_CONTROL in THREAD. */
313 1.1 christos
314 1.1 christos static void
315 1.1 christos i386_gnu_dr_set_control_one (struct proc *thread, void *arg)
316 1.1 christos {
317 1.1 christos unsigned long *control = (unsigned long *) arg;
318 1.1 christos struct i386_debug_state regs;
319 1.1 christos
320 1.1 christos i386_gnu_dr_get (®s, thread);
321 1.1 christos regs.dr[DR_CONTROL] = *control;
322 1.1 christos i386_gnu_dr_set (®s, thread);
323 1.1 christos }
324 1.1 christos
325 1.1 christos /* Set DR_CONTROL to CONTROL in all threads. */
326 1.1 christos
327 1.1 christos static void
328 1.1 christos i386_gnu_dr_set_control (unsigned long control)
329 1.1 christos {
330 1.1 christos inf_update_procs (gnu_current_inf);
331 1.1 christos inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control);
332 1.1 christos }
333 1.1 christos
334 1.1 christos /* Parameters to set a debugging address. */
335 1.1 christos
336 1.1 christos struct reg_addr
337 1.1 christos {
338 1.1 christos int regnum; /* Register number (zero based). */
339 1.1 christos CORE_ADDR addr; /* Address. */
340 1.1 christos };
341 1.1 christos
342 1.1 christos /* Set address REGNUM (zero based) to ADDR in THREAD. */
343 1.1 christos
344 1.1 christos static void
345 1.1 christos i386_gnu_dr_set_addr_one (struct proc *thread, void *arg)
346 1.1 christos {
347 1.1 christos struct reg_addr *reg_addr = (struct reg_addr *) arg;
348 1.1 christos struct i386_debug_state regs;
349 1.1 christos
350 1.1 christos i386_gnu_dr_get (®s, thread);
351 1.1 christos regs.dr[reg_addr->regnum] = reg_addr->addr;
352 1.1 christos i386_gnu_dr_set (®s, thread);
353 1.1 christos }
354 1.1 christos
355 1.1 christos /* Set address REGNUM (zero based) to ADDR in all threads. */
356 1.1 christos
357 1.1 christos static void
358 1.1 christos i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr)
359 1.1 christos {
360 1.1 christos struct reg_addr reg_addr;
361 1.1 christos
362 1.1 christos gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
363 1.1 christos
364 1.1 christos reg_addr.regnum = regnum;
365 1.1 christos reg_addr.addr = addr;
366 1.1 christos
367 1.1 christos inf_update_procs (gnu_current_inf);
368 1.1 christos inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, ®_addr);
369 1.1 christos }
370 1.1 christos
371 1.1 christos /* Get debug register REGNUM value from only the one LWP of PTID. */
372 1.1 christos
373 1.1 christos static unsigned long
374 1.1 christos i386_gnu_dr_get_reg (ptid_t ptid, int regnum)
375 1.1 christos {
376 1.1 christos struct i386_debug_state regs;
377 1.1 christos struct proc *thread;
378 1.1 christos
379 1.1 christos /* Make sure we know about new threads. */
380 1.1 christos inf_update_procs (gnu_current_inf);
381 1.1 christos
382 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid));
383 1.1 christos i386_gnu_dr_get (®s, thread);
384 1.1 christos
385 1.1 christos return regs.dr[regnum];
386 1.1 christos }
387 1.1 christos
388 1.1 christos /* Return the inferior's debug register REGNUM. */
389 1.1 christos
390 1.1 christos static CORE_ADDR
391 1.1 christos i386_gnu_dr_get_addr (int regnum)
392 1.1 christos {
393 1.1 christos gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
394 1.1 christos
395 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, regnum);
396 1.1 christos }
397 1.1 christos
398 1.1 christos /* Get DR_STATUS from only the one thread of INFERIOR_PTID. */
399 1.1 christos
400 1.1 christos static unsigned long
401 1.1 christos i386_gnu_dr_get_status (void)
402 1.1 christos {
403 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, DR_STATUS);
404 1.1 christos }
405 1.1 christos
406 1.1 christos /* Return the inferior's DR7 debug control register. */
407 1.1 christos
408 1.1 christos static unsigned long
409 1.1 christos i386_gnu_dr_get_control (void)
410 1.1 christos {
411 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL);
412 1.1 christos }
413 1.1 christos #endif /* i386_DEBUG_STATE */
414 1.1 christos
415 1.1 christos /* Provide a prototype to silence -Wmissing-prototypes. */
416 1.1 christos extern initialize_file_ftype _initialize_i386gnu_nat;
417 1.1 christos
418 1.1 christos void
419 1.1 christos _initialize_i386gnu_nat (void)
420 1.1 christos {
421 1.1 christos struct target_ops *t;
422 1.1 christos
423 1.1 christos /* Fill in the generic GNU/Hurd methods. */
424 1.1 christos t = gnu_target ();
425 1.1 christos
426 1.1 christos #ifdef i386_DEBUG_STATE
427 1.1 christos x86_use_watchpoints (t);
428 1.1 christos
429 1.1 christos x86_dr_low.set_control = i386_gnu_dr_set_control;
430 1.1 christos gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT);
431 1.1 christos x86_dr_low.set_addr = i386_gnu_dr_set_addr;
432 1.1 christos x86_dr_low.get_addr = i386_gnu_dr_get_addr;
433 1.1 christos x86_dr_low.get_status = i386_gnu_dr_get_status;
434 1.1 christos x86_dr_low.get_control = i386_gnu_dr_get_control;
435 1.1 christos x86_set_debug_register_length (4);
436 1.1 christos #endif /* i386_DEBUG_STATE */
437 1.1 christos
438 1.1 christos t->to_fetch_registers = gnu_fetch_registers;
439 1.1 christos t->to_store_registers = gnu_store_registers;
440 1.1 christos
441 /* Register the target. */
442 add_target (t);
443 }
444