]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dlopen-RTLD_NOW.dtest/main.c
29f9b3194e094b521f2aad9bd3b5dce47751c88f
[apple/dyld.git] / testing / test-cases / dlopen-RTLD_NOW.dtest / main.c
1
2 // BUILD: $CC bar.c -dynamiclib -o $BUILD_DIR/libbar.dylib -install_name $RUN_DIR/libbar.dylib
3 // BUILD: $CC bar.c -dynamiclib -o $TEMP_DIR/libbar-present.dylib -install_name $RUN_DIR/libbar.dylib -DHAS_SYMBOL=1
4 // BUILD: $CC foo.c -dynamiclib -Os -install_name $RUN_DIR/libfoo.dylib -o $BUILD_DIR/libfoo.dylib $TEMP_DIR/libbar-present.dylib
5 // BUILD: $CC main.c -o $BUILD_DIR/dlopen-RTLD_NOW.exe -DRUN_DIR="$RUN_DIR"
6
7 // RUN: ./dlopen-RTLD_NOW.exe
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdbool.h>
12 #include <string.h>
13 #include <dlfcn.h>
14 #include <mach-o/getsect.h>
15
16 #if __LP64__
17 extern struct mach_header_64 __dso_handle;
18 #else
19 extern struct mach_header __dso_handle;
20 #endif
21
22 int main()
23 {
24 printf("[BEGIN] dlopen-RTLD_NOW\n");
25
26 ///
27 /// This tests that RTLD_NOW on dlopen() will return NULL because call from libfoo to libbar could not be bound
28 ///
29 void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_NOW);
30 if ( handle != NULL ) {
31 printf("[FAIL] dlopen-RTLD_NOW: dlopen(libfoo.dylib, RTLD_NOW) should have failed\n");
32 return 0;
33 }
34
35
36 #if __arm64e__
37 // arm64e always uses chained binds which does not support lazy binding
38 bool supportsLazyBinding = false;
39 #else
40 // other architectures may or may not use lazy binding
41 unsigned long sectSize = 0;
42 bool supportsLazyBinding = (getsectiondata(&__dso_handle, "__DATA", "__la_symbol_ptr", &sectSize) != NULL);
43 #if __ARM_ARCH_7K__
44 // armv7 has two names for lazy pointers section
45 if ( !supportsLazyBinding )
46 supportsLazyBinding = (getsectiondata(&__dso_handle, "__DATA", "__lazy_symbol", &sectSize) != NULL);
47 #endif
48 #endif
49
50 ///
51 /// This tests that RTLD_LAZY on dlopen() will succeed if libfoo.dylib
52 ///
53 handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_LAZY);
54 if ( supportsLazyBinding ) {
55 if ( handle == NULL ) {
56 printf("[FAIL] dlopen-RTLD_NOW: dlopen(libfoo.dylib, RTLD_LAZY) should have succeeded: %s\n", dlerror());
57 return 0;
58 }
59 }
60 else {
61 if ( handle != NULL ) {
62 printf("[FAIL] dlopen-RTLD_NOW: dlopen(libfoo.dylib, RTLD_LAZY) should have failed becuase a symbol was missing\n");
63 return 0;
64 }
65 }
66
67
68 printf("[PASS] dlopen-RTLD_NOW\n");
69 return 0;
70 }