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