gdb/gdbserver:
[deliverable/binutils-gdb.git] / gdb / i386gnu-nat.c
CommitLineData
da59e081 1/* Low level interface to i386 running the GNU Hurd.
f6052080 2
28e7fd62 3 Copyright (C) 1992-2013 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
SS
19
20#include "defs.h"
21#include "inferior.h"
22#include "floatformat.h"
4e052eda 23#include "regcache.h"
c906108c 24
780a49fa 25#include "gdb_assert.h"
c906108c 26#include <errno.h>
383d750b 27#include <stdio.h>
3303a276 28#include "gdb_string.h"
c906108c
SS
29
30#include <mach.h>
da59e081 31#include <mach_error.h>
c906108c
SS
32#include <mach/message.h>
33#include <mach/exception.h>
c906108c 34
4604bcad
MK
35#include "i386-tdep.h"
36
c906108c 37#include "gnu-nat.h"
e750d25e 38#include "i387-tdep.h"
c906108c 39
57e76fac
MS
40#ifdef HAVE_SYS_PROCFS_H
41# include <sys/procfs.h>
42# include "gregset.h"
43#endif
c906108c 44
da59e081
JM
45/* Offset to the thread_state_t location where REG is stored. */
46#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
c906108c 47
383d750b
MK
48/* At REG_OFFSET[N] is the offset to the thread_state_t location where
49 the GDB register N is stored. */
c5aa993b 50static int reg_offset[] =
c906108c 51{
c5aa993b
JM
52 REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
53 REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
54 REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
55 REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
c906108c
SS
56};
57
da59e081 58#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
7f7fe91e 59#define CREG_ADDR(state, regnum) ((const char *)(state) + reg_offset[regnum])
da59e081 60
c906108c 61\f
3303a276
MK
62/* Get the whole floating-point state of THREAD and record the values
63 of the corresponding (pseudo) registers. */
64
da59e081 65static void
56be3814 66fetch_fpregs (struct regcache *regcache, struct proc *thread)
c906108c 67{
da59e081
JM
68 mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
69 struct i386_float_state state;
da59e081 70 error_t err;
c906108c 71
da59e081
JM
72 err = thread_get_state (thread->port, i386_FLOAT_STATE,
73 (thread_state_t) &state, &count);
74 if (err)
c906108c 75 {
8a3fe4f8 76 warning (_("Couldn't fetch floating-point state from %s"),
da59e081
JM
77 proc_string (thread));
78 return;
c906108c 79 }
da59e081 80
383d750b 81 if (!state.initialized)
c906108c 82 {
3303a276 83 /* The floating-point state isn't initialized. */
56be3814 84 i387_supply_fsave (regcache, -1, NULL);
3303a276
MK
85 }
86 else
87 {
88 /* Supply the floating-point registers. */
56be3814 89 i387_supply_fsave (regcache, -1, state.hw_state);
c906108c
SS
90 }
91}
da59e081 92
57e76fac
MS
93#ifdef HAVE_SYS_PROCFS_H
94/* These two calls are used by the core-regset.c code for
95 reading ELF core files. */
96void
7f7fe91e 97supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregs)
57e76fac
MS
98{
99 int i;
65e78234 100 for (i = 0; i < I386_NUM_GREGS; i++)
7f7fe91e 101 regcache_raw_supply (regcache, i, CREG_ADDR (gregs, i));
57e76fac
MS
102}
103
104void
7f7fe91e 105supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
57e76fac 106{
7f7fe91e 107 i387_supply_fsave (regcache, -1, fpregs);
57e76fac
MS
108}
109#endif
110
da59e081 111/* Fetch register REGNO, or all regs if REGNO is -1. */
b4d1e8c7 112static void
85a772a5
TS
113gnu_fetch_registers (struct target_ops *ops,
114 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 203/* Store at least register REGNO, or all regs if REGNO == -1. */
b4d1e8c7 204static void
85a772a5
TS
205gnu_store_registers (struct target_ops *ops,
206 struct regcache *regcache, int regno)
c5aa993b 207{
da59e081 208 struct proc *thread;
875f8d0e 209 struct gdbarch *gdbarch = get_regcache_arch (regcache);
c906108c 210
da59e081 211 /* Make sure we know about new threads. */
c289427b 212 inf_update_procs (gnu_current_inf);
c5aa993b 213
c289427b 214 thread = inf_tid_to_thread (gnu_current_inf,
617fd3b5 215 ptid_get_tid (inferior_ptid));
c906108c 216 if (!thread)
617fd3b5
PA
217 error (_("Couldn't store registers into thread %s: No such thread"),
218 target_pid_to_str (inferior_ptid));
c906108c 219
65e78234 220 if (regno < I386_NUM_GREGS || regno == -1)
c906108c 221 {
da59e081
JM
222 thread_state_t state;
223 thread_state_data_t old_state;
224 int was_aborted = thread->aborted;
225 int was_valid = thread->state_valid;
fb557744 226 int trace;
c906108c 227
da59e081
JM
228 if (!was_aborted && was_valid)
229 memcpy (&old_state, &thread->state, sizeof (old_state));
c906108c 230
da59e081
JM
231 state = proc_get_state (thread, 1);
232 if (!state)
233 {
1777feb0
MS
234 warning (_("Couldn't store registers into %s"),
235 proc_string (thread));
da59e081
JM
236 return;
237 }
c906108c 238
fb557744
MK
239 /* Save the T bit. We might try to restore the %eflags register
240 below, but changing the T bit would seriously confuse GDB. */
241 trace = ((struct i386_thread_state *)state)->efl & 0x100;
242
da59e081
JM
243 if (!was_aborted && was_valid)
244 /* See which registers have changed after aborting the thread. */
245 {
246 int check_regno;
247
65e78234 248 for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
da59e081
JM
249 if ((thread->fetched_regs & (1 << check_regno))
250 && memcpy (REG_ADDR (&old_state, check_regno),
251 REG_ADDR (state, check_regno),
875f8d0e 252 register_size (gdbarch, check_regno)))
da59e081
JM
253 /* Register CHECK_REGNO has changed! Ack! */
254 {
8a3fe4f8 255 warning (_("Register %s changed after the thread was aborted"),
875f8d0e 256 gdbarch_register_name (gdbarch, check_regno));
da59e081 257 if (regno >= 0 && regno != check_regno)
383d750b 258 /* Update GDB's copy of the register. */
f6052080 259 regcache_raw_supply (regcache, check_regno,
23a6d369 260 REG_ADDR (state, check_regno));
da59e081 261 else
1777feb0
MS
262 warning (_("... also writing this register! "
263 "Suspicious..."));
da59e081
JM
264 }
265 }
c906108c 266
da59e081
JM
267 if (regno == -1)
268 {
269 int i;
383d750b 270
da59e081 271 proc_debug (thread, "storing all registers");
c5aa993b 272
65e78234 273 for (i = 0; i < I386_NUM_GREGS; i++)
672c9795 274 if (REG_VALID == regcache_register_status (regcache, i))
9b8607ce 275 regcache_raw_collect (regcache, i, REG_ADDR (state, i));
da59e081
JM
276 }
277 else
278 {
c9f4d572 279 proc_debug (thread, "storing register %s",
875f8d0e 280 gdbarch_register_name (gdbarch, regno));
c906108c 281
672c9795 282 gdb_assert (REG_VALID == regcache_register_status (regcache, regno));
ecac404d 283 regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
da59e081 284 }
fb557744
MK
285
286 /* Restore the T bit. */
287 ((struct i386_thread_state *)state)->efl &= ~0x100;
288 ((struct i386_thread_state *)state)->efl |= trace;
c906108c 289 }
c5aa993b 290
65e78234 291 if (regno >= I386_NUM_GREGS || regno == -1)
da59e081
JM
292 {
293 proc_debug (thread, "storing floating-point registers");
383d750b 294
56be3814 295 store_fpregs (regcache, thread, regno);
da59e081 296 }
c906108c 297}
b4d1e8c7
PA
298
299/* Provide a prototype to silence -Wmissing-prototypes. */
300extern initialize_file_ftype _initialize_i386gnu_nat;
301
302void
303_initialize_i386gnu_nat (void)
304{
305 struct target_ops *t;
306
307 /* Fill in the generic GNU/Hurd methods. */
308 t = gnu_target ();
309
310 t->to_fetch_registers = gnu_fetch_registers;
311 t->to_store_registers = gnu_store_registers;
312
313 /* Register the target. */
314 add_target (t);
315}
This page took 1.636377 seconds and 4 git commands to generate.