xref: /src/libexec/rtld-elf/tests/rtld_deepbind/rtld_deepbind.c (revision d9c543b6b0cabea6e6679d70b4e701018e7eab80) !
1d9c543b6SKyle Evans /*-
2d9c543b6SKyle Evans  *
3d9c543b6SKyle Evans  * Copyright (C) 2023 NetApp, Inc.
4d9c543b6SKyle Evans  *
5d9c543b6SKyle Evans  * SPDX-License-Identifier: BSD-2-Clause
6d9c543b6SKyle Evans  *
7d9c543b6SKyle Evans  */
8d9c543b6SKyle Evans 
9d9c543b6SKyle Evans #include <dlfcn.h>
10d9c543b6SKyle Evans 
11d9c543b6SKyle Evans #include <atf-c.h>
12d9c543b6SKyle Evans 
13d9c543b6SKyle Evans int get_value(void);
14d9c543b6SKyle Evans void set_value(int);
15d9c543b6SKyle Evans 
16d9c543b6SKyle Evans #define	APP_VALUE	5
17d9c543b6SKyle Evans #define	LIB_VALUE	20
18d9c543b6SKyle Evans 
19d9c543b6SKyle Evans ATF_TC_WITHOUT_HEAD(deepbind_simple);
ATF_TC_BODY(deepbind_simple,tc)20d9c543b6SKyle Evans ATF_TC_BODY(deepbind_simple, tc)
21d9c543b6SKyle Evans {
22d9c543b6SKyle Evans 	void *hdl;
23d9c543b6SKyle Evans 	void (*proxy_set_value)(int);
24d9c543b6SKyle Evans 	int (*proxy_get_value)(void);
25d9c543b6SKyle Evans 	int app_value, lib_value;
26d9c543b6SKyle Evans 
27d9c543b6SKyle Evans 	set_value(APP_VALUE);
28d9c543b6SKyle Evans 
29d9c543b6SKyle Evans 	/*
30d9c543b6SKyle Evans 	 * libdeep has a dependency on libval2.so, which is a rebuild of
31d9c543b6SKyle Evans 	 * libval.so that provides get_value() and set_value() for both us and
32d9c543b6SKyle Evans 	 * the lib.  The lib's get_value() and set_value() should bind to the
33d9c543b6SKyle Evans 	 * versions in libval2 instead of libval with RTLD_DEEPBIND.
34d9c543b6SKyle Evans 	 */
35d9c543b6SKyle Evans 	hdl = dlopen("$ORIGIN/libdeep.so", RTLD_LAZY | RTLD_DEEPBIND);
36d9c543b6SKyle Evans 	ATF_REQUIRE(hdl != NULL);
37d9c543b6SKyle Evans 
38d9c543b6SKyle Evans 	proxy_set_value = dlsym(hdl, "proxy_set_value");
39d9c543b6SKyle Evans 	ATF_REQUIRE(proxy_set_value != NULL);
40d9c543b6SKyle Evans 
41d9c543b6SKyle Evans 	proxy_get_value = dlsym(hdl, "proxy_get_value");
42d9c543b6SKyle Evans 	ATF_REQUIRE(proxy_get_value != NULL);
43d9c543b6SKyle Evans 
44d9c543b6SKyle Evans 	(*proxy_set_value)(LIB_VALUE);
45d9c543b6SKyle Evans 
46d9c543b6SKyle Evans 	lib_value = (*proxy_get_value)();
47d9c543b6SKyle Evans 	app_value = get_value();
48d9c543b6SKyle Evans 
49d9c543b6SKyle Evans 	/*
50d9c543b6SKyle Evans 	 * In the initial implementation or if libdeep.so is *not* linked
51d9c543b6SKyle Evans 	 * against its own libval2, then these both return the later set
52d9c543b6SKyle Evans 	 * LIB_VALUE (20) as they bind to the symbol provided by libval and
53d9c543b6SKyle Evans 	 * use its .bss val.
54d9c543b6SKyle Evans 	 */
55d9c543b6SKyle Evans 	ATF_REQUIRE_INTEQ(lib_value, LIB_VALUE);
56d9c543b6SKyle Evans 	ATF_REQUIRE_INTEQ(app_value, APP_VALUE);
57d9c543b6SKyle Evans }
58d9c543b6SKyle Evans 
ATF_TP_ADD_TCS(tp)59d9c543b6SKyle Evans ATF_TP_ADD_TCS(tp)
60d9c543b6SKyle Evans {
61d9c543b6SKyle Evans 
62d9c543b6SKyle Evans 	ATF_TP_ADD_TC(tp, deepbind_simple);
63d9c543b6SKyle Evans 
64d9c543b6SKyle Evans 	return atf_no_error();
65d9c543b6SKyle Evans }
66