aboutsummaryrefslogtreecommitdiff
path: root/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c')
-rw-r--r--libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c72
1 files changed, 72 insertions, 0 deletions
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
index 000000000000..30f71331bc62
--- /dev/null
+++ b/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c
@@ -0,0 +1,72 @@
+/*-
+ *
+ * Copyright (C) 2023 NetApp, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ */
+
+#include <dlfcn.h>
+
+#include <atf-c.h>
+
+int get_value(void);
+void set_value(int);
+
+#define APP_VALUE 5
+#define LIB_VALUE 20
+
+#ifndef ATF_REQUIRE_INTEQ
+/* atf-c/macros.h */
+#define ATF_REQUIRE_INTEQ(expected, actual) \
+ ATF_REQUIRE_MSG((expected) == (actual), "%s != %s (%jd != %jd)", #expected, \
+ #actual, (intmax_t)(expected), (intmax_t)(actual))
+#endif
+
+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();
+}