GDB (xrefs)
/tmp/gdb-8.1/gdb/i386-gnu-nat.c
Go to the documentation of this file.
1 /* Low level interface to i386 running the GNU Hurd.
2 
3  Copyright (C) 1992-2018 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 3 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, see <http://www.gnu.org/licenses/>. */
19 
20 /* Mach/Hurd headers are not yet ready for C++ compilation. */
21 extern "C"
22 {
23 #include <mach.h>
24 #include <mach_error.h>
25 #include <mach/message.h>
26 #include <mach/exception.h>
27 }
28 
29 #include "defs.h"
30 #include "x86-nat.h"
31 #include "inferior.h"
32 #include "floatformat.h"
33 #include "regcache.h"
34 
35 #include "i386-tdep.h"
36 
37 #include "gnu-nat.h"
38 #include "inf-child.h"
39 #include "i387-tdep.h"
40 
41 /* Offset to the thread_state_t location where REG is stored. */
42 #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
43 
44 /* At REG_OFFSET[N] is the offset to the thread_state_t location where
45  the GDB register N is stored. */
46 static int reg_offset[] =
47 {
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)
52 };
53 
54 #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
55 
56 
57 /* Get the whole floating-point state of THREAD and record the values
58  of the corresponding (pseudo) registers. */
59 
60 static void
61 fetch_fpregs (struct regcache *regcache, struct proc *thread)
62 {
63  mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
64  struct i386_float_state state;
65  kern_return_t err;
66 
67  err = thread_get_state (thread->port, i386_FLOAT_STATE,
68  (thread_state_t) &state, &count);
69  if (err)
70  {
71  warning (_("Couldn't fetch floating-point state from %s"),
72  proc_string (thread));
73  return;
74  }
75 
76  if (!state.initialized)
77  {
78  /* The floating-point state isn't initialized. */
79  i387_supply_fsave (regcache, -1, NULL);
80  }
81  else
82  {
83  /* Supply the floating-point registers. */
84  i387_supply_fsave (regcache, -1, state.hw_state);
85  }
86 }
87 
88 /* Fetch register REGNO, or all regs if REGNO is -1. */
89 static void
91  struct regcache *regcache, int regno)
92 {
93  struct proc *thread;
95 
96  /* Make sure we know about new threads. */
98 
100  if (!thread)
101  error (_("Can't fetch registers from thread %s: No such thread"),
102  target_pid_to_str (ptid));
103 
104  if (regno < I386_NUM_GREGS || regno == -1)
105  {
106  thread_state_t state;
107 
108  /* This does the dirty work for us. */
109  state = proc_get_state (thread, 0);
110  if (!state)
111  {
112  warning (_("Couldn't fetch registers from %s"),
113  proc_string (thread));
114  return;
115  }
116 
117  if (regno == -1)
118  {
119  int i;
120 
121  proc_debug (thread, "fetching all register");
122 
123  for (i = 0; i < I386_NUM_GREGS; i++)
125  thread->fetched_regs = ~0;
126  }
127  else
128  {
129  proc_debug (thread, "fetching register %s",
131  regno));
132 
134  REG_ADDR (state, regno));
135  thread->fetched_regs |= (1 << regno);
136  }
137  }
138 
139  if (regno >= I386_NUM_GREGS || regno == -1)
140  {
141  proc_debug (thread, "fetching floating-point registers");
142 
143  fetch_fpregs (regcache, thread);
144  }
145 }
146 
147 
148 /* Store the whole floating-point state into THREAD using information
149  from the corresponding (pseudo) registers. */
150 static void
151 store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
152 {
153  mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
154  struct i386_float_state state;
155  kern_return_t err;
156 
157  err = thread_get_state (thread->port, i386_FLOAT_STATE,
158  (thread_state_t) &state, &count);
159  if (err)
160  {
161  warning (_("Couldn't fetch floating-point state from %s"),
162  proc_string (thread));
163  return;
164  }
165 
166  /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
167  take into account DEPRECATED_REGISTER_VALID like the old code did? */
168  i387_collect_fsave (regcache, regno, state.hw_state);
169 
170  err = thread_set_state (thread->port, i386_FLOAT_STATE,
171  (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
172  if (err)
173  {
174  warning (_("Couldn't store floating-point state into %s"),
175  proc_string (thread));
176  return;
177  }
178 }
179 
180 /* Store at least register REGNO, or all regs if REGNO == -1. */
181 static void
183  struct regcache *regcache, int regno)
184 {
185  struct proc *thread;
186  struct gdbarch *gdbarch = regcache->arch ();
188 
189  /* Make sure we know about new threads. */
191 
193  if (!thread)
194  error (_("Couldn't store registers into thread %s: No such thread"),
195  target_pid_to_str (ptid));
196 
197  if (regno < I386_NUM_GREGS || regno == -1)
198  {
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;
203  int trace;
204 
205  if (!was_aborted && was_valid)
206  memcpy (&old_state, &thread->state, sizeof (old_state));
207 
208  state = proc_get_state (thread, 1);
209  if (!state)
210  {
211  warning (_("Couldn't store registers into %s"),
212  proc_string (thread));
213  return;
214  }
215 
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 
220  if (!was_aborted && was_valid)
221  /* See which registers have changed after aborting the thread. */
222  {
223  int check_regno;
224 
225  for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
226  if ((thread->fetched_regs & (1 << check_regno))
227  && memcpy (REG_ADDR (&old_state, check_regno),
228  REG_ADDR (state, check_regno),
229  register_size (gdbarch, check_regno)))
230  /* Register CHECK_REGNO has changed! Ack! */
231  {
232  warning (_("Register %s changed after the thread was aborted"),
233  gdbarch_register_name (gdbarch, check_regno));
234  if (regno >= 0 && regno != check_regno)
235  /* Update GDB's copy of the register. */
236  regcache_raw_supply (regcache, check_regno,
237  REG_ADDR (state, check_regno));
238  else
239  warning (_("... also writing this register! "
240  "Suspicious..."));
241  }
242  }
243 
244  if (regno == -1)
245  {
246  int i;
247 
248  proc_debug (thread, "storing all registers");
249 
250  for (i = 0; i < I386_NUM_GREGS; i++)
252  regcache_raw_collect (regcache, i, REG_ADDR (state, i));
253  }
254  else
255  {
256  proc_debug (thread, "storing register %s",
257  gdbarch_register_name (gdbarch, regno));
258 
260  regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
261  }
262 
263  /* Restore the T bit. */
264  ((struct i386_thread_state *)state)->efl &= ~0x100;
265  ((struct i386_thread_state *)state)->efl |= trace;
266  }
267 
268  if (regno >= I386_NUM_GREGS || regno == -1)
269  {
270  proc_debug (thread, "storing floating-point registers");
271 
272  store_fpregs (regcache, thread, regno);
273  }
274 }
275 
276 
277 /* Support for debug registers. */
278 
279 #ifdef i386_DEBUG_STATE
280 /* Get debug registers for thread THREAD. */
281 
282 static void
283 i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
284 {
285  mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
286  kern_return_t err;
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 
297 static void
298 i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
299 {
300  kern_return_t err;
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 
311 static void
312 i386_gnu_dr_set_control_one (struct proc *thread, void *arg)
313 {
314  unsigned long *control = (unsigned long *) arg;
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 
324 static void
325 i386_gnu_dr_set_control (unsigned long control)
326 {
328  inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control);
329 }
330 
331 /* Parameters to set a debugging address. */
332 
333 struct 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 
341 static void
342 i386_gnu_dr_set_addr_one (struct proc *thread, void *arg)
343 {
344  struct reg_addr *reg_addr = (struct reg_addr *) arg;
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 
354 static void
355 i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr)
356 {
357  struct reg_addr reg_addr;
358 
360 
361  reg_addr.regnum = regnum;
362  reg_addr.addr = addr;
363 
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 
370 static unsigned long
371 i386_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. */
378 
380  i386_gnu_dr_get (&regs, thread);
381 
382  return regs.dr[regnum];
383 }
384 
385 /* Return the inferior's debug register REGNUM. */
386 
387 static CORE_ADDR
388 i386_gnu_dr_get_addr (int regnum)
389 {
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 
397 static unsigned long
398 i386_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 
405 static unsigned long
406 i386_gnu_dr_get_control (void)
407 {
408  return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL);
409 }
410 #endif /* i386_DEBUG_STATE */
411 
412 void
414 {
415  struct target_ops *t;
416 
417  /* Fill in the generic GNU/Hurd methods. */
418  t = gnu_target ();
419 
420 #ifdef i386_DEBUG_STATE
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;
430 #endif /* i386_DEBUG_STATE */
431 
434 
435  /* Register the target. */
436  add_target (t);
437 }
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
Definition: gnu-nat.c:1822
void add_target(struct target_ops *t)
Definition: target.c:395
void i387_collect_fsave(const struct regcache *regcache, int regnum, void *fsave)
Definition: i387-tdep.c:493
#define I386_NUM_GREGS
Definition: i386-tdep.h:332
static int reg_offset[]
Definition: i386-gnu-nat.c:46
bfd_vma CORE_ADDR
Definition: common-types.h:41
char * proc_string(struct proc *proc)
Definition: gnu-nat.c:2702
thread_t port
Definition: gnu-nat.h:44
void warning(const char *fmt,...)
Definition: errors.c:26
unsigned long fetched_regs
Definition: gnu-nat.h:69
ptid_t regcache_get_ptid(const struct regcache *regcache)
Definition: regcache.c:229
static void fetch_fpregs(struct regcache *regcache, struct proc *thread)
Definition: i386-gnu-nat.c:61
void inf_threads(struct inf *inf, inf_threads_ftype *f, void *arg)
Definition: gnu-nat.c:996
void i387_supply_fsave(struct regcache *regcache, int regnum, const void *fsave)
Definition: i387-tdep.c:438
#define _(String)
Definition: gdb_locale.h:35
void(* set_control)(unsigned long)
Definition: x86-dregs.h:44
struct x86_dr_low_type x86_dr_low
Definition: x86-nat.c:37
CORE_ADDR(* get_addr)(int)
Definition: x86-dregs.h:52
#define DR_FIRSTADDR
Definition: x86-dregs.h:69
#define DR_STATUS
Definition: x86-dregs.h:72
static void gnu_fetch_registers(struct target_ops *ops, struct regcache *regcache, int regno)
Definition: i386-gnu-nat.c:90
void(* set_addr)(int, CORE_ADDR)
Definition: x86-dregs.h:48
Definition: gnu-nat.h:42
unsigned long(* get_status)(void)
Definition: x86-dregs.h:56
thread_state_data_t state
Definition: gnu-nat.h:59
Definition: ptid.h:35
struct target_ops * gnu_target(void)
Definition: gnu-nat.c:2737
#define REG_ADDR(state, regnum)
Definition: i386-gnu-nat.c:54
#define REG_OFFSET(reg)
Definition: i386-gnu-nat.c:42
const char * gdbarch_register_name(struct gdbarch *gdbarch, int regnr)
Definition: gdbarch.c:2282
int regnum
Definition: aarch64-tdep.c:77
long ptid_get_lwp(const ptid_t &ptid)
Definition: ptid.c:55
unsigned long(* get_control)(void)
Definition: x86-dregs.h:60
int inf_update_procs(struct inf *inf)
Definition: gnu-nat.c:1123
#define gdb_assert(expr)
Definition: gdb_assert.h:32
static void gnu_store_registers(struct target_ops *ops, struct regcache *regcache, int regno)
Definition: i386-gnu-nat.c:182
#define DR_CONTROL
Definition: x86-dregs.h:73
struct inf * gnu_current_inf
Definition: gnu-nat.c:1451
void(* to_fetch_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_IGNORE()
Definition: target.h:457
enum register_status regcache_register_status(const struct regcache *regcache, int regnum)
Definition: regcache.c:359
ptid_t inferior_ptid
Definition: infcmd.c:94
const char * target_pid_to_str(ptid_t ptid)
Definition: target.c:2194
gdbarch * arch() const
Definition: regcache.c:221
void regcache_raw_supply(struct regcache *regcache, int regnum, const void *buf)
Definition: regcache.c:1004
void x86_set_debug_register_length(int len)
Definition: x86-nat.c:303
int register_size(struct gdbarch *gdbarch, int regnum)
Definition: regcache.c:164
void _initialize_i386gnu_nat(void)
Definition: i386-gnu-nat.c:413
void regcache_raw_collect(const struct regcache *regcache, int regnum, void *buf)
Definition: regcache.c:1085
void x86_use_watchpoints(struct target_ops *t)
Definition: x86-nat.c:285
int aborted
Definition: gnu-nat.h:63
int state_valid
Definition: gnu-nat.h:60
void(* to_store_registers)(struct target_ops *, struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
Definition: target.h:459
thread_state_t proc_get_state(struct proc *proc, int will_modify)
Definition: gnu-nat.c:365
void error(const char *fmt,...)
Definition: errors.c:38
static void store_fpregs(const struct regcache *regcache, struct proc *thread, int regno)
Definition: i386-gnu-nat.c:151
struct proc * inf_tid_to_thread(struct inf *inf, int tid)
Definition: gnu-nat.c:967
#define proc_debug(_proc, msg, args...)
Definition: gnu-nat.h:93
#define DR_LASTADDR
Definition: x86-dregs.h:70