static void store_regs (const struct regcache *regcache) { int ret, regno, tid; elf_gregset_t regs; /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); /* Fetch the general registers. */ ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); if (ret < 0) { warning (_("Unable to fetch general registers.")); return; } for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++) { if (REG_VALID == regcache_register_status (regcache, regno)) regcache_raw_collect (regcache, regno, (char *) ®s[regno]); } if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM)) regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) ®s[ARM_CPSR_GREGNUM]); ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); if (ret < 0) { warning (_("Unable to store general registers.")); return; } }
static void store_fpregs (const struct regcache *regcache) { int ret, regno, tid; gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); /* Read the floating point state. */ ret = ptrace (PT_GETFPREGS, tid, 0, fp); if (ret < 0) { warning (_("Unable to fetch the floating point registers.")); return; } /* Store fpsr. */ if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); /* Store the floating point registers. */ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) if (REG_VALID == regcache_register_status (regcache, regno)) collect_nwfpe_register (regcache, regno, fp); ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); if (ret < 0) { warning (_("Unable to store floating point registers.")); return; } }
static void store_fpregs (const struct regcache *regcache) { int ret, regno, tid; gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE]; /* Get the thread id for the ptrace call. */ tid = ptid_get_lwp (inferior_ptid); /* Read the floating point state. */ if (have_ptrace_getregset == TRIBOOL_TRUE) { elf_fpregset_t fpregs; struct iovec iov; iov.iov_base = &fpregs; iov.iov_len = sizeof (fpregs); ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov); } else ret = ptrace (PT_GETFPREGS, tid, 0, fp); if (ret < 0) { warning (_("Unable to fetch the floating point registers.")); return; } /* Store fpsr. */ if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM)) regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET); /* Store the floating point registers. */ for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++) if (REG_VALID == regcache_register_status (regcache, regno)) collect_nwfpe_register (regcache, regno, fp); if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; iov.iov_base = &fp; iov.iov_len = ARM_LINUX_SIZEOF_NWFPE; ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov); } else ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp); if (ret < 0) { warning (_("Unable to store floating point registers.")); return; } }
static void store_regs (const struct regcache *regcache) { int ret, regno, tid; elf_gregset_t regs; /* Get the thread id for the ptrace call. */ tid = GET_THREAD_ID (inferior_ptid); /* Fetch the general registers. */ if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; iov.iov_base = ®s; iov.iov_len = sizeof (regs); ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov); } else ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); if (ret < 0) { warning (_("Unable to fetch general registers.")); return; } for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++) { if (REG_VALID == regcache_register_status (regcache, regno)) regcache_raw_collect (regcache, regno, (char *) ®s[regno]); } if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM)) regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) ®s[ARM_CPSR_GREGNUM]); if (have_ptrace_getregset == TRIBOOL_TRUE) { struct iovec iov; iov.iov_base = ®s; iov.iov_len = sizeof (regs); ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iov); } else ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); if (ret < 0) { warning (_("Unable to store general registers.")); return; } }
static void store_wmmx_regs (const struct regcache *regcache) { char regbuf[IWMMXT_REGS_SIZE]; int ret, regno, tid; /* Get the thread id for the ptrace call. */ tid = ptid_get_lwp (inferior_ptid); ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf); if (ret < 0) { warning (_("Unable to fetch WMMX registers.")); return; } for (regno = 0; regno < 16; regno++) if (REG_VALID == regcache_register_status (regcache, regno + ARM_WR0_REGNUM)) regcache_raw_collect (regcache, regno + ARM_WR0_REGNUM, ®buf[regno * 8]); for (regno = 0; regno < 2; regno++) if (REG_VALID == regcache_register_status (regcache, regno + ARM_WCSSF_REGNUM)) regcache_raw_collect (regcache, regno + ARM_WCSSF_REGNUM, ®buf[16 * 8 + regno * 4]); for (regno = 0; regno < 4; regno++) if (REG_VALID == regcache_register_status (regcache, regno + ARM_WCGR0_REGNUM)) regcache_raw_collect (regcache, regno + ARM_WCGR0_REGNUM, ®buf[16 * 8 + 2 * 4 + regno * 4]); ret = ptrace (PTRACE_SETWMMXREGS, tid, 0, regbuf); if (ret < 0) { warning (_("Unable to store WMMX registers.")); return; } }
static void get_core_registers (struct target_ops *ops, struct regcache *regcache, int regno) { struct core_regset_section *sect_list; int i; if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) && (core_vec == NULL || core_vec->core_read_registers == NULL)) { fprintf_filtered (gdb_stderr, "Can't fetch registers from this type of core file\n"); return; } sect_list = gdbarch_core_regset_sections (get_regcache_arch (regcache)); if (sect_list) while (sect_list->sect_name != NULL) { if (strcmp (sect_list->sect_name, ".reg") == 0) get_core_register_section (regcache, sect_list->sect_name, 0, sect_list->human_name, 1); else if (strcmp (sect_list->sect_name, ".reg2") == 0) get_core_register_section (regcache, sect_list->sect_name, 2, sect_list->human_name, 0); else get_core_register_section (regcache, sect_list->sect_name, 3, sect_list->human_name, 0); sect_list++; } else { get_core_register_section (regcache, ".reg", 0, "general-purpose", 1); get_core_register_section (regcache, ".reg2", 2, "floating-point", 0); } /* Mark all registers not found in the core as unavailable. */ for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) if (regcache_register_status (regcache, i) == REG_UNKNOWN) regcache_raw_supply (regcache, i, NULL); }
/* 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_lwp (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 (REG_VALID == regcache_register_status (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 (REG_VALID == regcache_register_status (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 ctf_fetch_registers (struct target_ops *ops, struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); struct bt_ctf_event *event = NULL; struct bt_iter_pos *pos; /* An uninitialized reg size says we're not going to be successful at getting register blocks. */ if (trace_regblock_size == 0) return; gdb_assert (ctf_iter != NULL); /* Save the current position. */ pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); gdb_assert (pos->type == BT_SEEK_RESTORE); while (1) { const char *name; struct bt_ctf_event *event1; event1 = bt_ctf_iter_read_event (ctf_iter); name = bt_ctf_event_name (event1); if (name == NULL || strcmp (name, "frame") == 0) break; else if (strcmp (name, "register") == 0) { event = event1; break; } if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) break; } /* Restore the position. */ bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); if (event != NULL) { int offset, regsize, regn; const struct bt_definition *scope = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); const struct bt_definition *array = bt_ctf_get_field (event, scope, "contents"); gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array); /* Assume the block is laid out in GDB register number order, each register with the size that it has in GDB. */ offset = 0; for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++) { regsize = register_size (gdbarch, regn); /* Make sure we stay within block bounds. */ if (offset + regsize >= trace_regblock_size) break; if (regcache_register_status (regcache, regn) == REG_UNKNOWN) { if (regno == regn) { regcache_raw_supply (regcache, regno, regs + offset); break; } else if (regno == -1) { regcache_raw_supply (regcache, regn, regs + offset); } } offset += regsize; } } else tracefile_fetch_registers (regcache, regno); }