1 /* LINTLIBRARY */ 2 /*- 3 * Copyright 1996-1998 John D. Polstra. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD: src/lib/csu/amd64/crt1.c,v 1.13 2003/04/30 19:27:07 peter Exp $ 27 */ 28 29 #ifndef lint 30 #ifndef __GNUC__ 31 #error "GCC is needed to compile this file" 32 #endif 33 #endif /* lint */ 34 35 #include <stdlib.h> 36 37 #include "libc_private.h" 38 #include "crtbrand.c" 39 40 extern int _DYNAMIC; 41 #pragma weak _DYNAMIC 42 43 typedef void (*fptr)(void); 44 45 extern void _fini(void); 46 extern void _init(void); 47 extern int main(int, char **, char **); 48 extern void _start(char **, void (*)(void)); 49 50 #ifdef GCRT 51 extern void _mcleanup(void); 52 extern void monstartup(void *, void *); 53 extern int eprol; 54 extern int etext; 55 #endif 56 57 char **environ; 58 const char *__progname = ""; 59 60 /* The entry function. */ 61 void 62 _start(char **ap, void (*cleanup)(void)) 63 { 64 int argc; 65 char **argv; 66 char **env; 67 const char *s; 68 69 argc = *(long *)(void *)ap; 70 argv = ap + 1; 71 env = ap + 2 + argc; 72 environ = env; 73 if (argc > 0 && argv[0] != NULL) { 74 __progname = argv[0]; 75 for (s = __progname; *s != '\0'; s++) 76 if (*s == '/') 77 __progname = s + 1; 78 } 79 80 /* 81 * Setup the initial TLS space. The RTLD does not set up our TLS 82 * (it can't, it doesn't know how our errno is declared). It simply 83 * does all the groundwork required so that we can call 84 * _rtld_allocate_tls(). 85 */ 86 _init_tls(); 87 _rtld_call_init(); 88 89 if (&_DYNAMIC != NULL) 90 atexit(cleanup); 91 92 #ifdef GCRT 93 atexit(_mcleanup); 94 #endif 95 atexit(_fini); 96 #ifdef GCRT 97 monstartup(&eprol, &etext); 98 #endif 99 _init(); 100 exit( main(argc, argv, env) ); 101 } 102 103 #ifdef GCRT 104 __asm__(".text"); 105 __asm__("eprol:"); 106 __asm__(".previous"); 107 #endif 108