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.diff -r1.187 -r1.188 src/distrib/sets/lists/tests/mi
(skrll)
--- 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 |
--- 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) | |
55 | int dladdr(const void * __restrict, Dl_info * __restrict); | 55 | int dladdr(const void * __restrict, Dl_info * __restrict); | |
56 | int dlctl(void *, int, void *); | 56 | int dlctl(void *, int, void *); | |
57 | int dlinfo(void *, int, void *); | 57 | int 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 |
--- 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 | |||
4 | WARNS= 4 | 4 | WARNS= 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}) | |
10 | ARCHSUBDIR= ${PTHREAD_MACHINE_ARCH} | 10 | ARCHSUBDIR= ${PTHREAD_MACHINE_ARCH} | |
11 | .elif exists(${.CURDIR}/arch/${MACHINE_ARCH}) | 11 | .elif exists(${.CURDIR}/arch/${MACHINE_ARCH}) | |
12 | ARCHSUBDIR= ${MACHINE_ARCH} | 12 | ARCHSUBDIR= ${MACHINE_ARCH} | |
13 | .elif exists(${.CURDIR}/arch/${MACHINE_CPU}) | 13 | .elif exists(${.CURDIR}/arch/${MACHINE_CPU}) | |
14 | ARCHSUBDIR= ${MACHINE_CPU} | 14 | ARCHSUBDIR= ${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 | |||
25 | ARCHDIR= ${.CURDIR}/arch/${ARCHSUBDIR} | 25 | ARCHDIR= ${.CURDIR}/arch/${ARCHSUBDIR} | |
26 | .PATH: ${ARCHDIR} | 26 | .PATH: ${ARCHDIR} | |
27 | 27 | |||
28 | CPPFLAGS+= -I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC | 28 | CPPFLAGS+= -I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC | |
29 | CPPFLAGS+= -D__LIBPTHREAD_SOURCE__ | 29 | CPPFLAGS+= -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. | |
32 | CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc | 32 | CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc | |
33 | 33 | |||
34 | LIB= pthread | 34 | LIB= pthread | |
35 | 35 | |||
36 | LDFLAGS+= -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 | # | |
41 | SRCS= pthread.c | 43 | SRCS= pthread.c | |
42 | SRCS+= pthread_attr.c | 44 | SRCS+= pthread_attr.c | |
43 | SRCS+= pthread_barrier.c | 45 | SRCS+= pthread_barrier.c | |
44 | SRCS+= pthread_cancelstub.c | 46 | SRCS+= pthread_cancelstub.c | |
45 | SRCS+= pthread_cond.c | 47 | SRCS+= pthread_cond.c | |
46 | SRCS+= pthread_lock.c | 48 | SRCS+= pthread_lock.c | |
47 | SRCS+= pthread_misc.c | 49 | SRCS+= pthread_misc.c | |
48 | SRCS+= pthread_mutex.c | 50 | SRCS+= pthread_mutex.c |
--- 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 && |
--- 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 | */ | |
111 | Obj_Entry * | 111 | Obj_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 | |||
185 | static bool | 197 | static 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 | */ | |
278 | int | 291 | int | |
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 | |
303 | int | 330 | int | |
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 |
--- 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; |
--- 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 | |||
763 | void | |||
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 | ||||
763 | static void | 781 | static 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) | |
782 | int | 804 | int | |
@@ -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) | |
813 | void * | 835 | void * | |
814 | dlopen(const char *name, int mode) | 836 | dlopen(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 | */ | |
854 | void * | 893 | void * | |
855 | _rtld_objmain_sym(const char *name) | 894 | _rtld_objmain_sym(const char *name) | |
856 | { | 895 | { |
--- 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 | |||
133 | typedef struct Struct_Obj_Entry { | 132 | typedef 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; | |||
241 | extern Obj_Entry *_rtld_objlist; | 247 | extern Obj_Entry *_rtld_objlist; | |
242 | extern Obj_Entry **_rtld_objtail; | 248 | extern Obj_Entry **_rtld_objtail; | |
243 | extern u_int _rtld_objcount; | 249 | extern u_int _rtld_objcount; | |
244 | extern u_int _rtld_objloads; | 250 | extern u_int _rtld_objloads; | |
245 | extern Obj_Entry *_rtld_objmain; | 251 | extern Obj_Entry *_rtld_objmain; | |
246 | extern Obj_Entry _rtld_objself; | 252 | extern Obj_Entry _rtld_objself; | |
247 | extern Search_Path *_rtld_paths; | 253 | extern Search_Path *_rtld_paths; | |
248 | extern Library_Xform *_rtld_xforms; | 254 | extern Library_Xform *_rtld_xforms; | |
249 | extern bool _rtld_trust; | 255 | extern bool _rtld_trust; | |
250 | extern Objlist _rtld_list_global; | 256 | extern Objlist _rtld_list_global; | |
251 | extern Objlist _rtld_list_main; | 257 | extern Objlist _rtld_list_main; | |
252 | extern Elf_Sym _rtld_sym_zero; | 258 | extern 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 */ | |
267 | void _rtld_error(const char *, ...) | 281 | void _rtld_error(const char *, ...) | |
268 | __attribute__((__format__(__printf__,1,2))); | 282 | __attribute__((__format__(__printf__,1,2))); | |
269 | void _rtld_die(void) __attribute__((__noreturn__)); | 283 | void _rtld_die(void) __attribute__((__noreturn__)); | |
270 | void *_rtld_objmain_sym(const char *); | 284 | void *_rtld_objmain_sym(const char *); | |
271 | void _rtld_debug_state(void); | 285 | void _rtld_debug_state(void); | |
272 | void _rtld_linkmap_add(Obj_Entry *); | 286 | void _rtld_linkmap_add(Obj_Entry *); | |
273 | void _rtld_linkmap_delete(Obj_Entry *); | 287 | void _rtld_linkmap_delete(Obj_Entry *); | |
274 | void _rtld_objlist_push_head(Objlist *, Obj_Entry *); | 288 | void _rtld_objlist_push_head(Objlist *, Obj_Entry *); | |
275 | void _rtld_objlist_push_tail(Objlist *, Obj_Entry *); | 289 | void _rtld_objlist_push_tail(Objlist *, Obj_Entry *); | |
276 | Objlist_Entry *_rtld_objlist_find(Objlist *, const Obj_Entry *); | 290 | Objlist_Entry *_rtld_objlist_find(Objlist *, const Obj_Entry *); | |
291 | void _rtld_ref_dag(Obj_Entry *); | |||
277 | 292 | |||
278 | /* expand.c */ | 293 | /* expand.c */ | |
279 | size_t _rtld_expand_path(char *, size_t, const char *, const char *,\ | 294 | size_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 */ | |
283 | void _rtld_digest_dynamic(const char *, Obj_Entry *); | 298 | void _rtld_digest_dynamic(const char *, Obj_Entry *); | |
284 | Obj_Entry *_rtld_digest_phdr(const Elf_Phdr *, int, caddr_t); | 299 | Obj_Entry *_rtld_digest_phdr(const Elf_Phdr *, int, caddr_t); | |
285 | 300 | |||
286 | /* load.c */ | 301 | /* load.c */ | |
287 | Obj_Entry *_rtld_load_object(const char *, int); | 302 | Obj_Entry *_rtld_load_object(const char *, int); | |
288 | int _rtld_load_needed_objects(Obj_Entry *, int); | 303 | int _rtld_load_needed_objects(Obj_Entry *, int); | |
289 | int _rtld_preload(const char *); | 304 | int _rtld_preload(const char *); | |
290 | 305 | |||
306 | #define OBJ_ERR (Obj_Entry *)(-1) | |||
291 | /* path.c */ | 307 | /* path.c */ | |
292 | void _rtld_add_paths(const char *, Search_Path **, const char *); | 308 | void _rtld_add_paths(const char *, Search_Path **, const char *); | |
293 | void _rtld_process_hints(const char *, Search_Path **, Library_Xform **, | 309 | void _rtld_process_hints(const char *, Search_Path **, Library_Xform **, | |
294 | const char *); | 310 | const char *); | |
295 | int _rtld_sysctl(const char *, void *, size_t *); | 311 | int _rtld_sysctl(const char *, void *, size_t *); | |
296 | 312 | |||
297 | /* reloc.c */ | 313 | /* reloc.c */ | |
298 | int _rtld_do_copy_relocations(const Obj_Entry *); | 314 | int _rtld_do_copy_relocations(const Obj_Entry *); | |
299 | int _rtld_relocate_objects(Obj_Entry *, bool); | 315 | int _rtld_relocate_objects(Obj_Entry *, bool); | |
300 | int _rtld_relocate_nonplt_objects(Obj_Entry *); | 316 | int _rtld_relocate_nonplt_objects(Obj_Entry *); | |
301 | int _rtld_relocate_plt_lazy(const Obj_Entry *); | 317 | int _rtld_relocate_plt_lazy(const Obj_Entry *); | |
302 | int _rtld_relocate_plt_objects(const Obj_Entry *); | 318 | int _rtld_relocate_plt_objects(const Obj_Entry *); | |
303 | void _rtld_setup_pltgot(const Obj_Entry *); | 319 | void _rtld_setup_pltgot(const Obj_Entry *); |
--- 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 | */ | |
63 | Search_Path *_rtld_invalid_paths; | 63 | Search_Path *_rtld_invalid_paths; | |
64 | 64 | |||
65 | static Obj_Entry *_rtld_search_library_path(const char *, size_t, | 65 | static Obj_Entry *_rtld_search_library_path(const char *, size_t, | |
66 | const char *, size_t, int); | 66 | const char *, size_t, int); | |
67 | 67 | |||
68 | static Obj_Entry * | 68 | static 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 | */ | |
117 | Obj_Entry * | 117 | Obj_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 | |||
165 | pathfound: | 165 | pathfound: | |
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 | |||
179 | found: | 185 | found: | |
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 |
--- 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
--- 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 | */ | |
676 | typedef struct { | 679 | typedef 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 | |||
681 | typedef struct { | 684 | typedef 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; |
--- 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 | |||
4 | NOMAN= # defined | |||
5 | ||||
4 | .include <bsd.own.mk> | 6 | .include <bsd.own.mk> | |
5 | 7 | |||
6 | TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so | 8 | TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so | |
7 | 9 | |||
8 | TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo | 10 | TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo | |
9 | 11 | |||
10 | LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib | 12 | LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib | |
11 | 13 | |||
14 | TESTS_SH+= t_df_1_noopen | |||
15 | ||||
16 | BINDIR= ${TESTSDIR} | |||
17 | PROGS+= h_df_1_noopen1 | |||
18 | SRCS.h_df_1_noopen1= h_df_1_noopen.c | |||
19 | ||||
20 | PROGS+= h_df_1_noopen2 | |||
21 | SRCS.h_df_1_noopen2= h_df_1_noopen.c | |||
22 | LDADD.h_df_1_noopen2= -lpthread | |||
23 | ||||
12 | .include <bsd.test.mk> | 24 | .include <bsd.test.mk> |
/*-
* 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;
}
# $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
}