*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / i386gnu-nat.c
CommitLineData
da59e081 1/* Low level interface to i386 running the GNU Hurd.
f6052080 2
0fb0cc75 3 Copyright (C) 1992, 1995, 1996, 1998, 2000, 2001, 2004, 2007, 2008, 2009
b6ba6518 4 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "defs.h"
22#include "inferior.h"
23#include "floatformat.h"
4e052eda 24#include "regcache.h"
c906108c 25
780a49fa 26#include "gdb_assert.h"
c906108c 27#include <errno.h>
383d750b 28#include <stdio.h>
3303a276 29#include "gdb_string.h"
c906108c
SS
30
31#include <mach.h>
da59e081 32#include <mach_error.h>
c906108c
SS
33#include <mach/message.h>
34#include <mach/exception.h>
c906108c 35
4604bcad
MK
36#include "i386-tdep.h"
37
c906108c 38#include "gnu-nat.h"
e750d25e 39#include "i387-tdep.h"
c906108c 40
57e76fac
MS
41#ifdef HAVE_SYS_PROCFS_H
42# include <sys/procfs.h>
43# include "gregset.h"
44#endif
c906108c 45
da59e081
JM
46/* Offset to the thread_state_t location where REG is stored. */
47#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
c906108c 48
383d750b
MK
49/* At REG_OFFSET[N] is the offset to the thread_state_t location where
50 the GDB register N is stored. */
c5aa993b 51static int reg_offset[] =
c906108c 52{
c5aa993b
JM
53 REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
54 REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
55 REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
56 REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
c906108c
SS
57};
58
da59e081 59#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
7f7fe91e 60#define CREG_ADDR(state, regnum) ((const char *)(state) + reg_offset[regnum])
da59e081 61
c906108c 62\f
3303a276
MK
63/* Get the whole floating-point state of THREAD and record the values
64 of the corresponding (pseudo) registers. */
65
da59e081 66static void
56be3814 67fetch_fpregs (struct regcache *regcache, struct proc *thread)
c906108c 68{
da59e081
JM
69 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
70 struct i386_float_state state;
da59e081 71 error_t err;
c906108c 72
da59e081
JM
73 err = thread_get_state (thread->port, i386_FLOAT_STATE,
74 (thread_state_t) &state, &count);
75 if (err)
c906108c 76 {
8a3fe4f8 77 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
78 proc_string (thread));
79 return;
c906108c 80 }
da59e081 81
383d750b 82 if (!state.initialized)
c906108c 83 {
3303a276 84 /* The floating-point state isn't initialized. */
56be3814 85 i387_supply_fsave (regcache, -1, NULL);
3303a276
MK
86 }
87 else
88 {
89 /* Supply the floating-point registers. */
56be3814 90 i387_supply_fsave (regcache, -1, state.hw_state);
c906108c
SS
91 }
92}
da59e081 93
57e76fac
MS
94#ifdef HAVE_SYS_PROCFS_H
95/* These two calls are used by the core-regset.c code for
96 reading ELF core files. */
97void
7f7fe91e 98supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregs)
57e76fac
MS
99{
100 int i;
65e78234 101 for (i = 0; i < I386_NUM_GREGS; i++)
7f7fe91e 102 regcache_raw_supply (regcache, i, CREG_ADDR (gregs, i));
57e76fac
MS
103}
104
105void
7f7fe91e 106supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
57e76fac 107{
7f7fe91e 108 i387_supply_fsave (regcache, -1, fpregs);
57e76fac
MS
109}
110#endif
111
da59e081 112/* Fetch register REGNO, or all regs if REGNO is -1. */
c906108c 113void
56be3814 114gnu_fetch_registers (struct regcache *regcache, int regno)
c906108c
SS
115{
116 struct proc *thread;
c5aa993b 117
da59e081 118 /* Make sure we know about new threads. */
c289427b 119 inf_update_procs (gnu_current_inf);
c906108c 120
c289427b 121 thread = inf_tid_to_thread (gnu_current_inf,
617fd3b5 122 ptid_get_tid (inferior_ptid));
c5aa993b 123 if (!thread)
617fd3b5
PA
124 error (_("Can't fetch registers from thread %s: No such thread"),
125 target_pid_to_str (inferior_ptid));
c906108c 126
65e78234 127 if (regno < I386_NUM_GREGS || regno == -1)
c906108c 128 {
da59e081 129 thread_state_t state;
383d750b 130
da59e081
JM
131 /* This does the dirty work for us. */
132 state = proc_get_state (thread, 0);
133 if (!state)
c906108c 134 {
8a3fe4f8 135 warning (_("Couldn't fetch registers from %s"),
da59e081
JM
136 proc_string (thread));
137 return;
c906108c
SS
138 }
139
da59e081 140 if (regno == -1)
c906108c 141 {
da59e081 142 int i;
383d750b 143
da59e081 144 proc_debug (thread, "fetching all register");
383d750b 145
65e78234 146 for (i = 0; i < I386_NUM_GREGS; i++)
56be3814 147 regcache_raw_supply (regcache, i, REG_ADDR (state, i));
da59e081 148 thread->fetched_regs = ~0;
c906108c
SS
149 }
150 else
151 {
c9f4d572 152 proc_debug (thread, "fetching register %s",
875f8d0e
UW
153 gdbarch_register_name (get_regcache_arch (regcache),
154 regno));
383d750b 155
56be3814 156 regcache_raw_supply (regcache, regno,
23a6d369 157 REG_ADDR (state, regno));
da59e081 158 thread->fetched_regs |= (1 << regno);
c906108c
SS
159 }
160 }
da59e081 161
65e78234 162 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
163 {
164 proc_debug (thread, "fetching floating-point registers");
383d750b 165
56be3814 166 fetch_fpregs (regcache, thread);
da59e081 167 }
c906108c
SS
168}
169\f
da59e081
JM
170
171/* Store the whole floating-point state into THREAD using information
172 from the corresponding (pseudo) registers. */
173static void
56be3814 174store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
da59e081
JM
175{
176 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
177 struct i386_float_state state;
178 error_t err;
c5aa993b 179
da59e081
JM
180 err = thread_get_state (thread->port, i386_FLOAT_STATE,
181 (thread_state_t) &state, &count);
182 if (err)
c906108c 183 {
8a3fe4f8 184 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
185 proc_string (thread));
186 return;
c906108c 187 }
c5aa993b 188
383d750b 189 /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
8262ee23 190 take into account DEPRECATED_REGISTER_VALID like the old code did? */
56be3814 191 i387_collect_fsave (regcache, regno, state.hw_state);
383d750b 192
da59e081
JM
193 err = thread_set_state (thread->port, i386_FLOAT_STATE,
194 (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
195 if (err)
c906108c 196 {
8a3fe4f8 197 warning (_("Couldn't store floating-point state into %s"),
da59e081
JM
198 proc_string (thread));
199 return;
c906108c 200 }
c906108c 201}
c5aa993b 202
da59e081
JM
203/* Store at least register REGNO, or all regs if REGNO == -1. */
204void
56be3814 205gnu_store_registers (struct regcache *regcache, int regno)
c5aa993b 206{
da59e081 207 struct proc *thread;
875f8d0e 208 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c 209
da59e081 210 /* Make sure we know about new threads. */
c289427b 211 inf_update_procs (gnu_current_inf);
c5aa993b 212
c289427b 213 thread = inf_tid_to_thread (gnu_current_inf,
617fd3b5 214 ptid_get_tid (inferior_ptid));
c906108c 215 if (!thread)
617fd3b5
PA
216 error (_("Couldn't store registers into thread %s: No such thread"),
217 target_pid_to_str (inferior_ptid));
c906108c 218
65e78234 219 if (regno < I386_NUM_GREGS || regno == -1)
c906108c 220 {
da59e081
JM
221 thread_state_t state;
222 thread_state_data_t old_state;
223 int was_aborted = thread->aborted;
224 int was_valid = thread->state_valid;
fb557744 225 int trace;
c906108c 226
da59e081
JM
227 if (!was_aborted && was_valid)
228 memcpy (&old_state, &thread->state, sizeof (old_state));
c906108c 229
da59e081
JM
230 state = proc_get_state (thread, 1);
231 if (!state)
232 {
8a3fe4f8 233 warning (_("Couldn't store registers into %s"), proc_string (thread));
da59e081
JM
234 return;
235 }
c906108c 236
fb557744
MK
237 /* Save the T bit. We might try to restore the %eflags register
238 below, but changing the T bit would seriously confuse GDB. */
239 trace = ((struct i386_thread_state *)state)->efl & 0x100;
240
da59e081
JM
241 if (!was_aborted && was_valid)
242 /* See which registers have changed after aborting the thread. */
243 {
244 int check_regno;
245
65e78234 246 for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
da59e081
JM
247 if ((thread->fetched_regs & (1 << check_regno))
248 && memcpy (REG_ADDR (&old_state, check_regno),
249 REG_ADDR (state, check_regno),
875f8d0e 250 register_size (gdbarch, check_regno)))
da59e081
JM
251 /* Register CHECK_REGNO has changed! Ack! */
252 {
8a3fe4f8 253 warning (_("Register %s changed after the thread was aborted"),
875f8d0e 254 gdbarch_register_name (gdbarch, check_regno));
da59e081 255 if (regno >= 0 && regno != check_regno)
383d750b 256 /* Update GDB's copy of the register. */
f6052080 257 regcache_raw_supply (regcache, check_regno,
23a6d369 258 REG_ADDR (state, check_regno));
da59e081 259 else
8a3fe4f8 260 warning (_("... also writing this register! Suspicious..."));
da59e081
JM
261 }
262 }
c906108c 263
da59e081
JM
264 if (regno == -1)
265 {
266 int i;
383d750b 267
da59e081 268 proc_debug (thread, "storing all registers");
c5aa993b 269
65e78234 270 for (i = 0; i < I386_NUM_GREGS; i++)
f6052080 271 if (regcache_valid_p (regcache, i))
9b8607ce 272 regcache_raw_collect (regcache, i, REG_ADDR (state, i));
da59e081
JM
273 }
274 else
275 {
c9f4d572 276 proc_debug (thread, "storing register %s",
875f8d0e 277 gdbarch_register_name (gdbarch, regno));
c906108c 278
f6052080 279 gdb_assert (regcache_valid_p (regcache, regno));
ecac404d 280 regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
da59e081 281 }
fb557744
MK
282
283 /* Restore the T bit. */
284 ((struct i386_thread_state *)state)->efl &= ~0x100;
285 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 286 }
c5aa993b 287
65e78234 288 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
289 {
290 proc_debug (thread, "storing floating-point registers");
383d750b 291
56be3814 292 store_fpregs (regcache, thread, regno);
da59e081 293 }
c906108c 294}
This page took 1.225479 seconds and 4 git commands to generate.