Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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));
	}
}
Exemplo n.º 3
0
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);
        }
    }
}
Exemplo n.º 4
0
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,
                                     &register_address);
      register_address += sparc_register_offsets [regnum];
    }
  else
    return;

  regcache_raw_collect (regcache, regnum, buf);
  write_memory (register_address,
                buf,
                buf_size);
}
Exemplo n.º 6
0
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);
		}
	}

}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
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);
    }
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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);
    }
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
	}
}
Exemplo n.º 16
0
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;
    }
}
Exemplo n.º 17
0
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);
    }
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
/*
 * 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);
        }
    }
}
Exemplo n.º 22
0
/* 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;
}
Exemplo n.º 23
0
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);
}
Exemplo n.º 24
0
/* 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);
    }
}
Exemplo n.º 25
0
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);
            }
        }
    }
}
Exemplo n.º 26
0
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;
	}
    }
}
Exemplo n.º 27
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);
    }
}
Exemplo n.º 28
0
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;
	}
    }
}
Exemplo n.º 29
0
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);
    }
}
Exemplo n.º 30
0
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);
        }
    }
}