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