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
26int 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

source code of compiler-rt/test/sanitizer_common/TestCases/Linux/replace_dlopen_main_program_test.cpp