static char * haiku_pid_to_str (ptid_t ptid) { static char buffer[B_OS_NAME_LENGTH + 64 + 64]; team_info teamInfo; thread_info threadInfo; status_t error; // get the team info for the target team error = get_team_info(ptid_get_pid(ptid), &teamInfo); if (error != B_OK) { sprintf(buffer, "invalid team ID %d", ptid_get_pid(ptid)); return buffer; } // get the thread info for the target thread error = get_thread_info(ptid_get_tid(ptid), &threadInfo); if (error != B_OK) { sprintf(buffer, "team %.*s (%ld) invalid thread ID %ld", (int)sizeof(teamInfo.args), teamInfo.args, teamInfo.team, ptid_get_tid(ptid)); return buffer; } sprintf(buffer, "team %.*s (%ld) thread %s (%ld)", (int)sizeof(teamInfo.args), teamInfo.args, teamInfo.team, threadInfo.name, threadInfo.thread); return buffer; }
static void haiku_child_store_inferior_registers (int reg) { status_t err; thread_id threadID = ptid_get_tid(inferior_ptid); debug_nub_get_cpu_state_reply reply; debug_nub_set_cpu_state message; TRACE(("haiku_child_store_inferior_registers(%d)\n", reg)); // get the current CPU state haiku_get_cpu_state(&sTeamDebugInfo, &reply); // collect the registers (architecture specific) haiku_collect_registers(reg, &reply.cpu_state); // set the new CPU state message.thread = threadID; memcpy(&message.cpu_state, &reply.cpu_state, sizeof(debug_cpu_state)); err = haiku_send_debugger_message(&sTeamDebugInfo, B_DEBUG_MESSAGE_SET_CPU_STATE, &message, sizeof(message), NULL, 0); if (err != B_OK) { printf_unfiltered ("Failed to set status of thread %ld: %s\n", threadID, strerror(err)); } }
static void ppc_ravenscar_generic_fetch_registers (const struct ravenscar_reg_info *reg_info, struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); const int sp_regnum = gdbarch_sp_regnum (gdbarch); const int num_regs = gdbarch_num_regs (gdbarch); int current_regnum; CORE_ADDR current_address; CORE_ADDR thread_descriptor_address; /* The tid is the thread_id field, which is a pointer to the thread. */ thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid); /* Read registers. */ for (current_regnum = 0; current_regnum < num_regs; current_regnum++) { if (register_in_thread_descriptor_p (reg_info, current_regnum)) { current_address = thread_descriptor_address + reg_info->context_offsets[current_regnum]; supply_register_at_address (regcache, current_regnum, current_address); } } }
static cma__t_int_tcb * find_tcb (ptid_t ptid) { cma__t_known_object queue_header; cma__t_queue *queue_ptr; int thread = ptid_get_tid (ptid); if (thread == cached_thread) return &cached_tcb; read_memory ((CORE_ADDR) P_cma__g_known_threads, (char *) &queue_header, sizeof queue_header); for (queue_ptr = queue_header.queue.flink; queue_ptr != (cma__t_queue *) P_cma__g_known_threads; queue_ptr = cached_tcb.threads.flink) { cma__t_int_tcb *tcb_ptr; tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb); read_memory ((CORE_ADDR) tcb_ptr, (char *) &cached_tcb, sizeof cached_tcb); if (cached_tcb.header.type == cma__c_obj_tcb) if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread) { cached_thread = thread; return &cached_tcb; } } error (_("Can't find TCB %d"), thread); return NULL; }
static void sparc_ravenscar_store_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int buf_size = register_size (gdbarch, regnum); char buf [buf_size]; ULONGEST register_address; if (register_in_thread_descriptor_p (regnum)) register_address = ptid_get_tid (inferior_ptid) + sparc_register_offsets [regnum]; else if (register_on_stack_p (regnum)) { regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, ®ister_address); register_address += sparc_register_offsets [regnum]; } else return; regcache_raw_collect (regcache, regnum, buf); write_memory (register_address, buf, buf_size); }
static void haiku_child_resume (ptid_t ptid, int step, enum target_signal sig) { team_id teamID = ptid_get_pid(ptid); thread_id threadID = ptid_get_tid(ptid); thread_debug_info *thread; TRACE(("haiku_child_resume(`%s', step: %d, signal: %d)\n", haiku_pid_to_str(ptid), step, sig)); if (teamID < 0) { // resume all stopped threads (at least all haiku_wait_child() has // reported to be stopped) for (thread = sTeamDebugInfo.threads; thread; thread = thread->next) { if (thread->stopped) haiku_resume_thread(&sTeamDebugInfo, thread, step, sig); } } else { // resume the thread in question thread = haiku_find_thread(&sTeamDebugInfo, threadID); if (thread) { haiku_resume_thread(&sTeamDebugInfo, thread, step, sig); } else { printf_unfiltered ("haiku_child_resume(): unknown thread %ld\n", threadID); } } }
static status_t haiku_get_cpu_state(team_debug_info *teamDebugInfo, debug_nub_get_cpu_state_reply *reply) { status_t err; thread_id threadID = ptid_get_tid(inferior_ptid); debug_nub_get_cpu_state message; // make sure the thread is stopped err = haiku_stop_thread(teamDebugInfo, threadID); if (err != B_OK) { printf_unfiltered ("Failed to stop thread %ld: %s\n", threadID, strerror(err)); return err; } message.reply_port = teamDebugInfo->context.reply_port; message.thread = threadID; err = haiku_send_debugger_message(teamDebugInfo, B_DEBUG_MESSAGE_GET_CPU_STATE, &message, sizeof(message), reply, sizeof(*reply)); if (err == B_OK) err = reply->error; if (err != B_OK) { printf_unfiltered ("Failed to get status of thread %ld: %s\n", threadID, strerror(err)); } return err; }
int ptid_is_pid (ptid_t ptid) { if (ptid_equal (minus_one_ptid, ptid) || ptid_equal (null_ptid, ptid)) return 0; return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0); }
int ptid_tid_p (ptid_t ptid) { if (ptid_equal (minus_one_ptid, ptid) || ptid_equal (null_ptid, ptid)) return 0; return (ptid_get_tid (ptid) != 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); } }
static int haiku_child_thread_alive (ptid_t ptid) { thread_info info; TRACE(("haiku_child_thread_alive(`%s')\n", haiku_pid_to_str(ptid))); return (get_thread_info(ptid_get_tid(ptid), &info) == B_OK); }
char * hpux_pid_to_str (ptid_t ptid) { static char buf[100]; int pid = PIDGET (ptid); sprintf (buf, "Thread %ld", ptid_get_tid (ptid)); return buf; }
void fetch_inferior_registers (int regno) { thread_t current_thread = ptid_get_tid (inferior_ptid); if ((regno == -1) || PPC_MACOSX_IS_GP_REGNUM (regno) || PPC_MACOSX_IS_GSP_REGNUM (regno)) { gdb_ppc_thread_state_64_t gp_regs; unsigned int gp_count = GDB_PPC_THREAD_STATE_64_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_PPC_THREAD_STATE_64, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for GP registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } ppc_macosx_fetch_gp_registers_64 (&gp_regs); } if ((regno == -1) || PPC_MACOSX_IS_FP_REGNUM (regno) || PPC_MACOSX_IS_FSP_REGNUM (regno)) { gdb_ppc_thread_fpstate_t fp_regs; unsigned int fp_count = GDB_PPC_THREAD_FPSTATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_PPC_THREAD_FPSTATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for FP registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } ppc_macosx_fetch_fp_registers (&fp_regs); } if ((regno == -1) || PPC_MACOSX_IS_VP_REGNUM (regno) || PPC_MACOSX_IS_VSP_REGNUM (regno)) { gdb_ppc_thread_vpstate_t vp_regs; unsigned int vp_count = GDB_PPC_THREAD_VPSTATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_PPC_THREAD_VPSTATE, (thread_state_t) & vp_regs, &vp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for Vector registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } ppc_macosx_fetch_vp_registers (&vp_regs); } }
const char * target_pid_to_str (ptid_t ptid) { static char buf[80]; if (ptid_equal (ptid, minus_one_ptid)) xsnprintf (buf, sizeof (buf), "<all threads>"); else if (ptid_equal (ptid, null_ptid)) xsnprintf (buf, sizeof (buf), "<null thread>"); else if (ptid_get_tid (ptid) != 0) xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx", ptid_get_pid (ptid), ptid_get_tid (ptid)); else if (ptid_get_lwp (ptid) != 0) xsnprintf (buf, sizeof (buf), "LWP %d.%ld", ptid_get_pid (ptid), ptid_get_lwp (ptid)); else xsnprintf (buf, sizeof (buf), "Process %d", ptid_get_pid (ptid)); return buf; }
static void haiku_child_stop_inferior (void) { status_t err; thread_id threadID = ptid_get_tid(inferior_ptid); TRACE(("haiku_child_stop_inferior()\n")); err = debug_thread(threadID); if (err != B_OK) { printf_unfiltered ("Failed to stop thread %ld: %s\n", threadID, strerror(err)); return; } }
static uint32_t i386_darwin_dr_get (int regnum) { thread_t current_thread; x86_debug_state_t dr_regs; kern_return_t ret; unsigned int dr_count = x86_DEBUG_STATE_COUNT; gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); current_thread = ptid_get_tid (inferior_ptid); dr_regs.dsh.flavor = x86_DEBUG_STATE32; dr_regs.dsh.count = x86_DEBUG_STATE32_COUNT; dr_count = x86_DEBUG_STATE_COUNT; ret = thread_get_state (current_thread, x86_DEBUG_STATE, (thread_state_t) &dr_regs, &dr_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error reading debug registers " "thread 0x%x via thread_get_state\n"), (int) current_thread); MACH_CHECK_ERROR (ret); } switch (regnum) { case 0: return dr_regs.uds.ds32.__dr0; case 1: return dr_regs.uds.ds32.__dr1; case 2: return dr_regs.uds.ds32.__dr2; case 3: return dr_regs.uds.ds32.__dr3; case 4: return dr_regs.uds.ds32.__dr4; case 5: return dr_regs.uds.ds32.__dr5; case 6: return dr_regs.uds.ds32.__dr6; case 7: return dr_regs.uds.ds32.__dr7; default: return -1; } }
void store_inferior_registers (int regno) { int current_pid; thread_t current_thread; current_pid = ptid_get_pid (inferior_ptid); current_thread = ptid_get_tid (inferior_ptid); validate_inferior_registers (regno); if ((regno == -1) || PPC_MACOSX_IS_GP_REGNUM (regno) || PPC_MACOSX_IS_GSP_REGNUM (regno)) { gdb_ppc_thread_state_64_t gp_regs; kern_return_t ret; ppc_macosx_store_gp_registers_64 (&gp_regs); ret = thread_set_state (current_thread, GDB_PPC_THREAD_STATE_64, (thread_state_t) & gp_regs, GDB_PPC_THREAD_STATE_64_COUNT); MACH_CHECK_ERROR (ret); } if ((regno == -1) || PPC_MACOSX_IS_FP_REGNUM (regno) || PPC_MACOSX_IS_FSP_REGNUM (regno)) { gdb_ppc_thread_fpstate_t fp_regs; kern_return_t ret; ppc_macosx_store_fp_registers (&fp_regs); ret = thread_set_state (current_thread, GDB_PPC_THREAD_FPSTATE, (thread_state_t) & fp_regs, GDB_PPC_THREAD_FPSTATE_COUNT); MACH_CHECK_ERROR (ret); } if ((regno == -1) || PPC_MACOSX_IS_VP_REGNUM (regno) || PPC_MACOSX_IS_VSP_REGNUM (regno)) { gdb_ppc_thread_vpstate_t vp_regs; kern_return_t ret; ppc_macosx_store_vp_registers (&vp_regs); ret = thread_set_state (current_thread, GDB_PPC_THREAD_VPSTATE, (thread_state_t) & vp_regs, GDB_PPC_THREAD_VPSTATE_COUNT); MACH_CHECK_ERROR (ret); } }
static void ppc_ravenscar_generic_store_registers (const struct ravenscar_reg_info *reg_info, struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); int buf_size = register_size (gdbarch, regnum); gdb_byte buf[buf_size]; ULONGEST register_address; if (register_in_thread_descriptor_p (reg_info, regnum)) register_address = ptid_get_tid (inferior_ptid) + reg_info->context_offsets [regnum]; else return; regcache_raw_collect (regcache, regnum, buf); write_memory (register_address, buf, buf_size); }
static ptid_t thread_from_lwp (ptid_t ptid) { td_thrhandle_t th; td_err_e err; ptid_t thread_ptid; struct thread_db_info *info; struct thread_get_info_inout io = {0}; /* This ptid comes from linux-nat.c, which should always fill in the LWP. */ gdb_assert (GET_LWP (ptid) != 0); info = get_thread_db_info (GET_PID (ptid)); /* Access an lwp we know is stopped. */ info->proc_handle.ptid = ptid; err = info->td_ta_map_lwp2thr_p (info->thread_agent, GET_LWP (ptid), &th); if (err != TD_OK) error (_("Cannot find user-level thread for LWP %ld: %s"), GET_LWP (ptid), thread_db_err_str (err)); /* Fetch the thread info. If we get back TD_THR_ZOMBIE, then the event thread has already died. If another gdb interface has called thread_alive() previously, the thread won't be found on the thread list anymore. In that case, we don't want to process this ptid anymore to avoid the possibility of later treating it as a newly discovered thread id that we should add to the list. Thus, we return a -1 ptid which is also how the thread list marks a dead thread. */ io.thread_db_info = info; io.thread_info = NULL; if (thread_get_info_callback (&th, &io) == TD_THR_ZOMBIE && io.thread_info == NULL) return minus_one_ptid; gdb_assert (ptid_get_tid (ptid) == 0); return ptid; }
/* * If the current thread is executing on a CPU, fetch the common_tss * for that CPU. * * This is painful because 'struct pcpu' is variant sized, so we can't * use it. Instead, we lookup the GDT selector for this CPU and * extract the base of the TSS from there. */ static CORE_ADDR i386fbsd_fetch_tss(void) { struct kthr *kt; struct segment_descriptor sd; CORE_ADDR addr, cpu0prvpage, tss; kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid)); if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0) return (0); addr = kgdb_lookup("gdt"); if (addr == 0) return (0); addr += (kt->cpu * NGDT + GPROC0_SEL) * sizeof(sd); if (target_read_memory(addr, (void *)&sd, sizeof(sd)) != 0) return (0); if (sd.sd_type != SDT_SYS386BSY) { warning ("descriptor is not a busy TSS"); return (0); } tss = sd.sd_hibase << 24 | sd.sd_lobase; /* * In SMP kernels, the TSS is stored as part of the per-CPU * data. On older kernels, the CPU0's private page * is stored at an address that isn't mapped in minidumps. * However, the data is mapped at the alternate cpu0prvpage * address. Thus, if the TSS is at the invalid address, * change it to be relative to cpu0prvpage instead. */ if (trunc_page(tss) == 0xffc00000) { TRY { cpu0prvpage = parse_and_eval_address("cpu0prvpage"); } CATCH(e, RETURN_MASK_ERROR) { return (0); } END_CATCH tss = cpu0prvpage + (tss & PAGE_MASK); }
static void sparc_ravenscar_fetch_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = get_regcache_arch (regcache); const int sp_regnum = gdbarch_sp_regnum (gdbarch); const int num_regs = gdbarch_num_regs (gdbarch); int current_regnum; CORE_ADDR current_address; CORE_ADDR thread_descriptor_address; ULONGEST stack_address; /* The tid is the thread_id field, which is a pointer to the thread. */ thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid); /* Read the saved SP in the context buffer. */ current_address = thread_descriptor_address + sparc_register_offsets [sp_regnum]; supply_register_at_address (regcache, sp_regnum, current_address); regcache_cooked_read_unsigned (regcache, sp_regnum, &stack_address); /* Read registers. */ for (current_regnum = 0; current_regnum < num_regs; current_regnum ++) { if (register_in_thread_descriptor_p (current_regnum)) { current_address = thread_descriptor_address + sparc_register_offsets [current_regnum]; supply_register_at_address (regcache, current_regnum, current_address); } else if (register_on_stack_p (current_regnum)) { current_address = stack_address + sparc_register_offsets [current_regnum]; supply_register_at_address (regcache, current_regnum, current_address); } } }
/* Getter for InferiorThread.ptid -> (pid, lwp, tid). Returns a tuple with the thread's ptid components. */ static PyObject * thpy_get_ptid (PyObject *self, void *closure) { int pid; long tid, lwp; thread_object *thread_obj = (thread_object *) self; PyObject *ret; THPY_REQUIRE_VALID (thread_obj); ret = PyTuple_New (3); if (!ret) return NULL; pid = ptid_get_pid (thread_obj->thread->ptid); lwp = ptid_get_lwp (thread_obj->thread->ptid); tid = ptid_get_tid (thread_obj->thread->ptid); PyTuple_SET_ITEM (ret, 0, PyInt_FromLong (pid)); PyTuple_SET_ITEM (ret, 1, PyInt_FromLong (lwp)); PyTuple_SET_ITEM (ret, 2, PyInt_FromLong (tid)); return ret; }
static void fbsd_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signo) { if (debug_fbsd_lwp) fprintf_unfiltered (gdb_stdlog, "FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n", ptid_get_pid (ptid), ptid_get_lwp (ptid), ptid_get_tid (ptid)); if (ptid_lwp_p (ptid)) { /* If ptid is a specific LWP, suspend all other LWPs in the process. */ iterate_over_threads (resume_one_thread_cb, &ptid); } else { /* If ptid is a wildcard, resume all matching threads (they won't run until the process is continued however). */ iterate_over_threads (resume_all_threads_cb, &ptid); ptid = inferior_ptid; } super_resume (ops, ptid, step, signo); }
/* 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 store_inferior_registers (int regno) { int current_pid; thread_t current_thread; current_pid = ptid_get_pid (inferior_ptid); current_thread = ptid_get_tid (inferior_ptid); validate_inferior_registers (regno); if (TARGET_OSABI == GDB_OSABI_DARWIN64) { if ((regno == -1) || IS_GP_REGNUM_64 (regno)) { gdb_x86_thread_state_t gp_regs; kern_return_t ret; gp_regs.tsh.flavor = GDB_x86_THREAD_STATE64; gp_regs.tsh.count = GDB_x86_THREAD_STATE64_COUNT; x86_64_macosx_store_gp_registers (&gp_regs.uts.ts64); ret = thread_set_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, GDB_x86_THREAD_STATE_COUNT); MACH_CHECK_ERROR (ret); } if ((regno == -1) || IS_FP_REGNUM_64 (regno) || IS_VP_REGNUM_64 (regno) || regno == REGS_64_MXCSR) { gdb_x86_float_state_t fp_regs; kern_return_t ret; fp_regs.fsh.flavor = GDB_x86_FLOAT_STATE64; fp_regs.fsh.count = GDB_x86_FLOAT_STATE64_COUNT; if (x86_64_macosx_store_fp_registers (&fp_regs.ufs.fs64)) { ret = thread_set_state (current_thread, GDB_x86_FLOAT_STATE, (thread_state_t) & fp_regs, GDB_x86_FLOAT_STATE_COUNT); MACH_CHECK_ERROR (ret); } } } else { if ((regno == -1) || IS_GP_REGNUM (regno)) { gdb_x86_thread_state_t gp_regs; kern_return_t ret; gp_regs.tsh.flavor = GDB_x86_THREAD_STATE32; gp_regs.tsh.count = GDB_x86_THREAD_STATE32_COUNT; i386_macosx_store_gp_registers (&(gp_regs.uts.ts32)); ret = thread_set_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, GDB_x86_THREAD_STATE_COUNT); MACH_CHECK_ERROR (ret); } if ((regno == -1) || IS_FP_REGNUM (regno) || i386_sse_regnum_p (current_gdbarch, regno) || i386_mxcsr_regnum_p (current_gdbarch, regno)) { gdb_i386_float_state_t fp_regs; kern_return_t ret; if (i386_macosx_store_fp_registers (&fp_regs)) { ret = thread_set_state (current_thread, GDB_i386_FLOAT_STATE, (thread_state_t) & fp_regs, GDB_i386_FLOAT_STATE_COUNT); MACH_CHECK_ERROR (ret); } } } }
void fetch_inferior_registers (int regno) { int i; thread_t current_thread = ptid_get_tid (inferior_ptid); kern_return_t ret = KERN_SUCCESS; if (TARGET_OSABI == GDB_OSABI_UNKNOWN) arm_set_osabi_from_host_info (); if ((regno == -1) || ARM_MACOSX_IS_GP_RELATED_REGNUM (regno)) { struct gdb_arm_thread_state gp_regs; unsigned int gp_count = GDB_ARM_THREAD_STATE_COUNT; ret = thread_get_state (current_thread, GDB_ARM_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for GP registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } MACH_CHECK_ERROR (ret); arm_macosx_fetch_gp_registers (&gp_regs); } if ((regno == -1) || ARM_MACOSX_IS_FP_RELATED_REGNUM (regno)) { /* We don't have F0-F7, though they need to exist in our register numbering scheme so we can connect to remote gdbserver's that use FSF register numbers. */ for (i = ARM_F0_REGNUM; i <= ARM_F7_REGNUM; i++) set_register_cached (i, 1); set_register_cached (ARM_FPS_REGNUM, 1); } if ((regno == -1) || ARM_MACOSX_IS_VFP_RELATED_REGNUM (regno)) { enum arm_vfp_version vfp_version; vfp_version = gdbarch_tdep (current_gdbarch)->vfp_version; int fp_byte_size = -1; switch (vfp_version) { case ARM_VFP_UNSUPPORTED: /* No VFP support, so nothing to do. */ fp_byte_size = 0; break; case ARM_VFP_VERSION_1: { gdb_arm_thread_vfpv1_state_t fp_regs; mach_msg_type_number_t fp_count = GDB_ARM_THREAD_FPSTATE_VFPV1_COUNT; ret = thread_get_state (current_thread, GDB_ARM_THREAD_FPSTATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for VFP registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } arm_macosx_fetch_vfpv1_regs (&fp_regs); } break; case ARM_VFP_VERSION_3: { gdb_arm_thread_vfpv3_state_t fp_regs; mach_msg_type_number_t fp_count = GDB_ARM_THREAD_FPSTATE_VFPV3_COUNT; ret = thread_get_state (current_thread, GDB_ARM_THREAD_FPSTATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf ("Error calling thread_get_state for VFP registers for thread 0x%ulx", current_thread); MACH_CHECK_ERROR (ret); } arm_macosx_fetch_vfpv3_regs (&fp_regs); } break; default: error ("fetch_inferior_registers: unable to fetch ARM_THREAD_FPSTATE: " "unsupported vfp version: %d", (int)vfp_version); break; } } }
/* 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); } }
void store_inferior_registers (int regno) { int current_pid; thread_t current_thread; kern_return_t ret; current_pid = ptid_get_pid (inferior_ptid); current_thread = ptid_get_tid (inferior_ptid); validate_inferior_registers (regno); if ((regno == -1) || ARM_MACOSX_IS_GP_RELATED_REGNUM (regno)) { struct gdb_arm_thread_state gp_regs; arm_macosx_store_gp_registers (&gp_regs); ret = thread_set_state (current_thread, GDB_ARM_THREAD_STATE, (thread_state_t) & gp_regs, GDB_ARM_THREAD_STATE_COUNT); MACH_CHECK_ERROR (ret); } if ((regno == -1) || ARM_MACOSX_IS_VFP_RELATED_REGNUM (regno)) { enum arm_vfp_version vfp_version; vfp_version = gdbarch_tdep (current_gdbarch)->vfp_version; int fp_byte_size = -1; switch (vfp_version) { case ARM_VFP_UNSUPPORTED: /* No VFP support, so nothing to do. */ fp_byte_size = 0; break; case ARM_VFP_VERSION_1: { gdb_arm_thread_vfpv1_state_t fp_regs; arm_macosx_store_vfpv1_regs (&fp_regs); ret = thread_set_state (current_thread, GDB_ARM_THREAD_FPSTATE, (thread_state_t) & fp_regs, GDB_ARM_THREAD_FPSTATE_VFPV1_COUNT); MACH_CHECK_ERROR (ret); } break; case ARM_VFP_VERSION_3: { gdb_arm_thread_vfpv3_state_t fp_regs; arm_macosx_store_vfpv3_regs (&fp_regs); ret = thread_set_state (current_thread, GDB_ARM_THREAD_FPSTATE, (thread_state_t) & fp_regs, GDB_ARM_THREAD_FPSTATE_VFPV3_COUNT); MACH_CHECK_ERROR (ret); } break; default: error ("store_inferior_registers: unable to store ARM_THREAD_FPSTATE: " "unsupported vfp version: %d", (int)vfp_version); break; } } }
static void i386_darwin_dr_set (int regnum, uint32_t value) { int current_pid; thread_t current_thread; x86_debug_state_t dr_regs; kern_return_t ret; unsigned int dr_count = x86_DEBUG_STATE_COUNT; gdb_assert (regnum >= 0 && regnum <= DR_CONTROL); current_thread = ptid_get_tid (inferior_ptid); dr_regs.dsh.flavor = x86_DEBUG_STATE32; dr_regs.dsh.count = x86_DEBUG_STATE32_COUNT; dr_count = x86_DEBUG_STATE_COUNT; ret = thread_get_state (current_thread, x86_DEBUG_STATE, (thread_state_t) &dr_regs, &dr_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error reading debug registers " "thread 0x%x via thread_get_state\n"), (int) current_thread); MACH_CHECK_ERROR (ret); } switch (regnum) { case 0: dr_regs.uds.ds32.__dr0 = value; break; case 1: dr_regs.uds.ds32.__dr1 = value; break; case 2: dr_regs.uds.ds32.__dr2 = value; break; case 3: dr_regs.uds.ds32.__dr3 = value; break; case 4: dr_regs.uds.ds32.__dr4 = value; break; case 5: dr_regs.uds.ds32.__dr5 = value; break; case 6: dr_regs.uds.ds32.__dr6 = value; break; case 7: dr_regs.uds.ds32.__dr7 = value; break; } ret = thread_set_state (current_thread, x86_DEBUG_STATE, (thread_state_t) &dr_regs, dr_count); if (ret != KERN_SUCCESS) { printf_unfiltered (_("Error writing debug registers " "thread 0x%x via thread_get_state\n"), (int) current_thread); MACH_CHECK_ERROR (ret); } }
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); } } }