dyld-625.13.tar.gz
[apple/dyld.git] / testing / test-cases / _dyld_register_for_image_loads.dtest / main.cxx
1
2 // BUILD: $CC foo.c -dynamiclib -install_name $RUN_DIR/libfoo.dylib -o $BUILD_DIR/libfoo.dylib
3 // BUILD: $CXX main.cxx -o $BUILD_DIR/dyld_register_test.exe $BUILD_DIR/libfoo.dylib -DRUN_DIR="$RUN_DIR"
4 // BUILD: $CC foo.c -dynamiclib -install_name $RUN_DIR/libfoo2.dylib -o $BUILD_DIR/libfoo2.dylib
5 // BUILD: $CC foo.c -bundle -o $BUILD_DIR/foo.bundle
6
7 // RUN: ./dyld_register_test.exe
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <dlfcn.h>
12 #include <mach-o/dyld.h>
13 #include <mach-o/dyld_priv.h>
14
15 #include <unordered_set>
16
17 extern "C" void foo();
18
19 extern mach_header __dso_handle;
20
21 static std::unordered_set<const mach_header*> sCurrentImages;
22
23 static void notify(const mach_header* mh, const char* path, bool unloadable)
24 {
25 fprintf(stderr, "mh=%p, path=%s, unloadable=%d\n", mh, path, unloadable);
26 if ( sCurrentImages.count(mh) != 0 ) {
27 printf("[FAIL] _dyld_register_for_image_loads: notified twice about %p\n", mh);
28 exit(0);
29 }
30 sCurrentImages.insert(mh);
31
32 const char* leaf = strrchr(path, '/');
33 if ( unloadable ) {
34 if ( (strcmp(leaf, "/libfoo2.dylib") != 0) && (strcmp(leaf, "/foo.bundle") != 0) ) {
35 printf("[FAIL] _dyld_register_for_image_loads: image incorrectly marked unloadable %p %s\n", mh, path);
36 exit(0);
37 }
38 }
39 else {
40 if ( (strcmp(leaf, "/libfoo2.dylib") == 0) || (strcmp(leaf, "/foo.bundle") == 0) ) {
41 printf("[FAIL] _dyld_register_for_image_loads: image incorrectly marked as not unloadable %p %s\n", mh, path);
42 exit(0);
43 }
44 }
45 }
46
47
48 int main()
49 {
50 printf("[BEGIN] _dyld_register_for_image_loads\n");
51
52 _dyld_register_for_image_loads(&notify);
53
54 // verify we were notified about already loaded images
55 if ( sCurrentImages.count(&__dso_handle) == 0 ) {
56 printf("[FAIL] _dyld_register_for_image_loads() did not notify us about main executable\n");
57 exit(0);
58 }
59 const mach_header* libSysMH = dyld_image_header_containing_address((void*)&printf);
60 if ( sCurrentImages.count(libSysMH) == 0 ) {
61 printf("[FAIL] _dyld_register_for_image_loads() did not notify us about libsystem_c.dylib\n");
62 exit(0);
63 }
64 const mach_header* libFoo = dyld_image_header_containing_address((void*)&foo);
65 if ( sCurrentImages.count(libFoo) == 0 ) {
66 printf("[FAIL] _dyld_register_for_image_loads() did not notify us about libfoo.dylib\n");
67 exit(0);
68 }
69
70 // verify we were notified about load of libfoo2.dylib
71 void* handle2 = dlopen(RUN_DIR "/libfoo2.dylib", RTLD_FIRST);
72 if ( handle2 == NULL ) {
73 printf("[FAIL] dlopen(\"%s\") failed with: %s\n", RUN_DIR "/libfoo.dylib", dlerror());
74 exit(0);
75 }
76 const void* libfoo2Foo = dlsym(handle2, "foo");
77 const mach_header* libfoo2MH = dyld_image_header_containing_address(libfoo2Foo);
78 if ( sCurrentImages.count(libfoo2MH) == 0 ) {
79 printf("[FAIL] _dyld_register_for_image_loads() did not notify us about libfoo2.dylib\n");
80 exit(0);
81 }
82
83 // verify we were notified about load of foo.bundle
84 void* handleB = dlopen(RUN_DIR "/foo.bundle", RTLD_FIRST);
85 if ( handleB == NULL ) {
86 printf("[FAIL] dlopen(\"%s\") failed with: %s\n", RUN_DIR "/foo.bundle", dlerror());
87 exit(0);
88 }
89 const void* libfooBFoo = dlsym(handle2, "foo");
90 const mach_header* libfooB = dyld_image_header_containing_address(libfooBFoo);
91 if ( sCurrentImages.count(libfooB) == 0 ) {
92 printf("[FAIL] _dyld_register_for_image_loads() did not notify us about foo.bundle\n");
93 exit(0);
94 }
95
96
97
98 printf("[PASS] _dyld_register_for_image_loads\n");
99 return 0;
100 }
101