Fri Dec 24 12:41:44 2010 UTC ()
Add support for DF_1_BIND_NOW, DF_1_NODELETE and DF_1_NOOPEN marked
objects, and the RTLD_NODELETE and RTLD_NOLOAD flags to dlopen(3).

Mark libpthread as DF_1_NOOPEN and use it to test the functionality.

Somewhat taken from FreeBSD.

Fixes PR 42029.

OK from christos and joerg.


(skrll)
diff -r1.187 -r1.188 src/distrib/sets/lists/tests/mi
diff -r1.21 -r1.22 src/include/dlfcn.h
diff -r1.70 -r1.71 src/lib/libpthread/Makefile
diff -r1.37 -r1.38 src/libexec/ld.elf_so/headers.c
diff -r1.41 -r1.42 src/libexec/ld.elf_so/load.c
diff -r1.102 -r1.103 src/libexec/ld.elf_so/reloc.c
diff -r1.136 -r1.137 src/libexec/ld.elf_so/rtld.c
diff -r1.96 -r1.97 src/libexec/ld.elf_so/rtld.h
diff -r1.22 -r1.23 src/libexec/ld.elf_so/search.c
diff -r1.27 -r1.28 src/share/man/man3/dlfcn.3
diff -r1.107 -r1.108 src/sys/sys/exec_elf.h
diff -r1.2 -r1.3 src/tests/libexec/ld.elf_so/Makefile
diff -r0 -r1.1 src/tests/libexec/ld.elf_so/h_df_1_noopen.c
diff -r0 -r1.1 src/tests/libexec/ld.elf_so/t_df_1_noopen.sh

cvs diff -r1.187 -r1.188 src/distrib/sets/lists/tests/mi (expand / switch to unified diff)

--- src/distrib/sets/lists/tests/mi 2010/12/23 15:27:44 1.187
+++ src/distrib/sets/lists/tests/mi 2010/12/24 12:41:42 1.188
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: mi,v 1.187 2010/12/23 15:27:44 pgoyette Exp $ 1# $NetBSD: mi,v 1.188 2010/12/24 12:41:42 skrll Exp $
2# 2#
3# Note: don't delete entries from here - mark them as "obsolete" instead. 3# Note: don't delete entries from here - mark them as "obsolete" instead.
4# 4#
5./etc/mtree/set.tests tests-sys-root 5./etc/mtree/set.tests tests-sys-root
6./usr/libdata/debug/usr/tests tests-base-debug 6./usr/libdata/debug/usr/tests tests-base-debug
7./usr/libdata/debug/usr/tests/atf tests-atf-debug 7./usr/libdata/debug/usr/tests/atf tests-atf-debug
8./usr/libdata/debug/usr/tests/atf/atf-c tests-atf-debug 8./usr/libdata/debug/usr/tests/atf/atf-c tests-atf-debug
9./usr/libdata/debug/usr/tests/atf/atf-c/atf_c_test.debug tests-atf-debug debug,atf 9./usr/libdata/debug/usr/tests/atf/atf-c/atf_c_test.debug tests-atf-debug debug,atf
10./usr/libdata/debug/usr/tests/atf/atf-c/build_test.debug tests-atf-debug debug,atf 10./usr/libdata/debug/usr/tests/atf/atf-c/build_test.debug tests-atf-debug debug,atf
11./usr/libdata/debug/usr/tests/atf/atf-c/check_test.debug tests-atf-debug debug,atf 11./usr/libdata/debug/usr/tests/atf/atf-c/check_test.debug tests-atf-debug debug,atf
12./usr/libdata/debug/usr/tests/atf/atf-c/config_test.debug tests-atf-debug debug,atf 12./usr/libdata/debug/usr/tests/atf/atf-c/config_test.debug tests-atf-debug debug,atf
13./usr/libdata/debug/usr/tests/atf/atf-c/detail tests-atf-debug 13./usr/libdata/debug/usr/tests/atf/atf-c/detail tests-atf-debug
14./usr/libdata/debug/usr/tests/atf/atf-c/detail/dynstr_test.debug tests-atf-debug debug,atf 14./usr/libdata/debug/usr/tests/atf/atf-c/detail/dynstr_test.debug tests-atf-debug debug,atf
@@ -377,26 +377,28 @@ @@ -377,26 +377,28 @@
377./usr/libdata/debug/usr/tests/lib/libpthread/t_siglongjmp.debug tests-lib-tests debug,atf 377./usr/libdata/debug/usr/tests/lib/libpthread/t_siglongjmp.debug tests-lib-tests debug,atf
378./usr/libdata/debug/usr/tests/lib/libpthread/t_sleep.debug tests-lib-tests debug,atf 378./usr/libdata/debug/usr/tests/lib/libpthread/t_sleep.debug tests-lib-tests debug,atf
379./usr/libdata/debug/usr/tests/lib/libpthread/t_status.debug tests-lib-tests debug,atf 379./usr/libdata/debug/usr/tests/lib/libpthread/t_status.debug tests-lib-tests debug,atf
380./usr/libdata/debug/usr/tests/lib/librt tests-lib-debug 380./usr/libdata/debug/usr/tests/lib/librt tests-lib-debug
381./usr/libdata/debug/usr/tests/lib/librt/t_sem.debug tests-lib-debug debug,atf 381./usr/libdata/debug/usr/tests/lib/librt/t_sem.debug tests-lib-debug debug,atf
382./usr/libdata/debug/usr/tests/lib/libskey tests-lib-debug 382./usr/libdata/debug/usr/tests/lib/libskey tests-lib-debug
383./usr/libdata/debug/usr/tests/lib/libskey/t_algorithms.debug tests-lib-debug debug,atf,skey 383./usr/libdata/debug/usr/tests/lib/libskey/t_algorithms.debug tests-lib-debug debug,atf,skey
384./usr/libdata/debug/usr/tests/lib/libutil tests-lib-debug 384./usr/libdata/debug/usr/tests/lib/libutil tests-lib-debug
385./usr/libdata/debug/usr/tests/lib/libutil/t_parsedate.debug tests-lib-debug debug,atf 385./usr/libdata/debug/usr/tests/lib/libutil/t_parsedate.debug tests-lib-debug debug,atf
386./usr/libdata/debug/usr/tests/lib/libutil/t_snprintb.debug tests-lib-debug debug,atf 386./usr/libdata/debug/usr/tests/lib/libutil/t_snprintb.debug tests-lib-debug debug,atf
387./usr/libdata/debug/usr/tests/lib/libutil/t_sockaddr_snprintf.debug tests-lib-debug debug,atf 387./usr/libdata/debug/usr/tests/lib/libutil/t_sockaddr_snprintf.debug tests-lib-debug debug,atf
388./usr/libdata/debug/usr/tests/libexec tests-lib-debug 388./usr/libdata/debug/usr/tests/libexec tests-lib-debug
389./usr/libdata/debug/usr/tests/libexec/ld.elf_so tests-libexec-debug 389./usr/libdata/debug/usr/tests/libexec/ld.elf_so tests-libexec-debug
 390./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen1.debug tests-libexec-debug debug,atf
 391./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen2.debug tests-libexec-debug debug,atf
390./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-cleared.debug tests-libexec-debug debug,atf 392./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-cleared.debug tests-libexec-debug debug,atf
391./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-false.debug tests-libexec-debug debug,atf 393./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-false.debug tests-libexec-debug debug,atf
392./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlinfo.debug tests-libexec-debug debug,atf 394./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlinfo.debug tests-libexec-debug debug,atf
393./usr/libdata/debug/usr/tests/modules tests-sys-debug 395./usr/libdata/debug/usr/tests/modules tests-sys-debug
394./usr/libdata/debug/usr/tests/modules/t_builtin.debug tests-sys-debug debug,atf 396./usr/libdata/debug/usr/tests/modules/t_builtin.debug tests-sys-debug debug,atf
395./usr/libdata/debug/usr/tests/modules/t_modctl.debug tests-sys-debug debug,atf 397./usr/libdata/debug/usr/tests/modules/t_modctl.debug tests-sys-debug debug,atf
396./usr/libdata/debug/usr/tests/net tests-net-debug 398./usr/libdata/debug/usr/tests/net tests-net-debug
397./usr/libdata/debug/usr/tests/net/bpf tests-net-debug 399./usr/libdata/debug/usr/tests/net/bpf tests-net-debug
398./usr/libdata/debug/usr/tests/net/bpf/t_bpf.debug tests-net-debug debug,atf 400./usr/libdata/debug/usr/tests/net/bpf/t_bpf.debug tests-net-debug debug,atf
399./usr/libdata/debug/usr/tests/net/bpf/t_div-by-zero.debug tests-net-debug debug,atf 401./usr/libdata/debug/usr/tests/net/bpf/t_div-by-zero.debug tests-net-debug debug,atf
400./usr/libdata/debug/usr/tests/net/carp tests-net-debug 402./usr/libdata/debug/usr/tests/net/carp tests-net-debug
401./usr/libdata/debug/usr/tests/net/carp/t_basic.debug tests-net-debug debug,atf 403./usr/libdata/debug/usr/tests/net/carp/t_basic.debug tests-net-debug debug,atf
402./usr/libdata/debug/usr/tests/net/icmp tests-net-debug 404./usr/libdata/debug/usr/tests/net/icmp tests-net-debug
@@ -1622,26 +1624,29 @@ @@ -1622,26 +1624,29 @@
1622./usr/tests/lib/librt/t_sem tests-lib-tests atf 1624./usr/tests/lib/librt/t_sem tests-lib-tests atf
1623./usr/tests/lib/libskey tests-lib-tests atf 1625./usr/tests/lib/libskey tests-lib-tests atf
1624./usr/tests/lib/libskey/Atffile tests-lib-tests atf,skey 1626./usr/tests/lib/libskey/Atffile tests-lib-tests atf,skey
1625./usr/tests/lib/libskey/t_algorithms tests-lib-tests atf,skey 1627./usr/tests/lib/libskey/t_algorithms tests-lib-tests atf,skey
1626./usr/tests/lib/libutil tests-lib-tests atf 1628./usr/tests/lib/libutil tests-lib-tests atf
1627./usr/tests/lib/libutil/Atffile tests-lib-tests atf 1629./usr/tests/lib/libutil/Atffile tests-lib-tests atf
1628./usr/tests/lib/libutil/t_parsedate tests-lib-tests atf 1630./usr/tests/lib/libutil/t_parsedate tests-lib-tests atf
1629./usr/tests/lib/libutil/t_snprintb tests-lib-tests atf 1631./usr/tests/lib/libutil/t_snprintb tests-lib-tests atf
1630./usr/tests/lib/libutil/t_sockaddr_snprintf tests-lib-tests atf 1632./usr/tests/lib/libutil/t_sockaddr_snprintf tests-lib-tests atf
1631./usr/tests/libexec tests-lib-tests 1633./usr/tests/libexec tests-lib-tests
1632./usr/tests/libexec/Atffile tests-lib-tests atf 1634./usr/tests/libexec/Atffile tests-lib-tests atf
1633./usr/tests/libexec/ld.elf_so tests-libexec-tests 1635./usr/tests/libexec/ld.elf_so tests-libexec-tests
1634./usr/tests/libexec/ld.elf_so/Atffile tests-libexec-tests atf 1636./usr/tests/libexec/ld.elf_so/Atffile tests-libexec-tests atf
 1637./usr/tests/libexec/ld.elf_so/h_df_1_noopen1 tests-libexec-tests atf
 1638./usr/tests/libexec/ld.elf_so/h_df_1_noopen2 tests-libexec-tests atf
 1639./usr/tests/libexec/ld.elf_so/t_df_1_noopen tests-libexec-tests atf
1635./usr/tests/libexec/ld.elf_so/t_dlerror-cleared tests-libexec-tests atf 1640./usr/tests/libexec/ld.elf_so/t_dlerror-cleared tests-libexec-tests atf
1636./usr/tests/libexec/ld.elf_so/t_dlerror-false tests-libexec-tests atf 1641./usr/tests/libexec/ld.elf_so/t_dlerror-false tests-libexec-tests atf
1637./usr/tests/libexec/ld.elf_so/t_dlinfo tests-libexec-tests atf 1642./usr/tests/libexec/ld.elf_so/t_dlinfo tests-libexec-tests atf
1638./usr/tests/modules tests-sys-tests 1643./usr/tests/modules tests-sys-tests
1639./usr/tests/net tests-net-tests 1644./usr/tests/net tests-net-tests
1640./usr/tests/net/Atffile tests-net-tests atf 1645./usr/tests/net/Atffile tests-net-tests atf
1641./usr/tests/net/bpf tests-net-tests 1646./usr/tests/net/bpf tests-net-tests
1642./usr/tests/net/bpf/Atffile tests-net-tests atf 1647./usr/tests/net/bpf/Atffile tests-net-tests atf
1643./usr/tests/net/bpf/t_bpf tests-net-tests atf 1648./usr/tests/net/bpf/t_bpf tests-net-tests atf
1644./usr/tests/net/bpf/t_div-by-zero tests-net-tests atf 1649./usr/tests/net/bpf/t_div-by-zero tests-net-tests atf
1645./usr/tests/net/carp tests-net-tests 1650./usr/tests/net/carp tests-net-tests
1646./usr/tests/net/carp/Atffile tests-net-tests atf 1651./usr/tests/net/carp/Atffile tests-net-tests atf
1647./usr/tests/net/carp/t_basic tests-net-tests atf 1652./usr/tests/net/carp/t_basic tests-net-tests atf

cvs diff -r1.21 -r1.22 src/include/dlfcn.h (expand / switch to unified diff)

--- src/include/dlfcn.h 2010/01/07 07:35:35 1.21
+++ src/include/dlfcn.h 2010/12/24 12:41:42 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dlfcn.h,v 1.21 2010/01/07 07:35:35 skrll Exp $ */ 1/* $NetBSD: dlfcn.h,v 1.22 2010/12/24 12:41:42 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 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 Paul Kranenburg. 8 * by Paul Kranenburg.
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.
@@ -54,26 +54,28 @@ void *dlsym(void * __restrict, const cha @@ -54,26 +54,28 @@ void *dlsym(void * __restrict, const cha
54#if defined(_NETBSD_SOURCE) 54#if defined(_NETBSD_SOURCE)
55int dladdr(const void * __restrict, Dl_info * __restrict); 55int dladdr(const void * __restrict, Dl_info * __restrict);
56int dlctl(void *, int, void *); 56int dlctl(void *, int, void *);
57int dlinfo(void *, int, void *); 57int dlinfo(void *, int, void *);
58#endif 58#endif
59__aconst char *dlerror(void); 59__aconst char *dlerror(void);
60__END_DECLS 60__END_DECLS
61 61
62/* Values for dlopen `mode'. */ 62/* Values for dlopen `mode'. */
63#define RTLD_LAZY 1 63#define RTLD_LAZY 1
64#define RTLD_NOW 2 64#define RTLD_NOW 2
65#define RTLD_GLOBAL 0x100 /* Allow global searches in object */ 65#define RTLD_GLOBAL 0x100 /* Allow global searches in object */
66#define RTLD_LOCAL 0x200 66#define RTLD_LOCAL 0x200
 67#define RTLD_NODELETE 0x01000 /* Do not remove members. */
 68#define RTLD_NOLOAD 0x02000 /* Do not load if not already loaded. */
67#if defined(_NETBSD_SOURCE) 69#if defined(_NETBSD_SOURCE)
68#define DL_LAZY RTLD_LAZY /* Compat */ 70#define DL_LAZY RTLD_LAZY /* Compat */
69#endif 71#endif
70 72
71/*  73/*
72 * Special handle arguments for dlsym(). 74 * Special handle arguments for dlsym().
73 */  75 */
74#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ 76#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
75#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ 77#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
76#define RTLD_SELF ((void *) -3) /* Search the caller itself. */ 78#define RTLD_SELF ((void *) -3) /* Search the caller itself. */
77 79
78/* 80/*
79 * dlctl() commands 81 * dlctl() commands

cvs diff -r1.70 -r1.71 src/lib/libpthread/Makefile (expand / switch to unified diff)

--- src/lib/libpthread/Makefile 2010/08/06 05:35:42 1.70
+++ src/lib/libpthread/Makefile 2010/12/24 12:41:42 1.71
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: Makefile,v 1.70 2010/08/06 05:35:42 christos Exp $ 1# $NetBSD: Makefile,v 1.71 2010/12/24 12:41:42 skrll Exp $
2# 2#
3 3
4WARNS= 4 4WARNS= 4
5 5
6.include <bsd.own.mk> 6.include <bsd.own.mk>
7 7
8.if defined(PTHREAD_MACHINE_ARCH) && !empty(PTHREAD_MACHINE_ARCH) && \ 8.if defined(PTHREAD_MACHINE_ARCH) && !empty(PTHREAD_MACHINE_ARCH) && \
9 exists(${.CURDIR}/arch/${PTHREAD_MACHINE_ARCH}) 9 exists(${.CURDIR}/arch/${PTHREAD_MACHINE_ARCH})
10ARCHSUBDIR= ${PTHREAD_MACHINE_ARCH} 10ARCHSUBDIR= ${PTHREAD_MACHINE_ARCH}
11.elif exists(${.CURDIR}/arch/${MACHINE_ARCH}) 11.elif exists(${.CURDIR}/arch/${MACHINE_ARCH})
12ARCHSUBDIR= ${MACHINE_ARCH} 12ARCHSUBDIR= ${MACHINE_ARCH}
13.elif exists(${.CURDIR}/arch/${MACHINE_CPU})  13.elif exists(${.CURDIR}/arch/${MACHINE_CPU})
14ARCHSUBDIR= ${MACHINE_CPU} 14ARCHSUBDIR= ${MACHINE_CPU}
@@ -23,26 +23,28 @@ INCSDIR=/usr/include @@ -23,26 +23,28 @@ INCSDIR=/usr/include
23.if defined(ARCHSUBDIR) 23.if defined(ARCHSUBDIR)
24 24
25ARCHDIR= ${.CURDIR}/arch/${ARCHSUBDIR} 25ARCHDIR= ${.CURDIR}/arch/${ARCHSUBDIR}
26.PATH: ${ARCHDIR} 26.PATH: ${ARCHDIR}
27 27
28CPPFLAGS+= -I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC 28CPPFLAGS+= -I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC
29CPPFLAGS+= -D__LIBPTHREAD_SOURCE__ 29CPPFLAGS+= -D__LIBPTHREAD_SOURCE__
30 30
31# XXX: This crappy poke at libc's internals needs to be fixed. 31# XXX: This crappy poke at libc's internals needs to be fixed.
32CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc 32CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc
33 33
34LIB= pthread 34LIB= pthread
35 35
 36LDFLAGS+= -Wl,-znodlopen
 37
36# 38#
37# NOTE: When you create a new file for libpthread, make sure that pthread.c 39# NOTE: When you create a new file for libpthread, make sure that pthread.c
38# gets a reference to a symbol in that file. Otherwise, Unix's stupid static 40# gets a reference to a symbol in that file. Otherwise, Unix's stupid static
39# library semantics will end up discarding potentially important objects. 41# library semantics will end up discarding potentially important objects.
40# 42#
41SRCS= pthread.c  43SRCS= pthread.c
42SRCS+= pthread_attr.c 44SRCS+= pthread_attr.c
43SRCS+= pthread_barrier.c 45SRCS+= pthread_barrier.c
44SRCS+= pthread_cancelstub.c 46SRCS+= pthread_cancelstub.c
45SRCS+= pthread_cond.c 47SRCS+= pthread_cond.c
46SRCS+= pthread_lock.c  48SRCS+= pthread_lock.c
47SRCS+= pthread_misc.c 49SRCS+= pthread_misc.c
48SRCS+= pthread_mutex.c 50SRCS+= pthread_mutex.c

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

--- src/libexec/ld.elf_so/headers.c 2010/10/16 17:48:12 1.37
+++ src/libexec/ld.elf_so/headers.c 2010/12/24 12:41:43 1.38
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: headers.c,v 1.37 2010/10/16 17:48:12 skrll Exp $ */ 1/* $NetBSD: headers.c,v 1.38 2010/12/24 12:41:43 skrll 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.37 2010/10/16 17:48:12 skrll Exp $"); 43__RCSID("$NetBSD: headers.c,v 1.38 2010/12/24 12:41:43 skrll 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>
@@ -232,28 +232,34 @@ _rtld_digest_dynamic(const char *execnam @@ -232,28 +232,34 @@ _rtld_digest_dynamic(const char *execnam
232 232
233 case DT_MIPS_GOTSYM: 233 case DT_MIPS_GOTSYM:
234 obj->gotsym = dynp->d_un.d_val; 234 obj->gotsym = dynp->d_un.d_val;
235 break; 235 break;
236 236
237 case DT_MIPS_RLD_MAP: 237 case DT_MIPS_RLD_MAP:
238#ifdef RTLD_LOADER 238#ifdef RTLD_LOADER
239 *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) 239 *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr)
240 &_rtld_debug; 240 &_rtld_debug;
241#endif 241#endif
242 break; 242 break;
243#endif 243#endif
244 case DT_FLAGS_1: 244 case DT_FLAGS_1:
245 obj->initfirst = 245 obj->z_now =
 246 ((dynp->d_un.d_val & DF_1_BIND_NOW) != 0);
 247 obj->z_nodelete =
 248 ((dynp->d_un.d_val & DF_1_NODELETE) != 0);
 249 obj->z_initfirst =
246 ((dynp->d_un.d_val & DF_1_INITFIRST) != 0); 250 ((dynp->d_un.d_val & DF_1_INITFIRST) != 0);
 251 obj->z_noopen =
 252 ((dynp->d_un.d_val & DF_1_NOOPEN) != 0);
247 break; 253 break;
248 } 254 }
249 } 255 }
250 256
251 obj->rellim = (const Elf_Rel *)((const uint8_t *)obj->rel + relsz); 257 obj->rellim = (const Elf_Rel *)((const uint8_t *)obj->rel + relsz);
252 obj->relalim = (const Elf_Rela *)((const uint8_t *)obj->rela + relasz); 258 obj->relalim = (const Elf_Rela *)((const uint8_t *)obj->rela + relasz);
253 if (use_pltrel) { 259 if (use_pltrel) {
254 obj->pltrel = (const Elf_Rel *)(obj->relocbase + pltrel); 260 obj->pltrel = (const Elf_Rel *)(obj->relocbase + pltrel);
255 obj->pltrellim = (const Elf_Rel *)(obj->relocbase + pltrel + pltrelsz); 261 obj->pltrellim = (const Elf_Rel *)(obj->relocbase + pltrel + pltrelsz);
256 obj->pltrelalim = 0; 262 obj->pltrelalim = 0;
257 /* On PPC and SPARC, at least, REL(A)SZ may include JMPREL. 263 /* On PPC and SPARC, at least, REL(A)SZ may include JMPREL.
258 Trim rel(a)lim to save time later. */ 264 Trim rel(a)lim to save time later. */
259 if (obj->rellim && obj->pltrel && 265 if (obj->rellim && obj->pltrel &&

cvs diff -r1.41 -r1.42 src/libexec/ld.elf_so/load.c (expand / switch to unified diff)

--- src/libexec/ld.elf_so/load.c 2010/12/19 17:26:51 1.41
+++ src/libexec/ld.elf_so/load.c 2010/12/24 12:41:43 1.42
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: load.c,v 1.41 2010/12/19 17:26:51 skrll Exp $ */ 1/* $NetBSD: load.c,v 1.42 2010/12/24 12:41:43 skrll 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: load.c,v 1.41 2010/12/19 17:26:51 skrll Exp $"); 43__RCSID("$NetBSD: load.c,v 1.42 2010/12/24 12:41:43 skrll 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/param.h> 55#include <sys/param.h>
56#include <sys/mman.h> 56#include <sys/mman.h>
@@ -99,27 +99,27 @@ _rtld_objlist_find(Objlist *list, const  @@ -99,27 +99,27 @@ _rtld_objlist_find(Objlist *list, const
99 return elm; 99 return elm;
100 } 100 }
101 return NULL; 101 return NULL;
102} 102}
103#endif 103#endif
104 104
105/* 105/*
106 * Load a shared object into memory, if it is not already loaded. 106 * Load a shared object into memory, if it is not already loaded.
107 * 107 *
108 * Returns a pointer to the Obj_Entry for the object. Returns NULL 108 * Returns a pointer to the Obj_Entry for the object. Returns NULL
109 * on failure. 109 * on failure.
110 */ 110 */
111Obj_Entry * 111Obj_Entry *
112_rtld_load_object(const char *filepath, int mode) 112_rtld_load_object(const char *filepath, int flags)
113{ 113{
114 Obj_Entry *obj; 114 Obj_Entry *obj;
115 int fd = -1; 115 int fd = -1;
116 struct stat sb; 116 struct stat sb;
117 size_t pathlen = strlen(filepath); 117 size_t pathlen = strlen(filepath);
118 118
119 for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next) 119 for (obj = _rtld_objlist->next; obj != NULL; obj = obj->next)
120 if (pathlen == obj->pathlen && !strcmp(obj->path, filepath))  120 if (pathlen == obj->pathlen && !strcmp(obj->path, filepath))
121 break; 121 break;
122 122
123 /* 123 /*
124 * If we didn't find a match by pathname, open the file and check 124 * If we didn't find a match by pathname, open the file and check
125 * again by device and inode. This avoids false mismatches caused 125 * again by device and inode. This avoids false mismatches caused
@@ -143,57 +143,70 @@ _rtld_load_object(const char *filepath,  @@ -143,57 +143,70 @@ _rtld_load_object(const char *filepath,
143 close(fd); 143 close(fd);
144 break; 144 break;
145 } 145 }
146 } 146 }
147 } 147 }
148 148
149 if (obj == NULL) { /* First use of this object, so we must map it in */ 149 if (obj == NULL) { /* First use of this object, so we must map it in */
150 obj = _rtld_map_object(filepath, fd, &sb); 150 obj = _rtld_map_object(filepath, fd, &sb);
151 (void)close(fd); 151 (void)close(fd);
152 if (obj == NULL) 152 if (obj == NULL)
153 return NULL; 153 return NULL;
154 _rtld_digest_dynamic(filepath, obj); 154 _rtld_digest_dynamic(filepath, obj);
155 155
 156 if (flags & _RTLD_DLOPEN) {
 157 if (obj->z_noopen || (flags & _RTLD_NOLOAD)) {
 158 dbg(("refusing to load non-loadable \"%s\"",
 159 obj->path));
 160 _rtld_error("Cannot dlopen non-loadable %s",
 161 obj->path);
 162 munmap(obj->mapbase, obj->mapsize);
 163 _rtld_obj_free(obj);
 164 return OBJ_ERR;
 165 }
 166 }
 167
156 *_rtld_objtail = obj; 168 *_rtld_objtail = obj;
157 _rtld_objtail = &obj->next; 169 _rtld_objtail = &obj->next;
158 _rtld_objcount++; 170 _rtld_objcount++;
159 _rtld_objloads++; 171 _rtld_objloads++;
160#ifdef RTLD_LOADER 172#ifdef RTLD_LOADER
161 _rtld_linkmap_add(obj); /* for GDB */ 173 _rtld_linkmap_add(obj); /* for GDB */
162#endif 174#endif
163 dbg((" %p .. %p: %s", obj->mapbase, 175 dbg((" %p .. %p: %s", obj->mapbase,
164 obj->mapbase + obj->mapsize - 1, obj->path)); 176 obj->mapbase + obj->mapsize - 1, obj->path));
165 if (obj->textrel) 177 if (obj->textrel)
166 dbg((" WARNING: %s has impure text", obj->path)); 178 dbg((" WARNING: %s has impure text", obj->path));
167 } 179 }
168 180
169 ++obj->refcount; 181 ++obj->refcount;
170#ifdef RTLD_LOADER 182#ifdef RTLD_LOADER
171 if (mode & RTLD_MAIN && !obj->mainref) { 183 if (flags & _RTLD_MAIN && !obj->mainref) {
172 obj->mainref = 1; 184 obj->mainref = 1;
173 dbg(("adding %p (%s) to _rtld_list_main", obj, obj->path)); 185 dbg(("adding %p (%s) to _rtld_list_main", obj, obj->path));
174 _rtld_objlist_push_tail(&_rtld_list_main, obj); 186 _rtld_objlist_push_tail(&_rtld_list_main, obj);
175 } 187 }
176 if (mode & RTLD_GLOBAL && !obj->globalref) { 188 if (flags & _RTLD_GLOBAL && !obj->globalref) {
177 obj->globalref = 1; 189 obj->globalref = 1;
178 dbg(("adding %p (%s) to _rtld_list_global", obj, obj->path)); 190 dbg(("adding %p (%s) to _rtld_list_global", obj, obj->path));
179 _rtld_objlist_push_tail(&_rtld_list_global, obj); 191 _rtld_objlist_push_tail(&_rtld_list_global, obj);
180 } 192 }
181#endif 193#endif
182 return obj; 194 return obj;
183} 195}
184 196
185static bool 197static bool
186_rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, int mode) 198_rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed,
 199 int flags)
187{ 200{
188 Library_Xform *x = _rtld_xforms; 201 Library_Xform *x = _rtld_xforms;
189 Obj_Entry *o = NULL; 202 Obj_Entry *o = NULL;
190 size_t j; 203 size_t j;
191 ssize_t i; 204 ssize_t i;
192 bool got = false; 205 bool got = false;
193 union { 206 union {
194 int i; 207 int i;
195 u_quad_t q; 208 u_quad_t q;
196 char s[16]; 209 char s[16];
197 } val; 210 } val;
198 211
199 dbg(("load by name %s %p", name, x)); 212 dbg(("load by name %s %p", name, x));
@@ -230,94 +243,108 @@ _rtld_load_by_name(const char *name, Obj @@ -230,94 +243,108 @@ _rtld_load_by_name(const char *name, Obj
230 if (strcmp(x->entry[i].value, val.s) == 0) 243 if (strcmp(x->entry[i].value, val.s) == 0)
231 break; 244 break;
232 } 245 }
233 246
234 if (i == RTLD_MAX_ENTRY) { 247 if (i == RTLD_MAX_ENTRY) {
235 xwarnx("sysctl value %s not found for lib%s", 248 xwarnx("sysctl value %s not found for lib%s",
236 val.s, name); 249 val.s, name);
237 break; 250 break;
238 } 251 }
239 252
240 for (j = 0; j < RTLD_MAX_LIBRARY && 253 for (j = 0; j < RTLD_MAX_LIBRARY &&
241 x->entry[i].library[j] != NULL; j++) { 254 x->entry[i].library[j] != NULL; j++) {
242 o = _rtld_load_library(x->entry[i].library[j], obj, 255 o = _rtld_load_library(x->entry[i].library[j], obj,
243 mode); 256 flags);
244 if (o == NULL) { 257 if (o == NULL) {
245 xwarnx("could not load %s for %s", 258 xwarnx("could not load %s for %s",
246 x->entry[i].library[j], name); 259 x->entry[i].library[j], name);
247 continue; 260 continue;
248 } 261 }
249 got = true; 262 got = true;
250 if (j == 0) 263 if (j == 0)
251 (*needed)->obj = o; 264 (*needed)->obj = o;
252 else { 265 else {
253 /* make a new one and put it in the chain */ 266 /* make a new one and put it in the chain */
254 Needed_Entry *ne = xmalloc(sizeof(*ne)); 267 Needed_Entry *ne = xmalloc(sizeof(*ne));
255 ne->name = (*needed)->name; 268 ne->name = (*needed)->name;
256 ne->obj = o; 269 ne->obj = o;
257 ne->next = (*needed)->next; 270 ne->next = (*needed)->next;
258 (*needed)->next = ne; 271 (*needed)->next = ne;
259 *needed = ne; 272 *needed = ne;
260 } 273 }
261  274
262 } 275 }
263  276
264 } 277 }
265 278
266 if (got) 279 if (got)
267 return true; 280 return true;
268 281
269 return ((*needed)->obj = _rtld_load_library(name, obj, mode)) != NULL; 282 return ((*needed)->obj = _rtld_load_library(name, obj, flags)) != NULL;
270} 283}
271 284
272 285
273/* 286/*
274 * Given a shared object, traverse its list of needed objects, and load 287 * Given a shared object, traverse its list of needed objects, and load
275 * each of them. Returns 0 on success. Generates an error message and 288 * each of them. Returns 0 on success. Generates an error message and
276 * returns -1 on failure. 289 * returns -1 on failure.
277 */ 290 */
278int 291int
279_rtld_load_needed_objects(Obj_Entry *first, int mode) 292_rtld_load_needed_objects(Obj_Entry *first, int flags)
280{ 293{
281 Obj_Entry *obj; 294 Obj_Entry *obj;
282 int status = 0; 295 int status = 0;
283 296
284 for (obj = first; obj != NULL; obj = obj->next) { 297 for (obj = first; obj != NULL; obj = obj->next) {
285 Needed_Entry *needed; 298 Needed_Entry *needed;
286 299
287 for (needed = obj->needed; needed != NULL; 300 for (needed = obj->needed; needed != NULL;
288 needed = needed->next) { 301 needed = needed->next) {
289 const char *name = obj->strtab + needed->name; 302 const char *name = obj->strtab + needed->name;
290 if (!_rtld_load_by_name(name, obj, &needed, mode)) 303#ifdef RTLD_LOADER
 304 Obj_Entry *nobj;
 305#endif
 306 if (!_rtld_load_by_name(name, obj, &needed,
 307 flags & ~_RTLD_NOLOAD))
291 status = -1; /* FIXME - cleanup */ 308 status = -1; /* FIXME - cleanup */
292#ifdef RTLD_LOADER 309#ifdef RTLD_LOADER
293 if (status == -1) 310 if (status == -1)
294 return status; 311 return status;
 312
 313 if (flags & _RTLD_MAIN)
 314 continue;
 315
 316 nobj = needed->obj;
 317 if (nobj->z_nodelete && !obj->ref_nodel) {
 318 dbg(("obj %s nodelete", nobj->path));
 319 _rtld_ref_dag(nobj);
 320 nobj->ref_nodel = true;
 321 }
295#endif 322#endif
296 } 323 }
297 } 324 }
298 325
299 return status; 326 return status;
300} 327}
301 328
302#ifdef RTLD_LOADER 329#ifdef RTLD_LOADER
303int 330int
304_rtld_preload(const char *preload_path) 331_rtld_preload(const char *preload_path)
305{ 332{
306 const char *path; 333 const char *path;
307 char *cp, *buf; 334 char *cp, *buf;
308 int status = 0; 335 int status = 0;
309 336
310 if (preload_path != NULL && *preload_path != '\0') { 337 if (preload_path != NULL && *preload_path != '\0') {
311 cp = buf = xstrdup(preload_path); 338 cp = buf = xstrdup(preload_path);
312 while ((path = strsep(&cp, " :")) != NULL && status == 0) { 339 while ((path = strsep(&cp, " :")) != NULL && status == 0) {
313 if (!_rtld_load_object(path, RTLD_MAIN)) 340 if (!_rtld_load_object(path, _RTLD_MAIN))
314 status = -1; 341 status = -1;
315 else 342 else
316 dbg((" preloaded \"%s\"", path)); 343 dbg((" preloaded \"%s\"", path));
317 } 344 }
318 xfree(buf); 345 xfree(buf);
319 } 346 }
320 347
321 return status; 348 return status;
322} 349}
323#endif 350#endif

cvs diff -r1.102 -r1.103 src/libexec/ld.elf_so/reloc.c (expand / switch to unified diff)

--- src/libexec/ld.elf_so/reloc.c 2010/04/05 14:01:26 1.102
+++ src/libexec/ld.elf_so/reloc.c 2010/12/24 12:41:43 1.103
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $ */ 1/* $NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll 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
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34/* 34/*
35 * Dynamic linker for ELF. 35 * Dynamic linker for ELF.
36 * 36 *
37 * John Polstra <jdp@polstra.com>. 37 * John Polstra <jdp@polstra.com>.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41#ifndef lint 41#ifndef lint
42__RCSID("$NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $"); 42__RCSID("$NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll Exp $");
43#endif /* not lint */ 43#endif /* not lint */
44 44
45#include <err.h> 45#include <err.h>
46#include <errno.h> 46#include <errno.h>
47#include <fcntl.h> 47#include <fcntl.h>
48#include <stdarg.h> 48#include <stdarg.h>
49#include <stdio.h> 49#include <stdio.h>
50#include <stdlib.h> 50#include <stdlib.h>
51#include <string.h> 51#include <string.h>
52#include <unistd.h> 52#include <unistd.h>
53#include <sys/types.h> 53#include <sys/types.h>
54#include <sys/mman.h> 54#include <sys/mman.h>
55#include <sys/bitops.h> 55#include <sys/bitops.h>
@@ -185,27 +185,27 @@ _rtld_relocate_objects(Obj_Entry *first, @@ -185,27 +185,27 @@ _rtld_relocate_objects(Obj_Entry *first,
185 if (mprotect(obj->mapbase, obj->textsize, 185 if (mprotect(obj->mapbase, obj->textsize,
186 PROT_READ | PROT_EXEC) == -1) { 186 PROT_READ | PROT_EXEC) == -1) {
187 _rtld_error("%s: Cannot write-protect text " 187 _rtld_error("%s: Cannot write-protect text "
188 "segment: %s", obj->path, xstrerror(errno)); 188 "segment: %s", obj->path, xstrerror(errno));
189 return -1; 189 return -1;
190 } 190 }
191 } 191 }
192 dbg(("doing lazy PLT binding")); 192 dbg(("doing lazy PLT binding"));
193 if (_rtld_relocate_plt_lazy(obj) < 0) 193 if (_rtld_relocate_plt_lazy(obj) < 0)
194 ok = 0; 194 ok = 0;
195#if defined(__hppa__) 195#if defined(__hppa__)
196 bind_now = 1; 196 bind_now = 1;
197#endif 197#endif
198 if (bind_now) { 198 if (obj->z_now || bind_now) {
199 dbg(("doing immediate PLT binding")); 199 dbg(("doing immediate PLT binding"));
200 if (_rtld_relocate_plt_objects(obj) < 0) 200 if (_rtld_relocate_plt_objects(obj) < 0)
201 ok = 0; 201 ok = 0;
202 } 202 }
203 if (!ok) 203 if (!ok)
204 return -1; 204 return -1;
205 205
206 /* Set some sanity-checking numbers in the Obj_Entry. */ 206 /* Set some sanity-checking numbers in the Obj_Entry. */
207 obj->magic = RTLD_MAGIC; 207 obj->magic = RTLD_MAGIC;
208 obj->version = RTLD_VERSION; 208 obj->version = RTLD_VERSION;
209 209
210 /* Fill in the dynamic linker entry points. */ 210 /* Fill in the dynamic linker entry points. */
211 obj->dlopen = dlopen; 211 obj->dlopen = dlopen;

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

--- src/libexec/ld.elf_so/rtld.c 2010/12/19 17:26:51 1.136
+++ src/libexec/ld.elf_so/rtld.c 2010/12/24 12:41:43 1.137
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtld.c,v 1.136 2010/12/19 17:26:51 skrll Exp $ */ 1/* $NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll 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.136 2010/12/19 17:26:51 skrll Exp $"); 43__RCSID("$NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll 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/param.h> 54#include <sys/param.h>
55#include <sys/mman.h> 55#include <sys/mman.h>
56#include <dirent.h> 56#include <dirent.h>
@@ -137,27 +137,27 @@ _rtld_call_fini_functions(int force) @@ -137,27 +137,27 @@ _rtld_call_fini_functions(int force)
137 Obj_Entry *obj; 137 Obj_Entry *obj;
138 138
139 dbg(("_rtld_call_fini_functions(%d)", force)); 139 dbg(("_rtld_call_fini_functions(%d)", force));
140 140
141 SIMPLEQ_INIT(&finilist); 141 SIMPLEQ_INIT(&finilist);
142 _rtld_initlist_tsort(&finilist, 1); 142 _rtld_initlist_tsort(&finilist, 1);
143 143
144 /* First pass: objects _not_ marked with DF_1_INITFIRST. */ 144 /* First pass: objects _not_ marked with DF_1_INITFIRST. */
145 SIMPLEQ_FOREACH(elm, &finilist, link) { 145 SIMPLEQ_FOREACH(elm, &finilist, link) {
146 obj = elm->obj; 146 obj = elm->obj;
147 if (obj->refcount > 0 && !force) { 147 if (obj->refcount > 0 && !force) {
148 continue; 148 continue;
149 } 149 }
150 if (obj->fini == NULL || obj->fini_called || obj->initfirst) { 150 if (obj->fini == NULL || obj->fini_called || obj->z_initfirst) {
151 continue; 151 continue;
152 } 152 }
153 dbg (("calling fini function %s at %p", obj->path, 153 dbg (("calling fini function %s at %p", obj->path,
154 (void *)obj->fini)); 154 (void *)obj->fini));
155 obj->fini_called = 1; 155 obj->fini_called = 1;
156 (*obj->fini)(); 156 (*obj->fini)();
157 } 157 }
158 158
159 /* Second pass: objects marked with DF_1_INITFIRST. */ 159 /* Second pass: objects marked with DF_1_INITFIRST. */
160 SIMPLEQ_FOREACH(elm, &finilist, link) { 160 SIMPLEQ_FOREACH(elm, &finilist, link) {
161 obj = elm->obj; 161 obj = elm->obj;
162 if (obj->refcount > 0 && !force) { 162 if (obj->refcount > 0 && !force) {
163 continue; 163 continue;
@@ -178,27 +178,27 @@ static void @@ -178,27 +178,27 @@ static void
178_rtld_call_init_functions() 178_rtld_call_init_functions()
179{ 179{
180 Objlist_Entry *elm; 180 Objlist_Entry *elm;
181 Objlist initlist; 181 Objlist initlist;
182 Obj_Entry *obj; 182 Obj_Entry *obj;
183 183
184 dbg(("_rtld_call_init_functions()")); 184 dbg(("_rtld_call_init_functions()"));
185 SIMPLEQ_INIT(&initlist); 185 SIMPLEQ_INIT(&initlist);
186 _rtld_initlist_tsort(&initlist, 0); 186 _rtld_initlist_tsort(&initlist, 0);
187 187
188 /* First pass: objects marked with DF_1_INITFIRST. */ 188 /* First pass: objects marked with DF_1_INITFIRST. */
189 SIMPLEQ_FOREACH(elm, &initlist, link) { 189 SIMPLEQ_FOREACH(elm, &initlist, link) {
190 obj = elm->obj; 190 obj = elm->obj;
191 if (obj->init == NULL || obj->init_called || !obj->initfirst) { 191 if (obj->init == NULL || obj->init_called || !obj->z_initfirst) {
192 continue; 192 continue;
193 } 193 }
194 dbg (("calling init function %s at %p (DF_1_INITFIRST)", 194 dbg (("calling init function %s at %p (DF_1_INITFIRST)",
195 obj->path, (void *)obj->init)); 195 obj->path, (void *)obj->init));
196 obj->init_called = 1; 196 obj->init_called = 1;
197 (*obj->init)(); 197 (*obj->init)();
198 } 198 }
199 199
200 /* Second pass: all other objects. */ 200 /* Second pass: all other objects. */
201 SIMPLEQ_FOREACH(elm, &initlist, link) { 201 SIMPLEQ_FOREACH(elm, &initlist, link) {
202 obj = elm->obj; 202 obj = elm->obj;
203 if (obj->init == NULL || obj->init_called) { 203 if (obj->init == NULL || obj->init_called) {
204 continue; 204 continue;
@@ -558,27 +558,27 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase) @@ -558,27 +558,27 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
558 _rtld_objlist_push_tail(&_rtld_list_main, _rtld_objmain); 558 _rtld_objlist_push_tail(&_rtld_list_main, _rtld_objmain);
559 559
560 if (ld_preload) { 560 if (ld_preload) {
561 /* 561 /*
562 * Pre-load user-specified objects after the main program 562 * Pre-load user-specified objects after the main program
563 * but before any shared object dependencies. 563 * but before any shared object dependencies.
564 */ 564 */
565 dbg(("preloading objects")); 565 dbg(("preloading objects"));
566 if (_rtld_preload(ld_preload) == -1) 566 if (_rtld_preload(ld_preload) == -1)
567 _rtld_die(); 567 _rtld_die();
568 } 568 }
569 569
570 dbg(("loading needed objects")); 570 dbg(("loading needed objects"));
571 if (_rtld_load_needed_objects(_rtld_objmain, RTLD_MAIN) == -1) 571 if (_rtld_load_needed_objects(_rtld_objmain, _RTLD_MAIN) == -1)
572 _rtld_die(); 572 _rtld_die();
573 573
574 dbg(("relocating objects")); 574 dbg(("relocating objects"));
575 if (_rtld_relocate_objects(_rtld_objmain, bind_now) == -1) 575 if (_rtld_relocate_objects(_rtld_objmain, bind_now) == -1)
576 _rtld_die(); 576 _rtld_die();
577 577
578 dbg(("doing copy relocations")); 578 dbg(("doing copy relocations"));
579 if (_rtld_do_copy_relocations(_rtld_objmain) == -1) 579 if (_rtld_do_copy_relocations(_rtld_objmain) == -1)
580 _rtld_die(); 580 _rtld_die();
581 581
582 /* 582 /*
583 * Set the __progname, environ and, __mainprog_obj before 583 * Set the __progname, environ and, __mainprog_obj before
584 * calling anything that might use them. 584 * calling anything that might use them.
@@ -750,33 +750,55 @@ _rtld_unload_object(Obj_Entry *root, boo @@ -750,33 +750,55 @@ _rtld_unload_object(Obj_Entry *root, boo
750 munmap(obj->mapbase, obj->mapsize); 750 munmap(obj->mapbase, obj->mapsize);
751 _rtld_objlist_remove(&_rtld_list_global, obj); 751 _rtld_objlist_remove(&_rtld_list_global, obj);
752 _rtld_linkmap_delete(obj); 752 _rtld_linkmap_delete(obj);
753 *linkp = obj->next; 753 *linkp = obj->next;
754 _rtld_objcount--; 754 _rtld_objcount--;
755 _rtld_obj_free(obj); 755 _rtld_obj_free(obj);
756 } else 756 } else
757 linkp = &obj->next; 757 linkp = &obj->next;
758 } 758 }
759 _rtld_objtail = linkp; 759 _rtld_objtail = linkp;
760 } 760 }
761} 761}
762 762
 763void
 764_rtld_ref_dag(Obj_Entry *root)
 765{
 766 const Needed_Entry *needed;
 767
 768 assert(root);
 769
 770 ++root->refcount;
 771
 772 dbg(("incremented reference on \"%s\" (%d)", root->path,
 773 root->refcount));
 774 for (needed = root->needed; needed != NULL;
 775 needed = needed->next) {
 776 if (needed->obj != NULL)
 777 _rtld_ref_dag(needed->obj);
 778 }
 779}
 780
763static void 781static void
764_rtld_unref_dag(Obj_Entry *root) 782_rtld_unref_dag(Obj_Entry *root)
765{ 783{
766 784
767 assert(root); 785 assert(root);
768 assert(root->refcount != 0); 786 assert(root->refcount != 0);
 787
769 --root->refcount; 788 --root->refcount;
 789 dbg(("decremented reference on \"%s\" (%d)", root->path,
 790 root->refcount));
 791
770 if (root->refcount == 0) { 792 if (root->refcount == 0) {
771 const Needed_Entry *needed; 793 const Needed_Entry *needed;
772 794
773 for (needed = root->needed; needed != NULL; 795 for (needed = root->needed; needed != NULL;
774 needed = needed->next) { 796 needed = needed->next) {
775 if (needed->obj != NULL) 797 if (needed->obj != NULL)
776 _rtld_unref_dag(needed->obj); 798 _rtld_unref_dag(needed->obj);
777 } 799 }
778 } 800 }
779} 801}
780 802
781__strong_alias(__dlclose,dlclose) 803__strong_alias(__dlclose,dlclose)
782int 804int
@@ -805,52 +827,69 @@ dlerror(void) @@ -805,52 +827,69 @@ dlerror(void)
805{ 827{
806 char *msg = error_message; 828 char *msg = error_message;
807 829
808 error_message = NULL; 830 error_message = NULL;
809 return msg; 831 return msg;
810} 832}
811 833
812__strong_alias(__dlopen,dlopen) 834__strong_alias(__dlopen,dlopen)
813void * 835void *
814dlopen(const char *name, int mode) 836dlopen(const char *name, int mode)
815{ 837{
816 Obj_Entry **old_obj_tail = _rtld_objtail; 838 Obj_Entry **old_obj_tail = _rtld_objtail;
817 Obj_Entry *obj = NULL; 839 Obj_Entry *obj = NULL;
 840 int flags = _RTLD_DLOPEN;
 841 bool nodelete;
 842 bool now;
 843
 844 flags |= (mode & RTLD_GLOBAL) ? _RTLD_GLOBAL : 0;
 845 flags |= (mode & RTLD_NOLOAD) ? _RTLD_NOLOAD : 0;
 846
 847 nodelete = (mode & RTLD_NODELETE) ? true : false;
 848 now = ((mode & RTLD_MODEMASK) == RTLD_NOW) ? true : false;
818 849
819 _rtld_debug.r_state = RT_ADD; 850 _rtld_debug.r_state = RT_ADD;
820 _rtld_debug_state(); 851 _rtld_debug_state();
821 852
822 if (name == NULL) { 853 if (name == NULL) {
823 obj = _rtld_objmain; 854 obj = _rtld_objmain;
824 obj->refcount++; 855 obj->refcount++;
825 } else 856 } else
826 obj = _rtld_load_library(name, _rtld_objmain, mode); 857 obj = _rtld_load_library(name, _rtld_objmain, flags);
 858
827 859
828 if (obj != NULL) { 860 if (obj != NULL) {
829 ++obj->dl_refcount; 861 ++obj->dl_refcount;
830 if (*old_obj_tail != NULL) { /* We loaded something new. */ 862 if (*old_obj_tail != NULL) { /* We loaded something new. */
831 assert(*old_obj_tail == obj); 863 assert(*old_obj_tail == obj);
832 864
833 if (_rtld_load_needed_objects(obj, mode) == -1 || 865 if (_rtld_load_needed_objects(obj, flags) == -1 ||
834 (_rtld_init_dag(obj), 866 (_rtld_init_dag(obj),
835 _rtld_relocate_objects(obj, 867 _rtld_relocate_objects(obj,
836 ((mode & 3) == RTLD_NOW))) == -1) { 868 (now || obj->z_now))) == -1) {
837 _rtld_unload_object(obj, false); 869 _rtld_unload_object(obj, false);
838 obj->dl_refcount--; 870 obj->dl_refcount--;
839 obj = NULL; 871 obj = NULL;
840 } else { 872 } else {
841 _rtld_call_init_functions(); 873 _rtld_call_init_functions();
842 } 874 }
843 } 875 }
 876 if (obj != NULL) {
 877 if ((nodelete || obj->z_nodelete) && !obj->ref_nodel) {
 878 dbg(("dlopen obj %s nodelete", obj->path));
 879 _rtld_ref_dag(obj);
 880 obj->z_nodelete = obj->ref_nodel = true;
 881 }
 882 }
844 } 883 }
845 _rtld_debug.r_state = RT_CONSISTENT; 884 _rtld_debug.r_state = RT_CONSISTENT;
846 _rtld_debug_state(); 885 _rtld_debug_state();
847 886
848 return obj; 887 return obj;
849} 888}
850 889
851/* 890/*
852 * Find a symbol in the main program. 891 * Find a symbol in the main program.
853 */ 892 */
854void * 893void *
855_rtld_objmain_sym(const char *name) 894_rtld_objmain_sym(const char *name)
856{ 895{

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

--- src/libexec/ld.elf_so/rtld.h 2010/12/05 00:56:06 1.96
+++ src/libexec/ld.elf_so/rtld.h 2010/12/24 12:41:43 1.97
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rtld.h,v 1.96 2010/12/05 00:56:06 joerg Exp $ */ 1/* $NetBSD: rtld.h,v 1.97 2010/12/24 12:41:43 skrll 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
@@ -118,27 +118,26 @@ typedef struct _rtld_library_xform_t { @@ -118,27 +118,26 @@ typedef struct _rtld_library_xform_t {
118 118
119/* 119/*
120 * Shared object descriptor. 120 * Shared object descriptor.
121 * 121 *
122 * Items marked with "(%)" are dynamically allocated, and must be freed 122 * Items marked with "(%)" are dynamically allocated, and must be freed
123 * when the structure is destroyed. 123 * when the structure is destroyed.
124 * 124 *
125 * The layout of this structure needs to be preserved because pre-2.0 binaries 125 * The layout of this structure needs to be preserved because pre-2.0 binaries
126 * hard-coded the location of dlopen() and friends. 126 * hard-coded the location of dlopen() and friends.
127 */ 127 */
128 128
129#define RTLD_MAGIC 0xd550b87a 129#define RTLD_MAGIC 0xd550b87a
130#define RTLD_VERSION 1 130#define RTLD_VERSION 1
131#define RTLD_MAIN 0x800 
132 131
133typedef struct Struct_Obj_Entry { 132typedef struct Struct_Obj_Entry {
134 Elf32_Word magic; /* Magic number (sanity check) */ 133 Elf32_Word magic; /* Magic number (sanity check) */
135 Elf32_Word version; /* Version number of struct format */ 134 Elf32_Word version; /* Version number of struct format */
136 135
137 struct Struct_Obj_Entry *next; 136 struct Struct_Obj_Entry *next;
138 char *path; /* Pathname of underlying file (%) */ 137 char *path; /* Pathname of underlying file (%) */
139 int refcount; 138 int refcount;
140 int dl_refcount; /* Number of times loaded by dlopen */ 139 int dl_refcount; /* Number of times loaded by dlopen */
141 140
142 /* These items are computed by map_object() or by digest_phdr(). */ 141 /* These items are computed by map_object() or by digest_phdr(). */
143 caddr_t mapbase; /* Base address of mapped region */ 142 caddr_t mapbase; /* Base address of mapped region */
144 size_t mapsize; /* Size of mapped region in bytes */ 143 size_t mapsize; /* Size of mapped region in bytes */
@@ -192,30 +191,37 @@ typedef struct Struct_Obj_Entry { @@ -192,30 +191,37 @@ typedef struct Struct_Obj_Entry {
192 textrel:1, /* True if there are relocations to 191 textrel:1, /* True if there are relocations to
193 * text seg */ 192 * text seg */
194 symbolic:1, /* True if generated with 193 symbolic:1, /* True if generated with
195 * "-Bsymbolic" */ 194 * "-Bsymbolic" */
196 printed:1, /* True if ldd has printed it */ 195 printed:1, /* True if ldd has printed it */
197 isdynamic:1, /* True if this is a pure PIC object */ 196 isdynamic:1, /* True if this is a pure PIC object */
198 mainref:1, /* True if on _rtld_list_main */ 197 mainref:1, /* True if on _rtld_list_main */
199 globalref:1, /* True if on _rtld_list_global */ 198 globalref:1, /* True if on _rtld_list_global */
200 init_done:1, /* True if .init has been added */ 199 init_done:1, /* True if .init has been added */
201 init_called:1, /* True if .init function has been  200 init_called:1, /* True if .init function has been
202 * called */ 201 * called */
203 fini_called:1, /* True if .fini function has been  202 fini_called:1, /* True if .fini function has been
204 * called */ 203 * called */
205 initfirst:1, /* True if object's .init/.fini take 204 z_now:1, /* True if object's symbols should be
 205 bound immediately */
 206 z_nodelete:1, /* True if object should never be
 207 unloaded */
 208 z_initfirst:1, /* True if object's .init/.fini take
206 * priority over others */ 209 * priority over others */
207 phdr_loaded:1; /* Phdr is loaded and doesn't need to 210 z_noopen:1, /* True if object should never be
 211 dlopen'ed */
 212 phdr_loaded:1, /* Phdr is loaded and doesn't need to
208 * be freed. */ 213 * be freed. */
 214 ref_nodel:1; /* Refcount increased to prevent dlclose */
209 215
210 struct link_map linkmap; /* for GDB */ 216 struct link_map linkmap; /* for GDB */
211 217
212 /* These items are computed by map_object() or by digest_phdr(). */ 218 /* These items are computed by map_object() or by digest_phdr(). */
213 const char *interp; /* Pathname of the interpreter, if any */ 219 const char *interp; /* Pathname of the interpreter, if any */
214 Objlist dldags; /* Object belongs to these dlopened DAGs (%) */ 220 Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
215 Objlist dagmembers; /* DAG has these members (%) */ 221 Objlist dagmembers; /* DAG has these members (%) */
216 dev_t dev; /* Object's filesystem's device */ 222 dev_t dev; /* Object's filesystem's device */
217 ino_t ino; /* Object's inode number */ 223 ino_t ino; /* Object's inode number */
218 224
219 void *ehdr; 225 void *ehdr;
220 226
221 uint32_t nbuckets; /* Number of buckets */ 227 uint32_t nbuckets; /* Number of buckets */
@@ -241,63 +247,73 @@ extern Search_Path *_rtld_default_paths; @@ -241,63 +247,73 @@ extern Search_Path *_rtld_default_paths;
241extern Obj_Entry *_rtld_objlist; 247extern Obj_Entry *_rtld_objlist;
242extern Obj_Entry **_rtld_objtail; 248extern Obj_Entry **_rtld_objtail;
243extern u_int _rtld_objcount; 249extern u_int _rtld_objcount;
244extern u_int _rtld_objloads; 250extern u_int _rtld_objloads;
245extern Obj_Entry *_rtld_objmain; 251extern Obj_Entry *_rtld_objmain;
246extern Obj_Entry _rtld_objself; 252extern Obj_Entry _rtld_objself;
247extern Search_Path *_rtld_paths; 253extern Search_Path *_rtld_paths;
248extern Library_Xform *_rtld_xforms; 254extern Library_Xform *_rtld_xforms;
249extern bool _rtld_trust; 255extern bool _rtld_trust;
250extern Objlist _rtld_list_global; 256extern Objlist _rtld_list_global;
251extern Objlist _rtld_list_main; 257extern Objlist _rtld_list_main;
252extern Elf_Sym _rtld_sym_zero; 258extern Elf_Sym _rtld_sym_zero;
253 259
 260#define RTLD_MODEMASK 0x3
 261
 262/* Flags for _rtld_load_object() and friends. */
 263#define _RTLD_GLOBAL 0x01 /* Add object to global DAG. */
 264#define _RTLD_MAIN 0x02
 265#define _RTLD_NOLOAD 0x04 /* dlopen() specified RTLD_NOLOAD. */
 266#define _RTLD_DLOPEN 0x08 /* Load_object() called from dlopen(). */
 267
254/* rtld.c */ 268/* rtld.c */
255 269
256/* We export these symbols using _rtld_symbol_lookup and is_exported. */ 270/* We export these symbols using _rtld_symbol_lookup and is_exported. */
257__dso_public char *dlerror(void); 271__dso_public char *dlerror(void);
258__dso_public void *dlopen(const char *, int); 272__dso_public void *dlopen(const char *, int);
259__dso_public void *dlsym(void *, const char *); 273__dso_public void *dlsym(void *, const char *);
260__dso_public int dlclose(void *); 274__dso_public int dlclose(void *);
261__dso_public int dladdr(const void *, Dl_info *); 275__dso_public int dladdr(const void *, Dl_info *);
262__dso_public int dlinfo(void *, int, void *); 276__dso_public int dlinfo(void *, int, void *);
263__dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), 277__dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
264 void *); 278 void *);
265 279
266/* These aren't exported */ 280/* These aren't exported */
267void _rtld_error(const char *, ...) 281void _rtld_error(const char *, ...)
268 __attribute__((__format__(__printf__,1,2))); 282 __attribute__((__format__(__printf__,1,2)));
269void _rtld_die(void) __attribute__((__noreturn__)); 283void _rtld_die(void) __attribute__((__noreturn__));
270void *_rtld_objmain_sym(const char *); 284void *_rtld_objmain_sym(const char *);
271void _rtld_debug_state(void); 285void _rtld_debug_state(void);
272void _rtld_linkmap_add(Obj_Entry *); 286void _rtld_linkmap_add(Obj_Entry *);
273void _rtld_linkmap_delete(Obj_Entry *); 287void _rtld_linkmap_delete(Obj_Entry *);
274void _rtld_objlist_push_head(Objlist *, Obj_Entry *); 288void _rtld_objlist_push_head(Objlist *, Obj_Entry *);
275void _rtld_objlist_push_tail(Objlist *, Obj_Entry *); 289void _rtld_objlist_push_tail(Objlist *, Obj_Entry *);
276Objlist_Entry *_rtld_objlist_find(Objlist *, const Obj_Entry *); 290Objlist_Entry *_rtld_objlist_find(Objlist *, const Obj_Entry *);
 291void _rtld_ref_dag(Obj_Entry *);
277 292
278/* expand.c */ 293/* expand.c */
279size_t _rtld_expand_path(char *, size_t, const char *, const char *,\ 294size_t _rtld_expand_path(char *, size_t, const char *, const char *,\
280 const char *); 295 const char *);
281 296
282/* headers.c */ 297/* headers.c */
283void _rtld_digest_dynamic(const char *, Obj_Entry *); 298void _rtld_digest_dynamic(const char *, Obj_Entry *);
284Obj_Entry *_rtld_digest_phdr(const Elf_Phdr *, int, caddr_t); 299Obj_Entry *_rtld_digest_phdr(const Elf_Phdr *, int, caddr_t);
285 300
286/* load.c */ 301/* load.c */
287Obj_Entry *_rtld_load_object(const char *, int); 302Obj_Entry *_rtld_load_object(const char *, int);
288int _rtld_load_needed_objects(Obj_Entry *, int); 303int _rtld_load_needed_objects(Obj_Entry *, int);
289int _rtld_preload(const char *); 304int _rtld_preload(const char *);
290 305
 306#define OBJ_ERR (Obj_Entry *)(-1)
291/* path.c */ 307/* path.c */
292void _rtld_add_paths(const char *, Search_Path **, const char *); 308void _rtld_add_paths(const char *, Search_Path **, const char *);
293void _rtld_process_hints(const char *, Search_Path **, Library_Xform **, 309void _rtld_process_hints(const char *, Search_Path **, Library_Xform **,
294 const char *); 310 const char *);
295int _rtld_sysctl(const char *, void *, size_t *); 311int _rtld_sysctl(const char *, void *, size_t *);
296 312
297/* reloc.c */ 313/* reloc.c */
298int _rtld_do_copy_relocations(const Obj_Entry *); 314int _rtld_do_copy_relocations(const Obj_Entry *);
299int _rtld_relocate_objects(Obj_Entry *, bool); 315int _rtld_relocate_objects(Obj_Entry *, bool);
300int _rtld_relocate_nonplt_objects(Obj_Entry *); 316int _rtld_relocate_nonplt_objects(Obj_Entry *);
301int _rtld_relocate_plt_lazy(const Obj_Entry *); 317int _rtld_relocate_plt_lazy(const Obj_Entry *);
302int _rtld_relocate_plt_objects(const Obj_Entry *); 318int _rtld_relocate_plt_objects(const Obj_Entry *);
303void _rtld_setup_pltgot(const Obj_Entry *); 319void _rtld_setup_pltgot(const Obj_Entry *);

cvs diff -r1.22 -r1.23 src/libexec/ld.elf_so/search.c (expand / switch to unified diff)

--- src/libexec/ld.elf_so/search.c 2010/08/07 19:47:34 1.22
+++ src/libexec/ld.elf_so/search.c 2010/12/24 12:41:43 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: search.c,v 1.22 2010/08/07 19:47:34 joerg Exp $ */ 1/* $NetBSD: search.c,v 1.23 2010/12/24 12:41:43 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright 1996 Matt Thomas <matt@3am-software.com> 4 * Copyright 1996 Matt Thomas <matt@3am-software.com>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Dynamic linker for ELF. 34 * Dynamic linker for ELF.
35 * 35 *
36 * John Polstra <jdp@polstra.com>. 36 * John Polstra <jdp@polstra.com>.
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#ifndef lint 40#ifndef lint
41__RCSID("$NetBSD: search.c,v 1.22 2010/08/07 19:47:34 joerg Exp $"); 41__RCSID("$NetBSD: search.c,v 1.23 2010/12/24 12:41:43 skrll Exp $");
42#endif /* not lint */ 42#endif /* not lint */
43 43
44#include <err.h> 44#include <err.h>
45#include <errno.h> 45#include <errno.h>
46#include <fcntl.h> 46#include <fcntl.h>
47#include <stdarg.h> 47#include <stdarg.h>
48#include <stdio.h> 48#include <stdio.h>
49#include <stdlib.h> 49#include <stdlib.h>
50#include <string.h> 50#include <string.h>
51#include <unistd.h> 51#include <unistd.h>
52#include <sys/types.h> 52#include <sys/types.h>
53#include <sys/mman.h> 53#include <sys/mman.h>
54#include <sys/stat.h> 54#include <sys/stat.h>
@@ -57,75 +57,75 @@ __RCSID("$NetBSD: search.c,v 1.22 2010/0 @@ -57,75 +57,75 @@ __RCSID("$NetBSD: search.c,v 1.22 2010/0
57#include "debug.h" 57#include "debug.h"
58#include "rtld.h" 58#include "rtld.h"
59 59
60/* 60/*
61 * Data declarations. 61 * Data declarations.
62 */ 62 */
63Search_Path *_rtld_invalid_paths; 63Search_Path *_rtld_invalid_paths;
64 64
65static Obj_Entry *_rtld_search_library_path(const char *, size_t, 65static Obj_Entry *_rtld_search_library_path(const char *, size_t,
66 const char *, size_t, int); 66 const char *, size_t, int);
67 67
68static Obj_Entry * 68static Obj_Entry *
69_rtld_search_library_path(const char *name, size_t namelen, 69_rtld_search_library_path(const char *name, size_t namelen,
70 const char *dir, size_t dirlen, int mode) 70 const char *dir, size_t dirlen, int flags)
71{ 71{
72 char pathname[MAXPATHLEN]; 72 char pathname[MAXPATHLEN];
73 size_t pathnamelen; 73 size_t pathnamelen;
74 Obj_Entry *obj; 74 Obj_Entry *obj;
75 Search_Path *sp; 75 Search_Path *sp;
76 76
77 pathnamelen = dirlen + 1 + namelen; 77 pathnamelen = dirlen + 1 + namelen;
78 if (pathnamelen >= sizeof(pathname)) 78 if (pathnamelen >= sizeof(pathname))
79 return NULL; 79 return NULL;
80 80
81 for (sp = _rtld_invalid_paths; sp != NULL; sp = sp->sp_next) { 81 for (sp = _rtld_invalid_paths; sp != NULL; sp = sp->sp_next) {
82 if (sp->sp_pathlen == pathnamelen && 82 if (sp->sp_pathlen == pathnamelen &&
83 sp->sp_path[dirlen] == '/' && 83 sp->sp_path[dirlen] == '/' &&
84 !memcmp(name, sp->sp_path + dirlen + 1, namelen) && 84 !memcmp(name, sp->sp_path + dirlen + 1, namelen) &&
85 !memcmp(dir, sp->sp_path, dirlen)) { 85 !memcmp(dir, sp->sp_path, dirlen)) {
86 return NULL; 86 return NULL;
87 } 87 }
88 } 88 }
89 89
90 memcpy(pathname, dir, dirlen); 90 memcpy(pathname, dir, dirlen);
91 pathname[dirlen] = '/'; 91 pathname[dirlen] = '/';
92 memcpy(pathname + dirlen + 1, name, namelen); 92 memcpy(pathname + dirlen + 1, name, namelen);
93 pathname[pathnamelen] = '\0'; 93 pathname[pathnamelen] = '\0';
94 94
95 dbg((" Trying \"%s\"", pathname)); 95 dbg((" Trying \"%s\"", pathname));
96 obj = _rtld_load_object(pathname, mode); 96 obj = _rtld_load_object(pathname, flags);
97 if (obj == NULL) { 97 if (obj == NULL) {
98 Search_Path *path; 98 Search_Path *path;
99 99
100 path = NEW(Search_Path); 100 path = NEW(Search_Path);
101 path->sp_pathlen = pathnamelen; 101 path->sp_pathlen = pathnamelen;
102 path->sp_path = xstrdup(pathname); 102 path->sp_path = xstrdup(pathname);
103 path->sp_next = _rtld_invalid_paths; 103 path->sp_next = _rtld_invalid_paths;
104 _rtld_invalid_paths = path; 104 _rtld_invalid_paths = path;
105 } 105 }
106 return obj; 106 return obj;
107} 107}
108 108
109/* 109/*
110 * Find the library with the given name, and return its full pathname. 110 * Find the library with the given name, and return its full pathname.
111 * The returned string is dynamically allocated. Generates an error 111 * The returned string is dynamically allocated. Generates an error
112 * message and returns NULL if the library cannot be found. 112 * message and returns NULL if the library cannot be found.
113 * 113 *
114 * If the second argument is non-NULL, then it refers to an already- 114 * If the second argument is non-NULL, then it refers to an already-
115 * loaded shared object, whose library search path will be searched. 115 * loaded shared object, whose library search path will be searched.
116 */ 116 */
117Obj_Entry * 117Obj_Entry *
118_rtld_load_library(const char *name, const Obj_Entry *refobj, int mode) 118_rtld_load_library(const char *name, const Obj_Entry *refobj, int flags)
119{ 119{
120 char tmperror[512], *tmperrorp; 120 char tmperror[512], *tmperrorp;
121 Search_Path *sp; 121 Search_Path *sp;
122 const char *pathname; 122 const char *pathname;
123 int namelen; 123 int namelen;
124 Obj_Entry *obj; 124 Obj_Entry *obj;
125 125
126 if (strchr(name, '/') != NULL) { /* Hard coded pathname */ 126 if (strchr(name, '/') != NULL) { /* Hard coded pathname */
127 if (name[0] != '/' && !_rtld_trust) { 127 if (name[0] != '/' && !_rtld_trust) {
128 _rtld_error( 128 _rtld_error(
129 "absolute pathname required for shared object \"%s\"", 129 "absolute pathname required for shared object \"%s\"",
130 name); 130 name);
131 return NULL; 131 return NULL;
@@ -135,47 +135,58 @@ _rtld_load_library(const char *name, con @@ -135,47 +135,58 @@ _rtld_load_library(const char *name, con
135 } 135 }
136 dbg((" Searching for \"%s\" (%p)", name, refobj)); 136 dbg((" Searching for \"%s\" (%p)", name, refobj));
137 137
138 tmperrorp = dlerror(); 138 tmperrorp = dlerror();
139 if (tmperrorp != NULL) { 139 if (tmperrorp != NULL) {
140 strncpy(tmperror, tmperrorp, sizeof tmperror); 140 strncpy(tmperror, tmperrorp, sizeof tmperror);
141 tmperrorp = tmperror; 141 tmperrorp = tmperror;
142 } 142 }
143  143
144 namelen = strlen(name); 144 namelen = strlen(name);
145 145
146 for (sp = _rtld_paths; sp != NULL; sp = sp->sp_next) 146 for (sp = _rtld_paths; sp != NULL; sp = sp->sp_next)
147 if ((obj = _rtld_search_library_path(name, namelen, 147 if ((obj = _rtld_search_library_path(name, namelen,
148 sp->sp_path, sp->sp_pathlen, mode)) != NULL) 148 sp->sp_path, sp->sp_pathlen, flags)) != NULL)
149 goto pathfound; 149 goto pathfound;
150 150
151 if (refobj != NULL) 151 if (refobj != NULL)
152 for (sp = refobj->rpaths; sp != NULL; sp = sp->sp_next) 152 for (sp = refobj->rpaths; sp != NULL; sp = sp->sp_next)
153 if ((obj = _rtld_search_library_path(name, 153 if ((obj = _rtld_search_library_path(name,
154 namelen, sp->sp_path, sp->sp_pathlen, mode)) != NULL) 154 namelen, sp->sp_path, sp->sp_pathlen, flags)) != NULL)
155 goto pathfound; 155 goto pathfound;
156 156
157 for (sp = _rtld_default_paths; sp != NULL; sp = sp->sp_next) 157 for (sp = _rtld_default_paths; sp != NULL; sp = sp->sp_next)
158 if ((obj = _rtld_search_library_path(name, namelen, 158 if ((obj = _rtld_search_library_path(name, namelen,
159 sp->sp_path, sp->sp_pathlen, mode)) != NULL) 159 sp->sp_path, sp->sp_pathlen, flags)) != NULL)
160 goto pathfound; 160 goto pathfound;
161 161
162 _rtld_error("Shared object \"%s\" not found", name); 162 _rtld_error("Shared object \"%s\" not found", name);
163 return NULL; 163 return NULL;
164 164
165pathfound: 165pathfound:
166 /* 166 /*
 167 * The library has been found, but it couldn't be loaded for some
 168 * reason.
 169 */
 170 if (obj == OBJ_ERR)
 171 return NULL;
 172 /*
167 * Successfully found a library; restore the dlerror state as it was 173 * Successfully found a library; restore the dlerror state as it was
168 * before _rtld_load_library() was called (any failed call to 174 * before _rtld_load_library() was called (any failed call to
169 * _rtld_search_library_path() will set the dlerror state, but if the 175 * _rtld_search_library_path() will set the dlerror state, but if the
170 * library was eventually found, then the error state should not 176 * library was eventually found, then the error state should not
171 * change. 177 * change.
172 */ 178 */
173 if (tmperrorp) 179 if (tmperrorp)
174 _rtld_error("%s", tmperror); 180 _rtld_error("%s", tmperror);
175 else 181 else
176 (void)dlerror(); 182 (void)dlerror();
177 return obj; 183 return obj;
178 184
179found: 185found:
180 return _rtld_load_object(pathname, mode); 186 obj = _rtld_load_object(pathname, flags);
 187 if (obj == OBJ_ERR)
 188 return NULL;
 189
 190 return obj;
181} 191}
 192

cvs diff -r1.27 -r1.28 src/share/man/man3/dlfcn.3 (expand / switch to unified diff)

--- src/share/man/man3/dlfcn.3 2010/01/24 22:54:14 1.27
+++ src/share/man/man3/dlfcn.3 2010/12/24 12:41:43 1.28
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: dlfcn.3,v 1.27 2010/01/24 22:54:14 wiz Exp $ 1.\" $NetBSD: dlfcn.3,v 1.28 2010/12/24 12:41:43 skrll Exp $
2.\" 2.\"
3.\" Copyright (c) 1998 The NetBSD Foundation, Inc. 3.\" Copyright (c) 1998 The NetBSD Foundation, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation 6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Paul Kranenburg. 7.\" by Paul Kranenburg.
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
@@ -55,87 +55,109 @@ dynamically linked program automatically @@ -55,87 +55,109 @@ dynamically linked program automatically
55.Ft "int" 55.Ft "int"
56.Fn dlctl "void *handle" "int cmd" "void *data" 56.Fn dlctl "void *handle" "int cmd" "void *data"
57.Ft "char *" 57.Ft "char *"
58.Fn dlerror "void" 58.Fn dlerror "void"
59.Sh DESCRIPTION 59.Sh DESCRIPTION
60These functions provide an interface to the run-time linker 60These functions provide an interface to the run-time linker
61.Xr ld.so 1 . 61.Xr ld.so 1 .
62They allow new shared objects to be loaded into the process' address space 62They allow new shared objects to be loaded into the process' address space
63under program control. 63under program control.
64.Pp 64.Pp
65The 65The
66.Fn dlopen 66.Fn dlopen
67function takes the name of a shared object as the first argument. 67function takes the name of a shared object as the first argument.
68The shared object is mapped into the address space, relocated, and 
69its external references are resolved in the same way as is done 
70with the implicitly loaded shared libraries at program startup. 
71.Pp 
72The 68The
73.Fa path 69.Fa path
74argument can be specified as either an absolute pathname to a shared object 70argument can be specified as either an absolute pathname to a shared object
75or just the name of the shared object itself. 71or just the name of the shared object itself.
76When an absolute pathname is specified, 72When an absolute pathname is specified,
77only the path provided will be searched. 73only the path provided will be searched.
78When just a shared object name is specified, the same search rules apply that are 74When just a shared object name is specified, the same search rules apply that
79used for 75are used for
80.Dq intrinsic 76.Dq intrinsic
81shared object searches. 77shared object searches.
 78.Po
 79see
 80.Xr ld.elf_so 5
 81.Pc
82.Pp 82.Pp
83Shared libraries take the following form: 83Shared libraries take the following form:
84.Do lib Ns Ao name Ac Ns .so Ns Oo .xx Ns Oo .yy Oc Oc Dc . 84.Do lib Ns Ao name Ac Ns .so Ns Oo .xx Ns Oo .yy Oc Oc Dc .
85.Pp 85.Pp
 86The shared object is mapped into the address space, relocated, and
 87its external references are resolved in the same way as is done
 88with the implicitly loaded shared libraries at program startup.
 89.Pp
 90The
86If the first argument is 91If the first argument is
87.Dv NULL , 92.Dv NULL ,
88.Fn dlopen 93.Fn dlopen
89returns a 94returns a
90.Fa handle 95.Fa handle
91on the global symbol object. 96on the global symbol object.
92This object 97This object
93provides access to all symbols from an ordered set of objects consisting 98provides access to all symbols from an ordered set of objects consisting
94of the original program image and any dependencies loaded during startup. 99of the original program image and any dependencies loaded during startup.
95.Pp 100.Pp
96The 101The
97.Fa mode 102.Fa mode
98parameter specifies symbol resolution time and symbol visibility. 103parameter specifies symbol resolution time and symbol visibility.
99One of the following values may be used to specify symbol resolution time: 104One of the following values may be used to specify symbol resolution time:
100.Bl -tag -width "RTLD_LAZYXX" -offset indent 105.Bl -tag -width "RTLD_GLOBALXX" -offset indent
101.It Dv RTLD_NOW 106.It Dv RTLD_NOW
102Symbols are resolved immediately. 107Symbols are resolved immediately.
103.It Dv RTLD_LAZY 108.It Dv RTLD_LAZY
104Symbols are resolved when they are first referred to. 109Symbols are resolved when they are first referred to.
105This is the default value if resolution time is unspecified. 110This is the default value if resolution time is unspecified.
106.El 111.El
107.Pp 112.Pp
108One of the following values may be used to specify symbol visibility: 113One of the following values may be used to specify symbol visibility:
109.Pp 114.Pp
110.Bl -tag -width "RTLD_GLOBAL" -compact -offset indent 115.Bl -tag -width "RTLD_GLOBALXX" -offset indent
111.It Dv RTLD_GLOBAL 116.It Dv RTLD_GLOBAL
112The object's symbols and the symbols of its dependencies will be visible to 117The object's symbols and the symbols of its dependencies will be visible to
113other objects. 118other objects.
114.It Dv RTLD_LOCAL 119.It Dv RTLD_LOCAL
115The object's symbols and the symbols of its dependencies will not be visible to 120The object's symbols and the symbols of its dependencies will not be visible to
116other objects. 121other objects.
117This is the default value if visibility is unspecified. 122This is the default value if visibility is unspecified.
118.El 123.El
119.Pp 124.Pp
120To specify both resolution time and visibility, bitwise inclusive OR one of 125To specify both resolution time and visibility, bitwise inclusive OR one of
121each of the above values together. 126each of the above values together.
122If an object was opened with 127If an object was opened with
123.Dv RTLD_LOCAL 128.Dv RTLD_LOCAL
124and later opened with 129and later opened with
125.Dv RTLD_GLOBAL , 130.Dv RTLD_GLOBAL ,
126then it is promoted to 131then it is promoted to
127.Dv RTLD_GLOBAL . 132.Dv RTLD_GLOBAL .
128.Pp 133.Pp
 134Additionally, one of the following flags may be ORed into the
 135.Fa mode
 136argument:
 137.Bl -tag -width "RTLD_NODELETEXX" -offset indent
 138.It Dv RTLD_NODELETE
 139Prevents unload of the loaded object on
 140.Fn dlclose .
 141The same behaviour may be requested by
 142.Fl "z nodelete"
 143option of the static linker
 144.Xr ld 1 .
 145.It Dv RTLD_NOLOAD
 146Only return valid handle for the object if it is already loaded in
 147the process address space, otherwise do not load the object and return
 148.Dv NULL .
 149.El
 150.Pp
129.Fn dlopen 151.Fn dlopen
130returns a 152returns a
131.Fa handle 153.Fa handle
132to be used in calls to 154to be used in calls to
133.Fn dlclose , 155.Fn dlclose ,
134.Fn dlsym , 156.Fn dlsym ,
135and 157and
136.Fn dlctl . 158.Fn dlctl .
137If the named shared object has already 159If the named shared object has already
138been loaded by a previous call to 160been loaded by a previous call to
139.Fn dlopen 161.Fn dlopen
140.Pq and not yet unloaded by Fn dlclose , 162.Pq and not yet unloaded by Fn dlclose ,
141a 163a
@@ -182,33 +204,33 @@ with the --export-dynamic option where a @@ -182,33 +204,33 @@ with the --export-dynamic option where a
182visible. 204visible.
183The following special 205The following special
184.Fa handle 206.Fa handle
185values may be used with 207values may be used with
186.Fn dlsym : 208.Fn dlsym :
187.Bl -tag -width "RTLD_DEFAULTXX" -offset indent 209.Bl -tag -width "RTLD_DEFAULTXX" -offset indent
188.It Dv NULL 210.It Dv NULL
189Interpreted as a reference to the executable or shared object 211Interpreted as a reference to the executable or shared object
190from which the call is being made. 212from which the call is being made.
191Thus an object can reference its own symbols and the symbols of its 213Thus an object can reference its own symbols and the symbols of its
192dependencies without calling 214dependencies without calling
193.Fn dlopen . 215.Fn dlopen .
194.It Dv RTLD_DEFAULT 216.It Dv RTLD_DEFAULT
195All the visible shared objects and the executable will be searched in the order they 217All the visible shared objects and the executable will be searched in the order
196were loaded. 218they were loaded.
197.It Dv RTLD_NEXT 219.It Dv RTLD_NEXT
198The search for 220The search for
199.Fa symbol 221.Fa symbol
200is limited to the visible shared objects which were loaded after the one issuing the 222is limited to the visible shared objects which were loaded after the one
201call to 223issuing the call to
202.Fn dlsym . 224.Fn dlsym .
203Thus, if 225Thus, if
204.Fn dlsym 226.Fn dlsym
205is called from the main program, all the visible shared libraries are searched. 227is called from the main program, all the visible shared libraries are searched.
206If it is called from a shared library, all subsequently visible shared 228If it is called from a shared library, all subsequently visible shared
207libraries are searched. 229libraries are searched.
208.It Dv RTLD_SELF 230.It Dv RTLD_SELF
209The search for 231The search for
210.Fa symbol 232.Fa symbol
211is limited to the shared object issuing the call to 233is limited to the shared object issuing the call to
212.Fn dlsym 234.Fn dlsym
213and those shared objects which were loaded after it that are visible. 235and those shared objects which were loaded after it that are visible.
214.El 236.El

cvs diff -r1.107 -r1.108 src/sys/sys/exec_elf.h (expand / switch to unified diff)

--- src/sys/sys/exec_elf.h 2010/12/13 19:37:32 1.107
+++ src/sys/sys/exec_elf.h 2010/12/24 12:41:43 1.108
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: exec_elf.h,v 1.107 2010/12/13 19:37:32 joerg Exp $ */ 1/* $NetBSD: exec_elf.h,v 1.108 2010/12/24 12:41:43 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1994 The NetBSD Foundation, Inc. 4 * Copyright (c) 1994 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 Christos Zoulas. 8 * by Christos Zoulas.
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.
@@ -658,27 +658,30 @@ typedef struct { @@ -658,27 +658,30 @@ typedef struct {
658 658
659#define DT_LOOS 0x60000000 /* Operating system specific range */ 659#define DT_LOOS 0x60000000 /* Operating system specific range */
660#define DT_VERSYM 0x6ffffff0 /* Symbol versions */ 660#define DT_VERSYM 0x6ffffff0 /* Symbol versions */
661#define DT_FLAGS_1 0x6ffffffb /* ELF dynamic flags */ 661#define DT_FLAGS_1 0x6ffffffb /* ELF dynamic flags */
662#define DT_VERDEF 0x6ffffffc /* Versions defined by file */ 662#define DT_VERDEF 0x6ffffffc /* Versions defined by file */
663#define DT_VERDEFNUM 0x6ffffffd /* Number of versions defined by file */ 663#define DT_VERDEFNUM 0x6ffffffd /* Number of versions defined by file */
664#define DT_VERNEED 0x6ffffffe /* Versions needed by file */ 664#define DT_VERNEED 0x6ffffffe /* Versions needed by file */
665#define DT_VERNEEDNUM 0x6fffffff /* Number of versions needed by file */ 665#define DT_VERNEEDNUM 0x6fffffff /* Number of versions needed by file */
666#define DT_HIOS 0x6fffffff 666#define DT_HIOS 0x6fffffff
667#define DT_LOPROC 0x70000000 /* Processor-specific range */ 667#define DT_LOPROC 0x70000000 /* Processor-specific range */
668#define DT_HIPROC 0x7fffffff 668#define DT_HIPROC 0x7fffffff
669 669
670/* Flag values for DT_FLAGS_1 (incomplete) */ 670/* Flag values for DT_FLAGS_1 (incomplete) */
 671#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
 672#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
671#define DF_1_INITFIRST 0x00000020 /* Object's init/fini take priority */ 673#define DF_1_INITFIRST 0x00000020 /* Object's init/fini take priority */
 674#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */
672 675
673/* 676/*
674 * Auxiliary Vectors 677 * Auxiliary Vectors
675 */ 678 */
676typedef struct { 679typedef struct {
677 Elf32_Word a_type; /* 32-bit id */ 680 Elf32_Word a_type; /* 32-bit id */
678 Elf32_Word a_v; /* 32-bit id */ 681 Elf32_Word a_v; /* 32-bit id */
679} Aux32Info; 682} Aux32Info;
680 683
681typedef struct { 684typedef struct {
682 Elf64_Word a_type; /* 32-bit id */ 685 Elf64_Word a_type; /* 32-bit id */
683 Elf64_Xword a_v; /* 64-bit id */ 686 Elf64_Xword a_v; /* 64-bit id */
684} Aux64Info; 687} Aux64Info;

cvs diff -r1.2 -r1.3 src/tests/libexec/ld.elf_so/Makefile (expand / switch to unified diff)

--- src/tests/libexec/ld.elf_so/Makefile 2010/12/14 05:57:32 1.2
+++ src/tests/libexec/ld.elf_so/Makefile 2010/12/24 12:41:43 1.3
@@ -1,12 +1,24 @@ @@ -1,12 +1,24 @@
1# $NetBSD 1# $NetBSD
2# 2#
3 3
 4NOMAN= # defined
 5
4.include <bsd.own.mk> 6.include <bsd.own.mk>
5 7
6TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so 8TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so
7 9
8TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo 10TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo
9 11
10LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib 12LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib
11 13
 14TESTS_SH+= t_df_1_noopen
 15
 16BINDIR= ${TESTSDIR}
 17PROGS+= h_df_1_noopen1
 18SRCS.h_df_1_noopen1= h_df_1_noopen.c
 19
 20PROGS+= h_df_1_noopen2
 21SRCS.h_df_1_noopen2= h_df_1_noopen.c
 22LDADD.h_df_1_noopen2= -lpthread
 23
12.include <bsd.test.mk> 24.include <bsd.test.mk>

File Added: src/tests/libexec/ld.elf_so/h_df_1_noopen.c
/*-
 * Copyright (c) 2010 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <dlfcn.h>
#include <err.h>
#include <unistd.h>

int
main(void)
{
	void *handle;

	handle = dlopen("libpthread.so", RTLD_NOLOAD);
	if (handle == NULL)
		errx(1, dlerror());

	printf("libpthread loaded successfully\n");
	return 0;
}

File Added: src/tests/libexec/ld.elf_so/t_df_1_noopen.sh
# $NetBSD: t_df_1_noopen.sh,v 1.1 2010/12/24 12:41:43 skrll Exp $
#
# Copyright (c) 2010 The NetBSD Foundation, Inc.
# All rights reserved.
#
# This code is derived from software contributed to The NetBSD Foundation
# by
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

atf_test_case df_1_noopen1
df_1_noopen1_head()
{
	atf_set "descr" "Checks DF_1_NOOPEN prevents dlopening of library"
}
df_1_noopen1_body()
{
	cat >expout <<EOF
h_df_1_noopen1: Cannot dlopen non-loadable /usr/lib/libpthread.so
EOF

	atf_check -o file:expout "$(atf_get_srcdir)/h_df_1_noopen1"
	atf_expect_exit 1 "libpthread is marked DF_1_NOOPEN"
}

atf_test_case df_1_noopen2
df_1_noopen2_head()
{
	atf_set "descr" "Checks DF_1_NOOPEN is allowed on already loaded library"
}
df_1_noopen2_body()
{
	cat >expout <<EOF
libpthread loaded successfully
EOF

	atf_check -o file:expout "$(atf_get_srcdir)/h_df_1_noopen2"
}

atf_init_test_cases()
{
	atf_add_test_case df_1_noopen1
	atf_add_test_case df_1_noopen2
}