/* * Fetch inferiors registers for gdb. * REG specifies which (as gdb views it) register, -1 for all. */ void gnu_fetch_registers (int reg) { struct proc *thread; thread_state_t state; inf_update_procs (current_inferior); /* Make sure we know about new threads. */ thread = inf_tid_to_thread (current_inferior, inferior_pid); if (! thread) error ("fetch inferior registers: %d: Invalid thread", inferior_pid); state = proc_get_state (thread, 0); if (! state) warning ("Couldn't fetch register %s from %s (invalid thread).", reg_names[reg], proc_string (thread)); else if (reg >= 0) { proc_debug (thread, "fetching register: %s", reg_names[reg]); supply_register (reg, REG_ADDR(state, reg)); thread->fetched_regs |= (1 << reg); } else { proc_debug (thread, "fetching all registers"); for (reg = 0; reg < NUM_REGS; reg++) supply_register (reg, REG_ADDR(state, reg)); thread->fetched_regs = ~0; } }
/* Fetch register REGNO, or all regs if REGNO is -1. */ static void gnu_fetch_registers (struct target_ops *ops, struct regcache *regcache, int regno) { struct proc *thread; /* Make sure we know about new threads. */ inf_update_procs (gnu_current_inf); thread = inf_tid_to_thread (gnu_current_inf, ptid_get_tid (inferior_ptid)); if (!thread) error (_("Can't fetch registers from thread %s: No such thread"), target_pid_to_str (inferior_ptid)); if (regno < I386_NUM_GREGS || regno == -1) { thread_state_t state; /* This does the dirty work for us. */ state = proc_get_state (thread, 0); if (!state) { warning (_("Couldn't fetch registers from %s"), proc_string (thread)); return; } if (regno == -1) { int i; proc_debug (thread, "fetching all register"); for (i = 0; i < I386_NUM_GREGS; i++) regcache_raw_supply (regcache, i, REG_ADDR (state, i)); thread->fetched_regs = ~0; } else { proc_debug (thread, "fetching register %s", gdbarch_register_name (get_regcache_arch (regcache), regno)); regcache_raw_supply (regcache, regno, REG_ADDR (state, regno)); thread->fetched_regs |= (1 << regno); } } if (regno >= I386_NUM_GREGS || regno == -1) { proc_debug (thread, "fetching floating-point registers"); fetch_fpregs (regcache, thread); } }
/* Fetch register REGNO, or all regs if REGNO is -1. */ void gnu_fetch_registers (int regno) { struct proc *thread; /* Make sure we know about new threads. */ inf_update_procs (current_inferior); thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); if (!thread) error ("Can't fetch registers from thread %d: No such thread", PIDGET (inferior_ptid)); if (regno < I386_NUM_GREGS || regno == -1) { thread_state_t state; /* This does the dirty work for us. */ state = proc_get_state (thread, 0); if (!state) { warning ("Couldn't fetch registers from %s", proc_string (thread)); return; } if (regno == -1) { int i; proc_debug (thread, "fetching all register"); for (i = 0; i < I386_NUM_GREGS; i++) supply_register (i, REG_ADDR (state, i)); thread->fetched_regs = ~0; } else { proc_debug (thread, "fetching register %s", REGISTER_NAME (regno)); supply_register (regno, REG_ADDR (state, regno)); thread->fetched_regs |= (1 << regno); } } if (regno >= I386_NUM_GREGS || regno == -1) { proc_debug (thread, "fetching floating-point registers"); fetch_fpregs (thread); } }
static void i386_gnu_dr_set_addr (int regnum, CORE_ADDR addr) { struct reg_addr reg_addr; gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); reg_addr.regnum = regnum; reg_addr.addr = addr; inf_update_procs (gnu_current_inf); inf_threads (gnu_current_inf, i386_gnu_dr_set_addr_one, ®_addr); }
static unsigned long i386_gnu_dr_get_reg (ptid_t ptid, int regnum) { struct i386_debug_state regs; struct proc *thread; /* Make sure we know about new threads. */ inf_update_procs (gnu_current_inf); thread = inf_tid_to_thread (gnu_current_inf, ptid_get_lwp (ptid)); i386_gnu_dr_get (®s, thread); return regs.dr[regnum]; }
/* Store at least register REGNO, or all regs if REGNO == -1. */ static void gnu_store_registers (struct target_ops *ops, struct regcache *regcache, int regno) { struct proc *thread; struct gdbarch *gdbarch = get_regcache_arch (regcache); /* Make sure we know about new threads. */ inf_update_procs (gnu_current_inf); thread = inf_tid_to_thread (gnu_current_inf, ptid_get_tid (inferior_ptid)); if (!thread) error (_("Couldn't store registers into thread %s: No such thread"), target_pid_to_str (inferior_ptid)); if (regno < I386_NUM_GREGS || regno == -1) { thread_state_t state; thread_state_data_t old_state; int was_aborted = thread->aborted; int was_valid = thread->state_valid; int trace; if (!was_aborted && was_valid) memcpy (&old_state, &thread->state, sizeof (old_state)); state = proc_get_state (thread, 1); if (!state) { warning (_("Couldn't store registers into %s"), proc_string (thread)); return; } /* Save the T bit. We might try to restore the %eflags register below, but changing the T bit would seriously confuse GDB. */ trace = ((struct i386_thread_state *)state)->efl & 0x100; if (!was_aborted && was_valid) /* See which registers have changed after aborting the thread. */ { int check_regno; for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) if ((thread->fetched_regs & (1 << check_regno)) && memcpy (REG_ADDR (&old_state, check_regno), REG_ADDR (state, check_regno), register_size (gdbarch, check_regno))) /* Register CHECK_REGNO has changed! Ack! */ { warning (_("Register %s changed after the thread was aborted"), gdbarch_register_name (gdbarch, check_regno)); if (regno >= 0 && regno != check_regno) /* Update GDB's copy of the register. */ regcache_raw_supply (regcache, check_regno, REG_ADDR (state, check_regno)); else warning (_("... also writing this register! Suspicious...")); } } if (regno == -1) { int i; proc_debug (thread, "storing all registers"); for (i = 0; i < I386_NUM_GREGS; i++) if (regcache_valid_p (regcache, i)) regcache_raw_collect (regcache, i, REG_ADDR (state, i)); } else { proc_debug (thread, "storing register %s", gdbarch_register_name (gdbarch, regno)); gdb_assert (regcache_valid_p (regcache, regno)); regcache_raw_collect (regcache, regno, REG_ADDR (state, regno)); } /* Restore the T bit. */ ((struct i386_thread_state *)state)->efl &= ~0x100; ((struct i386_thread_state *)state)->efl |= trace; } if (regno >= I386_NUM_GREGS || regno == -1) { proc_debug (thread, "storing floating-point registers"); store_fpregs (regcache, thread, regno); } }
static void i386_gnu_dr_set_control (unsigned long control) { inf_update_procs (gnu_current_inf); inf_threads (gnu_current_inf, i386_gnu_dr_set_control_one, &control); }
/* Store at least register REGNO, or all regs if REGNO == -1. */ void gnu_store_registers (int regno) { struct proc *thread; /* Make sure we know about new threads. */ inf_update_procs (current_inferior); thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); if (!thread) error ("Couldn't store registers into thread %d: No such thread", PIDGET (inferior_ptid)); if (regno < I386_NUM_GREGS || regno == -1) { thread_state_t state; thread_state_data_t old_state; int was_aborted = thread->aborted; int was_valid = thread->state_valid; int trace; if (!was_aborted && was_valid) memcpy (&old_state, &thread->state, sizeof (old_state)); state = proc_get_state (thread, 1); if (!state) { warning ("Couldn't store registers into %s", proc_string (thread)); return; } /* Save the T bit. We might try to restore the %eflags register below, but changing the T bit would seriously confuse GDB. */ trace = ((struct i386_thread_state *)state)->efl & 0x100; if (!was_aborted && was_valid) /* See which registers have changed after aborting the thread. */ { int check_regno; for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) if ((thread->fetched_regs & (1 << check_regno)) && memcpy (REG_ADDR (&old_state, check_regno), REG_ADDR (state, check_regno), DEPRECATED_REGISTER_RAW_SIZE (check_regno))) /* Register CHECK_REGNO has changed! Ack! */ { warning ("Register %s changed after the thread was aborted", REGISTER_NAME (check_regno)); if (regno >= 0 && regno != check_regno) /* Update GDB's copy of the register. */ supply_register (check_regno, REG_ADDR (state, check_regno)); else warning ("... also writing this register! Suspicious..."); } } #define fill(state, regno) \ memcpy (REG_ADDR(state, regno), &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], \ DEPRECATED_REGISTER_RAW_SIZE (regno)) if (regno == -1) { int i; proc_debug (thread, "storing all registers"); for (i = 0; i < I386_NUM_GREGS; i++) if (deprecated_register_valid[i]) fill (state, i); } else { proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); gdb_assert (deprecated_register_valid[regno]); fill (state, regno); } /* Restore the T bit. */ ((struct i386_thread_state *)state)->efl &= ~0x100; ((struct i386_thread_state *)state)->efl |= trace; } #undef fill if (regno >= I386_NUM_GREGS || regno == -1) { proc_debug (thread, "storing floating-point registers"); store_fpregs (thread, regno); } }