PERFORCE change 59055 for review
David Xu
davidxu at FreeBSD.org
Fri Aug 6 21:11:55 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=59055
Change 59055 by davidxu at davidxu_alona on 2004/08/07 04:11:30
Add code to support retrieving tls variable.
Affected files ...
.. //depot/projects/davidxu_ksedbg/src/lib/libthread_db/Makefile#4 edit
.. //depot/projects/davidxu_ksedbg/src/lib/libthread_db/libpthread_db.c#2 edit
Differences ...
==== //depot/projects/davidxu_ksedbg/src/lib/libthread_db/Makefile#4 (text+ko) ====
@@ -11,7 +11,13 @@
INCS= thread_db.h
WARNS?= 1
-CFLAGS+=-I. -I${.CURDIR}
+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
==== //depot/projects/davidxu_ksedbg/src/lib/libthread_db/libpthread_db.c#2 (text+ko) ====
@@ -27,6 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libthread_db/libpthread_db.c,v 1.3 2004/08/03 02:23:06 davidxu Exp $");
+#include <link.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -38,6 +39,8 @@
#include <proc_service.h>
#include <thread_db.h>
+#include "rtld.h"
+
#include "libpthread.h"
#include "libpthread_db.h"
@@ -413,8 +416,7 @@
psaddr_t tcb_addr, tmbx_addr, ptr;
lwpid_t lwp;
uint32_t dflags;
- int attrflags;
- int ret;
+ int attrflags, locklevel, ret;
TDBG_FUNC();
@@ -445,40 +447,57 @@
ret = ps_pread(ta->ph, ptr, &lwp, sizeof(lwpid_t));
if (ret != 0)
return (P2T(ret));
- /*
- * Don't stop lwp assigned to a M:N thread, it belongs
- * to UTS, UTS shouldn't be stopped.
- */
- if (lwp != 0 && (attrflags & PTHREAD_SCOPE_SYSTEM)) {
- /* dont' suspend signal thread */
+
+ if (lwp != 0) {
+ /* don't suspend signal thread */
if (attrflags & THR_SIGNAL_THREAD)
- return 0;
- ptr = ta->map[th->th_tid].thr +
- offsetof(struct pthread, kse);
- /* Too many indirect level :-( */
- /* read struct kse * */
- ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
- if (ret != 0)
- return (P2T(ret));
- ptr = ptr + offsetof(struct kse, k_kcb);
- /* read k_kcb * */
- ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
- if (ret != 0)
- return (P2T(ret));
- /* read kcb.kcb_kmbx.km_curthread */
- ptr = ptr + offsetof(struct kcb, kcb_kmbx.km_curthread);
- ret = ps_pread(ta->ph, ptr, &ptr, sizeof(ptr));
- if (ret != 0)
- return (P2T(ret));
- if (ptr != 0) { /* not in critical */
- if (suspend)
- ret = ps_lstop(ta->ph, lwp);
- else
+ 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);
+ 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));
+ if (ret != 0)
+ return (P2T(ret));
+ if (locklevel <= 0) {
+ ptr = ta->map[th->th_tid].thr +
+ offsetof(struct pthread, locklevel);
+ ret = ps_pread(ta->ph, ptr, &locklevel,
+ sizeof(int));
+ if (ret != 0)
+ return (P2T(ret));
+ }
+ if (suspend) {
+ if (locklevel <= 0)
+ ret = ps_lstop(ta->ph, lwp);
+ } else {
+ ret = ps_lcontinue(ta->ph, lwp);
+ }
+ if (ret != 0)
+ return (P2T(ret));
+ /* FALLTHROUGH */
+ } else {
+ struct ptrace_lwpinfo pl;
+
+ if (ptrace(PT_LWPINFO, lwp, (caddr_t) &pl, sizeof(pl)))
+ return (TD_ERR);
+ if (suspend) {
+ if (!(pl.pl_flags & PL_FLAG_BOUND))
+ ret = ps_lstop(ta->ph, lwp);
+ } else {
ret = ps_lcontinue(ta->ph, lwp);
+ }
if (ret != 0)
return (P2T(ret));
+ /* FALLTHROUGH */
}
- /* FALLTHROUGH */
}
/* read tm_dflags */
ret = ps_pread(ta->ph,
@@ -899,6 +918,62 @@
return (TD_OK);
}
+td_err_e
+pt_thr_tls_get_addr(const td_thrhandle_t *th, void *_linkmap, size_t offset,
+ void **address)
+{
+ Obj_Entry *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));
+
+ /* get tlsindex of the object file */
+ ret = ps_pread(ta->ph,
+ ((char *)obj_entry) + offsetof(Obj_Entry, 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),
+ &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),
+ &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));
+ if (ret != 0)
+ return (P2T(ret));
+
+ *address += offset;
+
+ return (TD_OK);
+}
+
struct ta_ops libpthread_db_ops = {
.to_init = pt_init,
.to_ta_clear_event = pt_ta_clear_event,
@@ -923,6 +998,7 @@
.to_thr_setfpregs = pt_thr_setfpregs,
.to_thr_setgregs = pt_thr_setgregs,
.to_thr_validate = pt_thr_validate,
+ .to_thr_tls_get_addr = pt_thr_tls_get_addr,
/* FreeBSD specific extensions. */
.to_thr_sstep = pt_thr_sstep,
More information about the p4-projects
mailing list