1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
26 #include <sys/types.h>
32 #if !defined (__GNUC__) || __GNUC__ < 2
33 #error This file uses GNU C extensions; you must compile with GCC version 2.
36 /* The first piece of initialized data. */
38 #ifdef HAVE_WEAK_SYMBOLS
39 weak_alias (__data_start
, data_start
)
43 strong_alias (__errno
, errno
)
46 extern void __libc_init
__P ((int argc
, char **argv
, char **envp
));
47 extern int main
__P ((int argc
, char **argv
, char **envp
));
49 register long int sp
asm("%sp"), fp
asm("%fp");
52 static void init_shlib
__P ((void));
55 #ifndef NO_EXPLICIT_START
56 /* Declare _start with an explicit assembly symbol name of `start'
57 (note no leading underscore). This is the name Sun's crt0.o uses,
58 and programs are often linked with `ld -e start'. */
59 void _start (void) asm ("start");
65 /* It is important that these be declared `register'.
66 Otherwise, when compiled without optimization, they are put on the
67 stack, which loses completely after we zero the FP. */
69 register char **argv
, **envp
;
71 /* Unwind the frame built when we entered the function. */
74 /* And clear the frame pointer. */
77 /* The argument info starts after one register
78 window (64 bytes) past the SP. */
79 argc
= ((int *) sp
)[16];
80 argv
= (char **) &((int *) sp
)[17];
81 envp
= &argv
[argc
+ 1];
88 /* Allocate 24 bytes of stack space for the register save area. */
90 __libc_init (argc
, argv
, envp
);
92 exit (main (argc
, argv
, envp
));
97 /* System calls for use by the bootstrap routine.
98 These are defined here since the usual calls may be dynamically linked. */
100 int syscall (int sysno
, ...) asm ("init_syscall");
101 asm ("init_syscall:\n"
105 " sethi %hi(_errno), %g1\n"
106 " st %o0, [%g1 + %lo(_errno)]\n"
114 extern struct link_dynamic _DYNAMIC
;
119 void (*ldstart
) (int, int);
126 struct link_dynamic
*crt_dp
;
131 /* If not dynamically linked, do nothing. */
135 /* Map in the dynamic linker. */
136 so
= syscall (SYS_open
, "/usr/lib/ld.so", O_RDONLY
);
137 if (syscall (SYS_read
, so
, &soexec
, sizeof (soexec
)) != sizeof (soexec
)
138 || soexec
.a_magic
!= ZMAGIC
)
140 static const char emsg
[] = "crt0: no /usr/lib/ld.so\n";
142 syscall (SYS_write
, 2, emsg
, sizeof (emsg
) - 1);
143 syscall (SYS_exit
, 127);
145 somap
= (caddr_t
) syscall (SYS_mmap
, 0,
146 soexec
.a_text
+ soexec
.a_data
+ soexec
.a_bss
,
147 PROT_READ
| PROT_EXEC
, _MAP_NEW
| MAP_PRIVATE
,
149 sodmap
= (caddr_t
) syscall (SYS_mmap
, somap
+ soexec
.a_text
, soexec
.a_data
,
150 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
151 _MAP_NEW
| MAP_FIXED
| MAP_PRIVATE
,
153 zf
= syscall (SYS_open
, "/dev/zero", O_RDONLY
);
154 if (soexec
.a_bss
!= 0)
155 sobssmap
= (caddr_t
) syscall (SYS_mmap
,
156 somap
+ soexec
.a_text
+ soexec
.a_data
,
158 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
159 _MAP_NEW
| MAP_FIXED
| MAP_PRIVATE
,
162 /* Call the entry point of the dynamic linker. */
163 soarg
.crt_ba
= somap
;
166 soarg
.crt_dp
= &_DYNAMIC
;
167 soarg
.crt_ep
= __environ
;
168 soarg
.crt_bp
= (caddr_t
) &&retaddr
;
170 ldstart
= (__typeof (ldstart
)) (somap
+ soexec
.a_entry
);
171 (*ldstart
) (1, (char *) &soarg
- (char *) sp
);