This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [HURD, PATCH] Fix stack switching at initialization time


Hi!

Thomas Schwinge <thomas@schwinge.name> skribis:

> This patch is to be put on top of our TopGit t/init-first.c branch, I
> guess, which itself is not yet in the sourceware repository, I think?

Right, other changes in t/init-first.c arenât in the Sourceware repo.
Hereâs the diff between the Savannah + this patch and Sourceware repo:

diff -ubB --show-c-function /data/src/glibc/sysdeps/mach/hurd/i386/init-first.c /data/src/hurd/glibc/sysdeps/mach/hurd/i386/init-first.c
--- /data/src/glibc/sysdeps/mach/hurd/i386/init-first.c	2011-07-22 16:26:37.000000000 +0200
+++ /data/src/hurd/glibc/sysdeps/mach/hurd/i386/init-first.c	2011-07-22 15:45:58.000000000 +0200
@@ -1,6 +1,7 @@
 /* Initialization code run first thing by the ELF startup code.  For i386/Hurd.
-   Copyright (C) 1995,96,97,98,99,2000,01,02,03,04,05
-	Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+	2005, 2007 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
@@ -92,7 +93,7 @@ posixland_init (int argc, char **argv, c
   __getopt_clean_environment (envp);
 #endif
 
-#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
+#ifdef SHARED
   __libc_global_ctors ();
 #endif
 }
@@ -104,10 +105,6 @@ init1 (int argc, char *arg0, ...)
   char **argv = &arg0;
   char **envp = &argv[argc + 1];
   struct hurd_startup_data *d;
-#ifndef SHARED
-  extern ElfW(Phdr) *_dl_phdr;
-  extern size_t _dl_phnum;
-#endif
 
   while (*envp)
     ++envp;
@@ -118,27 +115,9 @@ init1 (int argc, char *arg0, ...)
      data block; the argument strings start there.  */
   if ((void *) d == argv[0])
     {
-#ifndef SHARED
-      /* We may need to see our own phdrs, e.g. for TLS setup.
-         Try the usual kludge to find the headers without help from
-	 the exec server.  */
-      extern const void _start;
-      const ElfW(Ehdr) *const ehdr = &_start;
-      _dl_phdr = (ElfW(Phdr) *) ((const void *) ehdr + ehdr->e_phoff);
-      _dl_phnum = ehdr->e_phnum;
-      assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
-#endif
       return;
     }
 
-#ifndef SHARED
-  __libc_enable_secure = d->flags & EXEC_SECURE;
-
-  _dl_phdr = (ElfW(Phdr) *) d->phdr;
-  _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
-  assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
-#endif
-
   _hurd_init_dtable = d->dtable;
   _hurd_init_dtablesize = d->dtablesize;
 
@@ -172,13 +151,16 @@ init (int *data)
   char **envp = &argv[argc + 1];
   struct hurd_startup_data *d;
   unsigned long int threadvars[_HURD_THREADVAR_MAX];
+#ifndef SHARED
+  extern ElfW(Phdr) *_dl_phdr;
+  extern size_t _dl_phnum;
+#endif
 
   /* Provide temporary storage for thread-specific variables on the
      startup stack so the cthreads initialization code can use them
      for malloc et al, or so we can use malloc below for the real
      threadvars array.  */
   memset (threadvars, 0, sizeof threadvars);
-  threadvars[_HURD_THREADVAR_LOCALE] = (unsigned long int) &_nl_global_locale;
   __hurd_threadvar_stack_offset = (unsigned long int) threadvars;
 
   /* Since the cthreads initialization code uses malloc, and the
@@ -192,6 +174,39 @@ init (int *data)
     ++envp;
   d = (void *) ++envp;
 
+  /* If we are the bootstrap task started by the kernel,
+     then after the environment pointers there is no Hurd
+     data block; the argument strings start there.  */
+  if ((void *) d == argv[0])
+    {
+#ifndef SHARED
+      /* We may need to see our own phdrs, e.g. for TLS setup.
+         Try the usual kludge to find the headers without help from
+	 the exec server.  */
+      extern const void __executable_start;
+      const ElfW(Ehdr) *const ehdr = &__executable_start;
+      _dl_phdr = (ElfW(Phdr) *) ((const void *) ehdr + ehdr->e_phoff);
+      _dl_phnum = ehdr->e_phnum;
+      assert (ehdr->e_phentsize == sizeof (ElfW(Phdr)));
+#endif
+    }
+  else
+    {
+#ifndef SHARED
+      __libc_enable_secure = d->flags & EXEC_SECURE;
+
+      _dl_phdr = (ElfW(Phdr) *) d->phdr;
+      _dl_phnum = d->phdrsz / sizeof (ElfW(Phdr));
+      assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
+#endif
+    }
+
+#ifndef SHARED
+  /* We need to setup TLS before starting sigthread */
+  extern void __pthread_initialize_minimal(void);
+  __pthread_initialize_minimal();
+#endif
+
   /* The user might have defined a value for this, to get more variables.
      Otherwise it will be zero on startup.  We must make sure it is set
      properly before before cthreads initialization, so cthreads can know
@@ -242,9 +257,9 @@ init (int *data)
       /* Push the user code address on the top of the new stack.  It will
 	 be the return address for `init1'; we will jump there with NEWSP
 	 as the stack pointer.  */
-      *--newsp = data[-1];
-      ((void **) data)[-1] = switch_stacks;
-      /* Force NEWSP into %ecx and &init1 into %eax, which are not restored
+      *--newsp = __builtin_return_address (0);
+      * ((void **) __builtin_frame_address (0) + 1) = &switch_stacks;
+      /* Force NEWSP into %eax and &init1 into %ecx, which are not restored
 	 by function return.  */
       asm volatile ("# a %0 c %1" : : "a" (newsp), "c" (&init1));
     }
@@ -320,11 +335,11 @@ first_init (void)
    stack set up just as the user will see it, so it can switch stacks.  */
 
 void
-_dl_init_first (void)
+_dl_init_first (int argc, ...)
 {
   first_init ();
 
-  init ((int *) __builtin_frame_address (0) + 2);
+  init (&argc);
 }
 #endif
 
@@ -351,23 +366,23 @@ strong_alias (posixland_init, __libc_ini
    This poorly-named function is called by static-start.S,
    which should not exist at all.  */
 void
-_hurd_stack_setup (void)
+_hurd_stack_setup (void *arg, ...)
 {
-  intptr_t caller = (intptr_t) __builtin_return_address (0);
+  void *caller = (&arg)[-1];
 
   void doinit (intptr_t *data)
     {
       /* This function gets called with the argument data at TOS.  */
-      void doinit1 (void)
+      void doinit1 (volatile int argc, ...)
 	{
-	  init ((int *) __builtin_frame_address (0) + 2);
+	  init ((int *) &argc);
 	}
 
       /* Push the user return address after the argument data, and then
          jump to `doinit1' (above), so it is as if __libc_init_first's
          caller had called `doinit1' with the argument data already on the
          stack.  */
-      *--data = caller;
+      *--data = (intptr_t) caller;
       asm volatile ("movl %0, %%esp\n" /* Switch to new outermost stack.  */
 		    "movl $0, %%ebp\n" /* Clear outermost frame pointer.  */
 		    "jmp *%1" : : "r" (data), "r" (&doinit1) : "sp");
@@ -376,7 +391,7 @@ _hurd_stack_setup (void)
 
   first_init ();
 
-  _hurd_startup ((void **) __builtin_frame_address (0) + 2, &doinit);
+  _hurd_startup (&arg, &doinit);
 }
 #endif
So Iâll commit it to t/init-first.c, OK?

Thanks!

Ludoâ.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]