td_err_e
td_thr_getgregs (const td_thrhandle_t *th, prgregset_t regset)
{
  psaddr_t cancelhandling, tid;
  td_err_e err;

  LOG ("td_thr_getgregs");

  if (th->th_unique == 0)
    /* Special case for the main thread before initialization.  */
    return ps_lgetregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph),
			regset) != PS_OK ? TD_ERR : TD_OK;

  /* We have to get the state and the PID for this thread.  */
  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
		      cancelhandling, 0);
  if (err != TD_OK)
    return err;

  /* If the thread already terminated we return all zeroes.  */
  if (((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK)
    memset (regset, '\0', sizeof (*regset));
  /* Otherwise get the register content through the callback.  */
  else
    {
      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
      if (err != TD_OK)
	return err;

      if (ps_lgetregs (th->th_ta_p->ph, (uintptr_t) tid, regset) != PS_OK)
	return TD_ERR;
    }

  return TD_OK;
}
td_err_e
td_thr_getgregs (const td_thrhandle_t *th, prgregset_t gregs)
{
  struct _pthread_descr_struct pds;

  LOG ("td_thr_getgregs");

  /* We have to get the state and the PID for this thread.  */
  if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
		 sizeof (struct _pthread_descr_struct)) != PS_OK)
    return TD_ERR;

  /* If the thread already terminated we return all zeroes.  */
  if (pds.p_terminated)
    memset (gregs, '\0', sizeof (prgregset_t));
  /* Otherwise get the register content through the callback.  */
  else
    {
      pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);

      if (ps_lgetregs (th->th_ta_p->ph, pid, gregs) != PS_OK)
	return TD_ERR;
    }

  return TD_OK;
}
Exemple #3
0
ps_err_e
ps_lgetLDT(struct ps_prochandle *P, lwpid_t lwpid, struct ssd *ldt)
{
#if defined(__amd64) && defined(_LP64)
	if (P->status.pr_dmodel != PR_MODEL_NATIVE) {
#endif
	prgregset_t regs;
	struct ssd *ldtarray;
	ps_err_e error;
	uint_t gs;
	int nldt;
	int i;

	if (P->state != PS_STOP && P->state != PS_DEAD)
		return (PS_ERR);

	/*
	 * We need to get the ldt entry that matches the
	 * value in the lwp's GS register.
	 */
	if ((error = ps_lgetregs(P, lwpid, regs)) != PS_OK)
		return (error);

	gs = regs[GS];

	if ((nldt = Pldt(P, NULL, 0)) <= 0 ||
	    (ldtarray = malloc(nldt * sizeof (struct ssd))) == NULL)
		return (PS_ERR);
	if ((nldt = Pldt(P, ldtarray, nldt)) <= 0) {
		free(ldtarray);
		return (PS_ERR);
	}

	for (i = 0; i < nldt; i++) {
		if (gs == ldtarray[i].sel) {
			*ldt = ldtarray[i];
			break;
		}
	}
	free(ldtarray);

	if (i < nldt)
		return (PS_OK);
#if defined(__amd64) && defined(_LP64)
	}
#endif

	return (PS_ERR);
}