Date: Sat, 7 Aug 2004 04:11:53 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 59055 for review Message-ID: <200408070411.i774Br9n042690@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=59055 Change 59055 by davidxu@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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408070411.i774Br9n042690>