| Commit | Line | Data |
|---|---|---|
| 17030342 MD |
1 | /* LINTLIBRARY */ |
| 2 | /*- | |
| 984263bc MD |
3 | * Copyright 1996-1998 John D. Polstra. |
| 4 | * All rights reserved. | |
| 984263bc MD |
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. | |
| 984263bc MD |
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. | |
| 1de703da | 25 | * |
| 17030342 | 26 | * $FreeBSD: src/lib/csu/amd64/crt1.c,v 1.13 2003/04/30 19:27:07 peter Exp $ |
| 984263bc MD |
27 | */ |
| 28 | ||
| 17030342 | 29 | #ifndef lint |
| 984263bc MD |
30 | #ifndef __GNUC__ |
| 31 | #error "GCC is needed to compile this file" | |
| 32 | #endif | |
| 17030342 | 33 | #endif /* lint */ |
| 984263bc | 34 | |
| f54055f1 | 35 | #include <machine/tls.h> |
| 984263bc | 36 | #include <stdlib.h> |
| 984263bc | 37 | |
| 17030342 MD |
38 | #include "libc_private.h" |
| 39 | #include "crtbrand.c" | |
| 984263bc | 40 | |
| 984263bc | 41 | extern int _DYNAMIC; |
| 17030342 MD |
42 | #pragma weak _DYNAMIC |
| 43 | ||
| 44 | typedef void (*fptr)(void); | |
| 984263bc | 45 | |
| 984263bc | 46 | extern void _fini(void); |
| 17030342 | 47 | extern void _init(void); |
| 984263bc | 48 | extern int main(int, char **, char **); |
| 17030342 | 49 | extern void _start(char **, void (*)(void)); |
| 984263bc | 50 | |
| b28bf640 JM |
51 | extern void (*__preinit_array_start []) (int, char **, char **) __dso_hidden; |
| 52 | extern void (*__preinit_array_end []) (int, char **, char **) __dso_hidden; | |
| 53 | extern void (*__init_array_start []) (int, char **, char **) __dso_hidden; | |
| 54 | extern void (*__init_array_end []) (int, char **, char **) __dso_hidden; | |
| 55 | extern void (*__fini_array_start []) (void) __dso_hidden; | |
| 56 | extern void (*__fini_array_end []) (void) __dso_hidden; | |
| 57 | ||
| 984263bc MD |
58 | #ifdef GCRT |
| 59 | extern void _mcleanup(void); | |
| 60 | extern void monstartup(void *, void *); | |
| 61 | extern int eprol; | |
| 62 | extern int etext; | |
| 63 | #endif | |
| 64 | ||
| 65 | char **environ; | |
| 17030342 | 66 | const char *__progname = ""; |
| 984263bc MD |
67 | |
| 68 | /* The entry function. */ | |
| 69 | void | |
| 17030342 | 70 | _start(char **ap, void (*cleanup)(void)) |
| 984263bc MD |
71 | { |
| 72 | int argc; | |
| 73 | char **argv; | |
| 74 | char **env; | |
| 17030342 | 75 | const char *s; |
| b28bf640 | 76 | size_t n, array_size; |
| 984263bc | 77 | |
| 17030342 | 78 | argc = *(long *)(void *)ap; |
| 984263bc | 79 | argv = ap + 1; |
| 17030342 | 80 | env = ap + 2 + argc; |
| 984263bc | 81 | environ = env; |
| 17030342 | 82 | if (argc > 0 && argv[0] != NULL) { |
| 984263bc MD |
83 | __progname = argv[0]; |
| 84 | for (s = __progname; *s != '\0'; s++) | |
| 85 | if (*s == '/') | |
| 86 | __progname = s + 1; | |
| 87 | } | |
| 88 | ||
| e6a7a861 MD |
89 | /* |
| 90 | * Setup the initial TLS space. The RTLD does not set up our TLS | |
| 91 | * (it can't, it doesn't know how our errno is declared). It simply | |
| 92 | * does all the groundwork required so that we can call | |
| 93 | * _rtld_allocate_tls(). | |
| 94 | */ | |
| 95 | _init_tls(); | |
| 96 | _rtld_call_init(); | |
| 97 | ||
| 984263bc MD |
98 | if (&_DYNAMIC != NULL) |
| 99 | atexit(cleanup); | |
| 100 | ||
| 101 | #ifdef GCRT | |
| 102 | atexit(_mcleanup); | |
| 103 | #endif | |
| b28bf640 JM |
104 | /* |
| 105 | * The fini_array needs to be executed in the opposite order of its | |
| 106 | * definition. However, atexit works like a LIFO stack, so by | |
| 107 | * pushing functions in array order, they will be executed in the | |
| 108 | * reverse order as required. | |
| 109 | */ | |
| 984263bc | 110 | atexit(_fini); |
| b28bf640 JM |
111 | array_size = __fini_array_end - __fini_array_start; |
| 112 | for (n = 0; n < array_size; n++) | |
| 113 | atexit(*__fini_array_start [n]); | |
| 984263bc MD |
114 | #ifdef GCRT |
| 115 | monstartup(&eprol, &etext); | |
| 116 | #endif | |
| b28bf640 JM |
117 | if (&_DYNAMIC == NULL) { |
| 118 | /* | |
| 119 | * For static executables preinit happens right before init. | |
| 120 | * Dynamic executable preinit arrays are handled by rtld | |
| 121 | * before any DSOs are initialized. | |
| 122 | */ | |
| 123 | array_size = __preinit_array_end - __preinit_array_start; | |
| 124 | for (n = 0; n < array_size; n++) | |
| 125 | (*__preinit_array_start [n])(argc, argv, env); | |
| 126 | } | |
| 984263bc | 127 | _init(); |
| b28bf640 JM |
128 | array_size = __init_array_end - __init_array_start; |
| 129 | for (n = 0; n < array_size; n++) | |
| 130 | (*__init_array_start [n])(argc, argv, env); | |
| 984263bc MD |
131 | exit( main(argc, argv, env) ); |
| 132 | } | |
| 133 | ||
| 134 | #ifdef GCRT | |
| 135 | __asm__(".text"); | |
| 136 | __asm__("eprol:"); | |
| 137 | __asm__(".previous"); | |
| 138 | #endif |