1. Use libpthread's exported symbols to calcuate offset in data structure
2. Enable TLS debugger support.
This commit is contained in:
parent
4872917430
commit
83403f3840
@ -11,24 +11,6 @@ SRCS+= libthr_db.c
|
||||
INCS= thread_db.h
|
||||
WARNS?= 1
|
||||
|
||||
CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../../libexec/rtld-elf
|
||||
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf/${MACHINE_ARCH}
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
|
||||
CFLAGS+=-DTLS_DTV_AT_TCB
|
||||
.else
|
||||
CFLAGS+=-DTLS_DTV_AT_TP
|
||||
.endif
|
||||
|
||||
SRCS+= libpthread.h
|
||||
CLEANFILES+= libpthread.h
|
||||
|
||||
LIBPTHREAD= ${.CURDIR}/../libpthread
|
||||
LIBPTHREAD_ARCH= ${LIBPTHREAD}/arch/${MACHINE_ARCH}/include
|
||||
|
||||
libpthread.h:
|
||||
@echo '#define LIBTHREAD_DB 1' > ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD}/sys/lock.h"' >> ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD_ARCH}/pthread_md.h"' >> ${.TARGET}
|
||||
@echo '#include "${LIBPTHREAD}/thread/thr_private.h"' >> ${.TARGET}
|
||||
CFLAGS+=-I. -I${.CURDIR}
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <link.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -39,9 +38,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <proc_service.h>
|
||||
#include <thread_db.h>
|
||||
|
||||
#include "rtld.h"
|
||||
|
||||
#include "libpthread.h"
|
||||
#include "libpthread_db.h"
|
||||
|
||||
#define P2T(c) ps2td(c)
|
||||
@ -132,7 +128,22 @@ pt_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
|
||||
goto error; \
|
||||
}
|
||||
|
||||
#define LOOKUP_VAL(proc, sym, val) \
|
||||
ret = ps_pglobal_lookup(proc, NULL, sym, &vaddr);\
|
||||
if (ret != 0) { \
|
||||
TDBG("can not find symbol: %s\n", sym); \
|
||||
ret = TD_NOLIBTHREAD; \
|
||||
goto error; \
|
||||
} \
|
||||
ret = ps_pread(proc, vaddr, val, sizeof(int)); \
|
||||
if (ret != 0) { \
|
||||
TDBG("can not read value of %s\n", sym);\
|
||||
ret = TD_NOLIBTHREAD; \
|
||||
goto error; \
|
||||
}
|
||||
|
||||
td_thragent_t *ta;
|
||||
psaddr_t vaddr;
|
||||
int dbg;
|
||||
int ret;
|
||||
|
||||
@ -152,7 +163,23 @@ pt_ta_new(struct ps_prochandle *ph, td_thragent_t **pta)
|
||||
LOOKUP_SYM(ph, "_thread_activated", &ta->thread_activated_addr);
|
||||
LOOKUP_SYM(ph, "_thread_active_threads",&ta->thread_active_threads_addr);
|
||||
LOOKUP_SYM(ph, "_thread_keytable", &ta->thread_keytable_addr);
|
||||
|
||||
LOOKUP_VAL(ph, "_thread_off_dtv", &ta->thread_off_dtv);
|
||||
LOOKUP_VAL(ph, "_thread_off_kse_locklevel", &ta->thread_off_kse_locklevel);
|
||||
LOOKUP_VAL(ph, "_thread_off_kse", &ta->thread_off_kse);
|
||||
LOOKUP_VAL(ph, "_thread_off_tlsindex", &ta->thread_off_tlsindex);
|
||||
LOOKUP_VAL(ph, "_thread_off_attr_flags", &ta->thread_off_attr_flags);
|
||||
LOOKUP_VAL(ph, "_thread_size_key", &ta->thread_size_key);
|
||||
LOOKUP_VAL(ph, "_thread_off_tcb", &ta->thread_off_tcb);
|
||||
LOOKUP_VAL(ph, "_thread_off_linkmap", &ta->thread_off_linkmap);
|
||||
LOOKUP_VAL(ph, "_thread_off_tmbx", &ta->thread_off_tmbx);
|
||||
LOOKUP_VAL(ph, "_thread_off_thr_locklevel", &ta->thread_off_thr_locklevel);
|
||||
LOOKUP_VAL(ph, "_thread_off_next", &ta->thread_off_next);
|
||||
LOOKUP_VAL(ph, "_thread_off_state", &ta->thread_off_state);
|
||||
LOOKUP_VAL(ph, "_thread_max_keys", &ta->thread_max_keys);
|
||||
LOOKUP_VAL(ph, "_thread_off_key_allocated", &ta->thread_off_key_allocated);
|
||||
LOOKUP_VAL(ph, "_thread_off_key_destructor", &ta->thread_off_key_destructor);
|
||||
LOOKUP_VAL(ph, "_thread_state_running", &ta->thread_state_running);
|
||||
LOOKUP_VAL(ph, "_thread_state_zoombie", &ta->thread_state_zoombie);
|
||||
dbg = getpid();
|
||||
/*
|
||||
* If this fails it probably means we're debugging a core file and
|
||||
@ -211,13 +238,13 @@ pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
|
||||
*/
|
||||
while (pt != 0) {
|
||||
ret = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tcb),
|
||||
pt + ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ret = ps_pread(ta->ph,
|
||||
tcb_addr + offsetof(struct tcb,
|
||||
tcb_tmbx.tm_lwp),
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_lwp),
|
||||
&lwp, sizeof(lwp));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
@ -231,7 +258,7 @@ pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
|
||||
}
|
||||
/* get next thread */
|
||||
ret = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tle.tqe_next),
|
||||
pt + ta->thread_off_next,
|
||||
&pt, sizeof(pt));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
@ -246,13 +273,13 @@ pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
|
||||
} else {
|
||||
while (pt != 0 && ta->map[id].thr != pt) {
|
||||
ret = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tcb),
|
||||
pt + ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
/* get next thread */
|
||||
ret = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tle.tqe_next),
|
||||
pt + ta->thread_off_next,
|
||||
&pt, sizeof(pt));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
@ -285,11 +312,12 @@ pt_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
|
||||
return (P2T(ret));
|
||||
pt = (psaddr_t)thread_list.tqh_first;
|
||||
while (pt != 0) {
|
||||
ret = ps_pread(ta->ph, pt + offsetof(struct pthread, tcb),
|
||||
ret = ps_pread(ta->ph, pt + ta->thread_off_tcb,
|
||||
&ptr, sizeof(ptr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ptr += offsetof(struct tcb, tcb_tmbx.tm_lwp);
|
||||
ptr += ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &tmp_lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
@ -304,7 +332,7 @@ pt_ta_map_lwp2thr(const td_thragent_t *ta, lwpid_t lwp, td_thrhandle_t *th)
|
||||
|
||||
/* get next thread */
|
||||
ret = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tle.tqe_next),
|
||||
pt + ta->thread_off_next,
|
||||
&pt, sizeof(pt));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
@ -350,7 +378,7 @@ pt_ta_thr_iter(const td_thragent_t *ta,
|
||||
return (TD_DBERR);
|
||||
/* get next thread */
|
||||
pserr = ps_pread(ta->ph,
|
||||
pt + offsetof(struct pthread, tle.tqe_next), &pt,
|
||||
pt + ta->thread_off_next, &pt,
|
||||
sizeof(pt));
|
||||
if (pserr != PS_OK)
|
||||
return (P2T(pserr));
|
||||
@ -361,23 +389,33 @@ pt_ta_thr_iter(const td_thragent_t *ta,
|
||||
static td_err_e
|
||||
pt_ta_tsd_iter(const td_thragent_t *ta, td_key_iter_f *ki, void *arg)
|
||||
{
|
||||
struct pthread_key keytable[PTHREAD_KEYS_MAX];
|
||||
int i, ret;
|
||||
char *keytable;
|
||||
void *destructor;
|
||||
int i, ret, allocated;
|
||||
|
||||
TDBG_FUNC();
|
||||
|
||||
keytable = malloc(ta->thread_max_keys * ta->thread_size_key);
|
||||
if (keytable == NULL)
|
||||
return (TD_MALLOC);
|
||||
ret = ps_pread(ta->ph, (psaddr_t)ta->thread_keytable_addr, keytable,
|
||||
sizeof(keytable));
|
||||
ta->thread_max_keys * ta->thread_size_key);
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
|
||||
for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
|
||||
if (keytable[i].allocated) {
|
||||
ret = (ki)(i, keytable[i].destructor, arg);
|
||||
if (ret != 0)
|
||||
for (i = 0; i < ta->thread_max_keys; i++) {
|
||||
allocated = *(int *)(keytable + i * ta->thread_size_key +
|
||||
ta->thread_off_key_allocated);
|
||||
destructor = *(void **)(keytable + i * ta->thread_size_key +
|
||||
ta->thread_off_key_destructor);
|
||||
if (allocated) {
|
||||
ret = (ki)(i, destructor, arg);
|
||||
if (ret != 0) {
|
||||
free(keytable);
|
||||
return (TD_DBERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(keytable);
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
@ -433,16 +471,16 @@ pt_dbsuspend(const td_thrhandle_t *th, int suspend)
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, attr.flags),
|
||||
ta->thread_off_attr_flags,
|
||||
&attrflags, sizeof(attrflags));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
@ -450,25 +488,24 @@ pt_dbsuspend(const td_thrhandle_t *th, int suspend)
|
||||
|
||||
if (lwp != 0) {
|
||||
/* don't suspend signal thread */
|
||||
if (attrflags & THR_SIGNAL_THREAD)
|
||||
if (attrflags & 0x200)
|
||||
return (0);
|
||||
if (attrflags & PTHREAD_SCOPE_SYSTEM) {
|
||||
/*
|
||||
* don't suspend system scope thread if it is holding
|
||||
* some low level locks
|
||||
*/
|
||||
ptr = ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, kse);
|
||||
ptr = ta->map[th->th_tid].thr + ta->thread_off_kse;
|
||||
ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ret = ps_pread(ta->ph, ptr + offsetof(struct kse,
|
||||
k_locklevel), &locklevel, sizeof(int));
|
||||
ret = ps_pread(ta->ph, ptr + ta->thread_off_kse_locklevel,
|
||||
&locklevel, sizeof(int));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
if (locklevel <= 0) {
|
||||
ptr = ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, locklevel);
|
||||
ta->thread_off_thr_locklevel;
|
||||
ret = ps_pread(ta->ph, ptr, &locklevel,
|
||||
sizeof(int));
|
||||
if (ret != 0)
|
||||
@ -548,9 +585,10 @@ static td_err_e
|
||||
pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
|
||||
{
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
struct pthread pt;
|
||||
int ret;
|
||||
psaddr_t tcb_addr;
|
||||
uint32_t dflags;
|
||||
int state;
|
||||
int ret;
|
||||
|
||||
TDBG_FUNC();
|
||||
|
||||
@ -567,59 +605,34 @@ pt_thr_get_info(const td_thrhandle_t *th, td_thrinfo_t *info)
|
||||
info->ti_type = TD_THR_SYSTEM;
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, (psaddr_t)(ta->map[th->th_tid].thr),
|
||||
&pt, sizeof(pt));
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
if (pt.magic != THR_MAGIC)
|
||||
return (TD_BADTH);
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_state,
|
||||
&state, sizeof(state));
|
||||
ret = ps_pread(ta->ph,
|
||||
((psaddr_t)pt.tcb) + offsetof(struct tcb, tcb_tmbx.tm_lwp),
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_lwp),
|
||||
&info->ti_lid, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ret = ps_pread(ta->ph,
|
||||
((psaddr_t)pt.tcb) + offsetof(struct tcb, tcb_tmbx.tm_dflags),
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_dflags),
|
||||
&dflags, sizeof(dflags));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
info->ti_ta_p = th->th_ta;
|
||||
info->ti_tid = th->th_tid;
|
||||
info->ti_tls = (char *)pt.specific;
|
||||
info->ti_startfunc = (psaddr_t)pt.start_routine;
|
||||
info->ti_stkbase = (psaddr_t) pt.attr.stackaddr_attr;
|
||||
info->ti_stksize = pt.attr.stacksize_attr;
|
||||
switch (pt.state) {
|
||||
case PS_RUNNING:
|
||||
if (state == ta->thread_state_running)
|
||||
info->ti_state = TD_THR_RUN;
|
||||
break;
|
||||
case PS_LOCKWAIT:
|
||||
case PS_MUTEX_WAIT:
|
||||
case PS_COND_WAIT:
|
||||
case PS_SIGSUSPEND:
|
||||
case PS_SIGWAIT:
|
||||
case PS_JOIN:
|
||||
case PS_SUSPENDED:
|
||||
case PS_DEADLOCK:
|
||||
case PS_SLEEP_WAIT:
|
||||
info->ti_state = TD_THR_SLEEP;
|
||||
break;
|
||||
case PS_DEAD:
|
||||
else if (state == ta->thread_state_zoombie)
|
||||
info->ti_state = TD_THR_ZOMBIE;
|
||||
break;
|
||||
default:
|
||||
info->ti_state = TD_THR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
info->ti_state = TD_THR_SLEEP;
|
||||
info->ti_db_suspended = ((dflags & TMDF_SUSPEND) != 0);
|
||||
info->ti_type = TD_THR_USER;
|
||||
info->ti_pri = pt.active_priority;
|
||||
info->ti_sigmask = pt.sigmask;
|
||||
info->ti_traceme = 0;
|
||||
info->ti_pending = pt.sigpend;
|
||||
info->ti_events = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -643,12 +656,11 @@ pt_thr_getfpregs(const td_thrhandle_t *th, prfpregset_t *fpregs)
|
||||
return (P2T(ret));
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
@ -686,12 +698,11 @@ pt_thr_getgregs(const td_thrhandle_t *th, prgregset_t gregs)
|
||||
return (P2T(ret));
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr + ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
@ -728,11 +739,11 @@ pt_thr_setfpregs(const td_thrhandle_t *th, const prfpregset_t *fpregs)
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
@ -775,11 +786,11 @@ pt_thr_setgregs(const td_thrhandle_t *th, const prgregset_t gregs)
|
||||
}
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
ptr = tmbx_addr + offsetof(struct kse_thr_mailbox, tm_lwp);
|
||||
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
@ -850,33 +861,39 @@ pt_thr_sstep(const td_thrhandle_t *th, int step)
|
||||
return (TD_BADTH);
|
||||
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
|
||||
/* Clear or set single step flag in thread mailbox */
|
||||
ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb,
|
||||
tcb_tmbx.tm_dflags), &dflags, sizeof(uint32_t));
|
||||
ret = ps_pread(ta->ph,
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_dflags),
|
||||
&dflags, sizeof(uint32_t));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
if (step != 0)
|
||||
dflags |= TMDF_SSTEP;
|
||||
else
|
||||
dflags &= ~TMDF_SSTEP;
|
||||
ret = ps_pwrite(ta->ph, tcb_addr + offsetof(struct tcb,
|
||||
tcb_tmbx.tm_dflags), &dflags, sizeof(uint32_t));
|
||||
ret = ps_pwrite(ta->ph,
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_dflags),
|
||||
&dflags, sizeof(uint32_t));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
/* Get lwp */
|
||||
ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb,
|
||||
tcb_tmbx.tm_lwp), &lwp, sizeof(lwpid_t));
|
||||
ret = ps_pread(ta->ph,
|
||||
tcb_addr + ta->thread_off_tmbx +
|
||||
offsetof(struct kse_thr_mailbox, tm_lwp),
|
||||
&lwp, sizeof(lwpid_t));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
if (lwp != 0)
|
||||
return (0);
|
||||
|
||||
tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx);
|
||||
tmbx_addr = tcb_addr + ta->thread_off_tmbx;
|
||||
/*
|
||||
* context is in userland, some architectures store
|
||||
* single step status in registers, we should change
|
||||
@ -922,48 +939,33 @@ td_err_e
|
||||
pt_thr_tls_get_addr(const td_thrhandle_t *th, void *_linkmap, size_t offset,
|
||||
void **address)
|
||||
{
|
||||
#if 0
|
||||
Obj_Entry *obj_entry;
|
||||
char *obj_entry;
|
||||
const td_thragent_t *ta = th->th_ta;
|
||||
psaddr_t tcb_addr, *dtv_addr, tcb_tp;
|
||||
int tls_index, ret;
|
||||
|
||||
/* linkmap is a member of Obj_Entry */
|
||||
obj_entry = (Obj_Entry *)
|
||||
(((char *)_linkmap) - offsetof(Obj_Entry, linkmap));
|
||||
obj_entry = (char *)_linkmap - ta->thread_off_linkmap;
|
||||
|
||||
/* get tlsindex of the object file */
|
||||
ret = ps_pread(ta->ph,
|
||||
((char *)obj_entry) + offsetof(Obj_Entry, tlsindex),
|
||||
obj_entry + ta->thread_off_tlsindex,
|
||||
&tls_index, sizeof(tls_index));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
|
||||
/* get thread tcb */
|
||||
ret = ps_pread(ta->ph, ta->map[th->th_tid].thr +
|
||||
offsetof(struct pthread, tcb),
|
||||
ta->thread_off_tcb,
|
||||
&tcb_addr, sizeof(tcb_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
|
||||
#ifdef TLS_DTV_AT_TCB
|
||||
/* get dtv array address */
|
||||
ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb, tcb_dtv),
|
||||
ret = ps_pread(ta->ph, tcb_addr + ta->thread_off_dtv,
|
||||
&dtv_addr, sizeof(dtv_addr));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
#else
|
||||
#ifdef TLS_DTV_AT_TP
|
||||
ret = ps_pread(ta->ph, tcb_addr + offsetof(struct tcb, tcb_tp),
|
||||
&tcb_tp, sizeof(tcb_tp));
|
||||
if (ret != 0)
|
||||
return (P2T(ret));
|
||||
ret = ps_pread(ta->ph, tcb_tp + offsetof(struct tp, tp_dtv),
|
||||
&dtv_addr, sizeof(dtv_addr));
|
||||
#else
|
||||
#error "Either TLS_DTV_AT_TP or TLS_DTV_AT_TCB must be defined."
|
||||
#endif
|
||||
#endif
|
||||
/* now get the object's tls block base address */
|
||||
ret = ps_pread(ta->ph, &dtv_addr[tls_index+1], address,
|
||||
sizeof(*address));
|
||||
@ -971,7 +973,6 @@ pt_thr_tls_get_addr(const td_thrhandle_t *th, void *_linkmap, size_t offset,
|
||||
return (P2T(ret));
|
||||
|
||||
*address += offset;
|
||||
#endif
|
||||
return (TD_OK);
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,23 @@ struct td_thragent {
|
||||
psaddr_t thread_active_threads_addr;
|
||||
psaddr_t thread_keytable_addr;
|
||||
int thread_activated;
|
||||
int thread_off_dtv;
|
||||
int thread_off_kse_locklevel;
|
||||
int thread_off_kse;
|
||||
int thread_off_tlsindex;
|
||||
int thread_off_attr_flags;
|
||||
int thread_size_key;
|
||||
int thread_off_tcb;
|
||||
int thread_off_linkmap;
|
||||
int thread_off_tmbx;
|
||||
int thread_off_thr_locklevel;
|
||||
int thread_off_next;
|
||||
int thread_off_state;
|
||||
int thread_max_keys;
|
||||
int thread_off_key_allocated;
|
||||
int thread_off_key_destructor;
|
||||
int thread_state_zoombie;
|
||||
int thread_state_running;
|
||||
struct pt_map *map;
|
||||
int map_len;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user