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