Bug 161344 - Failure to init TLS variables with func ptr inside shared lib
Summary: Failure to init TLS variables with func ptr inside shared lib
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: threads (show other bugs)
Version: 8.2-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Konstantin Belousov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-06 22:00 UTC by Alex Dupre
Modified: 2012-03-05 12:06 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Dupre freebsd_committer 2011-10-06 22:00:18 UTC
Initialisation of Thread Local Storage variables to some values
which are function address doesn't work inside a shared library.

How-To-Repeat: 	
t1.c:

int f(int x) {
  return x;
}
struct s_t {
  int (*func)(int);
};
struct s_t __thread x = { f };

Build it as:
cc -shared -o t1.so -fPIC t1.c

t2.c:

struct s_t {
  int (*func)(int);
};
extern struct s_t __thread x;
int main(int argc, const char *argv[]) {
  return (*x.func)(argc);
}

Build it as:
cc t2.c t1.so

export LD_LIBRARY_PATH=.
./a.out
Segmentation fault
Comment 1 Konstantin Belousov freebsd_committer 2011-10-07 06:39:06 UTC
Responsible Changed
From-To: freebsd-threads->kib

Grab.
Comment 2 dfilter service freebsd_committer 2011-10-08 13:40:04 UTC
Author: kib
Date: Sat Oct  8 12:39:47 2011
New Revision: 226155
URL: http://svn.freebsd.org/changeset/base/226155

Log:
  Setting up TLS block for the main thread must be done after the
  relocations are processed, since tls initialization section might be
  itself subject for relocations. Only set up of the block is postponed,
  the tls block offsets are allocated before relocation processing, since
  TLS-related relocations may need offsets ready.
  
  Reported by:	ale
  PR:	threads/161344
  Reviewed by:	kan
  MFC after:	1 week

Modified:
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Sat Oct  8 12:33:10 2011	(r226154)
+++ head/libexec/rtld-elf/rtld.c	Sat Oct  8 12:39:47 2011	(r226155)
@@ -495,8 +495,12 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
        exit (0);
     }
 
-    /* setup TLS for main thread */
-    dbg("initializing initial thread local storage");
+    /*
+     * Processing tls relocations requires having the tls offsets
+     * initialized.  Prepare offsets before starting initial
+     * relocation processing.
+     */
+    dbg("initializing initial thread local storage offsets");
     STAILQ_FOREACH(entry, &list_main, link) {
 	/*
 	 * Allocate all the initial objects out of the static TLS
@@ -504,7 +508,6 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
 	 */
 	allocate_tls_offset(entry->obj);
     }
-    allocate_initial_tls(obj_list);
 
     if (relocate_objects(obj_main,
       ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld, NULL) == -1)
@@ -519,6 +522,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
        exit (0);
     }
 
+    /*
+     * Setup TLS for main thread.  This must be done after the
+     * relocations are processed, since tls initialization section
+     * might be the subject for relocations.
+     */
+    dbg("initializing initial thread local storage");
+    allocate_initial_tls(obj_list);
+
     dbg("initializing key program variables");
     set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
     set_program_var("environ", env);
_______________________________________________
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"
Comment 3 Konstantin Belousov freebsd_committer 2012-03-05 12:00:27 UTC
State Changed
From-To: open->closed

Committed to all supported branches already.