void riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum) { int tid; tid = get_ptrace_pid (regcache->ptid ()); if ((regnum >= RISCV_ZERO_REGNUM && regnum <= RISCV_PC_REGNUM) || (regnum == -1)) { struct iovec iov; elf_gregset_t regs; iov.iov_base = ®s; iov.iov_len = sizeof (regs); if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (PTRACE_TYPE_ARG3) &iov) == -1) perror_with_name (_("Couldn't get registers")); else { fill_gregset (regcache, ®s, regnum); if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (PTRACE_TYPE_ARG3) &iov) == -1) perror_with_name (_("Couldn't set registers")); } } if ((regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) || (regnum == RISCV_CSR_FCSR_REGNUM) || (regnum == -1)) { struct iovec iov; elf_fpregset_t regs; iov.iov_base = ®s; iov.iov_len = sizeof (regs); if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (PTRACE_TYPE_ARG3) &iov) == -1) perror_with_name (_("Couldn't get registers")); else { fill_fpregset (regcache, ®s, regnum); if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (PTRACE_TYPE_ARG3) &iov) == -1) perror_with_name (_("Couldn't set registers")); } } /* Access to CSRs has potential security issues, don't support them for now. */ }
ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, gdb_prfpregset_t *fpregset) { struct regcache *regcache = get_ps_regcache (ph, lwpid); target_fetch_registers (regcache, -1); fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); return PS_OK; }
ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); target_fetch_registers (-1); fill_fpregset (fpregset, -1); do_cleanups (old_chain); return PS_OK; }
static void fbsd_lwp_store_registers (struct target_ops *ops, struct regcache *regcache, int regnum) { gregset_t gregs; fpregset_t fpregs; lwpid_t lwp; #ifdef PT_GETXMMREGS char xmmregs[512]; #endif /* FIXME, is it possible ? */ if (!IS_LWP (inferior_ptid)) { struct target_ops *beneath = find_target_beneath (ops); beneath->to_store_registers (ops, regcache, regnum); return ; } lwp = GET_LWP (inferior_ptid); if (regnum != -1) if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1) error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno)); fill_gregset (regcache, &gregs, regnum); if (ptrace (PT_SETREGS, lwp, (caddr_t) &gregs, 0) == -1) error ("Cannot set lwp %d registers: %s\n", lwp, safe_strerror (errno)); #ifdef PT_GETXMMREGS if (regnum != -1) if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == -1) goto noxmm; i387_collect_fxsave (regcache, regnum, xmmregs); if (ptrace (PT_SETXMMREGS, lwp, xmmregs, 0) == -1) goto noxmm; return; noxmm: #endif if (regnum != -1) if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1) error ("Cannot get lwp %d float registers: %s\n", lwp, safe_strerror (errno)); fill_fpregset (regcache, &fpregs, regnum); if (ptrace (PT_SETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1) error ("Cannot set lwp %d float registers: %s\n", lwp, safe_strerror (errno)); }
static void store_fpregs (const struct regcache *regcache, int tid, int regno) { elf_fpregset_t fpregs; if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) perror_with_name (_("Couldn't get floating point status")); fill_fpregset (regcache, &fpregs, regno); if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0) perror_with_name (_("Couldn't write floating point status")); }
ps_err_e ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, gdb_prfpregset_t *fpregset) { ptid_t ptid = ptid_build (ptid_get_pid (ph->ptid), lwpid, 0); struct regcache *regcache = get_thread_arch_regcache (ptid, target_gdbarch ()); target_fetch_registers (regcache, -1); fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); return PS_OK; }
static void fbsd_lwp_store_registers (int regno) { gregset_t gregs; fpregset_t fpregs; lwpid_t lwp; #ifdef PT_GETXMMREGS char xmmregs[512]; #endif /* FIXME, is it possible ? */ if (!IS_LWP (inferior_ptid)) { child_ops.to_store_registers (regno); return ; } lwp = GET_LWP (inferior_ptid); if (regno != -1) if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1) error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno)); fill_gregset (&gregs, regno); if (ptrace (PT_SETREGS, lwp, (caddr_t) &gregs, 0) == -1) error ("Cannot set lwp %d registers: %s\n", lwp, safe_strerror (errno)); #ifdef PT_GETXMMREGS if (regno != -1) if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == -1) goto noxmm; i387_fill_fxsave (xmmregs, regno); if (ptrace (PT_SETXMMREGS, lwp, xmmregs, 0) == -1) goto noxmm; return; noxmm: #endif if (regno != -1) if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1) error ("Cannot get lwp %d float registers: %s\n", lwp, safe_strerror (errno)); fill_fpregset (&fpregs, regno); if (ptrace (PT_SETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1) error ("Cannot set lwp %d float registers: %s\n", lwp, safe_strerror (errno)); }
ps_err_e ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, gdb_prfpregset_t *fpregset) { struct cleanup *old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); target_fetch_registers (-1); fill_fpregset ((gdb_fpregset_t *) fpregset, -1); do_cleanups (old_chain); return PS_OK; }
ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset) { struct cleanup *old_chain; struct regcache *regcache; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, ph->pid); regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_fpregset (regcache, fpregset, -1); do_cleanups (old_chain); return PS_OK; }
static int nbsd_thread_proc_getregs (void *arg, int regset, int lwp, void *buf) { struct nbsd_thread_proc_arg *a = (struct nbsd_thread_proc_arg *) arg; struct regcache *cache = a->cache; struct target_ops *ops = a->ops; struct cleanup *old_chain; struct target_ops *beneath = find_target_beneath (ops); int ret; old_chain = save_inferior_ptid (); if (target_has_execution) { /* Fetching registers from a live process requires that inferior_ptid is a LWP value rather than a thread value. */ inferior_ptid = ptid_build (ptid_get_pid (main_ptid), lwp, 0); beneath->to_fetch_registers (beneath, cache, -1); } else { /* Fetching registers from a core process requires that the PID value of inferior_ptid have the funky value that the kernel drops rather than the real PID. Gross. */ inferior_ptid = pid_to_ptid ((lwp << 16) | ptid_get_pid (main_ptid)); beneath->to_fetch_registers (ops, cache, -1); } ret = 0; switch (regset) { case 0: fill_gregset (cache, (gregset_t *)buf, -1); break; case 1: #ifdef HAVE_FPREGS fill_fpregset (cache, (fpregset_t *)buf, -1); #endif break; default: /* XXX need to handle other reg sets: SSE, AltiVec, etc. */ ret = TD_ERR_INVAL; } do_cleanups (old_chain); return ret; }
/* Store all valid floating-point registers in GDB's register cache into the process/thread specified by TID. */ static void store_fpregs (int tid, int regnum) { fpregset_t fpregs; ptrace_area parea; parea.len = sizeof (fpregs); parea.process_addr = (addr_t) &fpregs; parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs); if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) perror_with_name ("Couldn't get floating point status"); fill_fpregset (&fpregs, regnum); if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0) perror_with_name ("Couldn't write floating point status"); }
ps_err_e ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prfpregset_t * fpregset) { struct cleanup *old_chain; old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); if (target_has_execution) procfs_ops.to_fetch_registers (-1); else orig_core_ops.to_fetch_registers (-1); fill_fpregset ((gdb_fpregset_t *) fpregset, -1); do_cleanups (old_chain); return PS_OK; }
static char * fbsd_make_corefile_notes (bfd *obfd, int *note_size) { gregset_t gregs; fpregset_t fpregs; char *note_data = NULL; Elf_Internal_Ehdr *i_ehdrp; char fakename; /* Put a "FreeBSD" label in the ELF header. */ i_ehdrp = elf_elfheader (obfd); i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; fill_gregset (&gregs, -1); note_data = elfcore_write_prstatus (obfd, note_data, note_size, ptid_get_pid (inferior_ptid), stop_signal, &gregs); fill_fpregset (&fpregs, -1); note_data = elfcore_write_prfpreg (obfd, note_data, note_size, &fpregs, sizeof (fpregs)); fakename = '\0'; note_data = elfcore_write_thrmisc (obfd, note_data, note_size, &fakename, sizeof (fakename)); if (get_exec_file (0)) { char *fname = strrchr (get_exec_file (0), '/') + 1; char *psargs = xstrdup (fname); if (get_inferior_args ()) psargs = reconcat (psargs, psargs, " ", get_inferior_args (), NULL); note_data = elfcore_write_prpsinfo (obfd, note_data, note_size, fname, psargs); } make_cleanup (xfree, note_data); return note_data; }
static void fbsd_thread_store_registers (int regno) { prgregset_t gregset; prfpregset_t fpregset; td_thrhandle_t th; td_err_e err; #ifdef PT_GETXMMREGS char xmmregs[512]; #endif if (!IS_THREAD (inferior_ptid)) { fbsd_lwp_store_registers (regno); return; } err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) error ("Cannot find thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); if (regno != -1) { char old_value[MAX_REGISTER_SIZE]; regcache_collect (regno, old_value); err = td_thr_getgregs_p (&th, gregset); if (err != TD_OK) error ("%s: td_thr_getgregs %s", __func__, thread_db_err_str (err)); #ifdef PT_GETXMMREGS err = td_thr_getxmmregs_p (&th, xmmregs); if (err != TD_OK) { #endif err = td_thr_getfpregs_p (&th, &fpregset); if (err != TD_OK) error ("%s: td_thr_getfpgregs %s", __func__, thread_db_err_str (err)); #ifdef PT_GETXMMREGS } #endif supply_register (regno, old_value); } fill_gregset (gregset, regno); err = td_thr_setgregs_p (&th, gregset); if (err != TD_OK) error ("Cannot store general-purpose registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); #ifdef PT_GETXMMREGS i387_fill_fxsave (xmmregs, regno); err = td_thr_setxmmregs_p (&th, xmmregs); if (err == TD_OK) return; #endif fill_fpregset (&fpregset, regno); err = td_thr_setfpregs_p (&th, &fpregset); if (err != TD_OK) error ("Cannot store floating-point registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); }
static void sol_thread_store_registers (int regno) { thread_t thread; td_thrhandle_t thandle; td_err_e val; prgregset_t gregset; prfpregset_t fpregset; #if 0 int xregsize; caddr_t xregset; #endif if (!is_thread (inferior_ptid)) { /* LWP: pass the request on to procfs.c */ procfs_ops.to_store_registers (regno); return; } /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */ thread = GET_THREAD (inferior_ptid); val = p_td_ta_map_id2thr (main_ta, thread, &thandle); if (val != TD_OK) error ("sol_thread_store_registers: td_ta_map_id2thr %s", td_err_string (val)); if (regno != -1) { /* Not writing all the regs */ char old_value[MAX_REGISTER_SIZE]; /* Save new register value. */ regcache_collect (regno, old_value); val = p_td_thr_getgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getgregs %s", td_err_string (val)); val = p_td_thr_getfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getfpregs %s", td_err_string (val)); /* Restore new register value. */ supply_register (regno, old_value); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); if (val == TD_OK) { xregset = alloca (xregsize); val = td_thr_getxregs (&thandle, xregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_getxregs %s", td_err_string (val)); } #endif } fill_gregset ((gdb_gregset_t *) &gregset, regno); fill_fpregset ((gdb_fpregset_t *) &fpregset, regno); val = p_td_thr_setgregs (&thandle, gregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setgregs %s", td_err_string (val)); val = p_td_thr_setfpregs (&thandle, &fpregset); if (val != TD_OK) error ("sol_thread_store_registers: td_thr_setfpregs %s", td_err_string (val)); #if 0 /* thread_db doesn't seem to handle this right */ val = td_thr_getxregsize (&thandle, &xregsize); if (val != TD_OK && val != TD_NOXREGS) error ("sol_thread_store_registers: td_thr_getxregsize %s", td_err_string (val)); /* Should probably do something about writing the xregs here, but what are they? */ #endif }