dyld-750.5.tar.gz
[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 $BUILD_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 $BUILD_DIR/libbar-present.dylib
5 // BUILD: $CC main.c -o $BUILD_DIR/dlopen-RTLD_NOW.exe -DRUN_DIR="$RUN_DIR"
6
7 // BUILD: $SKIP_INSTALL $BUILD_DIR/libbar-present.dylib
8
9 // RUN: ./dlopen-RTLD_NOW.exe
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <string.h>
15 #include <dlfcn.h>
16 #include <mach-o/getsect.h>
17
18 #include "test_support.h"
19
20 #if __LP64__
21 extern struct mach_header_64 __dso_handle;
22 #else
23 extern struct mach_header __dso_handle;
24 #endif
25
26 int main(int argc, const char* argv[], const char* envp[], const char* apple[]) {
27 ///
28 /// This tests that RTLD_NOW on dlopen() will return NULL because call from libfoo to libbar could not be bound
29 ///
30 void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_NOW);
31 if ( handle != NULL ) {
32 FAIL("dlopen(\"libfoo.dylib\", RTLD_NOW) should have failed");
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 FAIL("dlopen(\"libfoo.dylib\", RTLD_LAZY) should have succeeded: %s", dlerror());
57 }
58 }
59 else {
60 if ( handle != NULL ) {
61 FAIL("dlopen(\"libfoo.dylib\", RTLD_LAZY) should have failed becuase a symbol was missing");
62 }
63 }
64
65 PASS("Success");
66 }