| @@ -1,164 +1,164 @@ | | | @@ -1,164 +1,164 @@ |
1 | /* $NetBSD: crt0-common.c,v 1.9 2012/08/13 02:15:35 matt Exp $ */ | | 1 | /* $NetBSD: crt0-common.c,v 1.10 2013/01/22 22:57:37 matt Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998 Christos Zoulas | | 4 | * Copyright (c) 1998 Christos Zoulas |
5 | * Copyright (c) 1995 Christopher G. Demetriou | | 5 | * Copyright (c) 1995 Christopher G. Demetriou |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
17 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
18 | * This product includes software developed for the | | 18 | * This product includes software developed for the |
19 | * NetBSD Project. See http://www.NetBSD.org/ for | | 19 | * NetBSD Project. See http://www.NetBSD.org/ for |
20 | * information about NetBSD. | | 20 | * information about NetBSD. |
21 | * 4. The name of the author may not be used to endorse or promote products | | 21 | * 4. The name of the author may not be used to endorse or promote products |
22 | * derived from this software without specific prior written permission. | | 22 | * derived from this software without specific prior written permission. |
23 | * | | 23 | * |
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | * | | 34 | * |
35 | * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> | | 35 | * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>> |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | __RCSID("$NetBSD: crt0-common.c,v 1.9 2012/08/13 02:15:35 matt Exp $"); | | 39 | __RCSID("$NetBSD: crt0-common.c,v 1.10 2013/01/22 22:57:37 matt Exp $"); |
40 | | | 40 | |
41 | #include <sys/types.h> | | 41 | #include <sys/types.h> |
42 | #include <sys/exec.h> | | 42 | #include <sys/exec.h> |
43 | #include <sys/syscall.h> | | 43 | #include <sys/syscall.h> |
44 | #include <machine/profile.h> | | 44 | #include <machine/profile.h> |
45 | #include <stdlib.h> | | 45 | #include <stdlib.h> |
46 | #include <unistd.h> | | 46 | #include <unistd.h> |
47 | | | 47 | |
48 | #include "rtld.h" | | 48 | #include "rtld.h" |
49 | | | 49 | |
50 | extern int main(int, char **, char **); | | 50 | extern int main(int, char **, char **); |
51 | | | 51 | |
52 | #ifndef HAVE_INITFINI_ARRAY | | 52 | #ifndef HAVE_INITFINI_ARRAY |
53 | extern void _init(void); | | 53 | extern void _init(void); |
54 | extern void _fini(void); | | 54 | extern void _fini(void); |
55 | #endif | | 55 | #endif |
56 | extern void _libc_init(void); | | 56 | extern void _libc_init(void); |
57 | | | 57 | |
58 | /* | | 58 | /* |
59 | * Arrange for _DYNAMIC to be weak and undefined (and therefore to show up | | 59 | * Arrange for _DYNAMIC to be weak and undefined (and therefore to show up |
60 | * as being at address zero, unless something else defines it). That way, | | 60 | * as being at address zero, unless something else defines it). That way, |
61 | * if we happen to be compiling without -static but with without any | | 61 | * if we happen to be compiling without -static but with without any |
62 | * shared libs present, things will still work. | | 62 | * shared libs present, things will still work. |
63 | */ | | 63 | */ |
64 | | | 64 | |
65 | __weakref_visible int rtld_DYNAMIC __weak_reference(_DYNAMIC); | | 65 | __weakref_visible int rtld_DYNAMIC __weak_reference(_DYNAMIC); |
66 | | | 66 | |
67 | #ifdef MCRT0 | | 67 | #ifdef MCRT0 |
68 | extern void monstartup(u_long, u_long); | | 68 | extern void monstartup(u_long, u_long); |
69 | extern void _mcleanup(void); | | 69 | extern void _mcleanup(void); |
70 | extern unsigned char __etext, __eprol; | | 70 | extern unsigned char __etext, __eprol; |
71 | #endif /* MCRT0 */ | | 71 | #endif /* MCRT0 */ |
72 | | | 72 | |
73 | char **environ; | | 73 | char **environ; |
74 | struct ps_strings *__ps_strings = 0; | | 74 | struct ps_strings *__ps_strings = 0; |
75 | | | 75 | |
76 | static char empty_string[] = ""; | | 76 | static char empty_string[] = ""; |
77 | char *__progname = empty_string; | | 77 | char *__progname = empty_string; |
78 | | | 78 | |
79 | __dead __dso_hidden void ___start(void (*)(void), const Obj_Entry *, | | 79 | __dead __dso_hidden void ___start(void (*)(void), const Obj_Entry *, |
80 | struct ps_strings *); | | 80 | struct ps_strings *); |
81 | | | 81 | |
82 | #define write(fd, s, n) __syscall(SYS_write, (fd), (s), (n)) | | 82 | #define write(fd, s, n) __syscall(SYS_write, (fd), (s), (n)) |
83 | | | 83 | |
84 | #define _FATAL(str) \ | | 84 | #define _FATAL(str) \ |
85 | do { \ | | 85 | do { \ |
86 | write(2, str, sizeof(str)-1); \ | | 86 | write(2, str, sizeof(str)-1); \ |
87 | _exit(1); \ | | 87 | _exit(1); \ |
88 | } while (0) | | 88 | } while (0) |
89 | | | 89 | |
90 | #ifdef HAVE_INITFINI_ARRAY | | 90 | #ifdef HAVE_INITFINI_ARRAY |
91 | /* | | 91 | /* |
92 | * If we are using INIT_ARRAY/FINI_ARRAY and we are linked statically, | | 92 | * If we are using INIT_ARRAY/FINI_ARRAY and we are linked statically, |
93 | * we have to process these instead of relying on RTLD to do it for us. | | 93 | * we have to process these instead of relying on RTLD to do it for us. |
94 | * | | 94 | * |
95 | * Since we don't need .init or .fini sections, just code them in C | | 95 | * Since we don't need .init or .fini sections, just code them in C |
96 | * to make life easier. | | 96 | * to make life easier. |
97 | */ | | 97 | */ |
98 | static const fptr_t init_array_start[] __weak_reference(__init_array_start); | | 98 | extern const fptr_t init_array_start[] __weak_reference(__init_array_start); |
99 | static const fptr_t init_array_end[] __weak_reference(__init_array_end); | | 99 | extern const fptr_t init_array_end[] __weak_reference(__init_array_end); |
100 | static const fptr_t fini_array_start[] __weak_reference(__fini_array_start); | | 100 | extern const fptr_t fini_array_start[] __weak_reference(__fini_array_start); |
101 | static const fptr_t fini_array_end[] __weak_reference(__fini_array_end); | | 101 | extern const fptr_t fini_array_end[] __weak_reference(__fini_array_end); |
102 | | | 102 | |
103 | static inline void | | 103 | static inline void |
104 | _init(void) | | 104 | _init(void) |
105 | { | | 105 | { |
106 | for (const fptr_t *f = init_array_start; f < init_array_end; f++) { | | 106 | for (const fptr_t *f = init_array_start; f < init_array_end; f++) { |
107 | (*f)(); | | 107 | (*f)(); |
108 | } | | 108 | } |
109 | } | | 109 | } |
110 | | | 110 | |
111 | static void | | 111 | static void |
112 | _fini(void) | | 112 | _fini(void) |
113 | { | | 113 | { |
114 | for (const fptr_t *f = fini_array_start; f < fini_array_end; f++) { | | 114 | for (const fptr_t *f = fini_array_start; f < fini_array_end; f++) { |
115 | (*f)(); | | 115 | (*f)(); |
116 | } | | 116 | } |
117 | } | | 117 | } |
118 | #endif /* HAVE_INITFINI_ARRAY */ | | 118 | #endif /* HAVE_INITFINI_ARRAY */ |
119 | | | 119 | |
120 | void | | 120 | void |
121 | ___start(void (*cleanup)(void), /* from shared loader */ | | 121 | ___start(void (*cleanup)(void), /* from shared loader */ |
122 | const Obj_Entry *obj, /* from shared loader */ | | 122 | const Obj_Entry *obj, /* from shared loader */ |
123 | struct ps_strings *ps_strings) | | 123 | struct ps_strings *ps_strings) |
124 | { | | 124 | { |
125 | | | 125 | |
126 | if (ps_strings == NULL) | | 126 | if (ps_strings == NULL) |
127 | _FATAL("ps_strings missing\n"); | | 127 | _FATAL("ps_strings missing\n"); |
128 | __ps_strings = ps_strings; | | 128 | __ps_strings = ps_strings; |
129 | | | 129 | |
130 | environ = ps_strings->ps_envstr; | | 130 | environ = ps_strings->ps_envstr; |
131 | | | 131 | |
132 | if (ps_strings->ps_argvstr[0] != NULL) { | | 132 | if (ps_strings->ps_argvstr[0] != NULL) { |
133 | char *c; | | 133 | char *c; |
134 | __progname = ps_strings->ps_argvstr[0]; | | 134 | __progname = ps_strings->ps_argvstr[0]; |
135 | for (c = ps_strings->ps_argvstr[0]; *c; ++c) { | | 135 | for (c = ps_strings->ps_argvstr[0]; *c; ++c) { |
136 | if (*c == '/') | | 136 | if (*c == '/') |
137 | __progname = c + 1; | | 137 | __progname = c + 1; |
138 | } | | 138 | } |
139 | } else { | | 139 | } else { |
140 | __progname = empty_string; | | 140 | __progname = empty_string; |
141 | } | | 141 | } |
142 | | | 142 | |
143 | if (&rtld_DYNAMIC != NULL) { | | 143 | if (&rtld_DYNAMIC != NULL) { |
144 | if (obj == NULL) | | 144 | if (obj == NULL) |
145 | _FATAL("NULL Obj_Entry pointer in GOT\n"); | | 145 | _FATAL("NULL Obj_Entry pointer in GOT\n"); |
146 | if (obj->magic != RTLD_MAGIC) | | 146 | if (obj->magic != RTLD_MAGIC) |
147 | _FATAL("Corrupt Obj_Entry pointer in GOT\n"); | | 147 | _FATAL("Corrupt Obj_Entry pointer in GOT\n"); |
148 | if (obj->version != RTLD_VERSION) | | 148 | if (obj->version != RTLD_VERSION) |
149 | _FATAL("Dynamic linker version mismatch\n"); | | 149 | _FATAL("Dynamic linker version mismatch\n"); |
150 | atexit(cleanup); | | 150 | atexit(cleanup); |
151 | } | | 151 | } |
152 | | | 152 | |
153 | _libc_init(); | | 153 | _libc_init(); |
154 | | | 154 | |
155 | #ifdef MCRT0 | | 155 | #ifdef MCRT0 |
156 | atexit(_mcleanup); | | 156 | atexit(_mcleanup); |
157 | monstartup((u_long)&__eprol, (u_long)&__etext); | | 157 | monstartup((u_long)&__eprol, (u_long)&__etext); |
158 | #endif | | 158 | #endif |
159 | | | 159 | |
160 | atexit(_fini); | | 160 | atexit(_fini); |
161 | _init(); | | 161 | _init(); |
162 | | | 162 | |
163 | exit(main(ps_strings->ps_nargvstr, ps_strings->ps_argvstr, environ)); | | 163 | exit(main(ps_strings->ps_nargvstr, ps_strings->ps_argvstr, environ)); |
164 | } | | 164 | } |