From thinker.li@gmail.com  Wed Sep 14 02:01:34 2011
Return-Path: <thinker.li@gmail.com>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 7D1AD106564A
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Sep 2011 02:01:34 +0000 (UTC)
	(envelope-from thinker.li@gmail.com)
Received: from mail-gw0-f45.google.com (mail-gw0-f45.google.com [74.125.83.45])
	by mx1.freebsd.org (Postfix) with ESMTP id 38A3C8FC0C
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Sep 2011 02:01:34 +0000 (UTC)
Received: by gwb19 with SMTP id 19so1344151gwb.18
        for <FreeBSD-gnats-submit@freebsd.org>; Tue, 13 Sep 2011 19:01:33 -0700 (PDT)
Received: by 10.150.157.21 with SMTP id f21mr1290747ybe.126.1315963888217;
        Tue, 13 Sep 2011 18:31:28 -0700 (PDT)
Received: from eeebox.branda.to (123-194-52-90.dynamic.kbronet.com.tw [123.194.52.90])
        by mx.google.com with ESMTPS id v5sm5240676anc.6.2011.09.13.18.31.24
        (version=TLSv1/SSLv3 cipher=OTHER);
        Tue, 13 Sep 2011 18:31:25 -0700 (PDT)
Received: from eeebox.branda.to (localhost [127.0.0.1])
	by eeebox.branda.to (8.14.4/8.14.4) with ESMTP id p8E1ZAv5078901
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 14 Sep 2011 09:35:11 +0800 (CST)
	(envelope-from thinker@branda.to)
Received: (from root@localhost)
	by eeebox.branda.to (8.14.4/8.14.4/Submit) id p8E1ZA4o078900;
	Wed, 14 Sep 2011 09:35:10 +0800 (CST)
	(envelope-from thinker)
Message-Id: <201109140135.p8E1ZA4o078900@eeebox.branda.to>
Date: Wed, 14 Sep 2011 09:35:10 +0800 (CST)
From: "Thinker K.F. Li" <thinker@codemud.net>
Sender: Thinker Li <thinker.li@gmail.com>
Reply-To: "Thinker K.F. Li" <thinker@codemud.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: TLS is inconsistent
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         160721
>Category:       kern
>Synopsis:       TLS is inconsistent
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    flo
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 14 02:10:10 UTC 2011
>Closed-Date:    Thu Sep 22 08:40:10 UTC 2011
>Last-Modified:  Thu Sep 22 08:50:04 UTC 2011
>Originator:     Thinker K.F. Li
>Release:        FreeBSD 9.0-CURRENT i386
>Organization:
Allwitz Tech.
>Environment:
System: FreeBSD eeebox.branda.to 9.0-CURRENT FreeBSD 9.0-CURRENT #1: Sun Jun 5 17:08:32 CST 2011 thinker@eeebox.branda.to:/usr/src/sys/i386/compile/eeebox i386


	
>Description:
Compiler generated code will call ___tls_get_addr() of ld-elf.so
for TLS variable.  It is supposed to return the same address, every time,
for the same passed address and thread, but it does not.

	
>How-To-Repeat:
Compile following code with commands

 1. cc -shared -o test-tls-1.so -pthread -fpic test-tls-1.c
 2. cc -o test-tls -pthread test-tls.c

test-tls is supposed to print "100" on stdout, but it print out "50",
instead.  If you dig into opcodes, you will find that ___tls_get_addr()
return two different base addresses for modify() and for show() respective.
This issue is only making troubles for programs accessing TLS after dlopen().

--- test-tls-1.c begins here ---
#include <stdio.h>

__thread int var = 50;

void
modify(void) {
    var = 100;
}

void
show(void) {
    printf("%d\n", var);
}
--- test-tls-1.c ends here ---

--- test-tls.c begins here ---
#include <stdio.h>
#include <dlfcn.h>

int
main(int argc, char * const *argv) {
    void (*modify)(void);
    void (*modify)(void);
    void *sohdl;

    sohdl = dlopen("./test-tls-1.so", RTLD_NOW);
    modify = (void (*)(void))dlsym(sohdl, "modify");
    show = (void (*)(void))dlsym(sohdl, "show");

    modify();
    show();

    return 0;
}
--- test-tls.c ends here ---

	
>Fix:

Apply following patch on the root of source tree can fix this issue.

	

--- libexec-rtld_elf-rtld.c.diff begins here ---
--- libexec/rtld-elf/rtld.c.orig	2011-09-13 14:25:17.000000000 +0800
+++ libexec/rtld-elf/rtld.c	2011-09-13 14:25:43.000000000 +0800
@@ -3371,6 +3371,7 @@
 	free(dtv);
 	lock_release(rtld_bind_lock, &lockstate);
 	*dtvp = newdtv;
+	dtv = newdtv;
     }
 
     /* Dynamically allocate module TLS if necessary */
--- libexec-rtld_elf-rtld.c.diff ends here ---


>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: misc/160721: commit references a PR
Date: Thu, 15 Sep 2011 11:50:20 +0000 (UTC)

 Author: kib
 Date: Thu Sep 15 11:50:09 2011
 New Revision: 225582
 URL: http://svn.freebsd.org/changeset/base/225582
 
 Log:
   Use the proper dynamic tls block to calculate the tls variable address
   in case tls data generation was updated.
   
   PR:	misc/160721
   Submitted by:	"Thinker K.F. Li" <thinker codemud net>
   Tested by:	flo
   Approved by:	re (bz)
   MFC after:	1 week
 
 Modified:
   head/libexec/rtld-elf/rtld.c
 
 Modified: head/libexec/rtld-elf/rtld.c
 ==============================================================================
 --- head/libexec/rtld-elf/rtld.c	Thu Sep 15 11:17:07 2011	(r225581)
 +++ head/libexec/rtld-elf/rtld.c	Thu Sep 15 11:50:09 2011	(r225582)
 @@ -3370,7 +3370,7 @@ tls_get_addr_common(Elf_Addr** dtvp, int
  	newdtv[1] = tls_max_index;
  	free(dtv);
  	lock_release(rtld_bind_lock, &lockstate);
 -	*dtvp = newdtv;
 +	dtv = *dtvp = newdtv;
      }
  
      /* Dynamically allocate module TLS if necessary */
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: linimon 
State-Changed-When: Mon Sep 19 05:18:15 UTC 2011 
State-Changed-Why:  
assign to committer as MFC reminder. 


Responsible-Changed-From-To: freebsd-bugs->flo 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon Sep 19 05:18:15 UTC 2011 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=160721 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Thu Sep 22 08:39:32 UTC 2011 
State-Changed-Why:  
Merged to 8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=160721 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/160721: commit references a PR
Date: Thu, 22 Sep 2011 08:39:29 +0000 (UTC)

 Author: kib
 Date: Thu Sep 22 08:39:20 2011
 New Revision: 225726
 URL: http://svn.freebsd.org/changeset/base/225726
 
 Log:
   MFC r225582:
   Use the proper dynamic tls block to calculate the tls variable address
   in case tls data generation was updated.
   
   PR:	misc/160721
 
 Modified:
   stable/8/libexec/rtld-elf/rtld.c
 Directory Properties:
   stable/8/libexec/rtld-elf/   (props changed)
 
 Modified: stable/8/libexec/rtld-elf/rtld.c
 ==============================================================================
 --- stable/8/libexec/rtld-elf/rtld.c	Thu Sep 22 08:24:33 2011	(r225725)
 +++ stable/8/libexec/rtld-elf/rtld.c	Thu Sep 22 08:39:20 2011	(r225726)
 @@ -3126,7 +3126,7 @@ tls_get_addr_common(Elf_Addr** dtvp, int
  	newdtv[1] = tls_max_index;
  	free(dtv);
  	wlock_release(rtld_bind_lock, lockstate);
 -	*dtvp = newdtv;
 +	dtv = *dtvp = newdtv;
      }
  
      /* Dynamically allocate module TLS if necessary */
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
