]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - lib/csu/common/ignore_init.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / lib / csu / common / ignore_init.c
1 /*-
2  * Copyright 2012 Konstantin Belousov <kib@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include "notes.h"
30
31 extern int main(int, char **, char **);
32
33 extern void (*__preinit_array_start[])(int, char **, char **) __hidden;
34 extern void (*__preinit_array_end[])(int, char **, char **) __hidden;
35 extern void (*__init_array_start[])(int, char **, char **) __hidden;
36 extern void (*__init_array_end[])(int, char **, char **) __hidden;
37 extern void (*__fini_array_start[])(void) __hidden;
38 extern void (*__fini_array_end[])(void) __hidden;
39 extern void _fini(void) __hidden;
40 extern void _init(void) __hidden;
41
42 extern int _DYNAMIC;
43 #pragma weak _DYNAMIC
44
45 char **environ;
46 const char *__progname = "";
47
48 static void
49 finalizer(void)
50 {
51         void (*fn)(void);
52         size_t array_size, n;
53
54         array_size = __fini_array_end - __fini_array_start;
55         for (n = array_size; n > 0; n--) {
56                 fn = __fini_array_start[n - 1];
57                 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
58                         (fn)();
59         }
60         _fini();
61 }
62
63 static inline void
64 handle_static_init(int argc, char **argv, char **env)
65 {
66         void (*fn)(int, char **, char **);
67         size_t array_size, n;
68
69         if (&_DYNAMIC != NULL)
70                 return;
71
72         atexit(finalizer);
73
74         array_size = __preinit_array_end - __preinit_array_start;
75         for (n = 0; n < array_size; n++) {
76                 fn = __preinit_array_start[n];
77                 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
78                         fn(argc, argv, env);
79         }
80         _init();
81         array_size = __init_array_end - __init_array_start;
82         for (n = 0; n < array_size; n++) {
83                 fn = __init_array_start[n];
84                 if ((uintptr_t)fn != 0 && (uintptr_t)fn != 1)
85                         fn(argc, argv, env);
86         }
87 }
88
89 static inline void
90 handle_argv(int argc, char *argv[], char **env)
91 {
92         const char *s;
93
94         if (environ == NULL)
95                 environ = env;
96         if (argc > 0 && argv[0] != NULL) {
97                 __progname = argv[0];
98                 for (s = __progname; *s != '\0'; s++) {
99                         if (*s == '/')
100                                 __progname = s + 1;
101                 }
102         }
103 }
104
105 static const struct {
106         int32_t namesz;
107         int32_t descsz;
108         int32_t type;
109         char    name[sizeof(NOTE_FREEBSD_VENDOR)];
110         uint32_t desc;
111 } crt_noinit_tag __attribute__ ((section (NOTE_SECTION),
112     aligned(4))) __used = {
113         .namesz = sizeof(NOTE_FREEBSD_VENDOR),
114         .descsz = sizeof(uint32_t),
115         .type = CRT_NOINIT_NOTETYPE,
116         .name = NOTE_FREEBSD_VENDOR,
117         .desc = 0
118 };