1130812Smarcel/* Low level interface to i386 running the GNU Hurd. 2130812Smarcel Copyright 1992, 1995, 1996, 1998, 2000, 2001 3130812Smarcel Free Software Foundation, Inc. 4130812Smarcel 5130812Smarcel This file is part of GDB. 6130812Smarcel 7130812Smarcel This program is free software; you can redistribute it and/or modify 8130812Smarcel it under the terms of the GNU General Public License as published by 9130812Smarcel the Free Software Foundation; either version 2 of the License, or 10130812Smarcel (at your option) any later version. 11130812Smarcel 12130812Smarcel This program is distributed in the hope that it will be useful, 13130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130812Smarcel GNU General Public License for more details. 16130812Smarcel 17130812Smarcel You should have received a copy of the GNU General Public License 18130812Smarcel along with this program; if not, write to the Free Software 19130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130812Smarcel Boston, MA 02111-1307, USA. */ 21130812Smarcel 22130812Smarcel#include "defs.h" 23130812Smarcel#include "inferior.h" 24130812Smarcel#include "floatformat.h" 25130812Smarcel#include "regcache.h" 26130812Smarcel 27130812Smarcel#include "gdb_assert.h" 28130812Smarcel#include <errno.h> 29130812Smarcel#include <stdio.h> 30130812Smarcel 31130812Smarcel#include <mach.h> 32130812Smarcel#include <mach_error.h> 33130812Smarcel#include <mach/message.h> 34130812Smarcel#include <mach/exception.h> 35130812Smarcel 36130812Smarcel#include "i386-tdep.h" 37130812Smarcel 38130812Smarcel#include "gnu-nat.h" 39130812Smarcel#include "i387-tdep.h" 40130812Smarcel 41130812Smarcel#ifdef HAVE_SYS_PROCFS_H 42130812Smarcel# include <sys/procfs.h> 43130812Smarcel# include "gregset.h" 44130812Smarcel#endif 45130812Smarcel 46130812Smarcel/* Offset to the thread_state_t location where REG is stored. */ 47130812Smarcel#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg) 48130812Smarcel 49130812Smarcel/* At REG_OFFSET[N] is the offset to the thread_state_t location where 50130812Smarcel the GDB register N is stored. */ 51130812Smarcelstatic int reg_offset[] = 52130812Smarcel{ 53130812Smarcel REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx), 54130812Smarcel REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi), 55130812Smarcel REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss), 56130812Smarcel REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs) 57130812Smarcel}; 58130812Smarcel 59130812Smarcel#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum]) 60130812Smarcel 61130812Smarcel 62130812Smarcel/* Get the whole floating-point state of THREAD and record the 63130812Smarcel values of the corresponding (pseudo) registers. */ 64130812Smarcelstatic void 65130812Smarcelfetch_fpregs (struct proc *thread) 66130812Smarcel{ 67130812Smarcel mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; 68130812Smarcel struct i386_float_state state; 69130812Smarcel error_t err; 70130812Smarcel 71130812Smarcel err = thread_get_state (thread->port, i386_FLOAT_STATE, 72130812Smarcel (thread_state_t) &state, &count); 73130812Smarcel if (err) 74130812Smarcel { 75130812Smarcel warning ("Couldn't fetch floating-point state from %s", 76130812Smarcel proc_string (thread)); 77130812Smarcel return; 78130812Smarcel } 79130812Smarcel 80130812Smarcel if (!state.initialized) 81130812Smarcel /* The floating-point state isn't initialized. */ 82130812Smarcel { 83130812Smarcel int i; 84130812Smarcel 85130812Smarcel for (i = FP0_REGNUM; i <= FOP_REGNUM; i++) 86130812Smarcel supply_register (i, NULL); 87130812Smarcel 88130812Smarcel return; 89130812Smarcel } 90130812Smarcel 91130812Smarcel /* Supply the floating-point registers. */ 92130812Smarcel i387_supply_fsave (current_regcache, -1, state.hw_state); 93130812Smarcel} 94130812Smarcel 95130812Smarcel#ifdef HAVE_SYS_PROCFS_H 96130812Smarcel/* These two calls are used by the core-regset.c code for 97130812Smarcel reading ELF core files. */ 98130812Smarcelvoid 99130812Smarcelsupply_gregset (gdb_gregset_t *gregs) 100130812Smarcel{ 101130812Smarcel int i; 102130812Smarcel for (i = 0; i < I386_NUM_GREGS; i++) 103130812Smarcel supply_register (i, REG_ADDR (gregs, i)); 104130812Smarcel} 105130812Smarcel 106130812Smarcelvoid 107130812Smarcelsupply_fpregset (gdb_fpregset_t *fpregs) 108130812Smarcel{ 109130812Smarcel i387_supply_fsave (current_regcache, -1, fpregs); 110130812Smarcel} 111130812Smarcel#endif 112130812Smarcel 113130812Smarcel/* Fetch register REGNO, or all regs if REGNO is -1. */ 114130812Smarcelvoid 115130812Smarcelgnu_fetch_registers (int regno) 116130812Smarcel{ 117130812Smarcel struct proc *thread; 118130812Smarcel 119130812Smarcel /* Make sure we know about new threads. */ 120130812Smarcel inf_update_procs (current_inferior); 121130812Smarcel 122130812Smarcel thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); 123130812Smarcel if (!thread) 124130812Smarcel error ("Can't fetch registers from thread %d: No such thread", 125130812Smarcel PIDGET (inferior_ptid)); 126130812Smarcel 127130812Smarcel if (regno < I386_NUM_GREGS || regno == -1) 128130812Smarcel { 129130812Smarcel thread_state_t state; 130130812Smarcel 131130812Smarcel /* This does the dirty work for us. */ 132130812Smarcel state = proc_get_state (thread, 0); 133130812Smarcel if (!state) 134130812Smarcel { 135130812Smarcel warning ("Couldn't fetch registers from %s", 136130812Smarcel proc_string (thread)); 137130812Smarcel return; 138130812Smarcel } 139130812Smarcel 140130812Smarcel if (regno == -1) 141130812Smarcel { 142130812Smarcel int i; 143130812Smarcel 144130812Smarcel proc_debug (thread, "fetching all register"); 145130812Smarcel 146130812Smarcel for (i = 0; i < I386_NUM_GREGS; i++) 147130812Smarcel supply_register (i, REG_ADDR (state, i)); 148130812Smarcel thread->fetched_regs = ~0; 149130812Smarcel } 150130812Smarcel else 151130812Smarcel { 152130812Smarcel proc_debug (thread, "fetching register %s", REGISTER_NAME (regno)); 153130812Smarcel 154130812Smarcel supply_register (regno, REG_ADDR (state, regno)); 155130812Smarcel thread->fetched_regs |= (1 << regno); 156130812Smarcel } 157130812Smarcel } 158130812Smarcel 159130812Smarcel if (regno >= I386_NUM_GREGS || regno == -1) 160130812Smarcel { 161130812Smarcel proc_debug (thread, "fetching floating-point registers"); 162130812Smarcel 163130812Smarcel fetch_fpregs (thread); 164130812Smarcel } 165130812Smarcel} 166130812Smarcel 167130812Smarcel 168130812Smarcel/* Store the whole floating-point state into THREAD using information 169130812Smarcel from the corresponding (pseudo) registers. */ 170130812Smarcelstatic void 171130812Smarcelstore_fpregs (struct proc *thread, int regno) 172130812Smarcel{ 173130812Smarcel mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; 174130812Smarcel struct i386_float_state state; 175130812Smarcel error_t err; 176130812Smarcel 177130812Smarcel err = thread_get_state (thread->port, i386_FLOAT_STATE, 178130812Smarcel (thread_state_t) &state, &count); 179130812Smarcel if (err) 180130812Smarcel { 181130812Smarcel warning ("Couldn't fetch floating-point state from %s", 182130812Smarcel proc_string (thread)); 183130812Smarcel return; 184130812Smarcel } 185130812Smarcel 186130812Smarcel /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow 187130812Smarcel take into account DEPRECATED_REGISTER_VALID like the old code did? */ 188130812Smarcel i387_fill_fsave (state.hw_state, regno); 189130812Smarcel 190130812Smarcel err = thread_set_state (thread->port, i386_FLOAT_STATE, 191130812Smarcel (thread_state_t) &state, i386_FLOAT_STATE_COUNT); 192130812Smarcel if (err) 193130812Smarcel { 194130812Smarcel warning ("Couldn't store floating-point state into %s", 195130812Smarcel proc_string (thread)); 196130812Smarcel return; 197130812Smarcel } 198130812Smarcel} 199130812Smarcel 200130812Smarcel/* Store at least register REGNO, or all regs if REGNO == -1. */ 201130812Smarcelvoid 202130812Smarcelgnu_store_registers (int regno) 203130812Smarcel{ 204130812Smarcel struct proc *thread; 205130812Smarcel 206130812Smarcel /* Make sure we know about new threads. */ 207130812Smarcel inf_update_procs (current_inferior); 208130812Smarcel 209130812Smarcel thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); 210130812Smarcel if (!thread) 211130812Smarcel error ("Couldn't store registers into thread %d: No such thread", 212130812Smarcel PIDGET (inferior_ptid)); 213130812Smarcel 214130812Smarcel if (regno < I386_NUM_GREGS || regno == -1) 215130812Smarcel { 216130812Smarcel thread_state_t state; 217130812Smarcel thread_state_data_t old_state; 218130812Smarcel int was_aborted = thread->aborted; 219130812Smarcel int was_valid = thread->state_valid; 220130812Smarcel int trace; 221130812Smarcel 222130812Smarcel if (!was_aborted && was_valid) 223130812Smarcel memcpy (&old_state, &thread->state, sizeof (old_state)); 224130812Smarcel 225130812Smarcel state = proc_get_state (thread, 1); 226130812Smarcel if (!state) 227130812Smarcel { 228130812Smarcel warning ("Couldn't store registers into %s", proc_string (thread)); 229130812Smarcel return; 230130812Smarcel } 231130812Smarcel 232130812Smarcel /* Save the T bit. We might try to restore the %eflags register 233130812Smarcel below, but changing the T bit would seriously confuse GDB. */ 234130812Smarcel trace = ((struct i386_thread_state *)state)->efl & 0x100; 235130812Smarcel 236130812Smarcel if (!was_aborted && was_valid) 237130812Smarcel /* See which registers have changed after aborting the thread. */ 238130812Smarcel { 239130812Smarcel int check_regno; 240130812Smarcel 241130812Smarcel for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) 242130812Smarcel if ((thread->fetched_regs & (1 << check_regno)) 243130812Smarcel && memcpy (REG_ADDR (&old_state, check_regno), 244130812Smarcel REG_ADDR (state, check_regno), 245130812Smarcel DEPRECATED_REGISTER_RAW_SIZE (check_regno))) 246130812Smarcel /* Register CHECK_REGNO has changed! Ack! */ 247130812Smarcel { 248130812Smarcel warning ("Register %s changed after the thread was aborted", 249130812Smarcel REGISTER_NAME (check_regno)); 250130812Smarcel if (regno >= 0 && regno != check_regno) 251130812Smarcel /* Update GDB's copy of the register. */ 252130812Smarcel supply_register (check_regno, REG_ADDR (state, check_regno)); 253130812Smarcel else 254130812Smarcel warning ("... also writing this register! Suspicious..."); 255130812Smarcel } 256130812Smarcel } 257130812Smarcel 258130812Smarcel#define fill(state, regno) \ 259130812Smarcel memcpy (REG_ADDR(state, regno), &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], \ 260130812Smarcel DEPRECATED_REGISTER_RAW_SIZE (regno)) 261130812Smarcel 262130812Smarcel if (regno == -1) 263130812Smarcel { 264130812Smarcel int i; 265130812Smarcel 266130812Smarcel proc_debug (thread, "storing all registers"); 267130812Smarcel 268130812Smarcel for (i = 0; i < I386_NUM_GREGS; i++) 269130812Smarcel if (deprecated_register_valid[i]) 270130812Smarcel fill (state, i); 271130812Smarcel } 272130812Smarcel else 273130812Smarcel { 274130812Smarcel proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); 275130812Smarcel 276130812Smarcel gdb_assert (deprecated_register_valid[regno]); 277130812Smarcel fill (state, regno); 278130812Smarcel } 279130812Smarcel 280130812Smarcel /* Restore the T bit. */ 281130812Smarcel ((struct i386_thread_state *)state)->efl &= ~0x100; 282130812Smarcel ((struct i386_thread_state *)state)->efl |= trace; 283130812Smarcel } 284130812Smarcel 285130812Smarcel#undef fill 286130812Smarcel 287130812Smarcel if (regno >= I386_NUM_GREGS || regno == -1) 288130812Smarcel { 289130812Smarcel proc_debug (thread, "storing floating-point registers"); 290130812Smarcel 291130812Smarcel store_fpregs (thread, regno); 292130812Smarcel } 293130812Smarcel} 294