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. |
22 | __attribute__((noinline, no_sanitize("address" ))) void foo() { |
23 | printf(format: "Hello World!\n" ); |
24 | } |
25 | |
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(format: "dlopen(NULL,...): %p\n" , correct_handle); |
32 | |
33 | Dl_info info; |
34 | if (dladdr(address: (void *)&foo, info: &info) == 0) { |
35 | printf(format: "dladdr failed\n" ); |
36 | return 1; |
37 | } |
38 | printf(format: "dladdr(&foo): %s\n" , info.dli_fname); |
39 | void *test_handle = dlopen(file: info.dli_fname, RTLD_LAZY); |
40 | printf(format: "dlopen(%s,...): %p\n" , info.dli_fname, test_handle); |
41 | |
42 | if (test_handle != correct_handle) { |
43 | printf(format: "Error: handles do not match\n" ); |
44 | return 1; |
45 | } |
46 | |
47 | return 0; |
48 | } |
49 | |