1 1.1 christos /* Low level interface to i386 running the GNU Hurd. 2 1.1 christos 3 1.1.1.5 christos Copyright (C) 1992-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1.1.2 christos /* Include this first, to pick up the <mach.h> 'thread_info' diversion. */ 21 1.1.1.2 christos #include "gnu-nat.h" 22 1.1.1.2 christos 23 1.1 christos /* Mach/Hurd headers are not yet ready for C++ compilation. */ 24 1.1 christos extern "C" 25 1.1 christos { 26 1.1 christos #include <mach.h> 27 1.1 christos #include <mach_error.h> 28 1.1 christos #include <mach/message.h> 29 1.1 christos #include <mach/exception.h> 30 1.1 christos } 31 1.1 christos 32 1.1 christos #include "x86-nat.h" 33 1.1 christos #include "inferior.h" 34 1.1 christos #include "floatformat.h" 35 1.1 christos #include "regcache.h" 36 1.1 christos 37 1.1 christos #include "i386-tdep.h" 38 1.1 christos 39 1.1 christos #include "inf-child.h" 40 1.1 christos #include "i387-tdep.h" 41 1.1 christos 42 1.1 christos /* Offset to the thread_state_t location where REG is stored. */ 43 1.1 christos #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg) 44 1.1 christos 45 1.1 christos /* At REG_OFFSET[N] is the offset to the thread_state_t location where 46 1.1 christos the GDB register N is stored. */ 47 1.1 christos static int reg_offset[] = 48 1.1 christos { 49 1.1 christos REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx), 50 1.1 christos REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi), 51 1.1 christos REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss), 52 1.1 christos REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs) 53 1.1 christos }; 54 1.1 christos 55 1.1 christos #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum]) 56 1.1 christos 57 1.1 christos 58 1.1.1.2 christos 60 1.1.1.2 christos /* The i386 GNU Hurd target. */ 61 1.1.1.2 christos 62 1.1.1.2 christos #ifdef i386_DEBUG_STATE 63 1.1.1.2 christos using gnu_base_target = x86_nat_target<gnu_nat_target>; 64 1.1.1.2 christos #else 65 1.1.1.2 christos using gnu_base_target = gnu_nat_target; 66 1.1.1.2 christos #endif 67 1.1.1.2 christos 68 1.1.1.2 christos struct i386_gnu_nat_target final : public gnu_base_target 69 1.1.1.2 christos { 70 1.1.1.2 christos void fetch_registers (struct regcache *, int) override; 71 1.1.1.2 christos void store_registers (struct regcache *, int) override; 72 1.1.1.2 christos }; 73 1.1.1.2 christos 74 1.1.1.2 christos static i386_gnu_nat_target the_i386_gnu_nat_target; 75 1.1 christos 76 1.1 christos /* Get the whole floating-point state of THREAD and record the values 77 1.1 christos of the corresponding (pseudo) registers. */ 78 1.1 christos 79 1.1 christos static void 80 1.1 christos fetch_fpregs (struct regcache *regcache, struct proc *thread) 81 1.1 christos { 82 1.1 christos mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; 83 1.1 christos struct i386_float_state state; 84 1.1 christos kern_return_t err; 85 1.1 christos 86 1.1 christos err = thread_get_state (thread->port, i386_FLOAT_STATE, 87 1.1 christos (thread_state_t) &state, &count); 88 1.1 christos if (err) 89 1.1 christos { 90 1.1 christos warning (_("Couldn't fetch floating-point state from %s"), 91 1.1 christos proc_string (thread)); 92 1.1 christos return; 93 1.1 christos } 94 1.1 christos 95 1.1 christos if (!state.initialized) 96 1.1 christos { 97 1.1 christos /* The floating-point state isn't initialized. */ 98 1.1 christos i387_supply_fsave (regcache, -1, NULL); 99 1.1 christos } 100 1.1 christos else 101 1.1 christos { 102 1.1 christos /* Supply the floating-point registers. */ 103 1.1 christos i387_supply_fsave (regcache, -1, state.hw_state); 104 1.1 christos } 105 1.1 christos } 106 1.1 christos 107 1.1.1.2 christos /* Fetch register REGNO, or all regs if REGNO is -1. */ 108 1.1.1.2 christos void 109 1.1 christos i386_gnu_nat_target::fetch_registers (struct regcache *regcache, int regno) 110 1.1 christos { 111 1.1.1.2 christos struct proc *thread; 112 1.1 christos ptid_t ptid = regcache->ptid (); 113 1.1 christos 114 1.1 christos /* Make sure we know about new threads. */ 115 1.1 christos inf_update_procs (gnu_current_inf); 116 1.1.1.2 christos 117 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ()); 118 1.1 christos if (!thread) 119 1.1.1.3 christos error (_("Can't fetch registers from thread %s: No such thread"), 120 1.1 christos target_pid_to_str (ptid).c_str ()); 121 1.1 christos 122 1.1 christos if (regno < I386_NUM_GREGS || regno == -1) 123 1.1 christos { 124 1.1 christos thread_state_t state; 125 1.1 christos 126 1.1 christos /* This does the dirty work for us. */ 127 1.1 christos state = proc_get_state (thread, 0); 128 1.1 christos if (!state) 129 1.1 christos { 130 1.1 christos warning (_("Couldn't fetch registers from %s"), 131 1.1 christos proc_string (thread)); 132 1.1 christos return; 133 1.1 christos } 134 1.1 christos 135 1.1 christos if (regno == -1) 136 1.1 christos { 137 1.1 christos int i; 138 1.1 christos 139 1.1 christos proc_debug (thread, "fetching all register"); 140 1.1 christos 141 1.1.1.2 christos for (i = 0; i < I386_NUM_GREGS; i++) 142 1.1 christos regcache->raw_supply (i, REG_ADDR (state, i)); 143 1.1 christos thread->fetched_regs = ~0; 144 1.1 christos } 145 1.1 christos else 146 1.1 christos { 147 1.1.1.2 christos proc_debug (thread, "fetching register %s", 148 1.1 christos gdbarch_register_name (regcache->arch (), 149 1.1 christos regno)); 150 1.1.1.2 christos 151 1.1 christos regcache->raw_supply (regno, REG_ADDR (state, regno)); 152 1.1 christos thread->fetched_regs |= (1 << regno); 153 1.1 christos } 154 1.1 christos } 155 1.1 christos 156 1.1 christos if (regno >= I386_NUM_GREGS || regno == -1) 157 1.1 christos { 158 1.1 christos proc_debug (thread, "fetching floating-point registers"); 159 1.1 christos 160 1.1 christos fetch_fpregs (regcache, thread); 161 1.1 christos } 162 1.1 christos } 163 1.1 christos 164 1.1 christos 166 1.1 christos /* Store the whole floating-point state into THREAD using information 167 1.1 christos from the corresponding (pseudo) registers. */ 168 1.1 christos static void 169 1.1 christos store_fpregs (const struct regcache *regcache, struct proc *thread, int regno) 170 1.1 christos { 171 1.1 christos mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT; 172 1.1 christos struct i386_float_state state; 173 1.1 christos kern_return_t err; 174 1.1 christos 175 1.1 christos err = thread_get_state (thread->port, i386_FLOAT_STATE, 176 1.1 christos (thread_state_t) &state, &count); 177 1.1 christos if (err) 178 1.1 christos { 179 1.1 christos warning (_("Couldn't fetch floating-point state from %s"), 180 1.1 christos proc_string (thread)); 181 1.1 christos return; 182 1.1 christos } 183 1.1 christos 184 1.1 christos /* FIXME: kettenis/2001-07-15: Is this right? Should we somehow 185 1.1 christos take into account DEPRECATED_REGISTER_VALID like the old code did? */ 186 1.1 christos i387_collect_fsave (regcache, regno, state.hw_state); 187 1.1 christos 188 1.1 christos err = thread_set_state (thread->port, i386_FLOAT_STATE, 189 1.1 christos (thread_state_t) &state, i386_FLOAT_STATE_COUNT); 190 1.1 christos if (err) 191 1.1 christos { 192 1.1 christos warning (_("Couldn't store floating-point state into %s"), 193 1.1 christos proc_string (thread)); 194 1.1 christos return; 195 1.1 christos } 196 1.1 christos } 197 1.1.1.2 christos 198 1.1.1.2 christos /* Store at least register REGNO, or all regs if REGNO == -1. */ 199 1.1 christos void 200 1.1 christos i386_gnu_nat_target::store_registers (struct regcache *regcache, int regno) 201 1.1.1.2 christos { 202 1.1.1.2 christos struct proc *thread; 203 1.1 christos struct gdbarch *gdbarch = regcache->arch (); 204 1.1 christos ptid_t ptid = regcache->ptid (); 205 1.1 christos 206 1.1 christos /* Make sure we know about new threads. */ 207 1.1.1.2 christos inf_update_procs (gnu_current_inf); 208 1.1 christos 209 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ()); 210 1.1.1.3 christos if (!thread) 211 1.1 christos error (_("Couldn't store registers into thread %s: No such thread"), 212 1.1 christos target_pid_to_str (ptid).c_str ()); 213 1.1 christos 214 1.1 christos if (regno < I386_NUM_GREGS || regno == -1) 215 1.1 christos { 216 1.1 christos thread_state_t state; 217 1.1 christos thread_state_data_t old_state; 218 1.1 christos int was_aborted = thread->aborted; 219 1.1 christos int was_valid = thread->state_valid; 220 1.1 christos int trace; 221 1.1 christos 222 1.1 christos if (!was_aborted && was_valid) 223 1.1 christos memcpy (&old_state, &thread->state, sizeof (old_state)); 224 1.1 christos 225 1.1 christos state = proc_get_state (thread, 1); 226 1.1 christos if (!state) 227 1.1 christos { 228 1.1 christos warning (_("Couldn't store registers into %s"), 229 1.1 christos proc_string (thread)); 230 1.1 christos return; 231 1.1 christos } 232 1.1.1.4 christos 233 1.1 christos /* Save the T bit. We might try to restore the %eflags register 234 1.1 christos below, but changing the T bit would seriously confuse GDB. */ 235 1.1 christos trace = ((struct i386_thread_state *)state)->efl & 0x100; 236 1.1 christos 237 1.1 christos if (!was_aborted && was_valid) 238 1.1 christos /* See which registers have changed after aborting the thread. */ 239 1.1 christos { 240 1.1 christos int check_regno; 241 1.1 christos 242 1.1 christos for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) 243 1.1 christos if ((thread->fetched_regs & (1 << check_regno)) 244 1.1 christos && memcpy (REG_ADDR (&old_state, check_regno), 245 1.1 christos REG_ADDR (state, check_regno), 246 1.1 christos register_size (gdbarch, check_regno))) 247 1.1 christos /* Register CHECK_REGNO has changed! Ack! */ 248 1.1 christos { 249 1.1 christos warning (_("Register %s changed after the thread was aborted"), 250 1.1 christos gdbarch_register_name (gdbarch, check_regno)); 251 1.1.1.2 christos if (regno >= 0 && regno != check_regno) 252 1.1.1.2 christos /* Update GDB's copy of the register. */ 253 1.1 christos regcache->raw_supply (check_regno, 254 1.1 christos REG_ADDR (state, check_regno)); 255 1.1 christos else 256 1.1 christos warning (_("... also writing this register! " 257 1.1 christos "Suspicious...")); 258 1.1 christos } 259 1.1 christos } 260 1.1 christos 261 1.1 christos if (regno == -1) 262 1.1 christos { 263 1.1 christos int i; 264 1.1 christos 265 1.1 christos proc_debug (thread, "storing all registers"); 266 1.1.1.2 christos 267 1.1.1.2 christos for (i = 0; i < I386_NUM_GREGS; i++) 268 1.1 christos if (REG_VALID == regcache->get_register_status (i)) 269 1.1 christos regcache->raw_collect (i, REG_ADDR (state, i)); 270 1.1 christos } 271 1.1 christos else 272 1.1 christos { 273 1.1 christos proc_debug (thread, "storing register %s", 274 1.1.1.2 christos gdbarch_register_name (gdbarch, regno)); 275 1.1.1.2 christos 276 1.1 christos gdb_assert (REG_VALID == regcache->get_register_status (regno)); 277 1.1 christos regcache->raw_collect (regno, REG_ADDR (state, regno)); 278 1.1 christos } 279 1.1 christos 280 1.1 christos /* Restore the T bit. */ 281 1.1 christos ((struct i386_thread_state *)state)->efl &= ~0x100; 282 1.1 christos ((struct i386_thread_state *)state)->efl |= trace; 283 1.1 christos } 284 1.1 christos 285 1.1 christos if (regno >= I386_NUM_GREGS || regno == -1) 286 1.1 christos { 287 1.1 christos proc_debug (thread, "storing floating-point registers"); 288 1.1 christos 289 1.1 christos store_fpregs (regcache, thread, regno); 290 1.1 christos } 291 1.1 christos } 292 1.1 christos 293 1.1 christos 294 1.1 christos /* Support for debug registers. */ 296 1.1 christos 297 1.1 christos #ifdef i386_DEBUG_STATE 298 1.1 christos /* Get debug registers for thread THREAD. */ 299 1.1 christos 300 1.1 christos static void 301 1.1 christos i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread) 302 1.1 christos { 303 1.1 christos mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT; 304 1.1 christos kern_return_t err; 305 1.1 christos 306 1.1 christos err = thread_get_state (thread->port, i386_DEBUG_STATE, 307 1.1 christos (thread_state_t) regs, &count); 308 1.1 christos if (err != 0 || count != i386_DEBUG_STATE_COUNT) 309 1.1 christos warning (_("Couldn't fetch debug state from %s"), 310 1.1 christos proc_string (thread)); 311 1.1 christos } 312 1.1 christos 313 1.1 christos /* Set debug registers for thread THREAD. */ 314 1.1 christos 315 1.1 christos static void 316 1.1 christos i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread) 317 1.1 christos { 318 1.1 christos kern_return_t err; 319 1.1 christos 320 1.1 christos err = thread_set_state (thread->port, i386_DEBUG_STATE, 321 1.1 christos (thread_state_t) regs, i386_DEBUG_STATE_COUNT); 322 1.1 christos if (err != 0) 323 1.1 christos warning (_("Couldn't store debug state into %s"), 324 1.1 christos proc_string (thread)); 325 1.1 christos } 326 1.1 christos 327 1.1 christos /* Set DR_CONTROL in THREAD. */ 328 1.1 christos 329 1.1 christos static void 330 1.1 christos i386_gnu_dr_set_control_one (struct proc *thread, void *arg) 331 1.1 christos { 332 1.1 christos unsigned long *control = (unsigned long *) arg; 333 1.1 christos struct i386_debug_state regs; 334 1.1 christos 335 1.1 christos i386_gnu_dr_get (®s, thread); 336 1.1 christos regs.dr[DR_CONTROL] = *control; 337 1.1 christos i386_gnu_dr_set (®s, thread); 338 1.1 christos } 339 1.1 christos 340 1.1 christos /* Set DR_CONTROL to CONTROL in all threads. */ 341 1.1 christos 342 1.1 christos static void 343 1.1 christos i386_gnu_dr_set_control (unsigned long control) 344 1.1 christos { 345 1.1 christos inf_update_procs (gnu_current_inf); 346 1.1 christos inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control); 347 1.1 christos } 348 1.1 christos 349 1.1 christos /* Parameters to set a debugging address. */ 350 1.1 christos 351 1.1 christos struct reg_addr 352 1.1 christos { 353 1.1 christos int regnum; /* Register number (zero based). */ 354 1.1 christos CORE_ADDR addr; /* Address. */ 355 1.1 christos }; 356 1.1 christos 357 1.1 christos /* Set address REGNUM (zero based) to ADDR in THREAD. */ 358 1.1 christos 359 1.1 christos static void 360 1.1 christos i386_gnu_dr_set_addr_one (struct proc *thread, void *arg) 361 1.1 christos { 362 1.1 christos struct reg_addr *reg_addr = (struct reg_addr *) arg; 363 1.1 christos struct i386_debug_state regs; 364 1.1 christos 365 1.1 christos i386_gnu_dr_get (®s, thread); 366 1.1 christos regs.dr[reg_addr->regnum] = reg_addr->addr; 367 1.1 christos i386_gnu_dr_set (®s, thread); 368 1.1 christos } 369 1.1 christos 370 1.1 christos /* Set address REGNUM (zero based) to ADDR in all threads. */ 371 1.1 christos 372 1.1 christos static void 373 1.1 christos i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr) 374 1.1 christos { 375 1.1 christos struct reg_addr reg_addr; 376 1.1 christos 377 1.1 christos gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); 378 1.1 christos 379 1.1 christos reg_addr.regnum = regnum; 380 1.1 christos reg_addr.addr = addr; 381 1.1 christos 382 1.1 christos inf_update_procs (gnu_current_inf); 383 1.1 christos inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, ®_addr); 384 1.1 christos } 385 1.1 christos 386 1.1 christos /* Get debug register REGNUM value from only the one LWP of PTID. */ 387 1.1 christos 388 1.1 christos static unsigned long 389 1.1 christos i386_gnu_dr_get_reg (ptid_t ptid, int regnum) 390 1.1 christos { 391 1.1 christos struct i386_debug_state regs; 392 1.1 christos struct proc *thread; 393 1.1 christos 394 1.1.1.2 christos /* Make sure we know about new threads. */ 395 1.1 christos inf_update_procs (gnu_current_inf); 396 1.1 christos 397 1.1 christos thread = inf_tid_to_thread (gnu_current_inf, ptid.lwp ()); 398 1.1 christos i386_gnu_dr_get (®s, thread); 399 1.1 christos 400 1.1 christos return regs.dr[regnum]; 401 1.1 christos } 402 1.1 christos 403 1.1 christos /* Return the inferior's debug register REGNUM. */ 404 1.1 christos 405 1.1 christos static CORE_ADDR 406 1.1 christos i386_gnu_dr_get_addr (int regnum) 407 1.1 christos { 408 1.1 christos gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); 409 1.1 christos 410 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, regnum); 411 1.1 christos } 412 1.1 christos 413 1.1 christos /* Get DR_STATUS from only the one thread of INFERIOR_PTID. */ 414 1.1 christos 415 1.1 christos static unsigned long 416 1.1 christos i386_gnu_dr_get_status (void) 417 1.1 christos { 418 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, DR_STATUS); 419 1.1 christos } 420 1.1 christos 421 1.1 christos /* Return the inferior's DR7 debug control register. */ 422 1.1 christos 423 1.1 christos static unsigned long 424 1.1 christos i386_gnu_dr_get_control (void) 425 1.1 christos { 426 1.1 christos return i386_gnu_dr_get_reg (inferior_ptid, DR_CONTROL); 427 1.1.1.3 christos } 428 1.1 christos #endif /* i386_DEBUG_STATE */ 429 1.1.1.3 christos 430 1.1 christos void _initialize_i386gnu_nat (); 431 1.1 christos void 432 1.1 christos _initialize_i386gnu_nat () 433 1.1 christos { 434 1.1 christos #ifdef i386_DEBUG_STATE 435 1.1 christos x86_dr_low.set_control = i386_gnu_dr_set_control; 436 1.1 christos gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT); 437 1.1 christos x86_dr_low.set_addr = i386_gnu_dr_set_addr; 438 1.1 christos x86_dr_low.get_addr = i386_gnu_dr_get_addr; 439 1.1 christos x86_dr_low.get_status = i386_gnu_dr_get_status; 440 1.1 christos x86_dr_low.get_control = i386_gnu_dr_get_control; 441 1.1.1.3 christos x86_set_debug_register_length (4); 442 1.1.1.3 christos #endif /* i386_DEBUG_STATE */ 443 1.1 christos 444 1.1.1.2 christos gnu_target = &the_i386_gnu_nat_target; 445 1.1 christos 446 /* Register the target. */ 447 add_inf_child_target (&the_i386_gnu_nat_target); 448 } 449