diff options
Diffstat (limited to 'nptl_db/td_ta_tsd_iter.c')
-rw-r--r-- | nptl_db/td_ta_tsd_iter.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/nptl_db/td_ta_tsd_iter.c b/nptl_db/td_ta_tsd_iter.c index cbc2f37c51..9cfb1e8de0 100644 --- a/nptl_db/td_ta_tsd_iter.c +++ b/nptl_db/td_ta_tsd_iter.c @@ -1,5 +1,5 @@ /* Iterate over a process's thread-specific data. - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999,2000,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. @@ -22,32 +22,60 @@ #include <alloca.h> td_err_e -td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback, +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; - int pthread_keys_max = ta->pthread_keys_max; - struct pthread_key_struct *keys; - keys = (struct pthread_key_struct *) alloca (sizeof (keys[0]) - * pthread_keys_max); + /* 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; - /* Read all the information about the keys. */ - if (ps_pdread (ta->ph, ta->keys, keys, - sizeof (keys[0]) * pthread_keys_max) != PS_OK) - return TD_ERR; /* XXX Other error value? */ + /* 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. */ - int cnt; - for (cnt = 0; cnt < pthread_keys_max; ++cnt) - if (!KEY_UNUSED (keys[cnt].seq) - /* Return with an error if the callback returns a nonzero value. */ - && callback (cnt, keys[cnt].destr, cbdata_p) != 0) - return TD_DBERR; + 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; } |