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