PR/45015: ld.elf_so: support ELF symbol versioning
Applied latest patch.
This commit is contained in:
parent
c4e25001ef
commit
c52f9a5df2
@ -1,4 +1,4 @@
|
||||
# $NetBSD: mi,v 1.1630 2011/06/14 15:27:46 jmmv Exp $
|
||||
# $NetBSD: mi,v 1.1631 2011/06/25 05:45:11 nonaka Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
@ -5814,6 +5814,7 @@
|
||||
./usr/share/man/cat3/dlfcn.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dlopen.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dlsym.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dlvsym.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dm.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dn_comp.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/dn_expand.0 comp-c-catman .cat
|
||||
@ -11908,6 +11909,7 @@
|
||||
./usr/share/man/html3/dlfcn.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dlopen.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dlsym.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dlvsym.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dm.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dn_comp.html comp-c-htmlman html
|
||||
./usr/share/man/html3/dn_expand.html comp-c-htmlman html
|
||||
@ -17911,6 +17913,7 @@
|
||||
./usr/share/man/man3/dlfcn.3 comp-c-man .man
|
||||
./usr/share/man/man3/dlopen.3 comp-c-man .man
|
||||
./usr/share/man/man3/dlsym.3 comp-c-man .man
|
||||
./usr/share/man/man3/dlvsym.3 comp-c-man .man
|
||||
./usr/share/man/man3/dm.3 comp-c-man .man
|
||||
./usr/share/man/man3/dn_comp.3 comp-c-man .man
|
||||
./usr/share/man/man3/dn_expand.3 comp-c-man .man
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: mi,v 1.354 2011/06/20 18:03:41 jruoho Exp $
|
||||
# $NetBSD: mi,v 1.355 2011/06/25 05:45:13 nonaka Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
@ -559,10 +559,17 @@
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so tests-libexec-debug
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen2.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_dl_symver_v0.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_dl_symver_v1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_dl_symver_v2.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0 tests-libexec-debug
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1 tests-libexec-debug
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso2 tests-libexec-debug
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_locking.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-cleared.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-false.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlinfo.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlvsym.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/modules tests-sys-debug
|
||||
./usr/libdata/debug/usr/tests/modules/t_builtin.debug tests-sys-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/modules/t_modctl.debug tests-sys-debug debug,atf
|
||||
@ -2224,13 +2231,40 @@
|
||||
./usr/tests/libexec/Atffile tests-lib-tests atf
|
||||
./usr/tests/libexec/ld.elf_so tests-libexec-tests
|
||||
./usr/tests/libexec/ld.elf_so/Atffile tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_df_1_noopen1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_df_1_noopen2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_dl_symver_v0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_dl_symver_v1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_dl_symver_v2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_locking tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_df_1_noopen tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_dl_symver tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_dlerror-cleared tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_dlerror-false tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_dlinfo tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/t_dlvsym tests-libexec-tests atf
|
||||
./usr/tests/modules tests-sys-tests
|
||||
./usr/tests/net tests-net-tests
|
||||
./usr/tests/net/Atffile tests-net-tests atf
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: shl.mi,v 1.5 2011/05/30 02:10:26 christos Exp $
|
||||
# $NetBSD: shl.mi,v 1.6 2011/06/25 05:45:14 nonaka Exp $
|
||||
#
|
||||
./usr/libdata/debug/usr/tests/lib/csu/libh_initfini3_dso.so.1.debug tests-lib-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/lib/libc/tls/libh_tls_dlopen.so.1.debug tests-lib-debug debug,atf
|
||||
@ -18,8 +18,20 @@
|
||||
./usr/tests/lib/libc/tls/t_tls_dynamic tests-lib-tests atf
|
||||
./usr/tests/util/id/libfake.so.0 tests-obsolete obsolete
|
||||
./usr/tests/util/id/libfake.so.0.0 tests-obsolete obsolete
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso2/libh_helper_symver_dso.so.1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_dso1.so.1.debug tests-libexec-debug debug,atf
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/libh_helper_dso2.so.1.debug tests-libexec-debug debug,atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso_g.a -unknown- atf,debuglib
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso_g.a -unknown- atf,debuglib
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so.1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2/libh_helper_symver_dso_g.a -unknown- atf,debuglib
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2/libh_helper_symver_dso.so tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2/libh_helper_symver_dso.so.1 tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/libh_helper_dso1_g.a -unknown- atf,debuglib
|
||||
./usr/tests/libexec/ld.elf_so/libh_helper_dso1.so tests-libexec-tests atf
|
||||
./usr/tests/libexec/ld.elf_so/libh_helper_dso1.so.1 tests-libexec-tests atf
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: NetBSD.dist.tests,v 1.49 2011/05/30 18:14:11 njoly Exp $
|
||||
# $NetBSD: NetBSD.dist.tests,v 1.50 2011/06/25 05:45:12 nonaka Exp $
|
||||
|
||||
./usr/libdata/debug/usr/tests
|
||||
./usr/libdata/debug/usr/tests/atf
|
||||
@ -88,6 +88,9 @@
|
||||
./usr/libdata/debug/usr/tests/lib/libutil
|
||||
./usr/libdata/debug/usr/tests/libexec
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1
|
||||
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_helper_symver_dso2
|
||||
./usr/libdata/debug/usr/tests/modules
|
||||
./usr/libdata/debug/usr/tests/net
|
||||
./usr/libdata/debug/usr/tests/net/bpf
|
||||
@ -211,6 +214,10 @@
|
||||
./usr/tests/lib/libutil
|
||||
./usr/tests/libexec
|
||||
./usr/tests/libexec/ld.elf_so
|
||||
./usr/tests/libexec/ld.elf_so/data
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso0
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso1
|
||||
./usr/tests/libexec/ld.elf_so/h_helper_symver_dso2
|
||||
./usr/tests/modules
|
||||
./usr/tests/net
|
||||
./usr/tests/net/bpf
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dlfcn.h,v 1.22 2010/12/24 12:41:42 skrll Exp $ */
|
||||
/* $NetBSD: dlfcn.h,v 1.23 2011/06/25 05:45:11 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -55,6 +55,8 @@ void *dlsym(void * __restrict, const char * __restrict);
|
||||
int dladdr(const void * __restrict, Dl_info * __restrict);
|
||||
int dlctl(void *, int, void *);
|
||||
int dlinfo(void *, int, void *);
|
||||
void *dlvsym(void * __restrict, const char * __restrict,
|
||||
const char * __restrict);
|
||||
#endif
|
||||
__aconst char *dlerror(void);
|
||||
__END_DECLS
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dlfcn_elf.c,v 1.9 2011/03/12 21:55:09 joerg Exp $ */
|
||||
/* $NetBSD: dlfcn_elf.c,v 1.10 2011/06/25 05:45:11 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Takuya SHIOZAKI
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: dlfcn_elf.c,v 1.9 2011/03/12 21:55:09 joerg Exp $");
|
||||
__RCSID("$NetBSD: dlfcn_elf.c,v 1.10 2011/06/25 05:45:11 nonaka Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
@ -47,6 +47,7 @@ __RCSID("$NetBSD: dlfcn_elf.c,v 1.9 2011/03/12 21:55:09 joerg Exp $");
|
||||
#define dlopen ___dlopen
|
||||
#define dlclose ___dlclose
|
||||
#define dlsym ___dlsym
|
||||
#define dlvsym ___dlvsym
|
||||
#define dlerror ___dlerror
|
||||
#define dladdr ___dladdr
|
||||
#define dlinfo ___dlinfo
|
||||
@ -59,6 +60,7 @@ __RCSID("$NetBSD: dlfcn_elf.c,v 1.9 2011/03/12 21:55:09 joerg Exp $");
|
||||
__weak_alias(dlopen,___dlopen)
|
||||
__weak_alias(dlclose,___dlclose)
|
||||
__weak_alias(dlsym,___dlsym)
|
||||
__weak_alias(dlvsym,___dlvsym)
|
||||
__weak_alias(dlerror,___dlerror)
|
||||
__weak_alias(dladdr,___dladdr)
|
||||
__weak_alias(dlinfo,___dlinfo)
|
||||
@ -67,6 +69,7 @@ __weak_alias(dl_iterate_phdr,___dl_iterate_phdr)
|
||||
__weak_alias(__dlopen,___dlopen)
|
||||
__weak_alias(__dlclose,___dlclose)
|
||||
__weak_alias(__dlsym,___dlsym)
|
||||
__weak_alias(__dlvsym,___dlvsym)
|
||||
__weak_alias(__dlerror,___dlerror)
|
||||
__weak_alias(__dladdr,___dladdr)
|
||||
__weak_alias(__dlinfo,___dlinfo)
|
||||
@ -109,6 +112,14 @@ dlsym(void *handle, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void *
|
||||
dlvsym(void *handle, const char *name, const char *version)
|
||||
{
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
__aconst char *
|
||||
dlerror()
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.107 2011/06/05 23:08:17 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.108 2011/06/25 05:45:12 nonaka Exp $
|
||||
#
|
||||
# NOTE: when changing ld.so, ensure that ldd still compiles.
|
||||
#
|
||||
@ -63,7 +63,7 @@ CLIBOBJ!= cd ${NETBSDSRCDIR}/lib/libc && ${PRINTOBJDIR}
|
||||
|
||||
SRCS+= rtld.c reloc.c symbol.c xmalloc.c xprintf.c debug.c \
|
||||
map_object.c load.c search.c headers.c paths.c expand.c \
|
||||
tls.c
|
||||
tls.c symver.c
|
||||
|
||||
.if ${USE_FORT} == "yes"
|
||||
.PATH.c: ${NETBSDSRCDIR}/lib/libc/misc
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: headers.c,v 1.40 2011/03/09 23:10:07 joerg Exp $ */
|
||||
/* $NetBSD: headers.c,v 1.41 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: headers.c,v 1.40 2011/03/09 23:10:07 joerg Exp $");
|
||||
__RCSID("$NetBSD: headers.c,v 1.41 2011/06/25 05:45:12 nonaka Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
@ -136,6 +136,29 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
|
||||
obj->strsize = dynp->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_VERNEED:
|
||||
obj->verneed = (const Elf_Verneed *)
|
||||
(obj->relocbase + dynp->d_un.d_ptr);
|
||||
break;
|
||||
|
||||
case DT_VERNEEDNUM:
|
||||
obj->verneednum = dynp->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_VERDEF:
|
||||
obj->verdef = (const Elf_Verdef *)
|
||||
(obj->relocbase + dynp->d_un.d_ptr);
|
||||
break;
|
||||
|
||||
case DT_VERDEFNUM:
|
||||
obj->verdefnum = dynp->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_VERSYM:
|
||||
obj->versyms = (const Elf_Versym *)
|
||||
(obj->relocbase + dynp->d_un.d_ptr);
|
||||
break;
|
||||
|
||||
case DT_HASH:
|
||||
{
|
||||
const Elf_Symindx *hashtab = (const Elf_Symindx *)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll Exp $ */
|
||||
/* $NetBSD: reloc.c,v 1.104 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll Exp $");
|
||||
__RCSID("$NetBSD: reloc.c,v 1.104 2011/06/25 05:45:12 nonaka Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
@ -73,9 +73,12 @@ _rtld_do_copy_relocation(const Obj_Entry *dstobj, const Elf_Rela *rela)
|
||||
const Elf_Sym *srcsym = NULL;
|
||||
Obj_Entry *srcobj;
|
||||
|
||||
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
|
||||
if ((srcsym = _rtld_symlook_obj(name, hash, srcobj, false)) != NULL)
|
||||
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next) {
|
||||
srcsym = _rtld_symlook_obj(name, hash, srcobj, 0,
|
||||
_rtld_fetch_ventry(dstobj, ELF_R_SYM(rela->r_info)));
|
||||
if (srcsym != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (srcobj == NULL) {
|
||||
_rtld_error("Undefined symbol \"%s\" referenced from COPY"
|
||||
@ -210,6 +213,7 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now)
|
||||
/* Fill in the dynamic linker entry points. */
|
||||
obj->dlopen = dlopen;
|
||||
obj->dlsym = dlsym;
|
||||
obj->dlvsym = dlvsym;
|
||||
obj->dlerror = dlerror;
|
||||
obj->dlclose = dlclose;
|
||||
obj->dladdr = dladdr;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.c,v 1.150 2011/04/02 16:49:49 joerg Exp $ */
|
||||
/* $NetBSD: rtld.c,v 1.151 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: rtld.c,v 1.150 2011/04/02 16:49:49 joerg Exp $");
|
||||
__RCSID("$NetBSD: rtld.c,v 1.151 2011/06/25 05:45:12 nonaka Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -373,9 +373,7 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
|
||||
char **env, **oenvp;
|
||||
const AuxInfo *aux;
|
||||
const AuxInfo *auxp;
|
||||
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
|
||||
Obj_Entry *obj;
|
||||
#endif
|
||||
Elf_Addr *const osp = sp;
|
||||
bool bind_now = 0;
|
||||
const char *ld_bind_now, *ld_preload, *ld_library_path;
|
||||
@ -635,6 +633,12 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
|
||||
if (_rtld_load_needed_objects(_rtld_objmain, _RTLD_MAIN) == -1)
|
||||
_rtld_die();
|
||||
|
||||
dbg(("checking for required versions"));
|
||||
for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
|
||||
if (_rtld_verify_object_versions(obj) == -1)
|
||||
_rtld_die();
|
||||
}
|
||||
|
||||
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
|
||||
dbg(("initializing initial Thread Local Storage"));
|
||||
/*
|
||||
@ -930,6 +934,7 @@ dlopen(const char *name, int mode)
|
||||
bool nodelete;
|
||||
bool now;
|
||||
sigset_t mask;
|
||||
int result;
|
||||
|
||||
dbg(("dlopen of %s %d", name, mode));
|
||||
|
||||
@ -956,10 +961,18 @@ dlopen(const char *name, int mode)
|
||||
if (*old_obj_tail != NULL) { /* We loaded something new. */
|
||||
assert(*old_obj_tail == obj);
|
||||
|
||||
if (_rtld_load_needed_objects(obj, flags) == -1 ||
|
||||
(_rtld_init_dag(obj),
|
||||
_rtld_relocate_objects(obj,
|
||||
(now || obj->z_now))) == -1) {
|
||||
result = _rtld_load_needed_objects(obj, flags);
|
||||
if (result != -1) {
|
||||
Objlist_Entry *entry;
|
||||
_rtld_init_dag(obj);
|
||||
SIMPLEQ_FOREACH(entry, &obj->dagmembers, link) {
|
||||
result = _rtld_verify_object_versions(entry->obj);
|
||||
if (result == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == -1 || _rtld_relocate_objects(obj,
|
||||
(now || obj->z_now)) == -1) {
|
||||
_rtld_unload_object(&mask, obj, false);
|
||||
obj->dl_refcount--;
|
||||
obj = NULL;
|
||||
@ -998,8 +1011,8 @@ _rtld_objmain_sym(const char *name)
|
||||
obj = _rtld_objmain;
|
||||
_rtld_donelist_init(&donelist);
|
||||
|
||||
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, false,
|
||||
&donelist);
|
||||
def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, 0,
|
||||
NULL, &donelist);
|
||||
|
||||
if (def != NULL)
|
||||
return obj->relocbase + def->st_value;
|
||||
@ -1022,9 +1035,8 @@ hackish_return_address(void)
|
||||
#define lookup_mutex_exit() _rtld_shared_exit()
|
||||
#endif
|
||||
|
||||
__strong_alias(__dlsym,dlsym)
|
||||
void *
|
||||
dlsym(void *handle, const char *name)
|
||||
static void *
|
||||
do_dlsym(void *handle, const char *name, const Ver_Entry *ventry)
|
||||
{
|
||||
const Obj_Entry *obj;
|
||||
unsigned long hash;
|
||||
@ -1032,12 +1044,11 @@ dlsym(void *handle, const char *name)
|
||||
const Obj_Entry *defobj;
|
||||
void *retaddr;
|
||||
DoneList donelist;
|
||||
const u_int flags = SYMLOOK_DLSYM | SYMLOOK_IN_PLT;
|
||||
#ifdef __HAVE_FUNCTION_DESCRIPTORS
|
||||
sigset_t mask;
|
||||
#endif
|
||||
|
||||
dbg(("dlsym of %s in %p", name, handle));
|
||||
|
||||
lookup_mutex_enter();
|
||||
|
||||
hash = _rtld_elf_hash(name);
|
||||
@ -1062,7 +1073,7 @@ dlsym(void *handle, const char *name)
|
||||
|
||||
switch ((intptr_t)handle) {
|
||||
case (intptr_t)NULL: /* Just the caller's shared object. */
|
||||
def = _rtld_symlook_obj(name, hash, obj, false);
|
||||
def = _rtld_symlook_obj(name, hash, obj, flags, ventry);
|
||||
defobj = obj;
|
||||
break;
|
||||
|
||||
@ -1073,7 +1084,7 @@ dlsym(void *handle, const char *name)
|
||||
case (intptr_t)RTLD_SELF: /* Caller included */
|
||||
for (; obj; obj = obj->next) {
|
||||
if ((def = _rtld_symlook_obj(name, hash, obj,
|
||||
false)) != NULL) {
|
||||
flags, ventry)) != NULL) {
|
||||
defobj = obj;
|
||||
break;
|
||||
}
|
||||
@ -1082,7 +1093,7 @@ dlsym(void *handle, const char *name)
|
||||
|
||||
case (intptr_t)RTLD_DEFAULT:
|
||||
def = _rtld_symlook_default(name, hash, obj, &defobj,
|
||||
false);
|
||||
flags, ventry);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1101,7 +1112,7 @@ dlsym(void *handle, const char *name)
|
||||
if (obj->mainprog) {
|
||||
/* Search main program and all libraries loaded by it */
|
||||
def = _rtld_symlook_list(name, hash, &_rtld_list_main,
|
||||
&defobj, false, &donelist);
|
||||
&defobj, flags, ventry, &donelist);
|
||||
} else {
|
||||
Needed_Entry fake;
|
||||
DoneList depth;
|
||||
@ -1113,7 +1124,7 @@ dlsym(void *handle, const char *name)
|
||||
|
||||
_rtld_donelist_init(&depth);
|
||||
def = _rtld_symlook_needed(name, hash, &fake, &defobj,
|
||||
false, &donelist, &depth);
|
||||
flags, ventry, &donelist, &depth);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1139,6 +1150,35 @@ dlsym(void *handle, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__strong_alias(__dlsym,dlsym)
|
||||
void *
|
||||
dlsym(void *handle, const char *name)
|
||||
{
|
||||
|
||||
dbg(("dlsym of %s in %p", name, handle));
|
||||
|
||||
return do_dlsym(handle, name, NULL);
|
||||
}
|
||||
|
||||
__strong_alias(__dlvsym,dlvsym)
|
||||
void *
|
||||
dlvsym(void *handle, const char *name, const char *version)
|
||||
{
|
||||
Ver_Entry *ventry = NULL;
|
||||
Ver_Entry ver_entry;
|
||||
|
||||
dbg(("dlvsym of %s@%s in %p", name, version ? version : NULL, handle));
|
||||
|
||||
if (version != NULL) {
|
||||
ver_entry.name = version;
|
||||
ver_entry.file = NULL;
|
||||
ver_entry.hash = _rtld_elf_hash(version);
|
||||
ver_entry.flags = 0;
|
||||
ventry = &ver_entry;
|
||||
}
|
||||
return do_dlsym(handle, name, ventry);
|
||||
}
|
||||
|
||||
__strong_alias(__dladdr,dladdr)
|
||||
int
|
||||
dladdr(const void *addr, Dl_info *info)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtld.h,v 1.105 2011/03/29 20:56:35 joerg Exp $ */
|
||||
/* $NetBSD: rtld.h,v 1.106 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -104,6 +104,16 @@ typedef struct _rtld_search_path_t {
|
||||
size_t sp_pathlen;
|
||||
} Search_Path;
|
||||
|
||||
typedef struct Struct_Ver_Entry {
|
||||
Elf_Word hash;
|
||||
u_int flags;
|
||||
const char *name;
|
||||
const char *file;
|
||||
} Ver_Entry;
|
||||
|
||||
/* Ver_Entry.flags */
|
||||
#define VER_INFO_HIDDEN 0x01
|
||||
|
||||
|
||||
#define RTLD_MAX_ENTRY 10
|
||||
#define RTLD_MAX_LIBRARY 4
|
||||
@ -184,6 +194,7 @@ typedef struct Struct_Obj_Entry {
|
||||
/* Entry points for dlopen() and friends. */
|
||||
void *(*dlopen)(const char *, int);
|
||||
void *(*dlsym)(void *, const char *);
|
||||
void *(*dlvsym)(void *, const char *, const char *);
|
||||
char *(*dlerror)(void);
|
||||
int (*dlclose)(void *);
|
||||
int (*dladdr)(const void *, Dl_info *);
|
||||
@ -251,6 +262,17 @@ typedef struct Struct_Obj_Entry {
|
||||
size_t tlsoffset; /* Offset in the static TLS block */
|
||||
size_t tlsalign; /* Needed alignment for static TLS */
|
||||
#endif
|
||||
|
||||
/* symbol versioning */
|
||||
const Elf_Verneed *verneed; /* Required versions. */
|
||||
Elf_Word verneednum; /* Number of entries in verneed table */
|
||||
const Elf_Verdef *verdef; /* Provided versions. */
|
||||
Elf_Word verdefnum; /* Number of entries in verdef table */
|
||||
const Elf_Versym *versyms; /* Symbol versions table */
|
||||
|
||||
Ver_Entry *vertab; /* Versions required/defined by this
|
||||
* object */
|
||||
int vertabnum; /* Number of entries in vertab */
|
||||
} Obj_Entry;
|
||||
|
||||
typedef struct Struct_DoneList {
|
||||
@ -279,6 +301,11 @@ extern Elf_Sym _rtld_sym_zero;
|
||||
|
||||
#define RTLD_MODEMASK 0x3
|
||||
|
||||
/* Flags to be passed into _rtld_symlook_ family of functions. */
|
||||
#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */
|
||||
#define SYMLOOK_DLSYM 0x02 /* Return newes versioned symbol.
|
||||
Used by dlsym. */
|
||||
|
||||
/* Flags for _rtld_load_object() and friends. */
|
||||
#define _RTLD_GLOBAL 0x01 /* Add object to global DAG. */
|
||||
#define _RTLD_MAIN 0x02
|
||||
@ -352,23 +379,44 @@ Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
|
||||
/* symbol.c */
|
||||
unsigned long _rtld_elf_hash(const char *);
|
||||
const Elf_Sym *_rtld_symlook_obj(const char *, unsigned long,
|
||||
const Obj_Entry *, bool);
|
||||
const Obj_Entry *, u_int, const Ver_Entry *);
|
||||
const Elf_Sym *_rtld_find_symdef(unsigned long, const Obj_Entry *,
|
||||
const Obj_Entry **, bool);
|
||||
const Obj_Entry **, u_int);
|
||||
const Elf_Sym *_rtld_find_plt_symdef(unsigned long, const Obj_Entry *,
|
||||
const Obj_Entry **, bool);
|
||||
|
||||
const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
|
||||
const Objlist *, const Obj_Entry **, bool, DoneList *);
|
||||
const Objlist *, const Obj_Entry **, u_int, const Ver_Entry *, DoneList *);
|
||||
const Elf_Sym *_rtld_symlook_default(const char *, unsigned long,
|
||||
const Obj_Entry *, const Obj_Entry **, bool);
|
||||
const Obj_Entry *, const Obj_Entry **, u_int, const Ver_Entry *);
|
||||
const Elf_Sym *_rtld_symlook_needed(const char *, unsigned long,
|
||||
const Needed_Entry *, const Obj_Entry **, bool,
|
||||
const Needed_Entry *, const Obj_Entry **, u_int, const Ver_Entry *,
|
||||
DoneList *, DoneList *);
|
||||
#ifdef COMBRELOC
|
||||
void _rtld_combreloc_reset(const Obj_Entry *);
|
||||
#endif
|
||||
|
||||
/* symver.c */
|
||||
int _rtld_object_match_name(const Obj_Entry *, const char *);
|
||||
int _rtld_verify_object_versions(Obj_Entry *);
|
||||
|
||||
static __inline const Ver_Entry *
|
||||
_rtld_fetch_ventry(const Obj_Entry *obj, unsigned long symnum)
|
||||
{
|
||||
Elf_Half vernum;
|
||||
|
||||
if (obj->vertab) {
|
||||
vernum = VER_NDX(obj->versyms[symnum].vs_vers);
|
||||
if (vernum >= obj->vertabnum) {
|
||||
_rtld_error("%s: symbol %s has wrong verneed value %d",
|
||||
obj->path, &obj->strtab[symnum], vernum);
|
||||
} else if (obj->vertab[vernum].hash) {
|
||||
return &obj->vertab[vernum];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
|
||||
/* tls.c */
|
||||
void *_rtld_tls_get_addr(void *, size_t, size_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: symbol.c,v 1.56 2011/03/12 22:54:36 joerg Exp $ */
|
||||
/* $NetBSD: symbol.c,v 1.57 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 John D. Polstra.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: symbol.c,v 1.56 2011/03/12 22:54:36 joerg Exp $");
|
||||
__RCSID("$NetBSD: symbol.c,v 1.57 2011/06/25 05:45:12 nonaka Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <err.h>
|
||||
@ -89,6 +89,7 @@ _rtld_is_exported(const Elf_Sym *def)
|
||||
(fptr_t)dlopen,
|
||||
(fptr_t)dlclose,
|
||||
(fptr_t)dlsym,
|
||||
(fptr_t)dlvsym,
|
||||
(fptr_t)dlerror,
|
||||
(fptr_t)dladdr,
|
||||
(fptr_t)dlinfo,
|
||||
@ -139,7 +140,8 @@ _rtld_elf_hash(const char *name)
|
||||
|
||||
const Elf_Sym *
|
||||
_rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
|
||||
const Obj_Entry **defobj_out, bool in_plt, DoneList *dlp)
|
||||
const Obj_Entry **defobj_out, u_int flags, const Ver_Entry *ventry,
|
||||
DoneList *dlp)
|
||||
{
|
||||
const Elf_Sym *symp;
|
||||
const Elf_Sym *def;
|
||||
@ -153,8 +155,8 @@ _rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
|
||||
continue;
|
||||
rdbg(("search object %p (%s) for %s", elm->obj, elm->obj->path,
|
||||
name));
|
||||
if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
|
||||
!= NULL) {
|
||||
symp = _rtld_symlook_obj(name, hash, elm->obj, flags, ventry);
|
||||
if (symp != NULL) {
|
||||
if ((def == NULL) ||
|
||||
(ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||
def = symp;
|
||||
@ -176,8 +178,8 @@ _rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
|
||||
*/
|
||||
const Elf_Sym *
|
||||
_rtld_symlook_needed(const char *name, unsigned long hash,
|
||||
const Needed_Entry *needed, const Obj_Entry **defobj_out, bool inplt,
|
||||
DoneList *breadth, DoneList *depth)
|
||||
const Needed_Entry *needed, const Obj_Entry **defobj_out, u_int flags,
|
||||
const Ver_Entry *ventry, DoneList *breadth, DoneList *depth)
|
||||
{
|
||||
const Elf_Sym *def, *def_w;
|
||||
const Needed_Entry *n;
|
||||
@ -190,7 +192,8 @@ _rtld_symlook_needed(const char *name, unsigned long hash,
|
||||
continue;
|
||||
if (_rtld_donelist_check(breadth, obj))
|
||||
continue;
|
||||
if ((def = _rtld_symlook_obj(name, hash, obj, inplt)) == NULL)
|
||||
def = _rtld_symlook_obj(name, hash, obj, flags, ventry);
|
||||
if (def == NULL)
|
||||
continue;
|
||||
defobj = obj;
|
||||
if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
|
||||
@ -209,7 +212,7 @@ _rtld_symlook_needed(const char *name, unsigned long hash,
|
||||
if (_rtld_donelist_check(depth, obj))
|
||||
continue;
|
||||
def_w = _rtld_symlook_needed(name, hash, obj->needed, &defobj1,
|
||||
inplt, breadth, depth);
|
||||
flags, ventry, breadth, depth);
|
||||
if (def_w == NULL)
|
||||
continue;
|
||||
if (def == NULL || ELF_ST_BIND(def_w->st_info) != STB_WEAK) {
|
||||
@ -235,9 +238,12 @@ _rtld_symlook_needed(const char *name, unsigned long hash,
|
||||
*/
|
||||
const Elf_Sym *
|
||||
_rtld_symlook_obj(const char *name, unsigned long hash,
|
||||
const Obj_Entry *obj, bool in_plt)
|
||||
const Obj_Entry *obj, u_int flags, const Ver_Entry *ventry)
|
||||
{
|
||||
unsigned long symnum;
|
||||
const Elf_Sym *vsymp = NULL;
|
||||
Elf_Half verndx;
|
||||
int vcount = 0;
|
||||
|
||||
for (symnum = obj->buckets[fast_remainder32(hash, obj->nbuckets,
|
||||
obj->nbuckets_m, obj->nbuckets_s1, obj->nbuckets_s2)];
|
||||
@ -250,29 +256,105 @@ _rtld_symlook_obj(const char *name, unsigned long hash,
|
||||
symp = obj->symtab + symnum;
|
||||
strp = obj->strtab + symp->st_name;
|
||||
rdbg(("check \"%s\" vs \"%s\" in %p", name, strp, obj));
|
||||
if (name[1] == strp[1] && !strcmp(name, strp)) {
|
||||
if (symp->st_shndx != SHN_UNDEF)
|
||||
return symp;
|
||||
if (name[1] != strp[1] || strcmp(name, strp))
|
||||
continue;
|
||||
if (symp->st_shndx != SHN_UNDEF)
|
||||
/* Nothing to do */;
|
||||
#ifndef __mips__
|
||||
/*
|
||||
* XXX DANGER WILL ROBINSON!
|
||||
* If we have a function pointer in the executable's
|
||||
* data section, it points to the executable's PLT
|
||||
* slot, and there is NO relocation emitted. To make
|
||||
* the function pointer comparable to function pointers
|
||||
* in shared libraries, we must resolve data references
|
||||
* in the libraries to point to PLT slots in the
|
||||
* executable, if they exist.
|
||||
*/
|
||||
else if (!in_plt && symp->st_value != 0 &&
|
||||
ELF_ST_TYPE(symp->st_info) == STT_FUNC)
|
||||
return symp;
|
||||
/*
|
||||
* XXX DANGER WILL ROBINSON!
|
||||
* If we have a function pointer in the executable's
|
||||
* data section, it points to the executable's PLT
|
||||
* slot, and there is NO relocation emitted. To make
|
||||
* the function pointer comparable to function pointers
|
||||
* in shared libraries, we must resolve data references
|
||||
* in the libraries to point to PLT slots in the
|
||||
* executable, if they exist.
|
||||
*/
|
||||
else if (!(flags & SYMLOOK_IN_PLT) &&
|
||||
symp->st_value != 0 &&
|
||||
ELF_ST_TYPE(symp->st_info) == STT_FUNC)
|
||||
/* Nothing to do */;
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (ventry == NULL) {
|
||||
if (obj->versyms != NULL) {
|
||||
verndx = VER_NDX(obj->versyms[symnum].vs_vers);
|
||||
if (verndx > obj->vertabnum) {
|
||||
_rtld_error("%s: symbol %s references "
|
||||
"wrong version %d", obj->path,
|
||||
&obj->strtab[symnum], verndx);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are not called from dlsym (i.e. this
|
||||
* is a normal relocation from unversioned
|
||||
* binary), accept the symbol immediately
|
||||
* if it happens to have first version after
|
||||
* this shared object became versioned.
|
||||
* Otherwise, if symbol is versioned and not
|
||||
* hidden, remember it. If it is the only
|
||||
* symbol with this name exported by the shared
|
||||
* object, it will be returned as a match at the
|
||||
* end of the function. If symbol is global
|
||||
* (verndx < 2) accept it unconditionally.
|
||||
*/
|
||||
if (!(flags & SYMLOOK_DLSYM) &&
|
||||
verndx == VER_NDX_GIVEN) {
|
||||
return symp;
|
||||
} else if (verndx >= VER_NDX_GIVEN) {
|
||||
if (!(obj->versyms[symnum].vs_vers & VER_NDX_HIDDEN)) {
|
||||
if (vsymp == NULL)
|
||||
vsymp = symp;
|
||||
vcount++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return symp;
|
||||
} else {
|
||||
if (obj->versyms == NULL) {
|
||||
if (_rtld_object_match_name(obj, ventry->name)){
|
||||
_rtld_error("%s: object %s should "
|
||||
"provide version %s for symbol %s",
|
||||
_rtld_objself.path, obj->path,
|
||||
ventry->name, &obj->strtab[symnum]);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
verndx = VER_NDX(obj->versyms[symnum].vs_vers);
|
||||
if (verndx > obj->vertabnum) {
|
||||
_rtld_error("%s: symbol %s references "
|
||||
"wrong version %d", obj->path,
|
||||
&obj->strtab[symnum], verndx);
|
||||
continue;
|
||||
}
|
||||
if (obj->vertab[verndx].hash != ventry->hash ||
|
||||
strcmp(obj->vertab[verndx].name, ventry->name)) {
|
||||
/*
|
||||
* Version does not match. Look if this
|
||||
* is a global symbol and if it is not
|
||||
* hidden. If global symbol (verndx < 2)
|
||||
* is available, use it. Do not return
|
||||
* symbol if we are called by dlvsym,
|
||||
* because dlvsym looks for a specific
|
||||
* version and default one is not what
|
||||
* dlvsym wants.
|
||||
*/
|
||||
if ((flags & SYMLOOK_DLSYM) ||
|
||||
(obj->versyms[symnum].vs_vers & VER_NDX_HIDDEN) ||
|
||||
(verndx >= VER_NDX_GIVEN))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return symp;
|
||||
}
|
||||
}
|
||||
|
||||
if (vcount == 1)
|
||||
return vsymp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -299,7 +381,7 @@ _rtld_combreloc_reset(const Obj_Entry *obj)
|
||||
*/
|
||||
const Elf_Sym *
|
||||
_rtld_find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
const Obj_Entry **defobj_out, bool in_plt)
|
||||
const Obj_Entry **defobj_out, u_int flags)
|
||||
{
|
||||
const Elf_Sym *ref;
|
||||
const Elf_Sym *def;
|
||||
@ -320,7 +402,7 @@ _rtld_find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
static const Elf_Sym *last_def;
|
||||
|
||||
if (symnum == last_symnum && refobj == _rtld_last_refobj
|
||||
&& in_plt == false) {
|
||||
&& !(flags & SYMLOOK_IN_PLT)) {
|
||||
*defobj_out = last_defobj;
|
||||
return last_def;
|
||||
}
|
||||
@ -342,7 +424,8 @@ _rtld_find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
|
||||
hash = _rtld_elf_hash(name);
|
||||
defobj = NULL;
|
||||
def = _rtld_symlook_default(name, hash, refobj, &defobj, in_plt);
|
||||
def = _rtld_symlook_default(name, hash, refobj, &defobj, flags,
|
||||
_rtld_fetch_ventry(refobj, symnum));
|
||||
} else {
|
||||
rdbg(("STB_LOCAL symbol %s in %s", name, refobj->path));
|
||||
def = ref;
|
||||
@ -362,7 +445,7 @@ _rtld_find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
if (def != NULL) {
|
||||
*defobj_out = defobj;
|
||||
#ifdef COMBRELOC
|
||||
if (in_plt == false) {
|
||||
if (!(flags & SYMLOOK_IN_PLT)) {
|
||||
/*
|
||||
* Cache the lookup arguments and results if this was
|
||||
* non-PLT lookup.
|
||||
@ -376,7 +459,8 @@ _rtld_find_symdef(unsigned long symnum, const Obj_Entry *refobj,
|
||||
} else {
|
||||
rdbg(("lookup failed"));
|
||||
_rtld_error("%s: Undefined %ssymbol \"%s\" (symnum = %ld)",
|
||||
refobj->path, in_plt ? "PLT " : "", name, symnum);
|
||||
refobj->path, (flags & SYMLOOK_IN_PLT) ? "PLT " : "",
|
||||
name, symnum);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
@ -385,7 +469,8 @@ const Elf_Sym *
|
||||
_rtld_find_plt_symdef(unsigned long symnum, const Obj_Entry *obj,
|
||||
const Obj_Entry **defobj, bool imm)
|
||||
{
|
||||
const Elf_Sym *def = _rtld_find_symdef(symnum, obj, defobj, true);
|
||||
const Elf_Sym *def = _rtld_find_symdef(symnum, obj, defobj,
|
||||
SYMLOOK_IN_PLT);
|
||||
if (__predict_false(def == NULL))
|
||||
return NULL;
|
||||
|
||||
@ -412,7 +497,8 @@ _rtld_find_plt_symdef(unsigned long symnum, const Obj_Entry *obj,
|
||||
*/
|
||||
const Elf_Sym *
|
||||
_rtld_symlook_default(const char *name, unsigned long hash,
|
||||
const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt)
|
||||
const Obj_Entry *refobj, const Obj_Entry **defobj_out, u_int flags,
|
||||
const Ver_Entry *ventry)
|
||||
{
|
||||
const Elf_Sym *def;
|
||||
const Elf_Sym *symp;
|
||||
@ -428,7 +514,7 @@ _rtld_symlook_default(const char *name, unsigned long hash,
|
||||
/* Look first in the referencing object if linked symbolically. */
|
||||
if (refobj->symbolic && !_rtld_donelist_check(&donelist, refobj)) {
|
||||
rdbg(("search referencing object for %s", name));
|
||||
symp = _rtld_symlook_obj(name, hash, refobj, in_plt);
|
||||
symp = _rtld_symlook_obj(name, hash, refobj, flags, ventry);
|
||||
if (symp != NULL) {
|
||||
def = symp;
|
||||
defobj = refobj;
|
||||
@ -439,7 +525,7 @@ _rtld_symlook_default(const char *name, unsigned long hash,
|
||||
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
|
||||
rdbg(("search _rtld_list_main for %s", name));
|
||||
symp = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj,
|
||||
in_plt, &donelist);
|
||||
flags, ventry, &donelist);
|
||||
if (symp != NULL &&
|
||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||
def = symp;
|
||||
@ -451,7 +537,7 @@ _rtld_symlook_default(const char *name, unsigned long hash,
|
||||
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
|
||||
rdbg(("search _rtld_list_global for %s", name));
|
||||
symp = _rtld_symlook_list(name, hash, &_rtld_list_global,
|
||||
&obj, in_plt, &donelist);
|
||||
&obj, flags, ventry, &donelist);
|
||||
if (symp != NULL &&
|
||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||
def = symp;
|
||||
@ -466,7 +552,7 @@ _rtld_symlook_default(const char *name, unsigned long hash,
|
||||
rdbg(("search DAG with root %p (%s) for %s", elm->obj,
|
||||
elm->obj->path, name));
|
||||
symp = _rtld_symlook_list(name, hash, &elm->obj->dagmembers,
|
||||
&obj, in_plt, &donelist);
|
||||
&obj, flags, ventry, &donelist);
|
||||
if (symp != NULL &&
|
||||
(def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
|
||||
def = symp;
|
||||
@ -483,7 +569,8 @@ _rtld_symlook_default(const char *name, unsigned long hash,
|
||||
*/
|
||||
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
|
||||
rdbg(("Search the dynamic linker itself."));
|
||||
symp = _rtld_symlook_obj(name, hash, &_rtld_objself, in_plt);
|
||||
symp = _rtld_symlook_obj(name, hash, &_rtld_objself, flags,
|
||||
ventry);
|
||||
if (symp != NULL && _rtld_is_exported(symp)) {
|
||||
def = symp;
|
||||
defobj = &_rtld_objself;
|
||||
|
317
libexec/ld.elf_so/symver.c
Normal file
317
libexec/ld.elf_so/symver.c
Normal file
@ -0,0 +1,317 @@
|
||||
/* $NetBSD: symver.c,v 1.1 2011/06/25 05:45:12 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
|
||||
* Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
|
||||
* Copyright 2009, 2010, 2011 Konstantin Belousov <kib@FreeBSD.ORG>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD: head/libexec/rtld-elf/rtld.c 220004 2011-03-25 18:23:10Z avg $
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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 <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: symver.c,v 1.1 2011/06/25 05:45:12 nonaka Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/exec_elf.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "rtld.h"
|
||||
|
||||
|
||||
int
|
||||
_rtld_object_match_name(const Obj_Entry *obj, const char *name)
|
||||
{
|
||||
Name_Entry *entry;
|
||||
|
||||
STAILQ_FOREACH(entry, &obj->names, link) {
|
||||
dbg(("name: %s, entry->name: %s", name, entry->name));
|
||||
if (strcmp(name, entry->name) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Obj_Entry *
|
||||
locate_dependency(const Obj_Entry *obj, const char *name)
|
||||
{
|
||||
const Objlist_Entry *entry;
|
||||
const Needed_Entry *needed;
|
||||
|
||||
SIMPLEQ_FOREACH(entry, &_rtld_list_main, link) {
|
||||
if (_rtld_object_match_name(entry->obj, name))
|
||||
return entry->obj;
|
||||
}
|
||||
|
||||
for (needed = obj->needed; needed != NULL; needed = needed->next) {
|
||||
dbg(("needed: name: %s, str: %s", name,
|
||||
&obj->strtab[needed->name]));
|
||||
if (strcmp(name, &obj->strtab[needed->name]) == 0 ||
|
||||
(needed->obj != NULL && _rtld_object_match_name(needed->obj, name))) {
|
||||
/*
|
||||
* If there is DT_NEEDED for the name we are looking
|
||||
* for, we are all set. Note that object might not be
|
||||
* found if dependency was not loaded yet, so the
|
||||
* function can return NULL here. This is expected
|
||||
* and handled properly by the caller.
|
||||
*/
|
||||
return needed->obj;
|
||||
}
|
||||
}
|
||||
|
||||
_rtld_error("%s: Unexpected inconsistency: dependency %s not found",
|
||||
obj->path, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
check_object_provided_version(Obj_Entry *refobj, const Obj_Entry *depobj,
|
||||
const Elf_Vernaux *vna)
|
||||
{
|
||||
const char *vername = &refobj->strtab[vna->vna_name];
|
||||
const char *depstrtab = depobj->strtab;
|
||||
const Elf_Verdef *vd = depobj->verdef;
|
||||
const Elf_Word hash = vna->vna_hash;
|
||||
|
||||
if (vd == NULL) {
|
||||
_rtld_error("%s: version %s required by %s not defined",
|
||||
depobj->path, vername, refobj->path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;; vd = (const Elf_Verdef *)((const char *)vd + vd->vd_next)) {
|
||||
if (vd->vd_version != VER_DEF_CURRENT) {
|
||||
_rtld_error(
|
||||
"%s: Unsupported version %d of Elf_Verdef entry",
|
||||
depobj->path, vd->vd_version);
|
||||
return -1;
|
||||
}
|
||||
dbg(("hash: 0x%x, vd_hash: 0x%x", hash, vd->vd_hash));
|
||||
if (hash == vd->vd_hash) {
|
||||
const Elf_Verdaux *vda = (const Elf_Verdaux *)
|
||||
((const char *)vd + vd->vd_aux);
|
||||
dbg(("vername: %s, str: %s", vername,
|
||||
&depstrtab[vda->vda_name]));
|
||||
if (strcmp(vername, &depstrtab[vda->vda_name]) == 0)
|
||||
return 0;
|
||||
}
|
||||
if (vd->vd_next == 0)
|
||||
break;
|
||||
}
|
||||
if (vna->vna_flags & VER_FLG_WEAK)
|
||||
return 0;
|
||||
|
||||
_rtld_error("%s: version %s required by %s not found", depobj->path,
|
||||
vername, refobj->path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
_rtld_verify_object_versions(Obj_Entry *obj)
|
||||
{
|
||||
const char *strtab = obj->strtab;
|
||||
const Elf_Verneed *vn;
|
||||
const Elf_Vernaux *vna;
|
||||
const Elf_Verdef *vd;
|
||||
const Elf_Verdaux *vda;
|
||||
const Obj_Entry *depobj;
|
||||
int maxvertab, vernum;
|
||||
|
||||
dbg(("obj->path: %s", obj->path));
|
||||
|
||||
/*
|
||||
* If we don't have string table or objects that have their version
|
||||
* requirements already checked, we must be ok.
|
||||
*/
|
||||
if (strtab == NULL || obj->vertab != NULL)
|
||||
return 0;
|
||||
|
||||
maxvertab = 0;
|
||||
|
||||
/*
|
||||
* Walk over defined and required version records and figure out
|
||||
* max index used by any of them. Do very basic sanity checking
|
||||
* while there.
|
||||
*/
|
||||
for (vn = obj->verneed;
|
||||
vn != NULL;
|
||||
vn = (const Elf_Verneed *)((const char *)vn + vn->vn_next)) {
|
||||
|
||||
if (vn->vn_version != VER_NEED_CURRENT) {
|
||||
_rtld_error(
|
||||
"%s: Unsupported version %d of Elf_Verneed entry",
|
||||
obj->path, vn->vn_version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbg(("verneed: vn_file: %d, str: %s",
|
||||
vn->vn_file, &strtab[vn->vn_file]));
|
||||
depobj = locate_dependency(obj, &strtab[vn->vn_file]);
|
||||
assert(depobj != NULL);
|
||||
|
||||
for (vna = (const Elf_Vernaux *)((const char *)vn + vn->vn_aux);
|
||||
/*CONSTCOND*/1;
|
||||
vna = (const Elf_Vernaux *)((const char *)vna + vna->vna_next)) {
|
||||
|
||||
if (check_object_provided_version(obj, depobj, vna) == -1)
|
||||
return -1;
|
||||
|
||||
vernum = VER_NEED_IDX(vna->vna_other);
|
||||
if (vernum > maxvertab)
|
||||
maxvertab = vernum;
|
||||
|
||||
if (vna->vna_next == 0) {
|
||||
/* No more symbols. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vn->vn_next == 0) {
|
||||
/* No more dependencies. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (vd = obj->verdef;
|
||||
vd != NULL;
|
||||
vd = (const Elf_Verdef *)((const char *)vd + vd->vd_next)) {
|
||||
|
||||
if (vd->vd_version != VER_DEF_CURRENT) {
|
||||
_rtld_error(
|
||||
"%s: Unsupported version %d of Elf_Verdef entry",
|
||||
obj->path, vd->vd_version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbg(("verdef: vn_ndx: 0x%x", vd->vd_ndx));
|
||||
vernum = VER_DEF_IDX(vd->vd_ndx);
|
||||
if (vernum > maxvertab)
|
||||
maxvertab = vernum;
|
||||
|
||||
if (vd->vd_next == 0) {
|
||||
/* No more definitions. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dbg(("maxvertab: %d", maxvertab));
|
||||
if (maxvertab == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Store version information in array indexable by version index.
|
||||
* Verify that object version requirements are satisfied along the
|
||||
* way.
|
||||
*/
|
||||
obj->vertabnum = maxvertab + 1;
|
||||
obj->vertab = (Ver_Entry *)xcalloc(obj->vertabnum * sizeof(Ver_Entry));
|
||||
|
||||
for (vn = obj->verneed;
|
||||
vn != NULL;
|
||||
vn = (const Elf_Verneed *)((const char *)vn + vn->vn_next)) {
|
||||
|
||||
for (vna = (const Elf_Vernaux *)((const char *)vn + vn->vn_aux);
|
||||
/*CONSTCOND*/1;
|
||||
vna = (const Elf_Vernaux *)((const char *)vna + vna->vna_next)) {
|
||||
|
||||
vernum = VER_NEED_IDX(vna->vna_other);
|
||||
assert(vernum <= maxvertab);
|
||||
obj->vertab[vernum].hash = vna->vna_hash;
|
||||
obj->vertab[vernum].name = &strtab[vna->vna_name];
|
||||
obj->vertab[vernum].file = &strtab[vn->vn_file];
|
||||
obj->vertab[vernum].flags =
|
||||
(vna->vna_other & VER_NEED_HIDDEN)
|
||||
? VER_INFO_HIDDEN : 0;
|
||||
dbg(("verneed: vernum: %d, hash: 0x%x, name: %s, "
|
||||
"file: %s, flags: 0x%x", vernum,
|
||||
obj->vertab[vernum].hash, obj->vertab[vernum].name,
|
||||
obj->vertab[vernum].file,
|
||||
obj->vertab[vernum].flags));
|
||||
|
||||
if (vna->vna_next == 0) {
|
||||
/* No more symbols. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vn->vn_next == 0) {
|
||||
/* No more dependencies. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (vd = obj->verdef;
|
||||
vd != NULL;
|
||||
vd = (const Elf_Verdef *)((const char *)vd + vd->vd_next)) {
|
||||
|
||||
if ((vd->vd_flags & VER_FLG_BASE) == 0) {
|
||||
vernum = VER_DEF_IDX(vd->vd_ndx);
|
||||
assert(vernum <= maxvertab);
|
||||
vda = (const Elf_Verdaux *)
|
||||
((const char *)vd + vd->vd_aux);
|
||||
obj->vertab[vernum].hash = vd->vd_hash;
|
||||
obj->vertab[vernum].name = &strtab[vda->vda_name];
|
||||
obj->vertab[vernum].file = NULL;
|
||||
obj->vertab[vernum].flags = 0;
|
||||
dbg(("verdef: vernum: %d, hash: 0x%x, name: %s",
|
||||
vernum, obj->vertab[vernum].hash,
|
||||
obj->vertab[vernum].name));
|
||||
}
|
||||
|
||||
if (vd->vd_next == 0) {
|
||||
/* No more definitions. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.76 2011/05/19 21:39:03 riastradh Exp $
|
||||
# $NetBSD: Makefile,v 1.77 2011/06/25 05:45:11 nonaka Exp $
|
||||
# @(#)Makefile 8.2 (Berkeley) 12/13/93
|
||||
|
||||
MAN= _DIAGASSERT.3 __CONCAT.3 __UNCONST.3 CMSG_DATA.3 \
|
||||
@ -232,7 +232,7 @@ MLINKS+=dirent.3 dir.3 \
|
||||
dirent.3 IFTODT.3 \
|
||||
dirent.3 DTTOIF.3
|
||||
MLINKS+=dlfcn.3 dlopen.3 dlfcn.3 dlclose.3 dlfcn.3 dlsym.3 dlfcn.3 dlctl.3 \
|
||||
dlfcn.3 dlerror.3 dlfcn.3 dladdr.3
|
||||
dlfcn.3 dlerror.3 dlfcn.3 dladdr.3 dlfcn.3 dlvsym.3
|
||||
MLINKS+=timeradd.3 timersub.3 \
|
||||
timeradd.3 timerclear.3 \
|
||||
timeradd.3 timerisset.3 \
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: dlfcn.3,v 1.31 2011/02/13 16:01:39 wiz Exp $
|
||||
.\" $NetBSD: dlfcn.3,v 1.32 2011/06/25 05:45:11 nonaka Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
@ -34,6 +34,7 @@
|
||||
.Nm dlopen ,
|
||||
.Nm dlclose ,
|
||||
.Nm dlsym ,
|
||||
.Nm dlvsym ,
|
||||
.Nm dladdr ,
|
||||
.Nm dlctl ,
|
||||
.Nm dlerror
|
||||
@ -50,6 +51,8 @@ dynamically linked program automatically.)
|
||||
.Fn dlclose "void *handle"
|
||||
.Ft "void *"
|
||||
.Fn dlsym "void * restrict handle" "const char * restrict symbol"
|
||||
.Ft "void *"
|
||||
.Fn dlvsym "void * restrict handle" "const char * restrict symbol" "const char *version"
|
||||
.Ft "int"
|
||||
.Fn dladdr "void * restrict addr" "Dl_info * restrict dli"
|
||||
.Ft "int"
|
||||
@ -153,6 +156,7 @@ returns a
|
||||
to be used in calls to
|
||||
.Fn dlclose ,
|
||||
.Fn dlsym ,
|
||||
.Fn dlvsym ,
|
||||
and
|
||||
.Fn dlctl .
|
||||
If the named shared object has already
|
||||
@ -234,6 +238,18 @@ is limited to the shared object issuing the call to
|
||||
and those shared objects which were loaded after it that are visible.
|
||||
.El
|
||||
.Pp
|
||||
.Fn dlvsym
|
||||
does the same as
|
||||
.Fn dlsym
|
||||
but takes a
|
||||
.Fa version
|
||||
string as an additional argument.
|
||||
Both the
|
||||
.Fa symbol
|
||||
and the
|
||||
.Fa version
|
||||
must match in order for the symbol to be resolved.
|
||||
.Pp
|
||||
.Fn dladdr
|
||||
examines all currently mapped shared objects for a symbol whose address --
|
||||
as mapped in the process address space -- is closest to but not exceeding
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: exec_elf.h,v 1.112 2011/05/26 16:42:15 nonaka Exp $ */
|
||||
/* $NetBSD: exec_elf.h,v 1.113 2011/06/25 05:45:10 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994 The NetBSD Foundation, Inc.
|
||||
@ -870,6 +870,11 @@ struct netbsd_elfcore_procinfo {
|
||||
#define Elf_Off Elf32_Off
|
||||
#define Elf_SOff Elf32_SOff
|
||||
#define Elf_Nhdr Elf32_Nhdr
|
||||
#define Elf_Verdef Elf32_Verdef
|
||||
#define Elf_Verdaux Elf32_Verdaux
|
||||
#define Elf_Verneed Elf32_Verneed
|
||||
#define Elf_Vernaux Elf32_Vernaux
|
||||
#define Elf_Versym Elf32_Versym
|
||||
|
||||
#define ELF_R_SYM ELF32_R_SYM
|
||||
#define ELF_R_TYPE ELF32_R_TYPE
|
||||
@ -891,6 +896,11 @@ struct netbsd_elfcore_procinfo {
|
||||
#define Elf_Off Elf64_Off
|
||||
#define Elf_SOff Elf64_SOff
|
||||
#define Elf_Nhdr Elf64_Nhdr
|
||||
#define Elf_Verdef Elf64_Verdef
|
||||
#define Elf_Verdaux Elf64_Verdaux
|
||||
#define Elf_Verneed Elf64_Verneed
|
||||
#define Elf_Vernaux Elf64_Vernaux
|
||||
#define Elf_Versym Elf64_Versym
|
||||
|
||||
#define ELF_R_SYM ELF64_R_SYM
|
||||
#define ELF_R_TYPE ELF64_R_TYPE
|
||||
@ -952,6 +962,11 @@ typedef struct {
|
||||
#define VER_DEF_NONE 0
|
||||
#define VER_DEF_CURRENT 1
|
||||
|
||||
/*
|
||||
* These constants are used for Elf32_Verdef struct's vd_ndx.
|
||||
*/
|
||||
#define VER_DEF_IDX(x) VER_NDX(x)
|
||||
|
||||
/*
|
||||
* These constants are used for Elf32_Verdef struct's vd_flags.
|
||||
*/
|
||||
@ -963,6 +978,7 @@ typedef struct {
|
||||
*/
|
||||
#define VER_NDX_LOCAL 0
|
||||
#define VER_NDX_GLOBAL 1
|
||||
#define VER_NDX_GIVEN 2
|
||||
|
||||
/*
|
||||
* These constants are used for Elf32_Verneed struct's version number.
|
||||
@ -970,6 +986,16 @@ typedef struct {
|
||||
#define VER_NEED_NONE 0
|
||||
#define VER_NEED_CURRENT 1
|
||||
|
||||
/*
|
||||
* These constants are used for Elf32_Vernaux struct's vna_other.
|
||||
*/
|
||||
#define VER_NEED_HIDDEN VER_NDX_HIDDEN
|
||||
#define VER_NEED_IDX(x) VER_NDX(x)
|
||||
|
||||
/* index */
|
||||
#define VER_NDX_HIDDEN 0x8000
|
||||
#define VER_NDX(x) ((x) & ~VER_NDX_HIDDEN)
|
||||
|
||||
/*
|
||||
* GNU Extension hidding symbol
|
||||
*/
|
||||
|
@ -1,19 +1,23 @@
|
||||
# $NetBSD
|
||||
# $NetBSD: Makefile,v 1.5 2011/06/25 05:45:12 nonaka Exp $
|
||||
#
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR+= helper_dso1 .WAIT helper_dso2
|
||||
SUBDIR+= helper_dso1 .WAIT helper_dso2 .WAIT \
|
||||
helper_symver_dso0 .WAIT helper_symver_dso1 .WAIT \
|
||||
helper_symver_dso2 .WAIT \
|
||||
data
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so
|
||||
|
||||
TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo
|
||||
TESTS_C+= t_dlerror-cleared t_dlerror-false t_dlinfo t_dlvsym
|
||||
|
||||
LDADD.t_dlerror-false= -Wl,-rpath,/var/nonexistent/lib
|
||||
LDADD.t_dlvsym= -Wl,-rpath,${TESTSDIR}/h_helper_symver_dso2
|
||||
|
||||
TESTS_SH+= t_df_1_noopen
|
||||
TESTS_SH+= t_df_1_noopen t_dl_symver
|
||||
|
||||
BINDIR= ${TESTSDIR}
|
||||
PROGS+= h_df_1_noopen1
|
||||
@ -27,4 +31,19 @@ PROGS+= h_locking
|
||||
SRCS.h_locking= h_locking.c
|
||||
LDADD.h_locking= -lpthread -Wl,--export-dynamic -Wl,-rpath,${TESTSDIR}
|
||||
|
||||
PROGS+= h_dl_symver_v0
|
||||
SRCS.h_dl_symver_v0= h_dl_symver.c
|
||||
V0ODIR!= cd ${.CURDIR}/helper_symver_dso0 && ${PRINTOBJDIR}
|
||||
LDADD.h_dl_symver_v0= -L${V0ODIR} -lh_helper_symver_dso
|
||||
|
||||
PROGS+= h_dl_symver_v1
|
||||
SRCS.h_dl_symver_v1= h_dl_symver.c
|
||||
V1ODIR!= cd ${.CURDIR}/helper_symver_dso1 && ${PRINTOBJDIR}
|
||||
LDADD.h_dl_symver_v1= -L${V1ODIR} -lh_helper_symver_dso
|
||||
|
||||
PROGS+= h_dl_symver_v2
|
||||
SRCS.h_dl_symver_v2= h_dl_symver.c
|
||||
V2ODIR!= cd ${.CURDIR}/helper_symver_dso2 && ${PRINTOBJDIR}
|
||||
LDADD.h_dl_symver_v2= -L${V2ODIR} -lh_helper_symver_dso
|
||||
|
||||
.include <bsd.test.mk>
|
||||
|
28
tests/libexec/ld.elf_so/data/Makefile
Normal file
28
tests/libexec/ld.elf_so/data/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
# $NetBSD: Makefile,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
TESTSDIR= ${TESTSBASE}/libexec/ld.elf_so
|
||||
ATFFILE= no
|
||||
|
||||
FILESDIR= ${TESTSDIR}/data
|
||||
FILES= symver-output-ref-stderr.v0-v0
|
||||
FILES+= symver-output-ref-stderr.v0-v1
|
||||
FILES+= symver-output-ref-stderr.v0-v2
|
||||
FILES+= symver-output-ref-stderr.v1-v0
|
||||
FILES+= symver-output-ref-stderr.v1-v1
|
||||
FILES+= symver-output-ref-stderr.v1-v2
|
||||
FILES+= symver-output-ref-stderr.v2-v0
|
||||
FILES+= symver-output-ref-stderr.v2-v1
|
||||
FILES+= symver-output-ref-stderr.v2-v2
|
||||
FILES+= symver-output-ref-stdout.v0-v0
|
||||
FILES+= symver-output-ref-stdout.v0-v1
|
||||
FILES+= symver-output-ref-stdout.v0-v2
|
||||
FILES+= symver-output-ref-stdout.v1-v0
|
||||
FILES+= symver-output-ref-stdout.v1-v1
|
||||
FILES+= symver-output-ref-stdout.v1-v2
|
||||
FILES+= symver-output-ref-stdout.v2-v0
|
||||
FILES+= symver-output-ref-stdout.v2-v1
|
||||
FILES+= symver-output-ref-stdout.v2-v2
|
||||
|
||||
.include <bsd.test.mk>
|
||||
.include <bsd.files.mk>
|
||||
.include <bsd.prog.mk>
|
@ -0,0 +1 @@
|
||||
/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1: version V_1 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v1 not defined
|
@ -0,0 +1 @@
|
||||
/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1: version V_3 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v2 not defined
|
@ -0,0 +1 @@
|
||||
/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so.1: version V_3 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v2 not found
|
@ -0,0 +1 @@
|
||||
0
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1 @@
|
||||
3
|
42
tests/libexec/ld.elf_so/h_dl_symver.c
Normal file
42
tests/libexec/ld.elf_so/h_dl_symver.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* $NetBSD: h_dl_symver.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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>
|
||||
|
||||
extern int testfunc(void);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
printf("%d\n", testfunc());
|
||||
return 0;
|
||||
}
|
21
tests/libexec/ld.elf_so/helper_symver_dso0/Makefile
Normal file
21
tests/libexec/ld.elf_so/helper_symver_dso0/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
# $NetBSD: Makefile,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
LIB= h_helper_symver_dso
|
||||
SRCS= h_helper_symver_dso0.c
|
||||
|
||||
LIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso0
|
||||
SHLIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso0
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
MKSTATICLIB= no
|
||||
MKPROFILE= no
|
||||
MKPICINSTALL= no
|
||||
MKLINT= no
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
FILESDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso0
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -0,0 +1,39 @@
|
||||
/* $NetBSD: h_helper_symver_dso0.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
int testfunc(void);
|
||||
|
||||
int
|
||||
testfunc(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
23
tests/libexec/ld.elf_so/helper_symver_dso1/Makefile
Normal file
23
tests/libexec/ld.elf_so/helper_symver_dso1/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
# $NetBSD: Makefile,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
LIB= h_helper_symver_dso
|
||||
SRCS= h_helper_symver_dso1.c
|
||||
|
||||
LIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso1
|
||||
SHLIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso1
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
MKSTATICLIB= no
|
||||
MKPROFILE= no
|
||||
MKPICINSTALL= no
|
||||
MKLINT= no
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
FILESDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso1
|
||||
|
||||
LDFLAGS.lib${LIB} += -Wl,--version-script=${.CURDIR}/h_helper_symver_dso1.map
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -0,0 +1,41 @@
|
||||
/* $NetBSD: h_helper_symver_dso1.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
__asm(".symver testfunc_new, testfunc@@V_1");
|
||||
|
||||
int testfunc_new(void);
|
||||
|
||||
int
|
||||
testfunc_new(void)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
# $NetBSD: h_helper_symver_dso1.map,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
V_1 {
|
||||
testfunc;
|
||||
};
|
23
tests/libexec/ld.elf_so/helper_symver_dso2/Makefile
Normal file
23
tests/libexec/ld.elf_so/helper_symver_dso2/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
# $NetBSD: Makefile,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
LIB= h_helper_symver_dso
|
||||
SRCS= h_helper_symver_dso2.c
|
||||
|
||||
LIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso2
|
||||
SHLIBDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso2
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
MKSTATICLIB= no
|
||||
MKPROFILE= no
|
||||
MKPICINSTALL= no
|
||||
MKLINT= no
|
||||
|
||||
NOMAN= # defined
|
||||
|
||||
FILESDIR= ${TESTSBASE}/libexec/ld.elf_so/h_helper_symver_dso2
|
||||
|
||||
LDFLAGS.lib${LIB} += -Wl,--version-script=${.CURDIR}/h_helper_symver_dso2.map
|
||||
|
||||
.include <bsd.lib.mk>
|
@ -0,0 +1,59 @@
|
||||
/* $NetBSD: h_helper_symver_dso2.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
__asm(".symver testfunc_new, testfunc@@V_3");
|
||||
__asm(".symver testfunc_compat1, testfunc@V_1");
|
||||
__asm(".symver testfunc_compat2, testfunc@V_2");
|
||||
|
||||
int testfunc_new(void);
|
||||
int testfunc_compat1(void);
|
||||
int testfunc_compat2(void);
|
||||
|
||||
int
|
||||
testfunc_new(void)
|
||||
{
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
int
|
||||
testfunc_compat1(void)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
testfunc_compat2(void)
|
||||
{
|
||||
|
||||
return 2;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
# $NetBSD: h_helper_symver_dso2.map,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
|
||||
V_1 {
|
||||
testfunc;
|
||||
};
|
||||
|
||||
V_2 {
|
||||
testfunc;
|
||||
};
|
||||
|
||||
V_3 {
|
||||
testfunc;
|
||||
};
|
55
tests/libexec/ld.elf_so/t_dl_symver.sh
Normal file
55
tests/libexec/ld.elf_so/t_dl_symver.sh
Normal file
@ -0,0 +1,55 @@
|
||||
# $NetBSD: t_dl_symver.sh,v 1.1 2011/06/25 05:45:13 nonaka Exp $
|
||||
#
|
||||
# Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This code is derived from software contributed to The NetBSD Foundation
|
||||
# by NONAKA Kimihiro.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
datadir() {
|
||||
echo "$(atf_get_srcdir)/data"
|
||||
}
|
||||
|
||||
atf_test_case dl_symver
|
||||
dl_symver_head()
|
||||
{
|
||||
atf_set "descr" "Checks ELF symbol versioning functions"
|
||||
}
|
||||
dl_symver_body()
|
||||
{
|
||||
for tv in 0 1 2; do
|
||||
for lv in 0 1 2; do
|
||||
atf_check -s ignore \
|
||||
-o file:$(datadir)/symver-output-ref-stdout.v$tv-v$lv \
|
||||
-e file:$(datadir)/symver-output-ref-stderr.v$tv-v$lv \
|
||||
-x "LD_LIBRARY_PATH=$(atf_get_srcdir)/h_helper_symver_dso$lv $(atf_get_srcdir)/h_dl_symver_v$tv"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case dl_symver
|
||||
}
|
203
tests/libexec/ld.elf_so/t_dlvsym.c
Normal file
203
tests/libexec/ld.elf_so/t_dlvsym.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* $NetBSD: t_dlvsym.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by NONAKA Kimihiro.
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
ATF_TC(rtld_dlvsym_v1);
|
||||
ATF_TC_HEAD(rtld_dlvsym_v1, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Check dlvsym() function (V_1)");
|
||||
}
|
||||
ATF_TC_BODY(rtld_dlvsym_v1, tc)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
int (*sym)(void);
|
||||
int result;
|
||||
|
||||
/* Clear previous error */
|
||||
(void) dlerror();
|
||||
|
||||
handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
ATF_CHECK(handle != NULL);
|
||||
|
||||
sym = dlvsym(handle, "testfunc", "V_1");
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
|
||||
result = (*sym)();
|
||||
ATF_CHECK(result == 1);
|
||||
|
||||
dlclose(handle);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
}
|
||||
|
||||
ATF_TC(rtld_dlvsym_v3);
|
||||
ATF_TC_HEAD(rtld_dlvsym_v3, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Check dlvsym() function (V_3)");
|
||||
}
|
||||
ATF_TC_BODY(rtld_dlvsym_v3, tc)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
int (*sym)(void);
|
||||
int result;
|
||||
|
||||
/* Clear previous error */
|
||||
(void) dlerror();
|
||||
|
||||
handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
ATF_CHECK(handle != NULL);
|
||||
|
||||
sym = dlvsym(handle, "testfunc", "V_3");
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
|
||||
result = (*sym)();
|
||||
ATF_CHECK(result == 3);
|
||||
|
||||
dlclose(handle);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
}
|
||||
|
||||
ATF_TC(rtld_dlvsym_symbol_nonexistent);
|
||||
ATF_TC_HEAD(rtld_dlvsym_symbol_nonexistent, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Check dlvsym() function (symbol is nonexistent)");
|
||||
}
|
||||
ATF_TC_BODY(rtld_dlvsym_symbol_nonexistent, tc)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
int (*sym)(void);
|
||||
|
||||
/* Clear previous error */
|
||||
(void) dlerror();
|
||||
|
||||
handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
ATF_CHECK(handle != NULL);
|
||||
|
||||
sym = dlvsym(handle, "symbol_nonexistent", "V_3");
|
||||
error = dlerror();
|
||||
ATF_CHECK(sym == NULL);
|
||||
ATF_CHECK(error != NULL);
|
||||
|
||||
dlclose(handle);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
}
|
||||
|
||||
ATF_TC(rtld_dlvsym_version_nonexistent);
|
||||
ATF_TC_HEAD(rtld_dlvsym_version_nonexistent, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Check dlvsym() function (version is nonexistent)");
|
||||
}
|
||||
ATF_TC_BODY(rtld_dlvsym_version_nonexistent, tc)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
int (*sym)(void);
|
||||
|
||||
/* Clear previous error */
|
||||
(void) dlerror();
|
||||
|
||||
handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
ATF_CHECK(handle != NULL);
|
||||
|
||||
sym = dlvsym(handle, "testfunc", "");
|
||||
error = dlerror();
|
||||
ATF_CHECK(sym == NULL);
|
||||
ATF_CHECK(error != NULL);
|
||||
|
||||
dlclose(handle);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
}
|
||||
|
||||
ATF_TC(rtld_dlvsym_version_null);
|
||||
ATF_TC_HEAD(rtld_dlvsym_version_null, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Check dlvsym() function (version is NULL)");
|
||||
}
|
||||
ATF_TC_BODY(rtld_dlvsym_version_null, tc)
|
||||
{
|
||||
void *handle;
|
||||
char *error;
|
||||
int (*sym)(void);
|
||||
int result;
|
||||
|
||||
/* Clear previous error */
|
||||
(void) dlerror();
|
||||
|
||||
handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
ATF_CHECK(handle != NULL);
|
||||
|
||||
sym = dlvsym(handle, "testfunc", NULL);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
|
||||
result = (*sym)();
|
||||
ATF_CHECK(result == 3);
|
||||
|
||||
dlclose(handle);
|
||||
error = dlerror();
|
||||
ATF_CHECK(error == NULL);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, rtld_dlvsym_v1);
|
||||
ATF_TP_ADD_TC(tp, rtld_dlvsym_v3);
|
||||
ATF_TP_ADD_TC(tp, rtld_dlvsym_symbol_nonexistent);
|
||||
ATF_TP_ADD_TC(tp, rtld_dlvsym_version_nonexistent);
|
||||
ATF_TP_ADD_TC(tp, rtld_dlvsym_version_null);
|
||||
return atf_no_error();
|
||||
}
|
Loading…
Reference in New Issue
Block a user