Pullup from HEAD: Add .init_array/.fini_array support (conditionalized on HAVE_INITFINI_ARRAY).diff -r1.110 -r1.110.6.1 src/libexec/ld.elf_so/Makefile
(matt)
--- src/libexec/ld.elf_so/Makefile 2011/10/07 09:15:21 1.110
+++ src/libexec/ld.elf_so/Makefile 2013/01/22 21:47:27 1.110.6.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: Makefile,v 1.110 2011/10/07 09:15:21 mrg Exp $ | 1 | # $NetBSD: Makefile,v 1.110.6.1 2013/01/22 21:47:27 matt Exp $ | |
2 | # | 2 | # | |
3 | # NOTE: when changing ld.so, ensure that ldd still compiles. | 3 | # NOTE: when changing ld.so, ensure that ldd still compiles. | |
4 | # | 4 | # | |
5 | 5 | |||
6 | WARNS?=4 | 6 | WARNS?=4 | |
7 | 7 | |||
8 | # This needs to be before bsd.init.mk | 8 | # This needs to be before bsd.init.mk | |
9 | .if defined(BSD_MK_COMPAT_FILE) | 9 | .if defined(BSD_MK_COMPAT_FILE) | |
10 | .include <${BSD_MK_COMPAT_FILE}> | 10 | .include <${BSD_MK_COMPAT_FILE}> | |
11 | .endif | 11 | .endif | |
12 | 12 | |||
13 | # We are not building this with PIE | 13 | # We are not building this with PIE | |
14 | PIE_CFLAGS= | 14 | PIE_CFLAGS= | |
@@ -33,27 +33,27 @@ M= ${.CURDIR}/arch/${ARCHSUBDIR} | @@ -33,27 +33,27 @@ M= ${.CURDIR}/arch/${ARCHSUBDIR} | |||
33 | (${MACHINE_ARCH} == "powerpc") || \ | 33 | (${MACHINE_ARCH} == "powerpc") || \ | |
34 | (${MACHINE_CPU} == "sh3") || \ | 34 | (${MACHINE_CPU} == "sh3") || \ | |
35 | (${MACHINE_ARCH} == "sparc") || \ | 35 | (${MACHINE_ARCH} == "sparc") || \ | |
36 | (${MACHINE_ARCH} == "sparc64") || \ | 36 | (${MACHINE_ARCH} == "sparc64") || \ | |
37 | (${MACHINE_ARCH} == "x86_64") || \ | 37 | (${MACHINE_ARCH} == "x86_64") || \ | |
38 | (${MACHINE_ARCH} == "vax")) && \ | 38 | (${MACHINE_ARCH} == "vax")) && \ | |
39 | ${MKPIC} != "no" | 39 | ${MKPIC} != "no" | |
40 | 40 | |||
41 | LDFLAGS+= ${${ACTIVE_CC} == "clang":? -Wl,-Bsymbolic : -symbolic} \ | 41 | LDFLAGS+= ${${ACTIVE_CC} == "clang":? -Wl,-Bsymbolic : -symbolic} \ | |
42 | -shared -nostartfiles -nodefaultlibs | 42 | -shared -nostartfiles -nodefaultlibs | |
43 | LDFLAGS+= -Wl,-static | 43 | LDFLAGS+= -Wl,-static | |
44 | LDFLAGS+= -Wl,--warn-shared-textrel | 44 | LDFLAGS+= -Wl,--warn-shared-textrel | |
45 | 45 | |||
46 | CFLAGS+= -fvisibility=hidden | 46 | COPTS+= -fvisibility=hidden | |
47 | 47 | |||
48 | # Adds SRCS, CPPFLAGS, LDFLAGS, etc. Must go first so MD startup source | 48 | # Adds SRCS, CPPFLAGS, LDFLAGS, etc. Must go first so MD startup source | |
49 | # is first. | 49 | # is first. | |
50 | .if exists($M/Makefile.inc) | 50 | .if exists($M/Makefile.inc) | |
51 | .include "$M/Makefile.inc" | 51 | .include "$M/Makefile.inc" | |
52 | .endif | 52 | .endif | |
53 | 53 | |||
54 | # Support compat ld.elf_so. | 54 | # Support compat ld.elf_so. | |
55 | .if defined(MLIBDIR) | 55 | .if defined(MLIBDIR) | |
56 | PROG= ld.elf_so-${MLIBDIR} | 56 | PROG= ld.elf_so-${MLIBDIR} | |
57 | CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" | 57 | CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" | |
58 | .else | 58 | .else | |
59 | PROG= ld.elf_so | 59 | PROG= ld.elf_so | |
@@ -82,30 +82,30 @@ xprintf.c: errlist_concat.h | @@ -82,30 +82,30 @@ xprintf.c: errlist_concat.h | |||
82 | CLEANFILES+= errlist_concat.h | 82 | CLEANFILES+= errlist_concat.h | |
83 | 83 | |||
84 | BINDIR= ${SHLINKINSTALLDIR} | 84 | BINDIR= ${SHLINKINSTALLDIR} | |
85 | 85 | |||
86 | CPPFLAGS+= -DLIBDIR=\"${LIBDIR}\" -D_PATH_RTLD=\"${BINDIR}/${PROG}\" | 86 | CPPFLAGS+= -DLIBDIR=\"${LIBDIR}\" -D_PATH_RTLD=\"${BINDIR}/${PROG}\" | |
87 | CPPFLAGS+= -I${.CURDIR} -I. | 87 | CPPFLAGS+= -I${.CURDIR} -I. | |
88 | CPPFLAGS+= -DRTLD_LOADER | 88 | CPPFLAGS+= -DRTLD_LOADER | |
89 | CPPFLAGS+= -D_RTLD_SOURCE | 89 | CPPFLAGS+= -D_RTLD_SOURCE | |
90 | CPPFLAGS+= -DCOMBRELOC | 90 | CPPFLAGS+= -DCOMBRELOC | |
91 | #CPPFLAGS+= -DDEBUG | 91 | #CPPFLAGS+= -DDEBUG | |
92 | #CPPFLAGS+= -DRTLD_DEBUG | 92 | #CPPFLAGS+= -DRTLD_DEBUG | |
93 | #CPPFLAGS+= -DRTLD_DEBUG_RELOC | 93 | #CPPFLAGS+= -DRTLD_DEBUG_RELOC | |
94 | #DBG= -g | 94 | #DBG= -g | |
95 | DBG= -O3 -fomit-frame-pointer | 95 | COPTS= -O3 -fomit-frame-pointer | |
96 | 96 | |||
97 | .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64" | 97 | .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64" | |
98 | DBG+= -mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-sse3 | 98 | COPTS+= -mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-sse3 | |
99 | .endif | 99 | .endif | |
100 | 100 | |||
101 | 101 | |||
102 | .if ${SHLIBDIR} != ${LIBDIR} | 102 | .if ${SHLIBDIR} != ${LIBDIR} | |
103 | CPPFLAGS+= -DRTLD_DEFAULT_LIBRARY_PATH=\"${SHLIBDIR}:${LIBDIR}\" | 103 | CPPFLAGS+= -DRTLD_DEFAULT_LIBRARY_PATH=\"${SHLIBDIR}:${LIBDIR}\" | |
104 | .endif | 104 | .endif | |
105 | 105 | |||
106 | # rtld.c and symbol.c use alloca, so disable SSP warnings. | 106 | # rtld.c and symbol.c use alloca, so disable SSP warnings. | |
107 | COPTS.rtld.c+= -Wno-stack-protector | 107 | COPTS.rtld.c+= -Wno-stack-protector | |
108 | COPTS.symbol.c+=-Wno-stack-protector | 108 | COPTS.symbol.c+=-Wno-stack-protector | |
109 | 109 | |||
110 | LDADD+= -L${CLIBOBJ} -L${DESTDIR}${LIBDIR} | 110 | LDADD+= -L${CLIBOBJ} -L${DESTDIR}${LIBDIR} | |
111 | .if ${MKPICLIB} != "no" | 111 | .if ${MKPICLIB} != "no" |
--- src/libexec/ld.elf_so/headers.c 2012/08/08 06:24:51 1.41.4.1
+++ src/libexec/ld.elf_so/headers.c 2013/01/22 21:47:27 1.41.4.1.2.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: headers.c,v 1.41.4.1 2012/08/08 06:24:51 jdc Exp $ */ | 1 | /* $NetBSD: headers.c,v 1.41.4.1.2.1 2013/01/22 21:47:27 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright 1996 John D. Polstra. | 4 | * Copyright 1996 John D. Polstra. | |
5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | 5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | |
6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | 6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -30,27 +30,27 @@ | @@ -30,27 +30,27 @@ | |||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | /* | 35 | /* | |
36 | * Dynamic linker for ELF. | 36 | * Dynamic linker for ELF. | |
37 | * | 37 | * | |
38 | * John Polstra <jdp@polstra.com>. | 38 | * John Polstra <jdp@polstra.com>. | |
39 | */ | 39 | */ | |
40 | 40 | |||
41 | #include <sys/cdefs.h> | 41 | #include <sys/cdefs.h> | |
42 | #ifndef lint | 42 | #ifndef lint | |
43 | __RCSID("$NetBSD: headers.c,v 1.41.4.1 2012/08/08 06:24:51 jdc Exp $"); | 43 | __RCSID("$NetBSD: headers.c,v 1.41.4.1.2.1 2013/01/22 21:47:27 matt Exp $"); | |
44 | #endif /* not lint */ | 44 | #endif /* not lint */ | |
45 | 45 | |||
46 | #include <err.h> | 46 | #include <err.h> | |
47 | #include <errno.h> | 47 | #include <errno.h> | |
48 | #include <fcntl.h> | 48 | #include <fcntl.h> | |
49 | #include <stdarg.h> | 49 | #include <stdarg.h> | |
50 | #include <stdio.h> | 50 | #include <stdio.h> | |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> | |
52 | #include <string.h> | 52 | #include <string.h> | |
53 | #include <unistd.h> | 53 | #include <unistd.h> | |
54 | #include <sys/types.h> | 54 | #include <sys/types.h> | |
55 | #include <sys/mman.h> | 55 | #include <sys/mman.h> | |
56 | #include <sys/bitops.h> | 56 | #include <sys/bitops.h> | |
@@ -217,30 +217,52 @@ _rtld_digest_dynamic(const char *execnam | @@ -217,30 +217,52 @@ _rtld_digest_dynamic(const char *execnam | |||
217 | * table yet. | 217 | * table yet. | |
218 | */ | 218 | */ | |
219 | dyn_rpath = dynp; | 219 | dyn_rpath = dynp; | |
220 | break; | 220 | break; | |
221 | 221 | |||
222 | case DT_SONAME: | 222 | case DT_SONAME: | |
223 | /* Not used by the dynamic linker. */ | 223 | /* Not used by the dynamic linker. */ | |
224 | break; | 224 | break; | |
225 | 225 | |||
226 | case DT_INIT: | 226 | case DT_INIT: | |
227 | init = dynp->d_un.d_ptr; | 227 | init = dynp->d_un.d_ptr; | |
228 | break; | 228 | break; | |
229 | 229 | |||
230 | #ifdef HAVE_INITFINI_ARRAY | |||
231 | case DT_INIT_ARRAY: | |||
232 | obj->init_array = | |||
233 | (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr); | |||
234 | break; | |||
235 | ||||
236 | case DT_INIT_ARRAYSZ: | |||
237 | obj->init_arraysz = dynp->d_un.d_val / sizeof(fptr_t); | |||
238 | break; | |||
239 | #endif | |||
240 | ||||
230 | case DT_FINI: | 241 | case DT_FINI: | |
231 | fini = dynp->d_un.d_ptr; | 242 | fini = dynp->d_un.d_ptr; | |
232 | break; | 243 | break; | |
233 | 244 | |||
245 | #ifdef HAVE_INITFINI_ARRAY | |||
246 | case DT_FINI_ARRAY: | |||
247 | obj->fini_array = | |||
248 | (fptr_t *)(obj->relocbase + dynp->d_un.d_ptr); | |||
249 | break; | |||
250 | ||||
251 | case DT_FINI_ARRAYSZ: | |||
252 | obj->fini_arraysz = dynp->d_un.d_val / sizeof(fptr_t); | |||
253 | break; | |||
254 | #endif | |||
255 | ||||
234 | /* | 256 | /* | |
235 | * Don't process DT_DEBUG on MIPS as the dynamic section | 257 | * Don't process DT_DEBUG on MIPS as the dynamic section | |
236 | * is mapped read-only. DT_MIPS_RLD_MAP is used instead. | 258 | * is mapped read-only. DT_MIPS_RLD_MAP is used instead. | |
237 | * XXX: n32/n64 may use DT_DEBUG, not sure yet. | 259 | * XXX: n32/n64 may use DT_DEBUG, not sure yet. | |
238 | */ | 260 | */ | |
239 | #ifndef __mips__ | 261 | #ifndef __mips__ | |
240 | case DT_DEBUG: | 262 | case DT_DEBUG: | |
241 | #ifdef RTLD_LOADER | 263 | #ifdef RTLD_LOADER | |
242 | dynp->d_un.d_ptr = (Elf_Addr)&_rtld_debug; | 264 | dynp->d_un.d_ptr = (Elf_Addr)&_rtld_debug; | |
243 | #endif | 265 | #endif | |
244 | break; | 266 | break; | |
245 | #endif | 267 | #endif | |
246 | 268 |
--- src/libexec/ld.elf_so/rtld.c 2011/11/25 21:27:15 1.155
+++ src/libexec/ld.elf_so/rtld.c 2013/01/22 21:47:28 1.155.4.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rtld.c,v 1.155 2011/11/25 21:27:15 joerg Exp $ */ | 1 | /* $NetBSD: rtld.c,v 1.155.4.1 2013/01/22 21:47:28 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright 1996 John D. Polstra. | 4 | * Copyright 1996 John D. Polstra. | |
5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | 5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | |
6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | 6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -30,27 +30,27 @@ | @@ -30,27 +30,27 @@ | |||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | /* | 35 | /* | |
36 | * Dynamic linker for ELF. | 36 | * Dynamic linker for ELF. | |
37 | * | 37 | * | |
38 | * John Polstra <jdp@polstra.com>. | 38 | * John Polstra <jdp@polstra.com>. | |
39 | */ | 39 | */ | |
40 | 40 | |||
41 | #include <sys/cdefs.h> | 41 | #include <sys/cdefs.h> | |
42 | #ifndef lint | 42 | #ifndef lint | |
43 | __RCSID("$NetBSD: rtld.c,v 1.155 2011/11/25 21:27:15 joerg Exp $"); | 43 | __RCSID("$NetBSD: rtld.c,v 1.155.4.1 2013/01/22 21:47:28 matt Exp $"); | |
44 | #endif /* not lint */ | 44 | #endif /* not lint */ | |
45 | 45 | |||
46 | #include <sys/param.h> | 46 | #include <sys/param.h> | |
47 | #include <sys/atomic.h> | 47 | #include <sys/atomic.h> | |
48 | #include <sys/mman.h> | 48 | #include <sys/mman.h> | |
49 | #include <err.h> | 49 | #include <err.h> | |
50 | #include <errno.h> | 50 | #include <errno.h> | |
51 | #include <fcntl.h> | 51 | #include <fcntl.h> | |
52 | #include <lwp.h> | 52 | #include <lwp.h> | |
53 | #include <stdarg.h> | 53 | #include <stdarg.h> | |
54 | #include <stdio.h> | 54 | #include <stdio.h> | |
55 | #include <stdlib.h> | 55 | #include <stdlib.h> | |
56 | #include <string.h> | 56 | #include <string.h> | |
@@ -124,146 +124,180 @@ extern Elf_Dyn _DYNAMIC; | @@ -124,146 +124,180 @@ extern Elf_Dyn _DYNAMIC; | |||
124 | static void _rtld_call_fini_functions(sigset_t *, int); | 124 | static void _rtld_call_fini_functions(sigset_t *, int); | |
125 | static void _rtld_call_init_functions(sigset_t *); | 125 | static void _rtld_call_init_functions(sigset_t *); | |
126 | static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); | 126 | static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); | |
127 | static void _rtld_initlist_tsort(Objlist *, int); | 127 | static void _rtld_initlist_tsort(Objlist *, int); | |
128 | static Obj_Entry *_rtld_dlcheck(void *); | 128 | static Obj_Entry *_rtld_dlcheck(void *); | |
129 | static void _rtld_init_dag(Obj_Entry *); | 129 | static void _rtld_init_dag(Obj_Entry *); | |
130 | static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); | 130 | static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); | |
131 | static void _rtld_objlist_remove(Objlist *, Obj_Entry *); | 131 | static void _rtld_objlist_remove(Objlist *, Obj_Entry *); | |
132 | static void _rtld_objlist_clear(Objlist *); | 132 | static void _rtld_objlist_clear(Objlist *); | |
133 | static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool); | 133 | static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool); | |
134 | static void _rtld_unref_dag(Obj_Entry *); | 134 | static void _rtld_unref_dag(Obj_Entry *); | |
135 | static Obj_Entry *_rtld_obj_from_addr(const void *); | 135 | static Obj_Entry *_rtld_obj_from_addr(const void *); | |
136 | 136 | |||
137 | static inline void | |||
138 | _rtld_call_initfini_function(fptr_t func, sigset_t *mask) | |||
139 | { | |||
140 | _rtld_exclusive_exit(mask); | |||
141 | (*func)(); | |||
142 | _rtld_exclusive_enter(mask); | |||
143 | } | |||
144 | ||||
145 | static void | |||
146 | _rtld_call_fini_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen) | |||
147 | { | |||
148 | if (obj->fini_arraysz == 0 && (obj->fini == NULL || obj->fini_called)) { | |||
149 | return; | |||
150 | } | |||
151 | if (obj->fini != NULL && !obj->fini_called) { | |||
152 | dbg (("calling fini function %s at %p%s", obj->path, | |||
153 | (void *)obj->fini, | |||
154 | obj->z_initfirst ? " (DF_1_INITFIRST)" : "")); | |||
155 | obj->fini_called = 1; | |||
156 | _rtld_call_initfini_function(obj->fini, mask); | |||
157 | } | |||
158 | #ifdef HAVE_INITFINI_ARRAY | |||
159 | /* | |||
160 | * Now process the fini_array if it exists. Simply go from | |||
161 | * start to end. We need to make restartable so just advance | |||
162 | * the array pointer and decrement the size each time through | |||
163 | * the loop. | |||
164 | */ | |||
165 | while (obj->fini_arraysz > 0 && _rtld_objgen == cur_objgen) { | |||
166 | fptr_t fini = *obj->fini_array++; | |||
167 | obj->fini_arraysz--; | |||
168 | dbg (("calling fini array function %s at %p%s", obj->path, | |||
169 | (void *)fini, | |||
170 | obj->z_initfirst ? " (DF_1_INITFIRST)" : "")); | |||
171 | _rtld_call_initfini_function(fini, mask); | |||
172 | } | |||
173 | #endif /* HAVE_INITFINI_ARRAY */ | |||
174 | } | |||
175 | ||||
137 | static void | 176 | static void | |
138 | _rtld_call_fini_functions(sigset_t *mask, int force) | 177 | _rtld_call_fini_functions(sigset_t *mask, int force) | |
139 | { | 178 | { | |
140 | Objlist_Entry *elm; | 179 | Objlist_Entry *elm; | |
141 | Objlist finilist; | 180 | Objlist finilist; | |
142 | Obj_Entry *obj; | |||
143 | void (*fini)(void); | |||
144 | u_int cur_objgen; | 181 | u_int cur_objgen; | |
145 | 182 | |||
146 | dbg(("_rtld_call_fini_functions(%d)", force)); | 183 | dbg(("_rtld_call_fini_functions(%d)", force)); | |
147 | 184 | |||
148 | restart: | 185 | restart: | |
149 | cur_objgen = ++_rtld_objgen; | 186 | cur_objgen = ++_rtld_objgen; | |
150 | SIMPLEQ_INIT(&finilist); | 187 | SIMPLEQ_INIT(&finilist); | |
151 | _rtld_initlist_tsort(&finilist, 1); | 188 | _rtld_initlist_tsort(&finilist, 1); | |
152 | 189 | |||
153 | /* First pass: objects _not_ marked with DF_1_INITFIRST. */ | 190 | /* First pass: objects _not_ marked with DF_1_INITFIRST. */ | |
154 | SIMPLEQ_FOREACH(elm, &finilist, link) { | 191 | SIMPLEQ_FOREACH(elm, &finilist, link) { | |
155 | obj = elm->obj; | 192 | Obj_Entry * const obj = elm->obj; | |
156 | if (obj->refcount > 0 && !force) { | 193 | if (!obj->z_initfirst) { | |
157 | continue; | 194 | if (obj->refcount > 0 && !force) { | |
158 | } | 195 | continue; | |
159 | if (obj->fini == NULL || obj->fini_called || obj->z_initfirst) { | 196 | } | |
160 | continue; | 197 | /* | |
198 | * XXX This can race against a concurrent dlclose(). | |||
199 | * XXX In that case, the object could be unmapped before | |||
200 | * XXX the fini() call or the fini_array has completed. | |||
201 | */ | |||
202 | _rtld_call_fini_function(obj, mask, cur_objgen); | |||
203 | if (_rtld_objgen != cur_objgen) { | |||
204 | dbg(("restarting fini iteration")); | |||
205 | _rtld_objlist_clear(&finilist); | |||
206 | goto restart; | |||
161 | } | 207 | } | |
162 | dbg (("calling fini function %s at %p", obj->path, | |||
163 | (void *)obj->fini)); | |||
164 | obj->fini_called = 1; | |||
165 | /* | |||
166 | * XXX This can race against a concurrent dlclose(). | |||
167 | * XXX In that case, the object could be unmapped before | |||
168 | * XXX the fini() call is done. | |||
169 | */ | |||
170 | fini = obj->fini; | |||
171 | _rtld_exclusive_exit(mask); | |||
172 | (*fini)(); | |||
173 | _rtld_exclusive_enter(mask); | |||
174 | if (_rtld_objgen != cur_objgen) { | |||
175 | dbg(("restarting fini iteration")); | |||
176 | _rtld_objlist_clear(&finilist); | |||
177 | goto restart; | |||
178 | } | 208 | } | |
179 | } | 209 | } | |
180 | 210 | |||
181 | /* Second pass: objects marked with DF_1_INITFIRST. */ | 211 | /* Second pass: objects marked with DF_1_INITFIRST. */ | |
182 | SIMPLEQ_FOREACH(elm, &finilist, link) { | 212 | SIMPLEQ_FOREACH(elm, &finilist, link) { | |
183 | obj = elm->obj; | 213 | Obj_Entry * const obj = elm->obj; | |
184 | if (obj->refcount > 0 && !force) { | 214 | if (obj->refcount > 0 && !force) { | |
185 | continue; | 215 | continue; | |
186 | } | 216 | } | |
187 | if (obj->fini == NULL || obj->fini_called) { | |||
188 | continue; | |||
189 | } | |||
190 | dbg (("calling fini function %s at %p (DF_1_INITFIRST)", | |||
191 | obj->path, (void *)obj->fini)); | |||
192 | obj->fini_called = 1; | |||
193 | /* XXX See above for the race condition here */ | 217 | /* XXX See above for the race condition here */ | |
194 | fini = obj->fini; | 218 | _rtld_call_fini_function(obj, mask, cur_objgen); | |
195 | _rtld_exclusive_exit(mask); | |||
196 | (*fini)(); | |||
197 | _rtld_exclusive_enter(mask); | |||
198 | if (_rtld_objgen != cur_objgen) { | 219 | if (_rtld_objgen != cur_objgen) { | |
199 | dbg(("restarting fini iteration")); | 220 | dbg(("restarting fini iteration")); | |
200 | _rtld_objlist_clear(&finilist); | 221 | _rtld_objlist_clear(&finilist); | |
201 | goto restart; | 222 | goto restart; | |
202 | } | 223 | } | |
203 | } | 224 | } | |
204 | 225 | |||
205 | _rtld_objlist_clear(&finilist); | 226 | _rtld_objlist_clear(&finilist); | |
206 | } | 227 | } | |
207 | 228 | |||
208 | static void | 229 | static void | |
230 | _rtld_call_init_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen) | |||
231 | { | |||
232 | if (obj->init_arraysz == 0 && (obj->init_called || obj->init == NULL)) { | |||
233 | return; | |||
234 | } | |||
235 | if (!obj->init_called && obj->init != NULL) { | |||
236 | dbg (("calling init function %s at %p%s", | |||
237 | obj->path, (void *)obj->init, | |||
238 | obj->z_initfirst ? " (DF_1_INITFIRST)" : "")); | |||
239 | obj->init_called = 1; | |||
240 | _rtld_call_initfini_function(obj->init, mask); | |||
241 | } | |||
242 | ||||
243 | #ifdef HAVE_INITFINI_ARRAY | |||
244 | /* | |||
245 | * Now process the init_array if it exists. Simply go from | |||
246 | * start to end. We need to make restartable so just advance | |||
247 | * the array pointer and decrement the size each time through | |||
248 | * the loop. | |||
249 | */ | |||
250 | while (obj->init_arraysz > 0 && _rtld_objgen == cur_objgen) { | |||
251 | fptr_t init = *obj->init_array++; | |||
252 | obj->init_arraysz--; | |||
253 | dbg (("calling init_array function %s at %p%s", | |||
254 | obj->path, (void *)init, | |||
255 | obj->z_initfirst ? " (DF_1_INITFIRST)" : "")); | |||
256 | _rtld_call_initfini_function(init, mask); | |||
257 | } | |||
258 | #endif /* HAVE_INITFINI_ARRAY */ | |||
259 | } | |||
260 | ||||
261 | static void | |||
209 | _rtld_call_init_functions(sigset_t *mask) | 262 | _rtld_call_init_functions(sigset_t *mask) | |
210 | { | 263 | { | |
211 | Objlist_Entry *elm; | 264 | Objlist_Entry *elm; | |
212 | Objlist initlist; | 265 | Objlist initlist; | |
213 | Obj_Entry *obj; | |||
214 | void (*init)(void); | |||
215 | u_int cur_objgen; | 266 | u_int cur_objgen; | |
216 | 267 | |||
217 | dbg(("_rtld_call_init_functions()")); | 268 | dbg(("_rtld_call_init_functions()")); | |
218 | 269 | |||
219 | restart: | 270 | restart: | |
220 | cur_objgen = ++_rtld_objgen; | 271 | cur_objgen = ++_rtld_objgen; | |
221 | SIMPLEQ_INIT(&initlist); | 272 | SIMPLEQ_INIT(&initlist); | |
222 | _rtld_initlist_tsort(&initlist, 0); | 273 | _rtld_initlist_tsort(&initlist, 0); | |
223 | 274 | |||
224 | /* First pass: objects marked with DF_1_INITFIRST. */ | 275 | /* First pass: objects marked with DF_1_INITFIRST. */ | |
225 | SIMPLEQ_FOREACH(elm, &initlist, link) { | 276 | SIMPLEQ_FOREACH(elm, &initlist, link) { | |
226 | obj = elm->obj; | 277 | Obj_Entry * const obj = elm->obj; | |
227 | if (obj->init == NULL || obj->init_called || !obj->z_initfirst) { | 278 | if (obj->z_initfirst) { | |
228 | continue; | 279 | _rtld_call_init_function(obj, mask, cur_objgen); | |
229 | } | 280 | if (_rtld_objgen != cur_objgen) { | |
230 | dbg (("calling init function %s at %p (DF_1_INITFIRST)", | 281 | dbg(("restarting init iteration")); | |
231 | obj->path, (void *)obj->init)); | 282 | _rtld_objlist_clear(&initlist); | |
232 | obj->init_called = 1; | 283 | goto restart; | |
233 | init = obj->init; | 284 | } | |
234 | _rtld_exclusive_exit(mask); | |||
235 | (*init)(); | |||
236 | _rtld_exclusive_enter(mask); | |||
237 | if (_rtld_objgen != cur_objgen) { | |||
238 | dbg(("restarting init iteration")); | |||
239 | _rtld_objlist_clear(&initlist); | |||
240 | goto restart; | |||
241 | } | 285 | } | |
242 | } | 286 | } | |
243 | 287 | |||
244 | /* Second pass: all other objects. */ | 288 | /* Second pass: all other objects. */ | |
245 | SIMPLEQ_FOREACH(elm, &initlist, link) { | 289 | SIMPLEQ_FOREACH(elm, &initlist, link) { | |
246 | obj = elm->obj; | 290 | _rtld_call_init_function(elm->obj, mask, cur_objgen); | |
247 | if (obj->init == NULL || obj->init_called) { | |||
248 | continue; | |||
249 | } | |||
250 | dbg (("calling init function %s at %p", obj->path, | |||
251 | (void *)obj->init)); | |||
252 | obj->init_called = 1; | |||
253 | init = obj->init; | |||
254 | _rtld_exclusive_exit(mask); | |||
255 | (*init)(); | |||
256 | _rtld_exclusive_enter(mask); | |||
257 | if (_rtld_objgen != cur_objgen) { | 291 | if (_rtld_objgen != cur_objgen) { | |
258 | dbg(("restarting init iteration")); | 292 | dbg(("restarting init iteration")); | |
259 | _rtld_objlist_clear(&initlist); | 293 | _rtld_objlist_clear(&initlist); | |
260 | goto restart; | 294 | goto restart; | |
261 | } | 295 | } | |
262 | } | 296 | } | |
263 | 297 | |||
264 | _rtld_objlist_clear(&initlist); | 298 | _rtld_objlist_clear(&initlist); | |
265 | } | 299 | } | |
266 | 300 | |||
267 | /* | 301 | /* | |
268 | * Initialize the dynamic linker. The argument is the address at which | 302 | * Initialize the dynamic linker. The argument is the address at which | |
269 | * the dynamic linker has been mapped into memory. The primary task of | 303 | * the dynamic linker has been mapped into memory. The primary task of |
--- src/libexec/ld.elf_so/rtld.h 2011/12/02 09:06:49 1.107
+++ src/libexec/ld.elf_so/rtld.h 2013/01/22 21:47:28 1.107.4.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rtld.h,v 1.107 2011/12/02 09:06:49 skrll Exp $ */ | 1 | /* $NetBSD: rtld.h,v 1.107.4.1 2013/01/22 21:47:28 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright 1996 John D. Polstra. | 4 | * Copyright 1996 John D. Polstra. | |
5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | 5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | |
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 | |
@@ -104,53 +104,54 @@ typedef struct _rtld_search_path_t { | @@ -104,53 +104,54 @@ typedef struct _rtld_search_path_t { | |||
104 | size_t sp_pathlen; | 104 | size_t sp_pathlen; | |
105 | } Search_Path; | 105 | } Search_Path; | |
106 | 106 | |||
107 | typedef struct Struct_Ver_Entry { | 107 | typedef struct Struct_Ver_Entry { | |
108 | Elf_Word hash; | 108 | Elf_Word hash; | |
109 | u_int flags; | 109 | u_int flags; | |
110 | const char *name; | 110 | const char *name; | |
111 | const char *file; | 111 | const char *file; | |
112 | } Ver_Entry; | 112 | } Ver_Entry; | |
113 | 113 | |||
114 | /* Ver_Entry.flags */ | 114 | /* Ver_Entry.flags */ | |
115 | #define VER_INFO_HIDDEN 0x01 | 115 | #define VER_INFO_HIDDEN 0x01 | |
116 | 116 | |||
117 | ||||
118 | #define RTLD_MAX_ENTRY 10 | 117 | #define RTLD_MAX_ENTRY 10 | |
119 | #define RTLD_MAX_LIBRARY 4 | 118 | #define RTLD_MAX_LIBRARY 4 | |
120 | #define RTLD_MAX_CTL 2 | 119 | #define RTLD_MAX_CTL 2 | |
121 | typedef struct _rtld_library_xform_t { | 120 | typedef struct _rtld_library_xform_t { | |
122 | struct _rtld_library_xform_t *next; | 121 | struct _rtld_library_xform_t *next; | |
123 | char *name; | 122 | char *name; | |
124 | const char *ctlname; | 123 | const char *ctlname; | |
125 | struct { | 124 | struct { | |
126 | char *value; | 125 | char *value; | |
127 | char *library[RTLD_MAX_LIBRARY]; | 126 | char *library[RTLD_MAX_LIBRARY]; | |
128 | } entry[RTLD_MAX_ENTRY]; | 127 | } entry[RTLD_MAX_ENTRY]; | |
129 | } Library_Xform; | 128 | } Library_Xform; | |
130 | 129 | |||
131 | /* | 130 | /* | |
132 | * Shared object descriptor. | 131 | * Shared object descriptor. | |
133 | * | 132 | * | |
134 | * Items marked with "(%)" are dynamically allocated, and must be freed | 133 | * Items marked with "(%)" are dynamically allocated, and must be freed | |
135 | * when the structure is destroyed. | 134 | * when the structure is destroyed. | |
136 | * | 135 | * | |
137 | * The layout of this structure needs to be preserved because pre-2.0 binaries | 136 | * The layout of this structure needs to be preserved because pre-2.0 binaries | |
138 | * hard-coded the location of dlopen() and friends. | 137 | * hard-coded the location of dlopen() and friends. | |
139 | */ | 138 | */ | |
140 | 139 | |||
141 | #define RTLD_MAGIC 0xd550b87a | 140 | #define RTLD_MAGIC 0xd550b87a | |
142 | #define RTLD_VERSION 1 | 141 | #define RTLD_VERSION 1 | |
143 | 142 | |||
143 | typedef void (*fptr_t)(void); | |||
144 | ||||
144 | typedef struct Struct_Obj_Entry { | 145 | typedef struct Struct_Obj_Entry { | |
145 | Elf32_Word magic; /* Magic number (sanity check) */ | 146 | Elf32_Word magic; /* Magic number (sanity check) */ | |
146 | Elf32_Word version; /* Version number of struct format */ | 147 | Elf32_Word version; /* Version number of struct format */ | |
147 | 148 | |||
148 | struct Struct_Obj_Entry *next; | 149 | struct Struct_Obj_Entry *next; | |
149 | char *path; /* Pathname of underlying file (%) */ | 150 | char *path; /* Pathname of underlying file (%) */ | |
150 | int refcount; | 151 | int refcount; | |
151 | int dl_refcount; /* Number of times loaded by dlopen */ | 152 | int dl_refcount; /* Number of times loaded by dlopen */ | |
152 | 153 | |||
153 | /* These items are computed by map_object() or by digest_phdr(). */ | 154 | /* These items are computed by map_object() or by digest_phdr(). */ | |
154 | caddr_t mapbase; /* Base address of mapped region */ | 155 | caddr_t mapbase; /* Base address of mapped region */ | |
155 | size_t mapsize; /* Size of mapped region in bytes */ | 156 | size_t mapsize; /* Size of mapped region in bytes */ | |
156 | size_t textsize; /* Size of text segment in bytes */ | 157 | size_t textsize; /* Size of text segment in bytes */ | |
@@ -178,28 +179,28 @@ typedef struct Struct_Obj_Entry { | @@ -178,28 +179,28 @@ typedef struct Struct_Obj_Entry { | |||
178 | Elf_Word local_gotno; /* Number of local GOT entries */ | 179 | Elf_Word local_gotno; /* Number of local GOT entries */ | |
179 | Elf_Word symtabno; /* Number of dynamic symbols */ | 180 | Elf_Word symtabno; /* Number of dynamic symbols */ | |
180 | Elf_Word gotsym; /* First dynamic symbol in GOT */ | 181 | Elf_Word gotsym; /* First dynamic symbol in GOT */ | |
181 | #endif | 182 | #endif | |
182 | 183 | |||
183 | const Elf_Symindx *buckets; /* Hash table buckets array */ | 184 | const Elf_Symindx *buckets; /* Hash table buckets array */ | |
184 | unsigned long unused1; /* Used to be nbuckets */ | 185 | unsigned long unused1; /* Used to be nbuckets */ | |
185 | const Elf_Symindx *chains; /* Hash table chain array */ | 186 | const Elf_Symindx *chains; /* Hash table chain array */ | |
186 | unsigned long nchains; /* Number of chains */ | 187 | unsigned long nchains; /* Number of chains */ | |
187 | 188 | |||
188 | Search_Path *rpaths; /* Search path specified in object */ | 189 | Search_Path *rpaths; /* Search path specified in object */ | |
189 | Needed_Entry *needed; /* Shared objects needed by this (%) */ | 190 | Needed_Entry *needed; /* Shared objects needed by this (%) */ | |
190 | 191 | |||
191 | void (*init)(void); /* Initialization function to call */ | 192 | fptr_t init; /* Initialization function to call */ | |
192 | void (*fini)(void); /* Termination function to call */ | 193 | fptr_t fini; /* Termination function to call */ | |
193 | 194 | |||
194 | /* | 195 | /* | |
195 | * BACKWARDS COMPAT Entry points for dlopen() and friends. | 196 | * BACKWARDS COMPAT Entry points for dlopen() and friends. | |
196 | * | 197 | * | |
197 | * DO NOT MOVE OR ADD TO THE LIST | 198 | * DO NOT MOVE OR ADD TO THE LIST | |
198 | * | 199 | * | |
199 | */ | 200 | */ | |
200 | void *(*dlopen)(const char *, int); | 201 | void *(*dlopen)(const char *, int); | |
201 | void *(*dlsym)(void *, const char *); | 202 | void *(*dlsym)(void *, const char *); | |
202 | char *(*dlerror)(void); | 203 | char *(*dlerror)(void); | |
203 | int (*dlclose)(void *); | 204 | int (*dlclose)(void *); | |
204 | int (*dladdr)(const void *, Dl_info *); | 205 | int (*dladdr)(const void *, Dl_info *); | |
205 | 206 | |||
@@ -267,26 +268,32 @@ typedef struct Struct_Obj_Entry { | @@ -267,26 +268,32 @@ typedef struct Struct_Obj_Entry { | |||
267 | size_t tlsalign; /* Needed alignment for static TLS */ | 268 | size_t tlsalign; /* Needed alignment for static TLS */ | |
268 | #endif | 269 | #endif | |
269 | 270 | |||
270 | /* symbol versioning */ | 271 | /* symbol versioning */ | |
271 | const Elf_Verneed *verneed; /* Required versions. */ | 272 | const Elf_Verneed *verneed; /* Required versions. */ | |
272 | Elf_Word verneednum; /* Number of entries in verneed table */ | 273 | Elf_Word verneednum; /* Number of entries in verneed table */ | |
273 | const Elf_Verdef *verdef; /* Provided versions. */ | 274 | const Elf_Verdef *verdef; /* Provided versions. */ | |
274 | Elf_Word verdefnum; /* Number of entries in verdef table */ | 275 | Elf_Word verdefnum; /* Number of entries in verdef table */ | |
275 | const Elf_Versym *versyms; /* Symbol versions table */ | 276 | const Elf_Versym *versyms; /* Symbol versions table */ | |
276 | 277 | |||
277 | Ver_Entry *vertab; /* Versions required/defined by this | 278 | Ver_Entry *vertab; /* Versions required/defined by this | |
278 | * object */ | 279 | * object */ | |
279 | int vertabnum; /* Number of entries in vertab */ | 280 | int vertabnum; /* Number of entries in vertab */ | |
281 | ||||
282 | /* init_array/fini_array */ | |||
283 | fptr_t *init_array; /* start of init array */ | |||
284 | size_t init_arraysz; /* # of entries in it */ | |||
285 | fptr_t *fini_array; /* start of fini array */ | |||
286 | size_t fini_arraysz; /* # of entries in it */ | |||
280 | } Obj_Entry; | 287 | } Obj_Entry; | |
281 | 288 | |||
282 | typedef struct Struct_DoneList { | 289 | typedef struct Struct_DoneList { | |
283 | const Obj_Entry **objs; /* Array of object pointers */ | 290 | const Obj_Entry **objs; /* Array of object pointers */ | |
284 | unsigned int num_alloc; /* Allocated size of the array */ | 291 | unsigned int num_alloc; /* Allocated size of the array */ | |
285 | unsigned int num_used; /* Number of array slots used */ | 292 | unsigned int num_used; /* Number of array slots used */ | |
286 | } DoneList; | 293 | } DoneList; | |
287 | 294 | |||
288 | 295 | |||
289 | #if defined(_RTLD_SOURCE) | 296 | #if defined(_RTLD_SOURCE) | |
290 | 297 | |||
291 | extern struct r_debug _rtld_debug; | 298 | extern struct r_debug _rtld_debug; | |
292 | extern Search_Path *_rtld_default_paths; | 299 | extern Search_Path *_rtld_default_paths; |
--- src/libexec/ld.elf_so/symbol.c 2011/11/25 14:39:02 1.59
+++ src/libexec/ld.elf_so/symbol.c 2013/01/22 21:47:28 1.59.4.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: symbol.c,v 1.59 2011/11/25 14:39:02 joerg Exp $ */ | 1 | /* $NetBSD: symbol.c,v 1.59.4.1 2013/01/22 21:47:28 matt Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright 1996 John D. Polstra. | 4 | * Copyright 1996 John D. Polstra. | |
5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | 5 | * Copyright 1996 Matt Thomas <matt@3am-software.com> | |
6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | 6 | * Copyright 2002 Charles M. Hannum <root@ihack.net> | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -30,47 +30,45 @@ | @@ -30,47 +30,45 @@ | |||
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | 33 | */ | |
34 | 34 | |||
35 | /* | 35 | /* | |
36 | * Dynamic linker for ELF. | 36 | * Dynamic linker for ELF. | |
37 | * | 37 | * | |
38 | * John Polstra <jdp@polstra.com>. | 38 | * John Polstra <jdp@polstra.com>. | |
39 | */ | 39 | */ | |
40 | 40 | |||
41 | #include <sys/cdefs.h> | 41 | #include <sys/cdefs.h> | |
42 | #ifndef lint | 42 | #ifndef lint | |
43 | __RCSID("$NetBSD: symbol.c,v 1.59 2011/11/25 14:39:02 joerg Exp $"); | 43 | __RCSID("$NetBSD: symbol.c,v 1.59.4.1 2013/01/22 21:47:28 matt Exp $"); | |
44 | #endif /* not lint */ | 44 | #endif /* not lint */ | |
45 | 45 | |||
46 | #include <err.h> | 46 | #include <err.h> | |
47 | #include <errno.h> | 47 | #include <errno.h> | |
48 | #include <fcntl.h> | 48 | #include <fcntl.h> | |
49 | #include <stdarg.h> | 49 | #include <stdarg.h> | |
50 | #include <stdio.h> | 50 | #include <stdio.h> | |
51 | #include <stdlib.h> | 51 | #include <stdlib.h> | |
52 | #include <string.h> | 52 | #include <string.h> | |
53 | #include <unistd.h> | 53 | #include <unistd.h> | |
54 | #include <sys/types.h> | 54 | #include <sys/types.h> | |
55 | #include <sys/mman.h> | 55 | #include <sys/mman.h> | |
56 | #include <sys/bitops.h> | 56 | #include <sys/bitops.h> | |
57 | #include <dirent.h> | 57 | #include <dirent.h> | |
58 | 58 | |||
59 | #include "debug.h" | 59 | #include "debug.h" | |
60 | #include "rtld.h" | 60 | #include "rtld.h" | |
61 | 61 | |||
62 | typedef void (*fptr_t)(void); | |||
63 | ||||
64 | /* | 62 | /* | |
65 | * If the given object is already in the donelist, return true. Otherwise | 63 | * If the given object is already in the donelist, return true. Otherwise | |
66 | * add the object to the list and return false. | 64 | * add the object to the list and return false. | |
67 | */ | 65 | */ | |
68 | static bool | 66 | static bool | |
69 | _rtld_donelist_check(DoneList *dlp, const Obj_Entry *obj) | 67 | _rtld_donelist_check(DoneList *dlp, const Obj_Entry *obj) | |
70 | { | 68 | { | |
71 | unsigned int i; | 69 | unsigned int i; | |
72 | 70 | |||
73 | for (i = 0; i < dlp->num_used; i++) | 71 | for (i = 0; i < dlp->num_used; i++) | |
74 | if (dlp->objs[i] == obj) | 72 | if (dlp->objs[i] == obj) | |
75 | return true; | 73 | return true; | |
76 | /* | 74 | /* |
--- src/libexec/ld.elf_so/arch/arm/Makefile.inc 2005/06/04 16:17:17 1.11
+++ src/libexec/ld.elf_so/arch/arm/Makefile.inc 2013/01/22 21:47:28 1.11.46.1
@@ -1,10 +1,13 @@ | @@ -1,10 +1,13 @@ | |||
1 | # $NetBSD: Makefile.inc,v 1.11 2005/06/04 16:17:17 lukem Exp $ | 1 | # $NetBSD: Makefile.inc,v 1.11.46.1 2013/01/22 21:47:28 matt Exp $ | |
2 | 2 | |||
3 | SRCS+= rtld_start.S mdreloc.c | 3 | SRCS+= rtld_start.S mdreloc.c | |
4 | 4 | |||
5 | # XXX Should not be in CPPFLAGS! | 5 | # XXX Should not be in CPPFLAGS! | |
6 | CPPFLAGS+= -fpic | 6 | CPPFLAGS+= -fpic | |
7 | 7 | |||
8 | CPPFLAGS+= -DELFSIZE=32 | 8 | CPPFLAGS+= -DELFSIZE=32 | |
9 | .if ${MACHINE_ARCH} == "earm" || ${MACHINE_ARCH} == "earmeb" | |||
10 | CPPFLAGS+= -DHAVE_INITFINI_ARRAY | |||
11 | .endif | |||
9 | 12 | |||
10 | LDFLAGS+= -Wl,-e,_rtld_start | 13 | LDFLAGS+= -Wl,-e,_rtld_start |
--- src/libexec/ld.elf_so/arch/arm/rtld_start.S 2009/11/11 14:15:41 1.10
+++ src/libexec/ld.elf_so/arch/arm/rtld_start.S 2013/01/22 21:47:28 1.10.10.1
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rtld_start.S,v 1.10 2009/11/11 14:15:41 skrll Exp $ */ | 1 | /* $NetBSD: rtld_start.S,v 1.10.10.1 2013/01/22 21:47:28 matt Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas and by Charles M. Hannum. | 8 | * by Matt Thomas and by Charles M. Hannum. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -21,77 +21,76 @@ | @@ -21,77 +21,76 @@ | |||
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include <machine/asm.h> | 32 | #include <machine/asm.h> | |
33 | 33 | |||
34 | RCSID("$NetBSD: rtld_start.S,v 1.10 2009/11/11 14:15:41 skrll Exp $") | 34 | RCSID("$NetBSD: rtld_start.S,v 1.10.10.1 2013/01/22 21:47:28 matt Exp $") | |
35 | 35 | |||
36 | .text | 36 | .text | |
37 | .align 0 | 37 | .align 0 | |
38 | .globl _rtld_start | 38 | .globl _rtld_start | |
39 | .type _rtld_start,%function | 39 | .type _rtld_start,%function | |
40 | _rtld_start: | 40 | _rtld_start: | |
41 | sub sp, sp, #8 /* make room for obj_main & exit proc */ | 41 | sub sp, sp, #8 /* make room for obj_main & exit proc */ | |
42 | mov r4, r0 /* save ps_strings */ | 42 | mov r4, r0 /* save ps_strings */ | |
43 | 43 | |||
44 | ldr sl, .L2 | 44 | ldr sl, .L2 | |
45 | ldr r5, .L2+4 | 45 | ldr r5, .L2+4 | |
46 | ldr r0, .L2+8 | 46 | ldr r0, .L2+8 | |
47 | .L1: | 47 | .L1: | |
48 | add sl, pc, sl | 48 | add sl, pc, sl | |
49 | ldr r5, [sl, r5] | 49 | ldr r5, [sl, r5] | |
50 | ldr r0, [sl, r0] | 50 | ldr r0, [sl, r0] | |
51 | 51 | |||
52 | sub r1, sl, r5 /* relocbase */ | 52 | sub r1, sl, r5 /* relocbase */ | |
53 | add r0, r1, r0 /* &_DYNAMIC */ | 53 | add r0, r1, r0 /* &_DYNAMIC */ | |
54 | bl _rtld_relocate_nonplt_self | 54 | bl _rtld_relocate_nonplt_self | |
55 | 55 | |||
56 | sub r1, sl, r5 /* relocbase */ | 56 | sub r1, sl, r5 /* relocbase */ | |
57 | mov r0, sp /* sp */ | 57 | mov r0, sp /* sp */ | |
58 | bl _rtld /* call the shared loader */ | 58 | bl _rtld /* call the shared loader */ | |
59 | mov r3, r0 /* save entry point */ | 59 | mov r3, r0 /* save entry point */ | |
60 | 60 | |||
61 | ldr r2, [sp, #0] /* r2 = cleanup */ | 61 | ldr r2, [sp], #4 /* pop r2 = cleanup */ | |
62 | ldr r1, [sp, #4] /* r1 = obj_main */ | 62 | ldr r1, [sp], #4 /* pop r1 = obj_main */ | |
63 | add sp, sp, #8 /* restore stack */ | |||
64 | mov r0, r4 /* restore ps_strings */ | 63 | mov r0, r4 /* restore ps_strings */ | |
65 | #ifdef _ARM_ARCH_4T | 64 | #ifdef _ARM_ARCH_4T | |
66 | bx r3 /* jump to the entry point */ | 65 | bx r3 /* jump to the entry point */ | |
67 | #else | 66 | #else | |
68 | mov pc, r3 /* jump to the entry point */ | 67 | mov pc, r3 /* jump to the entry point */ | |
69 | #endif | 68 | #endif | |
70 | .L2: | 69 | .L2: | |
71 | .word _GLOBAL_OFFSET_TABLE_ - (.L1+8) | 70 | .word _GLOBAL_OFFSET_TABLE_ - (.L1+8) | |
72 | .word _GLOBAL_OFFSET_TABLE_(GOT) | 71 | .word _GLOBAL_OFFSET_TABLE_(GOT) | |
73 | .word _DYNAMIC(GOT) | 72 | .word _DYNAMIC(GOT) | |
74 | 73 | |||
75 | .align 0 | 74 | .align 0 | |
76 | .globl _rtld_bind_start | 75 | .globl _rtld_bind_start | |
77 | .type _rtld_bind_start,%function | 76 | .type _rtld_bind_start,%function | |
78 | /* | 77 | /* | |
79 | * stack[0] = RA | 78 | * stack[0] = RA | |
80 | * ip = &GOT[n+3] | 79 | * ip = &GOT[n+3] | |
81 | * lr = &GOT[2] | 80 | * lr = &GOT[2] | |
82 | */ | 81 | */ | |
83 | _rtld_bind_start: | 82 | _rtld_bind_start: | |
84 | stmdb sp!,{r0-r4,sl,fp} | 83 | stmdb sp!,{r0-r4,sl,fp} /* 8 byte aligned (lr already saved) */ | |
85 | 84 | |||
86 | sub r1, ip, lr /* r1 = 4 * (n + 1) */ | 85 | sub r1, ip, lr /* r1 = 4 * (n + 1) */ | |
87 | sub r1, r1, #4 /* r1 = 4 * n */ | 86 | sub r1, r1, #4 /* r1 = 4 * n */ | |
88 | add r1, r1, r1 /* r1 = 8 * n */ | 87 | add r1, r1, r1 /* r1 = 8 * n */ | |
89 | 88 | |||
90 | ldr r0, [lr, #-4] /* get obj ptr from GOT[1] */ | 89 | ldr r0, [lr, #-4] /* get obj ptr from GOT[1] */ | |
91 | mov r4, ip /* save GOT location */ | 90 | mov r4, ip /* save GOT location */ | |
92 | 91 | |||
93 | bl _rtld_bind /* Call the binder */ | 92 | bl _rtld_bind /* Call the binder */ | |
94 | 93 | |||
95 | str r0, [r4] /* save address in GOT */ | 94 | str r0, [r4] /* save address in GOT */ | |
96 | mov ip, r0 /* save new address */ | 95 | mov ip, r0 /* save new address */ | |
97 | 96 |