void arm_linux_supply_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs_buf, size_t len) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); const gdb_byte *gregs = gregs_buf; int regno; CORE_ADDR reg_pc; gdb_byte pc_buf[INT_REGISTER_SIZE]; for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++) if (regnum == -1 || regnum == regno) regcache_raw_supply (regcache, regno, gregs + INT_REGISTER_SIZE * regno); if (regnum == ARM_PS_REGNUM || regnum == -1) { if (arm_apcs_32) regcache_raw_supply (regcache, ARM_PS_REGNUM, gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM); else regcache_raw_supply (regcache, ARM_PS_REGNUM, gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM); } if (regnum == ARM_PC_REGNUM || regnum == -1) { reg_pc = extract_unsigned_integer (gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM, INT_REGISTER_SIZE, byte_order); reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc); store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, byte_order, reg_pc); regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf); } }
static void ppcnbsd_store_inferior_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); if (regnum == -1 || getregs_supplies (gdbarch, regnum)) { struct reg regs; if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); ppc_collect_gregset (&ppcnbsd_gregset, regcache, regnum, ®s, sizeof regs); if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); } if (regnum == -1 || getfpregs_supplies (gdbarch, regnum)) { struct fpreg fpregs; if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get FP registers")); ppc_collect_fpregset (&ppcnbsd_fpregset, regcache, regnum, &fpregs, sizeof fpregs); if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't set FP registers")); } }
static void alphabsd_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { if (regno == -1 || getregs_supplies (regno)) { struct reg gregs; if (ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)), (PTRACE_TYPE_ARG3) &gregs, 0) == -1) perror_with_name (_("Couldn't get registers")); alphabsd_fill_reg (regcache, (char *) &gregs, regno); if (ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)), (PTRACE_TYPE_ARG3) &gregs, 0) == -1) perror_with_name (_("Couldn't write registers")); if (regno != -1) return; } if (regno == -1 || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache))) { struct fpreg fpregs; if (ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating point status")); alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno); if (ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't write floating point status")); } }
static void supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp) { int i; struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1; int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum); int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum); for (i = 0; i < num_of_vrregs; i++) { /* The last 2 registers of this set are only 32 bit long, not 128. However an offset is necessary only for VSCR because it occupies a whole vector, while VRSAVE occupies a full 4 bytes slot. */ if (i == (num_of_vrregs - 2)) regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize + offset); else regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i, *vrregsetp + i * vrregsize); } }
static void ppc_linux_supply_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len) { const struct ppc_reg_offsets *offsets = regset->descr; ppc_supply_gregset (regset, regcache, regnum, gregs, len); if (ppc_linux_trap_reg_p (get_regcache_arch (regcache))) { /* "orig_r3" is stored 2 slots after "pc". */ if (regnum == -1 || regnum == PPC_ORIG_R3_REGNUM) ppc_supply_reg (regcache, PPC_ORIG_R3_REGNUM, gregs, offsets->pc_offset + 2 * offsets->gpr_size, offsets->gpr_size); /* "trap" is stored 8 slots after "pc". */ if (regnum == -1 || regnum == PPC_TRAP_REGNUM) ppc_supply_reg (regcache, PPC_TRAP_REGNUM, gregs, offsets->pc_offset + 8 * offsets->gpr_size, offsets->gpr_size); } }
/* Write into appropriate registers a function return value of type TYPE, given in virtual format. */ static void lm32_store_return_value (struct type *type, struct regcache *regcache, const gdb_byte *valbuf) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST val; int len = TYPE_LENGTH (type); if (len <= 4) { val = extract_unsigned_integer (valbuf, len, byte_order); regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val); } else if (len <= 8) { val = extract_unsigned_integer (valbuf, 4, byte_order); regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val); val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order); regcache_cooked_write_unsigned (regcache, SIM_LM32_R2_REGNUM, val); } else error (_("lm32_store_return_value: type length too large.")); }
void mips64_supply_gregset (struct regcache *regcache, const mips64_elf_gregset_t *gregsetp) { int regi; const mips64_elf_greg_t *regp = *gregsetp; gdb_byte zerobuf[MAX_REGISTER_SIZE]; struct gdbarch *gdbarch = get_regcache_arch (regcache); memset (zerobuf, 0, MAX_REGISTER_SIZE); for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++) supply_64bit_reg (regcache, regi - MIPS64_EF_REG0, (const gdb_byte *)(regp + regi)); if (mips_linux_restart_reg_p (gdbarch)) supply_64bit_reg (regcache, MIPS_RESTART_REGNUM, (const gdb_byte *)(regp + MIPS64_EF_REG0)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->lo, (const gdb_byte *) (regp + MIPS64_EF_LO)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->hi, (const gdb_byte *) (regp + MIPS64_EF_HI)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->pc, (const gdb_byte *) (regp + MIPS64_EF_CP0_EPC)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->badvaddr, (const gdb_byte *) (regp + MIPS64_EF_CP0_BADVADDR)); supply_64bit_reg (regcache, MIPS_PS_REGNUM, (const gdb_byte *) (regp + MIPS64_EF_CP0_STATUS)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->cause, (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE)); /* Fill the inaccessible zero register with zero. */ regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf); }
static void shnbsd_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno)) { struct reg inferior_registers; if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1) perror_with_name (_("Couldn't get registers")); sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno, (char *) &inferior_registers, SHNBSD_SIZEOF_GREGS); if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1) perror_with_name (_("Couldn't set registers")); if (regno != -1) return; } }
void fill_fpregset (const struct regcache *regcache, fpregset_t *fpregsetp, int regno) { int regi; char *from, *to; struct gdbarch *gdbarch = get_regcache_arch (regcache); /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */ for (regi = gdbarch_fp0_regnum (gdbarch); regi < gdbarch_fp0_regnum (gdbarch) + 32; regi++) { if ((regno == -1) || (regno == regi)) { to = (char *) &(fpregsetp->fp_r.fp_regs[regi - gdbarch_fp0_regnum (gdbarch)]); regcache_raw_collect (regcache, regi, to); } } if (regno == -1 || regno == mips_regnum (gdbarch)->fp_control_status) { char fsrbuf[8]; /* We can't fill the FSR register directly from the regcache, because there is a size issue: On one hand, fpregsetp->fp_csr is 32bits long, while the regcache expects a 64bits long buffer. So we use a buffer of the correct size and copy the register value from that buffer. */ regcache_raw_collect (regcache, mips_regnum (gdbarch)->fp_control_status, fsrbuf); memcpy (&fpregsetp->fp_csr, fsrbuf + 4, 4); } }
/* The Linux kernel ptrace interface for POWER7 VSX registers uses the registers set mechanism, as opposed to the interface for all the other registers, that stores/fetches each register individually. */ static void fetch_vsx_register (struct regcache *regcache, int tid, int regno) { int ret; gdb_vsxregset_t regs; struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum); ret = ptrace (PTRACE_GETVSXREGS, tid, 0, ®s); if (ret < 0) { if (errno == EIO) { have_ptrace_getsetvsxregs = 0; return; } perror_with_name (_("Unable to fetch VSX register")); } regcache_raw_supply (regcache, regno, regs + (regno - tdep->ppc_vsr0_upper_regnum) * vsxregsize); }
void mips_supply_fpregset (struct regcache *regcache, const mips_elf_fpregset_t *fpregsetp) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int regi; char zerobuf[MAX_REGISTER_SIZE]; memset (zerobuf, 0, MAX_REGISTER_SIZE); for (regi = 0; regi < 32; regi++) regcache_raw_supply (regcache, gdbarch_fp0_regnum (gdbarch) + regi, *fpregsetp + regi); regcache_raw_supply (regcache, mips_regnum (gdbarch)->fp_control_status, *fpregsetp + 32); /* FIXME: how can we supply FCRIR? The ABI doesn't tell us. */ regcache_raw_supply (regcache, mips_regnum (gdbarch)->fp_implementation_revision, zerobuf); }
static void fetch_core_registers (struct regcache *regcache, char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR reg_addr) { char *srcp = core_reg_sect; struct gdbarch *gdbarch = get_regcache_arch (regcache); int regsize = mips_isa_regsize (gdbarch); int regno; /* If regsize is 8, this is a N32 or N64 core file. If regsize is 4, this is an O32 core file. */ if (core_reg_size != regsize * gdbarch_num_regs (gdbarch)) { warning (_("wrong size gregset struct in core file")); return; } for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++) { regcache_raw_supply (regcache, regno, srcp); srcp += regsize; } }
static void mipsnbsd_supply_gregset (const struct regset *regset, struct regcache *regcache, int regnum, const void *gregs, size_t len) { size_t regsize = mips_isa_regsize (get_regcache_arch (regcache)); const char *regs = gregs; int i; gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize); for (i = 0; i <= MIPS_PC_REGNUM; i++) { if (regnum == i || regnum == -1) regcache_raw_supply (regcache, i, regs + i * regsize); } if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize) { regs += MIPSNBSD_NUM_GREGS * regsize; len -= MIPSNBSD_NUM_GREGS * regsize; mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len); } }
static void fetch_register (struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); pid_t tid; int val; if (gdbarch_cannot_fetch_register (gdbarch, regno)) { regcache_raw_supply (regcache, regno, NULL); return; } tid = get_ptrace_pid (regcache_get_ptid (regcache)); errno = 0; val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0); if (errno != 0) error (_("Couldn't read register %s (#%d): %s."), gdbarch_register_name (gdbarch, regno), regno, safe_strerror (errno)); regcache_raw_supply (regcache, regno, &val); }
static int ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) { struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct switchframe sf; struct callframe cf; int i, regnum; /* The following is true for OpenBSD 3.7: The pcb contains %r1 (the stack pointer) at the point of the context switch in cpu_switch(). At that point we have a stack frame as described by `struct switchframe', and below that a call frame as described by `struct callframe'. From this information we reconstruct the register state as it would look when we are in cpu_switch(). */ /* The stack pointer shouldn't be zero. */ if (pcb->pcb_sp == 0) return 0; read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf); regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp); regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2); for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++) regcache_raw_supply (regcache, regnum, &sf.fixreg[i]); read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf); regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30); regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31); return 1; }
static void store_register (const struct regcache *regcache, int regno) { int tid; int val; gdb_assert (!have_ptrace_getregs); if (i386_linux_gregset_reg_offset[regno] == -1) return; /* GNU/Linux LWP ID's are process ID's. */ tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ errno = 0; regcache_raw_collect (regcache, regno, &val); ptrace (PTRACE_POKEUSER, tid, i386_linux_gregset_reg_offset[regno], val); if (errno != 0) error (_("Couldn't write register %s (#%d): %s."), gdbarch_register_name (get_regcache_arch (regcache), regno), regno, safe_strerror (errno)); }
static int picobug_dumpregs (struct regcache *regcache) { struct gdbarch *gdbarch = get_regcache_arch (regcache); char buf[1024]; int resp_len; char *p; /* Send the dump register command to the monitor and get the reply. */ monitor_printf (picobug_cmds.dump_registers); resp_len = monitor_expect_prompt (buf, sizeof (buf)); p = strtok (buf, " \t\r\n"); while (p) { if (strchr (p, '-')) { /* Got a range. Either r0-r7, r8-r15 or ss0-ss4. */ if (strncmp (p, "r0", 2) == 0 || strncmp (p, "r8", 2) == 0) { int rn = (p[1] == '0' ? 0 : 8); int i = 0; /* Get the next 8 values and record them. */ while (i < 8) { p = strtok (NULL, " \t\r\n"); if (p) monitor_supply_register (regcache, rn + i, p); i++; } } else if (strncmp (p, "ss", 2) == 0) { /* Get the next five values, ignoring the first. */ int rn; p = strtok (NULL, " \t\r\n"); for (rn = 39; rn < 43; rn++) { p = strtok (NULL, " \t\r\n"); if (p) monitor_supply_register (regcache, rn, p); } } else { break; } } else { /* Simple register type, paired. */ char *name = p; int i; /* Get and record value. */ p = strtok (NULL, " \t\r\n"); if (p) { for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { if (picobug_regnames[i] && strcmp (picobug_regnames[i], name) == 0) break; } if (i <= gdbarch_num_regs (gdbarch)) monitor_supply_register (regcache, i, p); } } p = strtok (NULL, " \t\r\n"); } return 0; }
/* Read register values from the inferior process. If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */ static void i386_darwin_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { thread_t current_thread = ptid_get_tid (inferior_ptid); int fetched = 0; struct gdbarch *gdbarch = get_regcache_arch (regcache); #ifdef BFD64 if (gdbarch_ptr_bit (gdbarch) == 64) { if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno)) { x86_thread_state_t gp_regs; unsigned int gp_count = x86_THREAD_STATE_COUNT; kern_return_t ret; ret = thread_get_state (current_thread, x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error calling thread_get_state for " "GP registers for thread 0x%ulx"), current_thread); MACH_CHECK_ERROR (ret); } amd64_supply_native_gregset (regcache, &gp_regs.uts, -1); fetched++; } if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno)) { x86_float_state_t fp_regs; unsigned int fp_count = x86_FLOAT_STATE_COUNT; kern_return_t ret; ret = thread_get_state (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error calling thread_get_state for " "float registers for thread 0x%ulx"), current_thread); MACH_CHECK_ERROR (ret); } amd64_supply_fxsave (regcache, -1, &fp_regs.ufs.fs64.__fpu_fcw); fetched++; } } else #endif { if (regno == -1 || regno < I386_NUM_GREGS) { i386_thread_state_t gp_regs; unsigned int gp_count = i386_THREAD_STATE_COUNT; kern_return_t ret; int i; ret = thread_get_state (current_thread, i386_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error calling thread_get_state for " "GP registers for thread 0x%ulx"), current_thread); MACH_CHECK_ERROR (ret); } for (i = 0; i < I386_NUM_GREGS; i++) regcache_raw_supply (regcache, i, (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]); fetched++; } if (regno == -1 || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS)) { i386_float_state_t fp_regs; unsigned int fp_count = i386_FLOAT_STATE_COUNT; kern_return_t ret; ret = thread_get_state (current_thread, i386_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error calling thread_get_state for " "float registers for thread 0x%ulx"), current_thread); MACH_CHECK_ERROR (ret); } i387_supply_fxsave (regcache, -1, &fp_regs.__fpu_fcw); fetched++; } } if (! fetched) { warning (_("unknown register %d"), regno); regcache_raw_supply (regcache, regno, NULL); } }
static void i386_darwin_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { thread_t current_thread = ptid_get_tid (inferior_ptid); struct gdbarch *gdbarch = get_regcache_arch (regcache); #ifdef BFD64 if (gdbarch_ptr_bit (gdbarch) == 64) { if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno)) { x86_thread_state_t gp_regs; kern_return_t ret; unsigned int gp_count = x86_THREAD_STATE_COUNT; ret = thread_get_state (current_thread, x86_THREAD_STATE, (thread_state_t) &gp_regs, &gp_count); MACH_CHECK_ERROR (ret); gdb_assert (gp_regs.tsh.flavor == x86_THREAD_STATE64); gdb_assert (gp_regs.tsh.count == x86_THREAD_STATE64_COUNT); amd64_collect_native_gregset (regcache, &gp_regs.uts, regno); ret = thread_set_state (current_thread, x86_THREAD_STATE, (thread_state_t) &gp_regs, x86_THREAD_STATE_COUNT); MACH_CHECK_ERROR (ret); } if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno)) { x86_float_state_t fp_regs; kern_return_t ret; unsigned int fp_count = x86_FLOAT_STATE_COUNT; ret = thread_get_state (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); MACH_CHECK_ERROR (ret); gdb_assert (fp_regs.fsh.flavor == x86_FLOAT_STATE64); gdb_assert (fp_regs.fsh.count == x86_FLOAT_STATE64_COUNT); amd64_collect_fxsave (regcache, regno, &fp_regs.ufs.fs64.__fpu_fcw); ret = thread_set_state (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs, x86_FLOAT_STATE_COUNT); MACH_CHECK_ERROR (ret); } } else #endif { if (regno == -1 || regno < I386_NUM_GREGS) { i386_thread_state_t gp_regs; kern_return_t ret; unsigned int gp_count = i386_THREAD_STATE_COUNT; int i; ret = thread_get_state (current_thread, i386_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); MACH_CHECK_ERROR (ret); for (i = 0; i < I386_NUM_GREGS; i++) if (regno == -1 || regno == i) regcache_raw_collect (regcache, i, (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]); ret = thread_set_state (current_thread, i386_THREAD_STATE, (thread_state_t) & gp_regs, i386_THREAD_STATE_COUNT); MACH_CHECK_ERROR (ret); } if (regno == -1 || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS)) { i386_float_state_t fp_regs; unsigned int fp_count = i386_FLOAT_STATE_COUNT; kern_return_t ret; ret = thread_get_state (current_thread, i386_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); MACH_CHECK_ERROR (ret); i387_collect_fxsave (regcache, regno, &fp_regs.__fpu_fcw); ret = thread_set_state (current_thread, i386_FLOAT_STATE, (thread_state_t) & fp_regs, i386_FLOAT_STATE_COUNT); MACH_CHECK_ERROR (ret); } } }
/* 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); } }
void mips64_fill_fpregset (const struct regcache *regcache, mips64_elf_fpregset_t *fpregsetp, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte *to; if ((regno >= gdbarch_fp0_regnum (gdbarch)) && (regno < gdbarch_fp0_regnum (gdbarch) + 32)) { /* See mips_linux_o32_sigframe_init for a description of the peculiar FP register layout. */ if (register_size (gdbarch, regno) == 4) { int regi = regno - gdbarch_fp0_regnum (gdbarch); to = (gdb_byte *) (*fpregsetp + (regi & ~1)); if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1)) to += 4; regcache_raw_collect (regcache, regno, to); } else { to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch)); regcache_raw_collect (regcache, regno, to); } } else if (regno == mips_regnum (gdbarch)->fp_control_status) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (gdbarch, regno), byte_order); to = (gdb_byte *) (*fpregsetp + 32); store_signed_integer (to, 4, byte_order, val); } else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (gdbarch, regno), byte_order); to = (gdb_byte *) (*fpregsetp + 32) + 4; store_signed_integer (to, 4, byte_order, val); } else if (regno == -1) { int regi; for (regi = 0; regi < 32; regi++) mips64_fill_fpregset (regcache, fpregsetp, gdbarch_fp0_regnum (gdbarch) + regi); mips64_fill_fpregset (regcache, fpregsetp, mips_regnum (gdbarch)->fp_control_status); mips64_fill_fpregset (regcache, fpregsetp, (mips_regnum (gdbarch) ->fp_implementation_revision)); } }
static void i386_linux_fetch_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { int tid; /* Use the old method of peeking around in `struct user' if the GETREGS request isn't available. */ if (!have_ptrace_getregs) { int i; for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) if (regno == -1 || regno == i) fetch_register (regcache, i); return; } /* GNU/Linux LWP ID's are process ID's. */ tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ /* Use the PTRACE_GETFPXREGS request whenever possible, since it transfers more registers in one system call, and we'll cache the results. But remember that fetch_fpxregs can fail, and return zero. */ if (regno == -1) { fetch_regs (regcache, tid); /* The call above might reset `have_ptrace_getregs'. */ if (!have_ptrace_getregs) { i386_linux_fetch_inferior_registers (ops, regcache, regno); return; } if (fetch_xstateregs (regcache, tid)) return; if (fetch_fpxregs (regcache, tid)) return; fetch_fpregs (regcache, tid); return; } if (GETREGS_SUPPLIES (regno)) { fetch_regs (regcache, tid); return; } if (GETXSTATEREGS_SUPPLIES (regno)) { if (fetch_xstateregs (regcache, tid)) return; } if (GETFPXREGS_SUPPLIES (regno)) { if (fetch_fpxregs (regcache, tid)) return; /* Either our processor or our kernel doesn't support the SSE registers, so read the FP registers in the traditional way, and fill the SSE registers with dummy values. It would be more graceful to handle differences in the register set using gdbarch. Until then, this will at least make things work plausibly. */ fetch_fpregs (regcache, tid); return; } internal_error (__FILE__, __LINE__, _("Got request for bad register number %d."), regno); }
static CORE_ADDR m88k_store_arguments (struct regcache *regcache, int nargs, struct value **args, CORE_ADDR sp) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int num_register_words = 0; int num_stack_words = 0; int i; for (i = 0; i < nargs; i++) { struct type *type = value_type (args[i]); int len = TYPE_LENGTH (type); if (m88k_integral_or_pointer_p (type) && len < 4) { args[i] = value_cast (builtin_type (gdbarch)->builtin_int32, args[i]); type = value_type (args[i]); len = TYPE_LENGTH (type); } if (m88k_in_register_p (type)) { int num_words = 0; if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type)) num_words++; num_words += ((len + 3) / 4); if (num_register_words + num_words <= 8) { num_register_words += num_words; continue; } /* We've run out of available registers. Pass the argument on the stack. */ } if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type)) num_stack_words++; num_stack_words += ((len + 3) / 4); } /* Allocate stack space. */ sp = align_down (sp - 32 - num_stack_words * 4, 16); num_stack_words = num_register_words = 0; for (i = 0; i < nargs; i++) { const bfd_byte *valbuf = value_contents (args[i]); struct type *type = value_type (args[i]); int len = TYPE_LENGTH (type); int stack_word = num_stack_words; if (m88k_in_register_p (type)) { int register_word = num_register_words; if (register_word % 2 == 1 && m88k_8_byte_align_p (type)) register_word++; gdb_assert (len == 4 || len == 8); if (register_word + len / 8 < 8) { int regnum = M88K_R2_REGNUM + register_word; regcache_raw_write (regcache, regnum, valbuf); if (len > 4) regcache_raw_write (regcache, regnum + 1, valbuf + 4); num_register_words = (register_word + len / 4); continue; } } if (stack_word % 2 == -1 && m88k_8_byte_align_p (type)) stack_word++; write_memory (sp + stack_word * 4, valbuf, len); num_stack_words = (stack_word + (len + 3) / 4); } return sp; }
static void store_register (struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int addr[MAX_REGISTER_SIZE]; int nr, isfloat; /* Fetch the register's value from the register cache. */ regcache_raw_collect (regcache, regno, addr); /* -1 can be a successful return value, so infer errors from errno. */ errno = 0; nr = regmap (gdbarch, regno, &isfloat); /* Floating-point registers. */ if (isfloat) rs6000_ptrace32 (PT_WRITE_FPR, PIDGET (inferior_ptid), addr, nr, 0); /* Bogus register number. */ else if (nr < 0) { if (regno >= gdbarch_num_regs (gdbarch)) fprintf_unfiltered (gdb_stderr, "gdb error: register no %d not implemented.\n", regno); } /* Fixed-point registers. */ else { if (regno == gdbarch_sp_regnum (gdbarch)) /* Execute one dummy instruction (which is a breakpoint) in inferior process to give kernel a chance to do internal housekeeping. Otherwise the following ptrace(2) calls will mess up user stack since kernel will get confused about the bottom of the stack (%sp). */ exec_one_dummy_insn (regcache); /* The PT_WRITE_GPR operation is rather odd. For 32-bit inferiors, the register's value is passed by value, but for 64-bit inferiors, the address of a buffer containing the value is passed. */ if (!ARCH64 ()) rs6000_ptrace32 (PT_WRITE_GPR, PIDGET (inferior_ptid), (int *)nr, *addr, 0); else { /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte area, even if the register is really only 32 bits. */ long long buf; if (register_size (gdbarch, regno) == 8) memcpy (&buf, addr, 8); else buf = *addr; rs6000_ptrace64 (PT_WRITE_GPR, PIDGET (inferior_ptid), nr, 0, &buf); } } if (errno) { perror ("ptrace write"); errno = 0; } }
static void amd64_linux_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int tid; /* GNU/Linux LWP ID's are process ID's. */ tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum)) { elf_gregset_t regs; if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0) perror_with_name (_("Couldn't get registers")); amd64_collect_native_gregset (regcache, ®s, regnum); if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0) perror_with_name (_("Couldn't write registers")); if (regnum != -1) return; } if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum)) { elf_fpregset_t fpregs; if (have_ptrace_getregset) { char xstateregs[I386_XSTATE_MAX_SIZE]; struct iovec iov; iov.iov_base = xstateregs; iov.iov_len = sizeof (xstateregs); if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) perror_with_name (_("Couldn't get extended state status")); amd64_collect_xsave (regcache, regnum, xstateregs, 0); if (ptrace (PTRACE_SETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) perror_with_name (_("Couldn't write extended state status")); } else { if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) perror_with_name (_("Couldn't get floating point status")); amd64_collect_fxsave (regcache, regnum, &fpregs); if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0) perror_with_name (_("Couldn't write floating point status")); } } }
static void i386_linux_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signal) { int pid = ptid_get_pid (ptid); int request; if (catch_syscall_enabled () > 0) request = PTRACE_SYSCALL; else request = PTRACE_CONT; if (step) { struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid)); struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST pc; gdb_byte buf[LINUX_SYSCALL_LEN]; request = PTRACE_SINGLESTEP; regcache_cooked_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc); /* Returning from a signal trampoline is done by calling a special system call (sigreturn or rt_sigreturn, see i386-linux-tdep.c for more information). This system call restores the registers that were saved when the signal was raised, including %eflags. That means that single-stepping won't work. Instead, we'll have to modify the signal context that's about to be restored, and set the trace flag there. */ /* First check if PC is at a system call. */ if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) { ULONGEST syscall; regcache_cooked_read_unsigned (regcache, LINUX_SYSCALL_REGNUM, &syscall); /* Then check the system call number. */ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) { ULONGEST sp, addr; unsigned long int eflags; regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp); if (syscall == SYS_rt_sigreturn) addr = read_memory_unsigned_integer (sp + 8, 4, byte_order) + 20; else addr = sp; /* Set the trace flag in the context that's about to be restored. */ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; read_memory (addr, (gdb_byte *) &eflags, 4); eflags |= 0x0100; write_memory (addr, (gdb_byte *) &eflags, 4); } } } if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); }
void sparc_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int pid; /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers about threaded assumptions. */ pid = TIDGET (inferior_ptid); if (pid == 0) pid = PIDGET (inferior_ptid); if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum)) { gregset_t regs; if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); sparc_collect_gregset (sparc_gregset, regcache, regnum, ®s); if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); /* Deal with the stack regs. */ if (regnum == -1 || regnum == SPARC_SP_REGNUM || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)) { ULONGEST sp; regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp); sparc_collect_rwindow (regcache, sp, regnum); } if (regnum != -1) return; } if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum)) { fpregset_t fpregs, saved_fpregs; if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating-point registers")); memcpy (&saved_fpregs, &fpregs, sizeof (fpregs)); sparc_collect_fpregset (regcache, regnum, &fpregs); /* Writing the floating-point registers will fail on NetBSD with EINVAL if the inferior process doesn't have an FPU state (i.e. if it didn't use the FPU yet). Therefore we don't try to write the registers if nothing changed. */ if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0) { if (ptrace (PTRACE_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't write floating-point registers")); } if (regnum != -1) return; } }
static void ia64_linux_fetch_register (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); CORE_ADDR addr; size_t size; PTRACE_TYPE_RET *buf; int pid, i; /* r0 cannot be fetched but is always zero. */ if (regnum == IA64_GR0_REGNUM) { const gdb_byte zero[8] = { 0 }; gdb_assert (sizeof (zero) == register_size (gdbarch, regnum)); regcache_raw_supply (regcache, regnum, zero); return; } /* fr0 cannot be fetched but is always zero. */ if (regnum == IA64_FR0_REGNUM) { const gdb_byte f_zero[16] = { 0 }; gdb_assert (sizeof (f_zero) == register_size (gdbarch, regnum)); regcache_raw_supply (regcache, regnum, f_zero); return; } /* fr1 cannot be fetched but is always one (1.0). */ if (regnum == IA64_FR1_REGNUM) { const gdb_byte f_one[16] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 }; gdb_assert (sizeof (f_one) == register_size (gdbarch, regnum)); regcache_raw_supply (regcache, regnum, f_one); return; } if (ia64_cannot_fetch_register (gdbarch, regnum)) { regcache_raw_supply (regcache, regnum, NULL); return; } /* Cater for systems like GNU/Linux, that implement threads as separate processes. */ pid = ptid_get_lwp (inferior_ptid); if (pid == 0) pid = ptid_get_pid (inferior_ptid); /* This isn't really an address, but ptrace thinks of it as one. */ addr = ia64_register_addr (gdbarch, regnum); size = register_size (gdbarch, regnum); gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0); buf = alloca (size); /* Read the register contents from the inferior a chunk at a time. */ for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++) { errno = 0; buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0); if (errno != 0) error (_("Couldn't read register %s (#%d): %s."), gdbarch_register_name (gdbarch, regnum), regnum, safe_strerror (errno)); addr += sizeof (PTRACE_TYPE_RET); } regcache_raw_supply (regcache, regnum, buf); }
/* Store register REGNO back into the child process. If REGNO is -1, do this for all registers (including the floating point and SSE registers). */ static void i386_linux_store_inferior_registers (struct target_ops *ops, struct regcache *regcache, int regno) { int tid; /* Use the old method of poking around in `struct user' if the SETREGS request isn't available. */ if (!have_ptrace_getregs) { int i; for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++) if (regno == -1 || regno == i) store_register (regcache, i); return; } /* GNU/Linux LWP ID's are process ID's. */ tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ /* Use the PTRACE_SETFPXREGS requests whenever possible, since it transfers more registers in one system call. But remember that store_fpxregs can fail, and return zero. */ if (regno == -1) { store_regs (regcache, tid, regno); if (store_xstateregs (regcache, tid, regno)) return; if (store_fpxregs (regcache, tid, regno)) return; store_fpregs (regcache, tid, regno); return; } if (GETREGS_SUPPLIES (regno)) { store_regs (regcache, tid, regno); return; } if (GETXSTATEREGS_SUPPLIES (regno)) { if (store_xstateregs (regcache, tid, regno)) return; } if (GETFPXREGS_SUPPLIES (regno)) { if (store_fpxregs (regcache, tid, regno)) return; /* Either our processor or our kernel doesn't support the SSE registers, so just write the FP registers in the traditional way. */ store_fpregs (regcache, tid, regno); return; } internal_error (__FILE__, __LINE__, _("Got request to store bad register number %d."), regno); }
static void store_register (const struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); struct reg inferior_registers; int ret; ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), (PTRACE_TYPE_ARG3) &inferior_registers, 0); if (ret < 0) { warning (_("unable to fetch general registers")); return; } switch (regno) { case ARM_SP_REGNUM: regcache_raw_collect (regcache, ARM_SP_REGNUM, (char *) &inferior_registers.r_sp); break; case ARM_LR_REGNUM: regcache_raw_collect (regcache, ARM_LR_REGNUM, (char *) &inferior_registers.r_lr); break; case ARM_PC_REGNUM: if (arm_apcs_32) regcache_raw_collect (regcache, ARM_PC_REGNUM, (char *) &inferior_registers.r_pc); else { unsigned pc_val; regcache_raw_collect (regcache, ARM_PC_REGNUM, (char *) &pc_val); pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val); inferior_registers.r_pc ^= gdbarch_addr_bits_remove (gdbarch, inferior_registers.r_pc); inferior_registers.r_pc |= pc_val; } break; case ARM_PS_REGNUM: if (arm_apcs_32) regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr); else { unsigned psr_val; regcache_raw_collect (regcache, ARM_PS_REGNUM, (char *) &psr_val); psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val); inferior_registers.r_pc = gdbarch_addr_bits_remove (gdbarch, inferior_registers.r_pc); inferior_registers.r_pc |= psr_val; } break; default: regcache_raw_collect (regcache, regno, (char *) &inferior_registers.r[regno]); break; } ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), (PTRACE_TYPE_ARG3) &inferior_registers, 0); if (ret < 0) warning (_("unable to write register %d to inferior"), regno); }