Tue Jan 22 21:47:29 2013 UTC ()
Pullup from HEAD:
Add .init_array/.fini_array support (conditionalized on HAVE_INITFINI_ARRAY).


(matt)
diff -r1.110 -r1.110.6.1 src/libexec/ld.elf_so/Makefile
diff -r1.41.4.1 -r1.41.4.1.2.1 src/libexec/ld.elf_so/headers.c
diff -r1.155 -r1.155.4.1 src/libexec/ld.elf_so/rtld.c
diff -r1.107 -r1.107.4.1 src/libexec/ld.elf_so/rtld.h
diff -r1.59 -r1.59.4.1 src/libexec/ld.elf_so/symbol.c
diff -r1.11 -r1.11.46.1 src/libexec/ld.elf_so/arch/arm/Makefile.inc
diff -r1.10 -r1.10.10.1 src/libexec/ld.elf_so/arch/arm/rtld_start.S

cvs diff -r1.110 -r1.110.6.1 src/libexec/ld.elf_so/Makefile (expand / switch to unified diff)

--- 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
6WARNS?=4 6WARNS?=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
14PIE_CFLAGS= 14PIE_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
41LDFLAGS+= ${${ACTIVE_CC} == "clang":? -Wl,-Bsymbolic : -symbolic} \ 41LDFLAGS+= ${${ACTIVE_CC} == "clang":? -Wl,-Bsymbolic : -symbolic} \
42 -shared -nostartfiles -nodefaultlibs 42 -shared -nostartfiles -nodefaultlibs
43LDFLAGS+= -Wl,-static 43LDFLAGS+= -Wl,-static
44LDFLAGS+= -Wl,--warn-shared-textrel 44LDFLAGS+= -Wl,--warn-shared-textrel
45 45
46CFLAGS+= -fvisibility=hidden 46COPTS+= -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)
56PROG= ld.elf_so-${MLIBDIR} 56PROG= ld.elf_so-${MLIBDIR}
57CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\" 57CPPFLAGS+= -DRTLD_ARCH_SUBDIR=\"${MLIBDIR}\"
58.else 58.else
59PROG= ld.elf_so 59PROG= ld.elf_so
@@ -82,30 +82,30 @@ xprintf.c: errlist_concat.h @@ -82,30 +82,30 @@ xprintf.c: errlist_concat.h
82CLEANFILES+= errlist_concat.h 82CLEANFILES+= errlist_concat.h
83 83
84BINDIR= ${SHLINKINSTALLDIR} 84BINDIR= ${SHLINKINSTALLDIR}
85 85
86CPPFLAGS+= -DLIBDIR=\"${LIBDIR}\" -D_PATH_RTLD=\"${BINDIR}/${PROG}\" 86CPPFLAGS+= -DLIBDIR=\"${LIBDIR}\" -D_PATH_RTLD=\"${BINDIR}/${PROG}\"
87CPPFLAGS+= -I${.CURDIR} -I. 87CPPFLAGS+= -I${.CURDIR} -I.
88CPPFLAGS+= -DRTLD_LOADER 88CPPFLAGS+= -DRTLD_LOADER
89CPPFLAGS+= -D_RTLD_SOURCE 89CPPFLAGS+= -D_RTLD_SOURCE
90CPPFLAGS+= -DCOMBRELOC 90CPPFLAGS+= -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
95DBG= -O3 -fomit-frame-pointer 95COPTS= -O3 -fomit-frame-pointer
96 96
97.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64" 97.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64"
98DBG+= -mno-3dnow -mno-mmx -mno-sse -mno-sse2 -mno-sse3 98COPTS+= -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}
103CPPFLAGS+= -DRTLD_DEFAULT_LIBRARY_PATH=\"${SHLIBDIR}:${LIBDIR}\" 103CPPFLAGS+= -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.
107COPTS.rtld.c+= -Wno-stack-protector 107COPTS.rtld.c+= -Wno-stack-protector
108COPTS.symbol.c+=-Wno-stack-protector 108COPTS.symbol.c+=-Wno-stack-protector
109 109
110LDADD+= -L${CLIBOBJ} -L${DESTDIR}${LIBDIR} 110LDADD+= -L${CLIBOBJ} -L${DESTDIR}${LIBDIR}
111.if ${MKPICLIB} != "no" 111.if ${MKPICLIB} != "no"

cvs diff -r1.41.4.1 -r1.41.4.1.2.1 src/libexec/ld.elf_so/headers.c (expand / switch to unified diff)

--- 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

cvs diff -r1.155 -r1.155.4.1 src/libexec/ld.elf_so/rtld.c (expand / switch to unified diff)

--- 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;
124static void _rtld_call_fini_functions(sigset_t *, int); 124static void _rtld_call_fini_functions(sigset_t *, int);
125static void _rtld_call_init_functions(sigset_t *); 125static void _rtld_call_init_functions(sigset_t *);
126static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); 126static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int);
127static void _rtld_initlist_tsort(Objlist *, int); 127static void _rtld_initlist_tsort(Objlist *, int);
128static Obj_Entry *_rtld_dlcheck(void *); 128static Obj_Entry *_rtld_dlcheck(void *);
129static void _rtld_init_dag(Obj_Entry *); 129static void _rtld_init_dag(Obj_Entry *);
130static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); 130static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *);
131static void _rtld_objlist_remove(Objlist *, Obj_Entry *); 131static void _rtld_objlist_remove(Objlist *, Obj_Entry *);
132static void _rtld_objlist_clear(Objlist *); 132static void _rtld_objlist_clear(Objlist *);
133static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool); 133static void _rtld_unload_object(sigset_t *, Obj_Entry *, bool);
134static void _rtld_unref_dag(Obj_Entry *); 134static void _rtld_unref_dag(Obj_Entry *);
135static Obj_Entry *_rtld_obj_from_addr(const void *); 135static Obj_Entry *_rtld_obj_from_addr(const void *);
136 136
 137static 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
 145static 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
137static void 176static 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
148restart: 185restart:
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
208static void 229static 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
 261static 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
219restart: 270restart:
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

cvs diff -r1.107 -r1.107.4.1 src/libexec/ld.elf_so/rtld.h (expand / switch to unified diff)

--- 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
107typedef struct Struct_Ver_Entry { 107typedef 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
121typedef struct _rtld_library_xform_t { 120typedef 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
 143typedef void (*fptr_t)(void);
 144
144typedef struct Struct_Obj_Entry { 145typedef 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
282typedef struct Struct_DoneList { 289typedef 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
291extern struct r_debug _rtld_debug; 298extern struct r_debug _rtld_debug;
292extern Search_Path *_rtld_default_paths; 299extern Search_Path *_rtld_default_paths;

cvs diff -r1.59 -r1.59.4.1 src/libexec/ld.elf_so/symbol.c (expand / switch to unified diff)

--- 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
62typedef 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 */
68static bool 66static 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 /*

cvs diff -r1.11 -r1.11.46.1 src/libexec/ld.elf_so/arch/arm/Makefile.inc (expand / switch to unified diff)

--- 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
3SRCS+= rtld_start.S mdreloc.c 3SRCS+= rtld_start.S mdreloc.c
4 4
5# XXX Should not be in CPPFLAGS! 5# XXX Should not be in CPPFLAGS!
6CPPFLAGS+= -fpic 6CPPFLAGS+= -fpic
7 7
8CPPFLAGS+= -DELFSIZE=32 8CPPFLAGS+= -DELFSIZE=32
 9.if ${MACHINE_ARCH} == "earm" || ${MACHINE_ARCH} == "earmeb"
 10CPPFLAGS+= -DHAVE_INITFINI_ARRAY
 11.endif
9 12
10LDFLAGS+= -Wl,-e,_rtld_start 13LDFLAGS+= -Wl,-e,_rtld_start

cvs diff -r1.10 -r1.10.10.1 src/libexec/ld.elf_so/arch/arm/rtld_start.S (expand / switch to unified diff)

--- 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
34RCSID("$NetBSD: rtld_start.S,v 1.10 2009/11/11 14:15:41 skrll Exp $") 34RCSID("$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