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