xref: /illumos-gate/usr/src/lib/crt/common/common-crt.c (revision 3e76f9d6)
1*3e76f9d6SRichard Lowe /*
2*3e76f9d6SRichard Lowe  * This file and its contents are supplied under the terms of the
3*3e76f9d6SRichard Lowe  * Common Development and Distribution License ("CDDL"), version 1.0.
4*3e76f9d6SRichard Lowe  * You may only use this file in accordance with the terms of version
5*3e76f9d6SRichard Lowe  * 1.0 of the CDDL.
6*3e76f9d6SRichard Lowe  *
7*3e76f9d6SRichard Lowe  * A full copy of the text of the CDDL should have accompanied this
8*3e76f9d6SRichard Lowe  * source.  A copy of the CDDL is also available via the Internet at
9*3e76f9d6SRichard Lowe  * http://www.illumos.org/license/CDDL.
10*3e76f9d6SRichard Lowe  */
11*3e76f9d6SRichard Lowe 
12*3e76f9d6SRichard Lowe /*
13*3e76f9d6SRichard Lowe  * Copyright 2016, Richard Lowe.
14*3e76f9d6SRichard Lowe  */
15*3e76f9d6SRichard Lowe 
16*3e76f9d6SRichard Lowe /*
17*3e76f9d6SRichard Lowe  * That of the CRT startup routine which itself may be implemented in C.
18*3e76f9d6SRichard Lowe  */
19*3e76f9d6SRichard Lowe 
20*3e76f9d6SRichard Lowe #include <sys/feature_tests.h>
21*3e76f9d6SRichard Lowe #include <sys/types.h>
22*3e76f9d6SRichard Lowe 
23*3e76f9d6SRichard Lowe #include <stdlib.h>
24*3e76f9d6SRichard Lowe #include <synch.h>
25*3e76f9d6SRichard Lowe #include <unistd.h>
26*3e76f9d6SRichard Lowe 
27*3e76f9d6SRichard Lowe #pragma weak _DYNAMIC
28*3e76f9d6SRichard Lowe extern uintptr_t _DYNAMIC;
29*3e76f9d6SRichard Lowe 
30*3e76f9d6SRichard Lowe #pragma weak environ = _environ
31*3e76f9d6SRichard Lowe char **_environ = NULL;
32*3e76f9d6SRichard Lowe char **___Argv = NULL;
33*3e76f9d6SRichard Lowe 
34*3e76f9d6SRichard Lowe extern int main(int argc, char **argv, char **envp);
35*3e76f9d6SRichard Lowe extern void _init(void);
36*3e76f9d6SRichard Lowe extern void _fini(void);
37*3e76f9d6SRichard Lowe 
38*3e76f9d6SRichard Lowe #pragma weak _start_crt_compiler
39*3e76f9d6SRichard Lowe extern void _start_crt_compiler(int argc, char **argv);
40*3e76f9d6SRichard Lowe 
41*3e76f9d6SRichard Lowe #if defined(__x86)
42*3e76f9d6SRichard Lowe int __longdouble_used = 0;
43*3e76f9d6SRichard Lowe extern void __fpstart(void);
44*3e76f9d6SRichard Lowe #endif
45*3e76f9d6SRichard Lowe 
46*3e76f9d6SRichard Lowe #if defined(__i386)		/* Not amd64 */
47*3e76f9d6SRichard Lowe #pragma weak __fsr_init_value
48*3e76f9d6SRichard Lowe extern long __fsr_init_value;
49*3e76f9d6SRichard Lowe extern void __fsr(uintptr_t);
50*3e76f9d6SRichard Lowe #endif
51*3e76f9d6SRichard Lowe 
52*3e76f9d6SRichard Lowe 
53*3e76f9d6SRichard Lowe /*
54*3e76f9d6SRichard Lowe  * Defined here for ABI reasons, must match the definition in libc.
55*3e76f9d6SRichard Lowe  * If it cannot, a new symbol must be created.
56*3e76f9d6SRichard Lowe  */
57*3e76f9d6SRichard Lowe mutex_t __environ_lock = DEFAULTMUTEX;
58*3e76f9d6SRichard Lowe 
59*3e76f9d6SRichard Lowe void
60*3e76f9d6SRichard Lowe _start_crt(int argc, char **argv, void (*exit_handler)(void))
61*3e76f9d6SRichard Lowe {
62*3e76f9d6SRichard Lowe 	int ret = 0;
63*3e76f9d6SRichard Lowe 
64*3e76f9d6SRichard Lowe 	/*
65*3e76f9d6SRichard Lowe 	 * On x86, we check whether we're a dynamic executable to see whether
66*3e76f9d6SRichard Lowe 	 * we'll receive an exit_handler.
67*3e76f9d6SRichard Lowe 	 *
68*3e76f9d6SRichard Lowe 	 * On SPARC, we just need to check whether the handler was NULL.
69*3e76f9d6SRichard Lowe 	 */
70*3e76f9d6SRichard Lowe #if defined(__x86)
71*3e76f9d6SRichard Lowe 	if (&_DYNAMIC != NULL)
72*3e76f9d6SRichard Lowe 		(void) atexit(exit_handler);
73*3e76f9d6SRichard Lowe #elif defined(__sparc)
74*3e76f9d6SRichard Lowe 	if (exit_handler != NULL)
75*3e76f9d6SRichard Lowe 		(void) atexit(exit_handler);
76*3e76f9d6SRichard Lowe #endif
77*3e76f9d6SRichard Lowe 
78*3e76f9d6SRichard Lowe 	(void) atexit(_fini);
79*3e76f9d6SRichard Lowe 
80*3e76f9d6SRichard Lowe 	_environ = argv + (argc + 1);
81*3e76f9d6SRichard Lowe 	___Argv = argv;
82*3e76f9d6SRichard Lowe 
83*3e76f9d6SRichard Lowe 	if (&_start_crt_compiler != NULL)
84*3e76f9d6SRichard Lowe 		_start_crt_compiler(argc, argv);
85*3e76f9d6SRichard Lowe 
86*3e76f9d6SRichard Lowe #if defined(__x86)
87*3e76f9d6SRichard Lowe 	__fpstart();
88*3e76f9d6SRichard Lowe #endif
89*3e76f9d6SRichard Lowe #if defined(__i386) 		/* Not amd64 */
90*3e76f9d6SRichard Lowe 	/*
91*3e76f9d6SRichard Lowe 	 * Note that Studio cc(1) sets the _value of the symbol_, that is, its
92*3e76f9d6SRichard Lowe 	 * address.  Not the value _at_ that address.
93*3e76f9d6SRichard Lowe 	 */
94*3e76f9d6SRichard Lowe 	__fsr((uintptr_t)&__fsr_init_value);
95*3e76f9d6SRichard Lowe #endif
96*3e76f9d6SRichard Lowe 	_init();
97*3e76f9d6SRichard Lowe 	ret = main(argc, argv, _environ);
98*3e76f9d6SRichard Lowe 	exit(ret);
99*3e76f9d6SRichard Lowe 	_exit(ret);
100*3e76f9d6SRichard Lowe }
101