コード例 #1
0
ファイル: td_ta_tsd_iter.c プロジェクト: AubrCool/glibc
td_err_e
td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
		void *cbdata_p)
{
  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
  td_err_e err;
  void *keys;
  size_t keys_nb, keys_elemsize;
  psaddr_t addr;
  uint32_t idx;

  LOG ("td_ta_tsd_iter");

  /* Test whether the TA parameter is ok.  */
  if (! ta_ok (ta))
    return TD_BADTA;

  /* This makes sure we have the size information on hand.  */
  addr = 0;
  err = _td_locate_field (ta,
			  ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
			  (psaddr_t) 0 + 1, &addr);
  if (err != TD_OK)
    return err;

  /* Now copy in the entire array of key descriptors.  */
  keys_elemsize = (addr - (psaddr_t) 0) / 8;
  keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
  keys = __alloca (keys_nb);
  err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
  if (err != TD_OK)
    return err;
  if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
    return TD_ERR;

  /* Now get all descriptors, one after the other.  */
  for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
    {
      psaddr_t seq, destr;
      err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
      if (err != TD_OK)
	return err;
      if (((uintptr_t) seq) & 1)
	{
	  err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
				    destr, 0);
	  if (err != TD_OK)
	    return err;
	  /* Return with an error if the callback returns a nonzero value.  */
	  if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
	    return TD_DBERR;
	}
      /* Advance to the next element in the copied array.  */
      keys += keys_elemsize;
    }

  return TD_OK;
}
コード例 #2
0
ファイル: fetch-value.c プロジェクト: JamesLinus/glibc-mips
td_err_e
_td_locate_field (td_thragent_t *ta,
		  db_desc_t desc, int descriptor_name,
		  psaddr_t idx, psaddr_t *address)
{
  uint32_t elemsize;

  if (DB_DESC_SIZE (desc) == 0)
    {
      /* Read the information about this field from the inferior.  */
      psaddr_t descptr;
      ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
      if (err == PS_NOSYM)
	return TD_NOCAPAB;
      if (err == PS_OK)
	err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
      if (err != PS_OK)
	return TD_ERR;
      if (DB_DESC_SIZE (desc) == 0)
	return TD_DBERR;
      if (DB_DESC_SIZE (desc) & 0xff000000U)
	{
	  /* Byte-swap these words, though we leave the size word
	     in native order as the handy way to distinguish.  */
	  DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
	  DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
	}
    }

  if (idx != 0 && DB_DESC_NELEM (desc) != 0
      && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
    /* This is an internal indicator to callers with nonzero IDX
       that the IDX value is too big.  */
    return TD_NOAPLIC;

  elemsize = DB_DESC_SIZE (desc);
  if (elemsize & 0xff000000U)
    elemsize = bswap_32 (elemsize);

  *address += (int32_t) DB_DESC_OFFSET (desc);
  *address += (elemsize / 8 * (idx - (psaddr_t) 0));
  return TD_OK;
}
コード例 #3
0
ファイル: td_thr_tsd.c プロジェクト: mbref/eglibc-microblaze
td_err_e
td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data)
{
  td_err_e err;
  psaddr_t tk_seq, level1, level2, seq, value;
  void *copy;
  uint32_t pthread_key_2ndlevel_size, idx1st, idx2nd;

  LOG ("td_thr_tsd");

  /* Get the key entry.  */
  err = DB_GET_VALUE (tk_seq, th->th_ta_p, __pthread_keys, tk);
  if (err == TD_NOAPLIC)
    return TD_BADKEY;
  if (err != TD_OK)
    return err;

  /* Fail if this key is not at all used.  */
  if (((uintptr_t) tk_seq & 1) == 0)
    return TD_BADKEY;

  /* This makes sure we have the size information on hand.  */
  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p, 0, pthread_key_data_level2,
			      data, 1);
  if (err != TD_OK)
    return err;

  /* Compute the indeces.  */
  pthread_key_2ndlevel_size
    = DB_DESC_NELEM (th->th_ta_p->ta_field_pthread_key_data_level2_data);
  idx1st = tk / pthread_key_2ndlevel_size;
  idx2nd = tk % pthread_key_2ndlevel_size;

  /* Now fetch the first level pointer.  */
  err = DB_GET_FIELD (level1, th->th_ta_p, th->th_unique, pthread,
		      specific, idx1st);
  if (err == TD_NOAPLIC)
    return TD_DBERR;
  if (err != TD_OK)
    return err;

  /* Check the pointer to the second level array.  */
  if (level1 == 0)
    return TD_NOTSD;

  /* Locate the element within the second level array.  */
  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p,
			      level1, pthread_key_data_level2, data, idx2nd);
  if (err == TD_NOAPLIC)
    return TD_DBERR;
  if (err != TD_OK)
    return err;

  /* Now copy in that whole structure.  */
  err = DB_GET_STRUCT (copy, th->th_ta_p, level2, pthread_key_data);
  if (err != TD_OK)
    return err;

  /* Check whether the data is valid.  */
  err = DB_GET_FIELD_LOCAL (seq, th->th_ta_p, copy, pthread_key_data, seq, 0);
  if (err != TD_OK)
    return err;
  if (seq != tk_seq)
    return TD_NOTSD;

  /* Finally, fetch the value.  */
  err = DB_GET_FIELD_LOCAL (value, th->th_ta_p, copy, pthread_key_data,
			    data, 0);
  if (err == TD_OK)
    *data = value;

  return err;
}