diff --git a/libexec/rtld-elf/tests/Makefile b/libexec/rtld-elf/tests/Makefile --- a/libexec/rtld-elf/tests/Makefile +++ b/libexec/rtld-elf/tests/Makefile @@ -1,6 +1,8 @@ -SUBDIR+= libpythagoras target +SUBDIR+= libpythagoras libdeep libval libval2 rtld_deepbind target +SUBDIR_DEPEND_libdeep= libval2 +SUBDIR_DEPEND_rtld_deepbind= libval SUBDIR_DEPEND_target= libpythagoras ATF_TESTS_C= ld_library_pathfds diff --git a/libexec/rtld-elf/tests/Makefile.inc b/libexec/rtld-elf/tests/Makefile.inc new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/Makefile.inc @@ -0,0 +1,3 @@ + +PACKAGE?= tests +TESTSDIR?= ${TESTSBASE}/libexec/rtld-elf diff --git a/libexec/rtld-elf/tests/libdeep/Makefile b/libexec/rtld-elf/tests/libdeep/Makefile new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/libdeep/Makefile @@ -0,0 +1,18 @@ + +SHLIB?= deep +SHLIB_MAJOR= 0 + +LIBDIR= ${TESTSBASE}/libexec/rtld-elf +SHLIBDIR= ${TESTSBASE}/libexec/rtld-elf + +SRCS= libdeep.c + +# Too ugly? +LDFLAGS+= -Wl,-rpath ${TESTSDIR} + +LIBVAL2= ${.OBJDIR}/../libval2 +LDFLAGS+= -L${LIBVAL2} +DPADD+= -lval2 +LDADD+= -lval2 + +.include diff --git a/libexec/rtld-elf/tests/libdeep/libdeep.c b/libexec/rtld-elf/tests/libdeep/libdeep.c new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/libdeep/libdeep.c @@ -0,0 +1,28 @@ +/*- + * + * Copyright (C) 2023 NetApp, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + * + */ + +#include + +extern int get_value(void); +extern int proxy_get_value(void); +extern void set_value(int); +extern void proxy_set_value(int); + +int +proxy_get_value(void) +{ + + return (get_value()); +} + +void +proxy_set_value(int val) +{ + + return (set_value(val)); +} diff --git a/libexec/rtld-elf/tests/libval/Makefile b/libexec/rtld-elf/tests/libval/Makefile new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/libval/Makefile @@ -0,0 +1,10 @@ + +SHLIB?= val +SHLIB_MAJOR= 0 + +LIBDIR= ${TESTSBASE}/libexec/rtld-elf +SHLIBDIR= ${TESTSBASE}/libexec/rtld-elf + +SRCS= libval.c + +.include diff --git a/libexec/rtld-elf/tests/libval/libval.c b/libexec/rtld-elf/tests/libval/libval.c new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/libval/libval.c @@ -0,0 +1,26 @@ +/*- + * + * Copyright (C) 2023 NetApp, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + * + */ + +static int val; + +extern int get_value(void); +extern void set_value(int); + +int +get_value(void) +{ + + return (val); +} + +void +set_value(int nval) +{ + + val = nval; +} diff --git a/libexec/rtld-elf/tests/libval2/Makefile b/libexec/rtld-elf/tests/libval2/Makefile new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/libval2/Makefile @@ -0,0 +1,8 @@ + +LIBVAL= ${.CURDIR}/../libval + +# Just rebuild libval +.PATH: ${LIBVAL:tA} +SHLIB?= val2 + +.include "${LIBVAL}/Makefile" diff --git a/libexec/rtld-elf/tests/rtld_deepbind/Makefile b/libexec/rtld-elf/tests/rtld_deepbind/Makefile new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/rtld_deepbind/Makefile @@ -0,0 +1,12 @@ + +ATF_TESTS_C= rtld_deepbind + +# Too ugly? +LDFLAGS.rtld_deepbind+= -Wl,-rpath ${TESTSDIR} + +LIBVAL= ${.OBJDIR}/../libval +LDFLAGS.rtld_deepbind+= -L${LIBVAL} +DPADD+= -lval +LDADD+= -lval + +.include diff --git a/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c b/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c new file mode 100644 --- /dev/null +++ b/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c @@ -0,0 +1,65 @@ +/*- + * + * Copyright (C) 2023 NetApp, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + * + */ + +#include + +#include + +extern int get_value(void); +extern void set_value(int); + +#define APP_VALUE 5 +#define LIB_VALUE 20 + +ATF_TC_WITHOUT_HEAD(deepbind_simple); +ATF_TC_BODY(deepbind_simple, tc) +{ + void *hdl; + void (*proxy_set_value)(int); + int (*proxy_get_value)(void); + int app_value, lib_value; + + set_value(APP_VALUE); + + /* + * libdeep has a dependency on libval2.so, which is a rebuild of + * libval.so that provides get_value() and set_value() for both us and + * the lib. The lib's get_value() and set_value() should bind to the + * versions in libval2 instead of libval with RTLD_DEEPBIND. + */ + hdl = dlopen("$ORIGIN/libdeep.so", RTLD_LAZY | RTLD_DEEPBIND); + ATF_REQUIRE(hdl != NULL); + + proxy_set_value = dlsym(hdl, "proxy_set_value"); + ATF_REQUIRE(proxy_set_value != NULL); + + proxy_get_value = dlsym(hdl, "proxy_get_value"); + ATF_REQUIRE(proxy_get_value != NULL); + + (*proxy_set_value)(LIB_VALUE); + + lib_value = (*proxy_get_value)(); + app_value = get_value(); + + /* + * In the initial implementation or if libdeep.so is *not* linked + * against its own libval2, then these both return the later set + * LIB_VALUE (20) as they bind to the symbol provided by libval and + * use its .bss val. + */ + ATF_REQUIRE_INTEQ(lib_value, LIB_VALUE); + ATF_REQUIRE_INTEQ(app_value, APP_VALUE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, deepbind_simple); + + return atf_no_error(); +} diff --git a/libexec/rtld-elf/tests/target/Makefile b/libexec/rtld-elf/tests/target/Makefile --- a/libexec/rtld-elf/tests/target/Makefile +++ b/libexec/rtld-elf/tests/target/Makefile @@ -2,7 +2,7 @@ .include PROG= target -BINDIR= ${TESTSBASE}/libexec/rtld-elf +BINDIR= ${TESTSDIR} WARNS?= 3 CFLAGS+= -I${.CURDIR}/../libpythagoras