Back to index

glibc  2.9
Classes | Defines | Typedefs | Enumerations | Functions
thread_db.h File Reference
#include <pthread.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/procfs.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  td_thrhandle
struct  td_thr_events
struct  td_notify
struct  td_event_msg
struct  td_eventbuf_t
struct  td_ta_stats
struct  td_thrinfo
union  td_notify.u
union  td_event_msg.msg

Defines

#define TD_THR_ANY_USER_FLAGS   0xffffffff
#define TD_THR_LOWEST_PRIORITY   -20
#define TD_SIGNO_MASK   NULL
#define TD_EVENTSIZE   2
#define BT_UISHIFT   5 /* log base 2 of BT_NBIPUI, to extract word index */
#define BT_NBIPUI   (1 << BT_UISHIFT) /* n bits per uint */
#define BT_UIMASK   (BT_NBIPUI - 1) /* to extract bit index */
#define __td_eventmask(n)   (UINT32_C (1) << (((n) - 1) & BT_UIMASK))
#define __td_eventword(n)   ((UINT32_C ((n) - 1)) >> BT_UISHIFT)
#define td_event_emptyset(setp)
#define td_event_fillset(setp)
#define td_event_addset(setp, n)   (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))
#define td_event_delset(setp, n)   (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))
#define td_eventismember(setp, n)   (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))
#define td_eventisempty(setp)   (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))

Typedefs

typedef struct td_thragent
typedef struct td_thrhandle td_thrhandle_t
typedef struct td_thr_events td_thr_events_t
typedef struct td_notify td_notify_t
typedef struct td_event_msg td_event_msg_t
typedef struct td_ta_stats td_ta_stats_t
typedef pthread_t thread_t
typedef pthread_key_t thread_key_t
typedef int td_thr_iter_f (const td_thrhandle_t *, void *)
typedef int td_key_iter_f (thread_key_t, void(*)(void *), void *)
typedef struct td_thrinfo td_thrinfo_t

Enumerations

enum  td_err_e {
  TD_OK, TD_ERR, TD_NOTHR, TD_NOSV,
  TD_NOLWP, TD_BADPH, TD_BADTH, TD_BADSH,
  TD_BADTA, TD_BADKEY, TD_NOMSG, TD_NOFPREGS,
  TD_NOLIBTHREAD, TD_NOEVENT, TD_NOCAPAB, TD_DBERR,
  TD_NOAPLIC, TD_NOTSD, TD_MALLOC, TD_PARTIALREG,
  TD_NOXREGS, TD_TLSDEFER, TD_NOTALLOC = TD_TLSDEFER, TD_VERSION,
  TD_NOTLS, TD_OK, TD_ERR, TD_NOTHR,
  TD_NOSV, TD_NOLWP, TD_BADPH, TD_BADTH,
  TD_BADSH, TD_BADTA, TD_BADKEY, TD_NOMSG,
  TD_NOFPREGS, TD_NOLIBTHREAD, TD_NOEVENT, TD_NOCAPAB,
  TD_DBERR, TD_NOAPLIC, TD_NOTSD, TD_MALLOC,
  TD_PARTIALREG, TD_NOXREGS, TD_TLSDEFER, TD_NOTALLOC = TD_TLSDEFER,
  TD_VERSION, TD_NOTLS
}
enum  td_thr_state_e {
  TD_THR_ANY_STATE, TD_THR_UNKNOWN, TD_THR_STOPPED, TD_THR_RUN,
  TD_THR_ACTIVE, TD_THR_ZOMBIE, TD_THR_SLEEP, TD_THR_STOPPED_ASLEEP,
  TD_THR_ANY_STATE, TD_THR_UNKNOWN, TD_THR_STOPPED, TD_THR_RUN,
  TD_THR_ACTIVE, TD_THR_ZOMBIE, TD_THR_SLEEP, TD_THR_STOPPED_ASLEEP
}
enum  td_thr_type_e {
  TD_THR_ANY_TYPE, TD_THR_USER, TD_THR_SYSTEM, TD_THR_ANY_TYPE,
  TD_THR_USER, TD_THR_SYSTEM
}
enum  td_event_e {
  TD_ALL_EVENTS, TD_EVENT_NONE = TD_ALL_EVENTS, TD_READY, TD_SLEEP,
  TD_SWITCHTO, TD_SWITCHFROM, TD_LOCK_TRY, TD_CATCHSIG,
  TD_IDLE, TD_CREATE, TD_DEATH, TD_PREEMPT,
  TD_PRI_INHERIT, TD_REAP, TD_CONCURRENCY, TD_TIMEOUT,
  TD_MIN_EVENT_NUM = TD_READY, TD_MAX_EVENT_NUM = TD_TIMEOUT, TD_EVENTS_ENABLE = 31, TD_ALL_EVENTS,
  TD_EVENT_NONE = TD_ALL_EVENTS, TD_READY, TD_SLEEP, TD_SWITCHTO,
  TD_SWITCHFROM, TD_LOCK_TRY, TD_CATCHSIG, TD_IDLE,
  TD_CREATE, TD_DEATH, TD_PREEMPT, TD_PRI_INHERIT,
  TD_REAP, TD_CONCURRENCY, TD_TIMEOUT, TD_MIN_EVENT_NUM = TD_READY,
  TD_MAX_EVENT_NUM = TD_TIMEOUT, TD_EVENTS_ENABLE = 31
}
enum  td_notify_e {
  NOTIFY_BPT, NOTIFY_AUTOBPT, NOTIFY_SYSCALL, NOTIFY_BPT,
  NOTIFY_AUTOBPT, NOTIFY_SYSCALL
}

Functions

td_err_e td_init (void)
td_err_e td_log (void)
const char ** td_symbol_list (void)
td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta)
td_err_e td_ta_delete (td_thragent_t *__ta)
td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np)
td_err_e td_ta_get_ph (const td_thragent_t *__ta, struct ps_prochandle **__ph)
td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt, td_thrhandle_t *__th)
td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid, td_thrhandle_t *__th)
td_err_e td_ta_thr_iter (const td_thragent_t *__ta, td_thr_iter_f *__callback, void *__cbdata_p, td_thr_state_e __state, int __ti_pri, sigset_t *__ti_sigmask_p, unsigned int __ti_user_flags)
td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki, void *__p)
td_err_e td_ta_event_addr (const td_thragent_t *__ta, td_event_e __event, td_notify_t *__ptr)
td_err_e td_ta_set_event (const td_thragent_t *__ta, td_thr_events_t *__event)
td_err_e td_ta_clear_event (const td_thragent_t *__ta, td_thr_events_t *__event)
td_err_e td_ta_event_getmsg (const td_thragent_t *__ta, td_event_msg_t *__msg)
td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level)
td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable)
td_err_e td_ta_reset_stats (const td_thragent_t *__ta)
td_err_e td_ta_get_stats (const td_thragent_t *__ta, td_ta_stats_t *__statsp)
td_err_e td_thr_validate (const td_thrhandle_t *__th)
td_err_e td_thr_get_info (const td_thrhandle_t *__th, td_thrinfo_t *__infop)
td_err_e td_thr_getfpregs (const td_thrhandle_t *__th, prfpregset_t *__regset)
td_err_e td_thr_getgregs (const td_thrhandle_t *__th, prgregset_t __gregs)
td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs)
td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep)
td_err_e td_thr_setfpregs (const td_thrhandle_t *__th, const prfpregset_t *__fpregs)
td_err_e td_thr_setgregs (const td_thrhandle_t *__th, prgregset_t __gregs)
td_err_e td_thr_setxregs (const td_thrhandle_t *__th, const void *__addr)
td_err_e td_thr_tlsbase (const td_thrhandle_t *__th, unsigned long int __modid, psaddr_t *__base)
td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th, void *__map_address, size_t __offset, void **__address)
td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event)
td_err_e td_thr_set_event (const td_thrhandle_t *__th, td_thr_events_t *__event)
td_err_e td_thr_clear_event (const td_thrhandle_t *__th, td_thr_events_t *__event)
td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th, td_event_msg_t *__msg)
td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio)
td_err_e td_thr_setsigpending (const td_thrhandle_t *__th, unsigned char __n, const sigset_t *__ss)
td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th, const sigset_t *__ss)
td_err_e td_thr_tsd (const td_thrhandle_t *__th, const thread_key_t __tk, void **__data)
td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th)
td_err_e td_thr_dbresume (const td_thrhandle_t *__th)

Class Documentation

struct td_thrhandle

Definition at line 93 of file thread_db.h.

Class Members
td_thragent_t * th_ta_p
psaddr_t th_unique
struct td_thr_events

Definition at line 116 of file thread_db.h.

Class Members
uint32_t event_bits
struct td_notify

Definition at line 188 of file thread_db.h.

Class Members
td_notify_e type
union td_notify u
union td_notify u
struct td_event_msg

Definition at line 199 of file thread_db.h.

Collaboration diagram for td_event_msg:
Class Members
td_event_e event
union td_event_msg msg
union td_event_msg msg
const td_thrhandle_t * th_p
struct td_eventbuf_t

Definition at line 213 of file thread_db.h.

Collaboration diagram for td_eventbuf_t:
Class Members
void * eventdata
td_thr_events_t eventmask
td_event_e eventnum
struct td_ta_stats

Definition at line 222 of file thread_db.h.

Class Members
int a_concurrency_den
int a_concurrency_num
int nidle_den
int nidle_num
int nlwps_den
int nlwps_num
int nrunnable_den
int nrunnable_num
int nthreads
int r_concurrency
struct td_thrinfo

Definition at line 260 of file thread_db.h.

Collaboration diagram for td_thrinfo:
Class Members
unsigned char ti_db_suspended
td_thr_events_t ti_events
short int ti_flags
lwpid_t ti_lid
intptr_t ti_pc
sigset_t ti_pending
unsigned char ti_pirecflag
unsigned char ti_preemptflag
int ti_pri
psaddr_t ti_ro_area
int ti_ro_size
sigset_t ti_sigmask
intptr_t ti_sp
psaddr_t ti_startfunc
td_thr_state_e ti_state
psaddr_t ti_stkbase
long int ti_stksize
td_thragent_t * ti_ta_p
thread_t ti_tid
char * ti_tls
unsigned char ti_traceme
td_thr_type_e ti_type
unsigned int ti_user_flags
union td_notify.u

Definition at line 191 of file thread_db.h.

Class Members
psaddr_t bptaddr
int syscallno
union td_event_msg.msg

Definition at line 203 of file thread_db.h.

Class Members
uintptr_t data

Define Documentation

#define __td_eventmask (   n)    (UINT32_C (1) << (((n) - 1) & BT_UIMASK))

Definition at line 122 of file thread_db.h.

#define __td_eventword (   n)    ((UINT32_C ((n) - 1)) >> BT_UISHIFT)

Definition at line 124 of file thread_db.h.

#define BT_NBIPUI   (1 << BT_UISHIFT) /* n bits per uint */

Definition at line 112 of file thread_db.h.

#define BT_UIMASK   (BT_NBIPUI - 1) /* to extract bit index */

Definition at line 113 of file thread_db.h.

#define BT_UISHIFT   5 /* log base 2 of BT_NBIPUI, to extract word index */

Definition at line 111 of file thread_db.h.

#define td_event_addset (   setp,
  n 
)    (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))

Definition at line 141 of file thread_db.h.

#define td_event_delset (   setp,
  n 
)    (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))

Definition at line 143 of file thread_db.h.

#define td_event_emptyset (   setp)
Value:
do {                                                                 \
    int __i;                                                         \
    for (__i = TD_EVENTSIZE; __i > 0; --__i)                                \
      (setp)->event_bits[__i - 1] = 0;                                      \
  } while (0)

Definition at line 127 of file thread_db.h.

#define td_event_fillset (   setp)
Value:
do {                                                                 \
    int __i;                                                         \
    for (__i = TD_EVENTSIZE; __i > 0; --__i)                                \
      (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff);                  \
  } while (0)

Definition at line 134 of file thread_db.h.

#define td_eventisempty (   setp)    (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))

Definition at line 148 of file thread_db.h.

#define td_eventismember (   setp,
  n 
)    (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))

Definition at line 145 of file thread_db.h.

#define TD_EVENTSIZE   2

Definition at line 110 of file thread_db.h.

#define TD_SIGNO_MASK   NULL

Definition at line 107 of file thread_db.h.

#define TD_THR_ANY_USER_FLAGS   0xffffffff

Definition at line 105 of file thread_db.h.

#define TD_THR_LOWEST_PRIORITY   -20

Definition at line 106 of file thread_db.h.


Typedef Documentation

typedef struct td_event_msg td_event_msg_t
typedef int td_key_iter_f(thread_key_t, void(*)(void *), void *)

Definition at line 251 of file thread_db.h.

typedef struct td_notify td_notify_t
typedef struct td_ta_stats td_ta_stats_t
typedef int td_thr_iter_f(const td_thrhandle_t *, void *)

Definition at line 248 of file thread_db.h.

typedef struct td_thragent

Definition at line 90 of file thread_db.h.

typedef struct td_thrhandle td_thrhandle_t
typedef struct td_thrinfo td_thrinfo_t

Definition at line 244 of file thread_db.h.

Definition at line 243 of file thread_db.h.


Enumeration Type Documentation

enum td_err_e
Enumerator:
TD_OK 
TD_ERR 
TD_NOTHR 
TD_NOSV 
TD_NOLWP 
TD_BADPH 
TD_BADTH 
TD_BADSH 
TD_BADTA 
TD_BADKEY 
TD_NOMSG 
TD_NOFPREGS 
TD_NOLIBTHREAD 
TD_NOEVENT 
TD_NOCAPAB 
TD_DBERR 
TD_NOAPLIC 
TD_NOTSD 
TD_MALLOC 
TD_PARTIALREG 
TD_NOXREGS 
TD_TLSDEFER 
TD_NOTALLOC 
TD_VERSION 
TD_NOTLS 
TD_OK 
TD_ERR 
TD_NOTHR 
TD_NOSV 
TD_NOLWP 
TD_BADPH 
TD_BADTH 
TD_BADSH 
TD_BADTA 
TD_BADKEY 
TD_NOMSG 
TD_NOFPREGS 
TD_NOLIBTHREAD 
TD_NOEVENT 
TD_NOCAPAB 
TD_DBERR 
TD_NOAPLIC 
TD_NOTSD 
TD_MALLOC 
TD_PARTIALREG 
TD_NOXREGS 
TD_TLSDEFER 
TD_NOTALLOC 
TD_VERSION 
TD_NOTLS 

Definition at line 33 of file thread_db.h.

{
  TD_OK,        /* No error.  */
  TD_ERR,       /* No further specified error.  */
  TD_NOTHR,     /* No matching thread found.  */
  TD_NOSV,      /* No matching synchronization handle found.  */
  TD_NOLWP,     /* No matching light-weighted process found.  */
  TD_BADPH,     /* Invalid process handle.  */
  TD_BADTH,     /* Invalid thread handle.  */
  TD_BADSH,     /* Invalid synchronization handle.  */
  TD_BADTA,     /* Invalid thread agent.  */
  TD_BADKEY,    /* Invalid key.  */
  TD_NOMSG,     /* No event available.  */
  TD_NOFPREGS,         /* No floating-point register content available.  */
  TD_NOLIBTHREAD, /* Application not linked with thread library.  */
  TD_NOEVENT,   /* Requested event is not supported.  */
  TD_NOCAPAB,   /* Capability not available.  */
  TD_DBERR,     /* Internal debug library error.  */
  TD_NOAPLIC,   /* Operation is not applicable.  */
  TD_NOTSD,     /* No thread-specific data available.  */
  TD_MALLOC,    /* Out of memory.  */
  TD_PARTIALREG,  /* Not entire register set was read or written.  */
  TD_NOXREGS,   /* X register set not available for given thread.  */
  TD_TLSDEFER,         /* Thread has not yet allocated TLS for given module.  */
  TD_NOTALLOC = TD_TLSDEFER,
  TD_VERSION,   /* Version if libpthread and libthread_db do not match.  */
  TD_NOTLS      /* There is TLS segment in the given module.  */
} td_err_e;
enum td_event_e
Enumerator:
TD_ALL_EVENTS 
TD_EVENT_NONE 
TD_READY 
TD_SLEEP 
TD_SWITCHTO 
TD_SWITCHFROM 
TD_LOCK_TRY 
TD_CATCHSIG 
TD_IDLE 
TD_CREATE 
TD_DEATH 
TD_PREEMPT 
TD_PRI_INHERIT 
TD_REAP 
TD_CONCURRENCY 
TD_TIMEOUT 
TD_MIN_EVENT_NUM 
TD_MAX_EVENT_NUM 
TD_EVENTS_ENABLE 
TD_ALL_EVENTS 
TD_EVENT_NONE 
TD_READY 
TD_SLEEP 
TD_SWITCHTO 
TD_SWITCHFROM 
TD_LOCK_TRY 
TD_CATCHSIG 
TD_IDLE 
TD_CREATE 
TD_DEATH 
TD_PREEMPT 
TD_PRI_INHERIT 
TD_REAP 
TD_CONCURRENCY 
TD_TIMEOUT 
TD_MIN_EVENT_NUM 
TD_MAX_EVENT_NUM 
TD_EVENTS_ENABLE 

Definition at line 155 of file thread_db.h.

{
  TD_ALL_EVENTS,             /* Pseudo-event number.  */
  TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context.  */
  TD_READY,                  /* Is executable now. */
  TD_SLEEP,                  /* Blocked in a synchronization obj.  */
  TD_SWITCHTO,                      /* Now assigned to a process.  */
  TD_SWITCHFROM,             /* Not anymore assigned to a process.  */
  TD_LOCK_TRY,                      /* Trying to get an unavailable lock.  */
  TD_CATCHSIG,                      /* Signal posted to the thread.  */
  TD_IDLE,                   /* Process getting idle.  */
  TD_CREATE,                 /* New thread created.  */
  TD_DEATH,                  /* Thread terminated.  */
  TD_PREEMPT,                /* Preempted.  */
  TD_PRI_INHERIT,            /* Inherited elevated priority.  */
  TD_REAP,                   /* Reaped.  */
  TD_CONCURRENCY,            /* Number of processes changing.  */
  TD_TIMEOUT,                /* Conditional variable wait timed out.  */
  TD_MIN_EVENT_NUM = TD_READY,
  TD_MAX_EVENT_NUM = TD_TIMEOUT,
  TD_EVENTS_ENABLE = 31            /* Event reporting enabled.  */
} td_event_e;
Enumerator:
NOTIFY_BPT 
NOTIFY_AUTOBPT 
NOTIFY_SYSCALL 
NOTIFY_BPT 
NOTIFY_AUTOBPT 
NOTIFY_SYSCALL 

Definition at line 179 of file thread_db.h.

{
  NOTIFY_BPT,               /* User must insert breakpoint at u.bptaddr. */
  NOTIFY_AUTOBPT,           /* Breakpoint at u.bptaddr is automatically
                               inserted.  */
  NOTIFY_SYSCALL            /* System call u.syscallno will be invoked.  */
} td_notify_e;
Enumerator:
TD_THR_ANY_STATE 
TD_THR_UNKNOWN 
TD_THR_STOPPED 
TD_THR_RUN 
TD_THR_ACTIVE 
TD_THR_ZOMBIE 
TD_THR_SLEEP 
TD_THR_STOPPED_ASLEEP 
TD_THR_ANY_STATE 
TD_THR_UNKNOWN 
TD_THR_STOPPED 
TD_THR_RUN 
TD_THR_ACTIVE 
TD_THR_ZOMBIE 
TD_THR_SLEEP 
TD_THR_STOPPED_ASLEEP 

Definition at line 65 of file thread_db.h.

Enumerator:
TD_THR_ANY_TYPE 
TD_THR_USER 
TD_THR_SYSTEM 
TD_THR_ANY_TYPE 
TD_THR_USER 
TD_THR_SYSTEM 

Definition at line 79 of file thread_db.h.


Function Documentation

td_err_e td_init ( void  )

Definition at line 29 of file td_init.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_init");
  return TD_OK;
}
td_err_e td_log ( void  )

Definition at line 25 of file td_log.c.

{
  /* This interface is deprecated in the Sun interface.  We provide it
     for compatibility but don't do anything ourself.  We might in
     future do some logging if this seems reasonable.  */
  LOG ("td_log");
  return TD_OK;
}
const char** td_symbol_list ( void  )

Definition at line 51 of file td_symbol_list.c.

{
  return symbol_list_arr;
}
td_err_e td_ta_clear_event ( const td_thragent_t *  __ta,
td_thr_events_t __event 
)
td_err_e td_ta_delete ( td_thragent_t *  __ta)

Definition at line 27 of file td_ta_delete.c.

{
  LOG ("td_ta_delete");

  /* Safety check.  */
  if (ta == NULL || __td_agent_list == NULL)
    return TD_BADTA;

  /* Remove the handle from the list.  */
  if (ta == __td_agent_list->ta)
    /* It's the first element of the list.  */
    __td_agent_list = __td_agent_list->next;
  else
    {
      /* We have to search for it.  */
      struct agent_list *runp = __td_agent_list;

      while (runp->next != NULL && runp->next->ta != ta)
       runp = runp->next;

      if (runp->next == NULL)
       /* It's not a valid decriptor since it is not in the list.  */
       return TD_BADTA;

      runp->next = runp->next->next;
    }

  /* The handle was allocated in `td_ta_new'.  */
  free (ta);

  return TD_OK;
}
td_err_e td_ta_enable_stats ( const td_thragent_t *  __ta,
int  __enable 
)

Definition at line 25 of file td_ta_enable_stats.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_ta_enable_stats");

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

  return TD_OK;
}
td_err_e td_ta_event_addr ( const td_thragent_t *  __ta,
td_event_e  __event,
td_notify_t __ptr 
)

Definition at line 25 of file td_ta_event_addr.c.

{
  td_err_e res = TD_NOEVENT;
  int idx = -1;

  LOG ("td_ta_event_addr");

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

  switch (event)
    {
    case TD_CREATE:
      idx = LINUXTHREADS_CREATE_EVENT;
      break;

    case TD_DEATH:
      idx = LINUXTHREADS_DEATH_EVENT;
      break;

    case TD_REAP:
      idx = LINUXTHREADS_REAP_EVENT;
      break;

    default:
      /* Event cannot be handled.  */
      break;
    }

  /* Now get the address.  */
  if (idx != -1)
    {
      psaddr_t taddr;

      if (td_lookup (ta->ph, idx, &taddr) == PS_OK)
       {
         /* Success, we got the address.  */
         addr->type = NOTIFY_BPT;
         addr->u.bptaddr = taddr;

         res = TD_OK;
       }
      else
       res = TD_ERR;
    }

  return res;
}
td_err_e td_ta_event_getmsg ( const td_thragent_t *  __ta,
td_event_msg_t __msg 
)

Definition at line 29 of file td_ta_event_getmsg.c.

{
  /* XXX I cannot think of another way but using a static variable.  */
  static td_thrhandle_t th;
  td_eventbuf_t event;
  psaddr_t addr;

  LOG ("td_ta_event_getmsg");

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

  /* Get the pointer to the thread descriptor with the last event.  */
  if (ps_pdread (ta->ph, ta->pthread_last_event,
               &addr, sizeof (void *)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* If the pointer is NULL no event occurred.  */
  if (addr == 0)
    return TD_NOMSG;

  /* Read the even structure from the target.  */
  if (ps_pdread (ta->ph,
               ((char *) addr
                + offsetof (struct _pthread_descr_struct, p_eventbuf)),
               &event, sizeof (td_eventbuf_t)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Check whether an event occurred.  */
  if (event.eventnum == TD_EVENT_NONE)
    {
      /* Oh well, this means the last event was already read.  So
        we have to look for any other event.  */
      struct pthread_handle_struct handles[ta->pthread_threads_max];
      int num;
      int i;

      /* Read the number of currently active threads.  */
      if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int))
         != PS_OK)
       return TD_ERR;       /* XXX Other error value?  */

      /* Now read the handles.  */
      if (ps_pdread (ta->ph, ta->handles, handles,
                   ta->pthread_threads_max * sizeof (handles[0])) != PS_OK)
       return TD_ERR;       /* XXX Other error value?  */

      for (i = 0; i < ta->pthread_threads_max && num > 0; ++i)
       {
         if (handles[i].h_descr == NULL)
           /* No entry here.  */
           continue;

         /* First count this active thread.  */
         --num;

         if (handles[i].h_descr == addr)
           /* We already handled this.  */
           continue;

         /* Read the event data for this thread.  */
         if (ps_pdread (ta->ph,
                      ((char *) handles[i].h_descr
                       + offsetof (struct _pthread_descr_struct,
                                  p_eventbuf)),
                      &event, sizeof (td_eventbuf_t)) != PS_OK)
           return TD_ERR;

         if (event.eventnum != TD_EVENT_NONE)
           {
             /* We found a thread with an unreported event.  */
             addr = handles[i].h_descr;
             break;
           }
       }

      /* If we haven't found any other event signal this to the user.  */
      if (event.eventnum == TD_EVENT_NONE)
       return TD_NOMSG;
    }

  /* Generate the thread descriptor.  */
  th.th_ta_p = (td_thragent_t *) ta;
  th.th_unique = addr;

  /* Fill the user's data structure.  */
  msg->event = event.eventnum;
  msg->th_p = &th;
  msg->msg.data = (uintptr_t) event.eventdata;

  /* And clear the event message in the target.  */
  memset (&event, '\0', sizeof (td_eventbuf_t));
  if (ps_pdwrite (ta->ph,
                ((char *) addr
                 + offsetof (struct _pthread_descr_struct, p_eventbuf)),
                &event, sizeof (td_eventbuf_t)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  return TD_OK;
}
td_err_e td_ta_get_nthreads ( const td_thragent_t *  __ta,
int __np 
)

Definition at line 24 of file td_ta_get_nthreads.c.

{
  psaddr_t addr;

  LOG ("td_ta_get_nthreads");

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

  /* Access the variable `__pthread_handles_num'.  */
  if (td_lookup (ta->ph, PTHREAD_HANDLES_NUM, &addr) != PS_OK)
     return TD_ERR;  /* XXX Other error value?  */

  if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK)
     return TD_ERR;  /* XXX Other error value?  */

  return TD_OK;
}
td_err_e td_ta_get_ph ( const td_thragent_t *  __ta,
struct ps_prochandle **  __ph 
)

Definition at line 25 of file td_ta_get_ph.c.

{
  LOG ("td_ta_get_ph");

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

  *ph = ta->ph;

  return TD_OK;
}
td_err_e td_ta_get_stats ( const td_thragent_t *  __ta,
td_ta_stats_t __statsp 
)

Definition at line 25 of file td_ta_get_stats.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_ta_get_stats");

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

  return TD_OK;
}
td_err_e td_ta_map_id2thr ( const td_thragent_t *  __ta,
pthread_t  __pt,
td_thrhandle_t __th 
)

Definition at line 26 of file td_ta_map_id2thr.c.

{
  struct pthread_handle_struct phc;
  struct _pthread_descr_struct pds;
  int pthread_threads_max;

  LOG ("td_ta_map_id2thr");

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

  /* Make the following expression a bit smaller.  */
  pthread_threads_max = ta->pthread_threads_max;

  /* We can compute the entry in the handle array we want.  */
  if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc,
               sizeof (struct pthread_handle_struct)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Test whether this entry is in use.  */
  if (phc.h_descr == NULL)
    {
      if (pt % pthread_threads_max == 0)
       {
         /* The initial thread always exists but the thread library
            might not yet be initialized.  */
         th->th_ta_p = (td_thragent_t *) ta;
         th->th_unique = NULL;

         return TD_OK;
       }

      return TD_BADTH;
    }

  /* Next test: get the descriptor to see whether this is not an old
     thread handle.  */
  if (ps_pdread (ta->ph, phc.h_descr, &pds,
               sizeof (struct _pthread_descr_struct)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  if (pds.p_tid != pt)
    return TD_BADTH;

  if (pds.p_terminated != 0)
    return TD_NOTHR;

  /* Create the `td_thrhandle_t' object.  */
  th->th_ta_p = (td_thragent_t *) ta;
  th->th_unique = phc.h_descr;

  return TD_OK;
}
td_err_e td_ta_map_lwp2thr ( const td_thragent_t *  __ta,
lwpid_t  __lwpid,
td_thrhandle_t __th 
)

Definition at line 26 of file td_ta_map_lwp2thr.c.

{
  int pthread_threads_max = ta->pthread_threads_max;
  size_t sizeof_descr = ta->sizeof_descr;
  struct pthread_handle_struct phc[pthread_threads_max];
  size_t cnt;
#ifdef ALL_THREADS_STOPPED
  int num;
#else
# define num 1
#endif

  LOG ("td_ta_map_lwp2thr");

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

  /* Read all the descriptors.  */
  if (ps_pdread (ta->ph, ta->handles, phc,
               sizeof (struct pthread_handle_struct) * pthread_threads_max)
      != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

#ifdef ALL_THREADS_STOPPED
  /* Read the number of currently active threads.  */
  if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */
#endif

  /* Get the entries one after the other and find out whether the ID
     matches.  */
  for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt)
    if (phc[cnt].h_descr != NULL)
      {
       struct _pthread_descr_struct pds;

#ifdef ALL_THREADS_STOPPED
       /* First count this active thread.  */
       --num;
#endif

       if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) != PS_OK)
         return TD_ERR;     /* XXX Other error value?  */

       if ((pds.p_pid ?: ps_getpid (ta->ph)) == lwpid)
         {
           /* Found it.  Now fill in the `td_thrhandle_t' object.  */
           th->th_ta_p = (td_thragent_t *) ta;
           th->th_unique = phc[cnt].h_descr;

           return TD_OK;
         }
      }
    else if (cnt == 0)
      {
       /* The initial thread always exists.  But it might not yet be
          initialized.  Construct a value.  */
       th->th_ta_p = (td_thragent_t *) ta;
       th->th_unique = NULL;

       return TD_OK;
      }

  return TD_NOLWP;
}
td_err_e td_ta_new ( struct ps_prochandle *  __ps,
td_thragent_t **  __ta 
)

Definition at line 35 of file td_ta_new.c.

{
  psaddr_t addr;
  psaddr_t versaddr;
  char versbuf[sizeof (VERSION)];
  struct agent_list *elemp;

  LOG ("td_ta_new");

  /* Get the global event mask.  This is one of the variables which
     are new in the thread library to enable debugging.  If it is
     not available we cannot debug.  */
  if (td_lookup (ps, PTHREAD_THREADS_EVENTS, &addr) != PS_OK)
    return TD_NOLIBTHREAD;

  /* Check whether the versions match.  */
  if (td_lookup (ps, LINUXTHREADS_VERSION, &versaddr) != PS_OK)
    return TD_VERSION;
  if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
    return TD_ERR;

  versbuf[sizeof (versbuf) - 1] = '\0';
  if (strcmp (versbuf, VERSION) != 0)
    /* Not the right version.  */
    return TD_VERSION;

  /* Fill in the appropriate information.  */
  *ta = (td_thragent_t *) malloc (sizeof (td_thragent_t));
  if (*ta == NULL)
    return TD_MALLOC;

  /* Store the proc handle which we will pass to the callback functions
     back into the debugger.  */
  (*ta)->ph = ps;

  /* Remember the address.  */
  (*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr;

  /* Get the pointer to the variable pointing to the thread descriptor
     with the last event.  */
  if (td_lookup (ps, PTHREAD_LAST_EVENT, &(*ta)->pthread_last_event) != PS_OK)
    {
    free_return:
      free (*ta);
      return TD_ERR;
    }

  /* Get the pointer to the variable containing the number of active
     threads.  */
  if (td_lookup (ps, PTHREAD_HANDLES_NUM, &(*ta)->pthread_handles_num)
      != PS_OK)
    goto free_return;

  /* See whether the library contains the necessary symbols.  */
  if (td_lookup (ps, PTHREAD_HANDLES, &addr) != PS_OK)
    goto free_return;

  (*ta)->handles = (struct pthread_handle_struct *) addr;


  if (td_lookup (ps, PTHREAD_KEYS, &addr) != PS_OK)
    goto free_return;

  /* Cast to the right type.  */
  (*ta)->keys = (struct pthread_key_struct *) addr;

  /* Find out about the maximum number of threads.  Old implementations
     don't provide this information.  In this case we assume that the
     debug  library is compiled with the same values.  */
  if (td_lookup (ps, LINUXTHREADS_PTHREAD_THREADS_MAX, &addr) != PS_OK)
    (*ta)->pthread_threads_max = PTHREAD_THREADS_MAX;
  else
    {
      if (ps_pdread (ps, addr, &(*ta)->pthread_threads_max, sizeof (int))
         != PS_OK)
       goto free_return;
    }

  /* Similar for the maximum number of thread local data keys.  */
  if (td_lookup (ps, LINUXTHREADS_PTHREAD_KEYS_MAX, &addr) != PS_OK)
    (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX;
  else
    {
      if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int))
         != PS_OK)
       goto free_return;
    }

  /* And for the size of the second level arrays for the keys.  */
  if (td_lookup (ps, LINUXTHREADS_PTHREAD_SIZEOF_DESCR, &addr) != PS_OK)
    (*ta)->sizeof_descr = sizeof (struct _pthread_descr_struct);
  else
    {
      if (ps_pdread (ps, addr, &(*ta)->sizeof_descr, sizeof (int)) != PS_OK)
       goto free_return;
      /* Don't let bogons in the inferior make us mess ourselves.  */
      if ((*ta)->sizeof_descr > sizeof (struct _pthread_descr_struct))
       (*ta)->sizeof_descr = sizeof (struct _pthread_descr_struct);
    }

  /* Now add the new agent descriptor to the list.  */
  elemp = (struct agent_list *) malloc (sizeof (struct agent_list));
  if (elemp == NULL)
    {
      /* Argh, now that everything else worked...  */
      free (*ta);
      return TD_MALLOC;
    }

  /* We don't care for thread-safety here.  */
  elemp->ta = *ta;
  elemp->next = __td_agent_list;
  __td_agent_list = elemp;

  return TD_OK;
}
td_err_e td_ta_reset_stats ( const td_thragent_t *  __ta)

Definition at line 25 of file td_ta_reset_stats.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_ta_reset_stats");

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

  return TD_OK;
}
td_err_e td_ta_set_event ( const td_thragent_t *  __ta,
td_thr_events_t __event 
)
td_err_e td_ta_setconcurrency ( const td_thragent_t *  __ta,
int  __level 
)

Definition at line 25 of file td_ta_setconcurrency.c.

{
  /* This is something LinuxThreads does not support.  */
  LOG ("td_ta_setconcurrency");

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

  return TD_NOCAPAB;
}
td_err_e td_ta_thr_iter ( const td_thragent_t *  __ta,
td_thr_iter_f __callback,
void *  __cbdata_p,
td_thr_state_e  __state,
int  __ti_pri,
sigset_t __ti_sigmask_p,
unsigned int  __ti_user_flags 
)

Definition at line 109 of file td_ta_thr_iter.c.

{
  int pthread_threads_max;
  struct pthread_handle_struct *phc;
  td_err_e result = TD_OK;
  int cnt;
#ifdef ALL_THREADS_STOPPED
  int num;
#else
# define num 1
#endif

  LOG ("td_ta_thr_iter");

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

  pthread_threads_max = ta->pthread_threads_max;
  phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0])
                                           * pthread_threads_max);

  /* First read only the main thread and manager thread information.  */
  if (ps_pdread (ta->ph, ta->handles, phc,
               sizeof (struct pthread_handle_struct) * 2) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Now handle these descriptors.  */
  result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 0,
                      phc[0].h_descr);
  if (result != TD_OK)
    return result;
  result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 1,
                      phc[1].h_descr);
  if (result != TD_OK)
    return result;

  /* Read all the descriptors.  */
  if (ps_pdread (ta->ph, ta->handles + 2, &phc[2],
               (sizeof (struct pthread_handle_struct)
                * (pthread_threads_max - 2))) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

#ifdef ALL_THREADS_STOPPED
  /* Read the number of currently active threads.  */
  if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */
#endif

  /* Now get all descriptors, one after the other.  */
  for (cnt = 2; cnt < pthread_threads_max && num > 0; ++cnt)
    if (phc[cnt].h_descr != NULL)
      {
#ifdef ALL_THREADS_STOPPED
       /* First count this active thread.  */
       --num;
#endif

       result = handle_descr (ta, callback, cbdata_p, state, ti_pri, cnt,
                            phc[cnt].h_descr);
       if (result != TD_OK)
         break;
      }

  return result;
}
td_err_e td_ta_tsd_iter ( const td_thragent_t *  __ta,
td_key_iter_f __ki,
void *  __p 
)

Definition at line 26 of file td_ta_tsd_iter.c.

{
  struct pthread_key_struct *keys;
  int pthread_keys_max;
  int cnt;

  LOG ("td_ta_tsd_iter");

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

  pthread_keys_max = ta->pthread_keys_max;
  keys = (struct pthread_key_struct *) alloca (sizeof (keys[0])
                                          * pthread_keys_max);

  /* 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 get all descriptors, one after the other.  */
  for (cnt = 0; cnt < pthread_keys_max; ++cnt)
    if (keys[cnt].in_use
       /* Return with an error if the callback returns a nonzero value.  */
       && callback (cnt, keys[cnt].destr, cbdata_p) != 0)
      return TD_DBERR;

  return TD_OK;
}

Definition at line 25 of file td_thr_dbresume.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_thr_dbresume");
  return TD_NOCAPAB;
}

Definition at line 25 of file td_thr_dbsuspend.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_thr_dbsuspend");
  return TD_NOCAPAB;
}

Definition at line 28 of file td_thr_event_getmsg.c.

{
  td_eventbuf_t event;

  LOG ("td_thr_event_getmsg");

  /* If the thread descriptor has not yet been created there cannot be
     any event.  */
  if (th->th_unique == NULL)
    return TD_NOMSG;

  /* Read the even structure from the target.  */
  if (ps_pdread (th->th_ta_p->ph,
               ((char *) th->th_unique
                + offsetof (struct _pthread_descr_struct, p_eventbuf)),
               &event, sizeof (td_eventbuf_t)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Check whether an event occurred.  */
  if (event.eventnum == TD_EVENT_NONE)
    /* Nothing.  */
    return TD_NOMSG;

  /* Fill the user's data structure.  */
  msg->event = event.eventnum;
  msg->th_p = th;
  msg->msg.data = (uintptr_t) event.eventdata;

  /* And clear the event message in the target.  */
  memset (&event, '\0', sizeof (td_eventbuf_t));
  if (ps_pdwrite (th->th_ta_p->ph,
                ((char *) th->th_unique
                 + offsetof (struct _pthread_descr_struct, p_eventbuf)),
                &event, sizeof (td_eventbuf_t)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  return TD_OK;
}

Definition at line 28 of file td_thr_get_info.c.

{
  struct _pthread_descr_struct pds;

  LOG ("td_thr_get_info");

  /* Handle the case when the thread library is not yet initialized.  */
  if (th->th_unique == NULL)
    {
      memset (&pds, '\0', sizeof (pds));
      pds.p_tid = PTHREAD_THREADS_MAX;
    }
  else
    /* Get the thread descriptor.  */
    if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
                 th->th_ta_p->sizeof_descr) != PS_OK)
      return TD_ERR; /* XXX Other error value?  */

  /* Fill in information.  Clear first to provide reproducable
     results for the fields we do not fill in.  */
  memset (infop, '\0', sizeof (td_thrinfo_t));

  /* We have to handle the manager thread special since the thread
     descriptor in older versions is not fully initialized.  */
  if (pds.p_nr == 1)
    {
      infop->ti_tid = th->th_ta_p->pthread_threads_max * 2 + 1;
      infop->ti_type = TD_THR_SYSTEM;
      infop->ti_state = TD_THR_ACTIVE;
    }
  else
    {
      infop->ti_tid = pds.p_tid;
      infop->ti_tls = (char *) pds.p_specific;
      infop->ti_pri = pds.p_priority;
      infop->ti_type = TD_THR_USER;

      if (! pds.p_terminated)
       /* XXX For now there is no way to get more information.  */
       infop->ti_state = TD_THR_ACTIVE;
      else if (! pds.p_detached)
       infop->ti_state = TD_THR_ZOMBIE;
      else
       infop->ti_state = TD_THR_UNKNOWN;
    }

  /* Initialization which are the same in both cases.  */
  infop->ti_lid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);
  infop->ti_ta_p = th->th_ta_p;
  infop->ti_startfunc = pds.p_start_args.start_routine;
  memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask,
         sizeof (td_thr_events_t));
  infop->ti_traceme = pds.p_report_events != 0;

  return TD_OK;
}

Definition at line 25 of file td_thr_getfpregs.c.

{
  struct _pthread_descr_struct pds;

  LOG ("td_thr_getfpregs");

  if (th->th_unique == NULL)
    {
      /* No data yet.  Use the main thread.  */
      pid_t pid = ps_getpid (th->th_ta_p->ph);
      if (ps_lgetfpregs (th->th_ta_p->ph, pid, regset) != PS_OK)
       return TD_ERR;
      return TD_OK;
    }

  /* 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 (regset, '\0', sizeof (*regset));
  /* Otherwise get the register content through the callback.  */
  else
    {
      pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);

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

  return TD_OK;
}

Definition at line 25 of file td_thr_getgregs.c.

{
  struct _pthread_descr_struct pds;

  LOG ("td_thr_getgregs");

  if (th->th_unique == NULL)
    {
      /* No data yet.  Use the main thread.  */
      pid_t 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;
    }

  /* 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;
}
td_err_e td_thr_getxregs ( const td_thrhandle_t __th,
void *  __xregs 
)

Definition at line 25 of file td_thr_getxregs.c.

{
  /* XXX This might be platform specific.  */
  LOG ("td_thr_getxregs");
  return TD_NOXREGS;
}
td_err_e td_thr_getxregsize ( const td_thrhandle_t __th,
int __sizep 
)

Definition at line 25 of file td_thr_getxregsize.c.

{
  /* XXX This might be platform specific.  */
  LOG ("td_thr_getxregsize");
  return TD_NOXREGS;
}

Definition at line 25 of file td_thr_setfpregs.c.

{
  struct _pthread_descr_struct pds = { .p_terminated = 0, .p_pid = 0 };

  LOG ("td_thr_setfpregs");

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

  /* Only set the registers if the thread hasn't yet terminated.  */
  if (pds.p_terminated == 0)
    {
      pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);

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

  return TD_OK;
}

Definition at line 25 of file td_thr_setgregs.c.

{
  struct _pthread_descr_struct pds = { .p_terminated = 0, .p_pid = 0 };

  LOG ("td_thr_setgregs");

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

  /* Only set the registers if the thread hasn't yet terminated.  */
  if (pds.p_terminated == 0)
    {
      pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph);

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

  return TD_OK;
}
td_err_e td_thr_setprio ( const td_thrhandle_t __th,
int  __prio 
)

Definition at line 25 of file td_thr_setprio.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_thr_setprio");
  return TD_OK;
}
td_err_e td_thr_setsigpending ( const td_thrhandle_t __th,
unsigned char  __n,
const sigset_t __ss 
)

Definition at line 25 of file td_thr_setsigpending.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_thr_setsigpending");
  return TD_OK;
}
td_err_e td_thr_setxregs ( const td_thrhandle_t __th,
const void *  __addr 
)

Definition at line 25 of file td_thr_setxregs.c.

{
  /* XXX This might have to be platform specific.  */
  LOG ("td_thr_setxregs");
  return TD_NOXREGS;
}

Definition at line 25 of file td_thr_sigsetmask.c.

{
  /* XXX We have to figure out what has to be done.  */
  LOG ("td_thr_sigsetmask");
  return TD_OK;
}
td_err_e td_thr_tls_get_addr ( const td_thrhandle_t __th,
void *  __map_address,
size_t  __offset,
void **  __address 
)

Definition at line 25 of file td_thr_tls_get_addr.c.

{
  td_err_e err;
  psaddr_t modid;

  /* Get the TLS module ID from the `struct link_map' in the inferior.  */
  err = DB_GET_FIELD (modid, th->th_ta_p, map_address, link_map,
                    l_tls_modid, 0);
  if (err == TD_NOCAPAB)
    return TD_NOAPLIC;
  if (err == TD_OK)
    {
      err = td_thr_tlsbase (th, (uintptr_t) modid, address);
      if (err == TD_OK)
       *address += offset;
    }
  return err;
}
td_err_e td_thr_tlsbase ( const td_thrhandle_t __th,
unsigned long int  __modid,
psaddr_t __base 
)

Definition at line 26 of file td_thr_tlsbase.c.

{
  if (modid < 1)
    return TD_NOTLS;

#if USE_TLS
  union dtv pdtv, *dtvp;

  LOG ("td_thr_tlsbase");

  psaddr_t dtvpp = th->th_unique;
#if TLS_TCB_AT_TP
  dtvpp += offsetof (struct _pthread_descr_struct, p_header.data.dtvp);
#elif TLS_DTV_AT_TP
/* Special case hack.  If TLS_TCB_SIZE == 0 (on PowerPC), there is no TCB
   containing the DTV at the TP, but actually the TCB lies behind the TP,
   i.e. at the very end of the area covered by TLS_PRE_TCB_SIZE.  */
  dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv)
          - (TLS_TCB_SIZE == 0 ? sizeof (tcbhead_t) : 0);
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined."
#endif

  /* Get the DTV pointer from the thread descriptor.  */
  if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Get the corresponding entry in the DTV.  */
  if (ps_pdread (th->th_ta_p->ph, dtvp + modid,
               &pdtv, sizeof (union dtv)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* It could be that the memory for this module is not allocated for
     the given thread.  */
  if (pdtv.pointer.val == TLS_DTV_UNALLOCATED)
    return TD_TLSDEFER;

  *base = (char *) pdtv.pointer.val;

  return TD_OK;
#else
  return TD_ERR;
#endif
}
td_err_e td_thr_tsd ( const td_thrhandle_t __th,
const thread_key_t  __tk,
void **  __data 
)

Definition at line 26 of file td_thr_tsd.c.

{
  struct _pthread_descr_struct pds;
  struct pthread_key_struct *keys = th->th_ta_p->keys;
  struct pthread_key_struct key;
  int pthread_keys_max = th->th_ta_p->pthread_keys_max;
  int pthread_key_2ndlevel_size = th->th_ta_p->pthread_key_2ndlevel_size;
  unsigned int idx1st;
  unsigned int idx2nd;
  void *p;

  LOG ("td_thr_tsd");

  /* If there is no thread descriptor there cannot be any thread
     specific data.  */
  if (th->th_unique == NULL)
    return TD_BADKEY;

  /* Get the thread descriptor.  */
  if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
               sizeof (struct _pthread_descr_struct)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Check correct value of key.  */
  if (tk >= pthread_keys_max)
    return TD_BADKEY;

  /* Get the key entry.  */
  if (ps_pdread (th->th_ta_p->ph, &keys[tk], &key,
               sizeof (struct pthread_key_struct)) != PS_OK)
    return TD_ERR;   /* XXX Other error value?  */

  /* Fail if this key is not at all used.  */
  if (! key.in_use)
    return TD_BADKEY;

  /* Compute the indeces.  */
  idx1st = tk / pthread_key_2ndlevel_size;
  idx2nd = tk % pthread_key_2ndlevel_size;

  /* Check the pointer to the second level array.  */
  if (pds.p_specific[idx1st] == NULL)
    return TD_NOTSD;

  /* Now get the real key.
     XXX I don't know whether it's correct but there is currently no
     easy way to determine whether a key was never set or the value
     is NULL.  We return an error whenever the value is NULL.  */
  if (ps_pdread (th->th_ta_p->ph, &pds.p_specific[idx1st][idx2nd], &p,
               sizeof (void *)) != PS_OK)
    return TD_ERR;

  if (p != NULL)
    *data = p;

  return p != NULL ? TD_OK : TD_NOTSD;
}

Definition at line 26 of file td_thr_validate.c.

{
  struct pthread_handle_struct *handles = th->th_ta_p->handles;
  int pthread_threads_max = th->th_ta_p->pthread_threads_max;
  int cnt;
  struct pthread_handle_struct phc;

  LOG ("td_thr_validate");

  /* A special case: if the program just starts up the handle is
     NULL.  */
  if (th->th_unique == NULL)
    {
      /* Read the first handle.  If the pointer to the thread
        descriptor is not NULL this is an error.  */
      if (ps_pdread (th->th_ta_p->ph, handles, &phc,
                   sizeof (struct pthread_handle_struct)) != PS_OK)
       return TD_ERR;       /* XXX Other error value?  */

      return phc.h_descr == NULL ? TD_OK : TD_NOTHR;
    }

  /* Now get all descriptors, one after the other.  */
  for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles)
    {
      if (ps_pdread (th->th_ta_p->ph, handles, &phc,
                   sizeof (struct pthread_handle_struct)) != PS_OK)
       return TD_ERR;       /* XXX Other error value?  */

      if (phc.h_descr != NULL && phc.h_descr == th->th_unique)
       {
         struct _pthread_descr_struct pds;

         if (ps_pdread (th->th_ta_p->ph, phc.h_descr, &pds,
                      th->th_ta_p->sizeof_descr) != PS_OK)
           return TD_ERR;   /* XXX Other error value?  */

         /* XXX There should be another test using the TID but this is
            currently not available.  */
         return pds.p_terminated != 0 ? TD_NOTHR : TD_OK;
       }
    }

  return TD_ERR;
}