From owner-p4-projects@FreeBSD.ORG Sat Aug 7 04:11:54 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 43DFD16A4DC; Sat, 7 Aug 2004 04:11:54 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B23E116A4EC for ; Sat, 7 Aug 2004 04:11:53 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9F68A43D58 for ; Sat, 7 Aug 2004 04:11:53 +0000 (GMT) (envelope-from davidxu@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id i774Brob042694 for ; Sat, 7 Aug 2004 04:11:53 GMT (envelope-from davidxu@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id i774Br9n042690 for perforce@freebsd.org; Sat, 7 Aug 2004 04:11:53 GMT (envelope-from davidxu@freebsd.org) Date: Sat, 7 Aug 2004 04:11:53 GMT Message-Id: <200408070411.i774Br9n042690@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to davidxu@freebsd.org using -f From: David Xu To: Perforce Change Reviews Subject: PERFORCE change 59055 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Aug 2004 04:11:55 -0000 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 __FBSDID("$FreeBSD: src/lib/libthread_db/libpthread_db.c,v 1.3 2004/08/03 02:23:06 davidxu Exp $"); +#include #include #include #include @@ -38,6 +39,8 @@ #include #include +#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,