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