__ctype_init() every new TLS (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 23 Dec 2014 20:48:45 +0000 (12:48 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 31 Dec 2014 18:03:09 +0000 (13:03 -0500)
Functions like isspace() look in TLS for a pointer to an array used in the
ctype ops.  If you PF near there, then that pointer might not be set.
__ctype_init() initializes that pointer.

Every TLS needs this done once.  We do it a little more often than necessary
(right before vcore_entry, for example).  Thread0 also had a few issues with
this.  The new init-array business in glibc doesn't call _init (hence the
override of elf-init.c), and our custom init method didn't catch the update to
call __ctype_init().

tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/elf-init.c [new file with mode: 0644]
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/init-first.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/start.c
user/parlib/uthread.c

diff --git a/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/elf-init.c b/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/elf-init.c
new file mode 100644 (file)
index 0000000..2824f10
--- /dev/null
@@ -0,0 +1,38 @@
+/* Startup support for ELF initializers/finalizers in the main executable.
+   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Akaros, overriding the init-array version of elf-init.  The only diff is that
+ * the init-array version defines NO_INITFINI */
+#include <csu/elf-init.c>
index 6fab66e..a315bb3 100644 (file)
@@ -32,6 +32,7 @@
 #include <locale/localeinfo.h>
 #include <sys/time.h>
 #include <elf.h>
+#include <ctype.h>
 
 /* Set nonzero if we have to be prepared for more then one libc being
    used in the process.  Safe assumption if initializer never runs.  */
@@ -135,6 +136,9 @@ _init (int argc, char **argv, char **envp)
   __getopt_clean_environment (envp);
 #endif
 
+  /* Initialize ctype data.  */
+  __ctype_init ();
+
 #ifdef SHARED
   __libc_global_ctors ();
 #endif
index ba1844a..7404052 100644 (file)
@@ -79,8 +79,10 @@ _start(void)
                set_tls_desc((void*)__procdata.vcore_preempt_data[id].vcore_tls_desc,
                             id);
                #endif
+               /* These TLS setters actually only need to happen once, at init time */
                __vcoreid = id;
                __vcore_context = TRUE;
+               __ctype_init(); /* set locale info for ctype functions */
                vcore_entry();
                failmsg("why did vcore_entry() return?");
                goto diediedie;
index fd9d8a3..fcd32bb 100644 (file)
@@ -235,7 +235,14 @@ void uthread_init(struct uthread *new_thread, struct uth_thread_attr *attr)
                else
                        ret = __uthread_allocate_tls(new_thread);
                assert(!ret);
-               uthread_set_tls_var(new_thread, current_uthread, new_thread);
+               begin_access_tls_vars(new_thread->tls_desc);
+               current_uthread = new_thread;
+               /* ctypes stores locale info in TLS.  we need this only once per TLS, so
+                * we don't have to do it here, but it is convenient since we already
+                * loaded the uthread's TLS. */
+               extern void __ctype_init(void);
+               __ctype_init();
+               end_access_tls_vars();
        } else {
                new_thread->tls_desc = UTH_TLSDESC_NOTLS;
        }