1 /* Copyright (C) 1991, 92, 93, 94, 95, 96 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
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
27 #include <sys/types.h>
33 #if !defined (__GNUC__) || __GNUC__ < 2
34 #error This file uses GNU C extensions; you must compile with GCC version 2.
37 /* The first piece of initialized data. */
39 #ifdef HAVE_WEAK_SYMBOLS
40 weak_alias (__data_start
, data_start
)
44 strong_alias (__errno
, errno
)
47 extern void EXFUN(__libc_init
, (int argc
, char **argv
, char **envp
));
48 extern int EXFUN(main
, (int argc
, char **argv
, char **envp
));
50 register long int sp
asm("%sp"), fp
asm("%fp");
53 static void EXFUN(init_shlib
, (NOARGS
));
56 #ifndef NO_EXPLICIT_START
57 /* Declare _start with an explicit assembly symbol name of `start'
58 (note no leading underscore). This is the name Sun's crt0.o uses,
59 and programs are often linked with `ld -e start'. */
60 void _start (void) asm ("start");
66 /* It is important that these be declared `register'.
67 Otherwise, when compiled without optimization, they are put on the
68 stack, which loses completely after we zero the FP. */
70 register char **argv
, **envp
;
72 /* Unwind the frame built when we entered the function. */
75 /* And clear the frame pointer. */
78 /* The argument info starts after one register
79 window (64 bytes) past the SP. */
80 argc
= ((int *) sp
)[16];
81 argv
= (char **) &((int *) sp
)[17];
82 envp
= &argv
[argc
+ 1];
89 /* Allocate 24 bytes of stack space for the register save area. */
91 __libc_init (argc
, argv
, envp
);
93 exit (main (argc
, argv
, envp
));
98 /* System calls for use by the bootstrap routine.
99 These are defined here since the usual calls may be dynamically linked. */
101 int syscall (int sysno
, ...) asm ("init_syscall");
102 asm ("init_syscall:\n"
106 " sethi %hi(_errno), %g1\n"
107 " st %o0, [%g1 + %lo(_errno)]\n"
113 DEFUN_VOID(init_shlib
)
115 extern struct link_dynamic _DYNAMIC
;
120 void (*ldstart
) (int, int);
127 struct link_dynamic
*crt_dp
;
132 /* If not dynamically linked, do nothing. */
136 /* Map in the dynamic linker. */
137 so
= syscall (SYS_open
, "/usr/lib/ld.so", O_RDONLY
);
138 if (syscall (SYS_read
, so
, &soexec
, sizeof (soexec
)) != sizeof (soexec
)
139 || soexec
.a_magic
!= ZMAGIC
)
141 static CONST
char emsg
[] = "crt0: no /usr/lib/ld.so\n";
143 syscall (SYS_write
, 2, emsg
, sizeof (emsg
) - 1);
144 syscall (SYS_exit
, 127);
146 somap
= (caddr_t
) syscall (SYS_mmap
, 0,
147 soexec
.a_text
+ soexec
.a_data
+ soexec
.a_bss
,
148 PROT_READ
| PROT_EXEC
, _MAP_NEW
| MAP_PRIVATE
,
150 sodmap
= (caddr_t
) syscall (SYS_mmap
, somap
+ soexec
.a_text
, soexec
.a_data
,
151 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
152 _MAP_NEW
| MAP_FIXED
| MAP_PRIVATE
,
154 zf
= syscall (SYS_open
, "/dev/zero", O_RDONLY
);
155 if (soexec
.a_bss
!= 0)
156 sobssmap
= (caddr_t
) syscall (SYS_mmap
,
157 somap
+ soexec
.a_text
+ soexec
.a_data
,
159 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
160 _MAP_NEW
| MAP_FIXED
| MAP_PRIVATE
,
163 /* Call the entry point of the dynamic linker. */
164 soarg
.crt_ba
= somap
;
167 soarg
.crt_dp
= &_DYNAMIC
;
168 soarg
.crt_ep
= __environ
;
169 soarg
.crt_bp
= (caddr_t
) &&retaddr
;
171 ldstart
= (__typeof (ldstart
)) (somap
+ soexec
.a_entry
);
172 (*ldstart
) (1, (char *) &soarg
- (char *) sp
);