Fix stack initialization code
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / solaris2 / kopensolaris-gnu / init-first.c
1 /* Initialization code run first thing by the ELF startup code.
2     OpenSolaris version.
3    Copyright (C) 1995-2004, 2005, 2007 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <sysdep.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <fpu_control.h>
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <libc-internal.h>
30 #include <ucontext.h>
31 #include <sys/resource.h>
32
33 #include <ldsodefs.h>
34
35 /* Set nonzero if we have to be prepared for more then one libc being
36    used in the process.  Safe assumption if initializer never runs.  */
37 int __libc_multiple_libcs attribute_hidden = 1;
38
39 /* Remember the command line argument and enviroment contents for
40    later calls of initializers for dynamic libraries.  */
41 int __libc_argc attribute_hidden;
42 char **__libc_argv attribute_hidden;
43
44 stack_t _dl_stack;
45 int _dl_malloc_prot_exec;
46
47
48 void
49 __libc_init_first (int argc, char **argv, char **envp)
50 {
51 #ifdef SHARED
52   /* For DSOs we do not need __libc_init_first but instead _init.  */
53 }
54
55 void
56 attribute_hidden
57 _init (int argc, char **argv, char **envp)
58 {
59 #endif
60 #ifdef USE_NONOPTION_FLAGS
61   extern void __getopt_clean_environment (char **);
62 #endif
63
64   __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up;
65
66   /* Make sure we don't initialize twice.  */
67   if (!__libc_multiple_libcs)
68     {
69       /* Set the FPU control word to the proper default value if the
70          kernel would use a different value.  (In a static program we
71          don't have this information.)  */
72 #ifdef SHARED
73       if (__fpu_control != GLRO(dl_fpu_control))
74 #endif
75         __setfpucw (__fpu_control);
76
77       /* Setup stack.  */
78       ucontext_t ctx;
79       struct rlimit rlim;
80       if (getrlimit (RLIMIT_STACK, &rlim) == 0 &&
81           rlim.rlim_cur != RLIM_INFINITY && getcontext (&ctx) == 0)
82         {
83           _dl_stack.ss_sp = ctx.uc_stack.ss_sp +
84               ctx.uc_stack.ss_size - rlim.rlim_cur;
85           _dl_stack.ss_size = rlim.rlim_cur;
86         }
87       else
88         {
89           _dl_stack.ss_sp = ctx.uc_stack.ss_sp;
90           _dl_stack.ss_size = 0;
91         }
92       _dl_stack.ss_flags = 0;
93       setustack (&_dl_stack);
94     }
95
96   /* Save the command-line arguments.  */
97   __libc_argc = argc;
98   __libc_argv = argv;
99   __environ = envp;
100
101 #ifndef SHARED
102   __libc_init_secure ();
103
104   /* First the initialization which normally would be done by the
105      dynamic linker.  */
106   _dl_non_dynamic_init ();
107 #endif
108
109   __init_misc (argc, argv, envp);
110
111 #ifdef USE_NONOPTION_FLAGS
112   /* This is a hack to make the special getopt in GNU libc working.  */
113   __getopt_clean_environment (envp);
114 #endif
115
116 #ifdef SHARED
117   __libc_global_ctors ();
118 #endif
119 }
120
121
122 /* This function is defined here so that if this file ever gets into
123    ld.so we will get a link error.  Having this file silently included
124    in ld.so causes disaster, because the _init definition above will
125    cause ld.so to gain an init function, which is not a cool thing. */
126
127 extern void _dl_start (void) __attribute__ ((noreturn));
128
129 void
130 _dl_start (void)
131 {
132   abort ();
133 }