1 // Test 'test_only_replace_dlopen_main_program' flag
2
3 // RUN: %clangxx %s -pie -fPIE -o %t
4 // RUN: env %tool_options='test_only_replace_dlopen_main_program=true' %run %t
5 // RUN: env %tool_options='test_only_replace_dlopen_main_program=false' not %run %t
6
7 // dladdr is 'nonstandard GNU extensions that are also present on Solaris'
8 // REQUIRES: glibc
9
10 // Does not intercept dlopen
11 // UNSUPPORTED: hwasan, lsan, ubsan
12
13 // Flag has no effect with dynamic runtime
14 // UNSUPPORTED: asan-dynamic-runtime
15
16 #include <dlfcn.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 // We can't use the address of 'main' (error: ISO C++ does not allow 'main' to be used by a program [-Werror,-Wmain]')
21 // so we add this function.
foo()22 __attribute__((noinline, no_sanitize("address"))) void foo() {
23 printf("Hello World!\n");
24 }
25
main(int argc,char * argv[])26 int main(int argc, char *argv[]) {
27 foo();
28
29 // "If filename is NULL, then the returned handle is for the main program."
30 void *correct_handle = dlopen(NULL, RTLD_LAZY);
31 printf("dlopen(NULL,...): %p\n", correct_handle);
32
33 Dl_info info;
34 if (dladdr((void *)&foo, &info) == 0) {
35 printf("dladdr failed\n");
36 return 1;
37 }
38 printf("dladdr(&foo): %s\n", info.dli_fname);
39 void *test_handle = dlopen(info.dli_fname, RTLD_LAZY);
40 printf("dlopen(%s,...): %p\n", info.dli_fname, test_handle);
41
42 if (test_handle != correct_handle) {
43 printf("Error: handles do not match\n");
44 return 1;
45 }
46
47 return 0;
48 }
49