]>
git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/_dyld_register_for_image_loads.dtest/main.cxx
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 // BUILD: $CC up.c -dynamiclib -install_name $RUN_DIR/libup.dylib -o $BUILD_DIR/libup.dylib
7 // BUILD: $CC baz.c -dynamiclib -install_name $RUN_DIR/libbaz.dylib -o $BUILD_DIR/libbaz.dylib $BUILD_DIR/libup.dylib
8 // BUILD: $CC bar.c -dynamiclib -install_name $RUN_DIR/libbar.dylib -o $BUILD_DIR/libbar.dylib -Wl,-upward_library,$BUILD_DIR/libup.dylib -DRUN_DIR="$RUN_DIR"
10 // RUN: ./dyld_register_test.exe
15 #include <mach-o/dyld.h>
16 #include <mach-o/dyld_priv.h>
18 #include <unordered_set>
20 #include "test_support.h"
22 extern "C" void foo();
24 extern mach_header __dso_handle
;
26 static std::unordered_set
<const mach_header
*> sCurrentImages
;
27 static bool expectedUnloadableState
= false;
29 static void notify(const mach_header
* mh
, const char* path
, bool unloadable
)
31 LOG("mh=%p, path=%s, unloadable=%d", mh
, path
, unloadable
);
32 if ( sCurrentImages
.count(mh
) != 0 ) {
33 FAIL("notified twice about %p", mh
);
35 sCurrentImages
.insert(mh
);
37 const char* leaf
= strrchr(path
, '/');
38 if ( unloadable
!= expectedUnloadableState
) {
39 FAIL("image incorrectly marked unloadable(%s) but expected unloadable(%s) %p %s",
40 unloadable
? "true" : "true", expectedUnloadableState
? "true" : "false", mh
, path
);
45 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
46 // Initially all images must not be unloadable as they are directly linked to the main executable
47 expectedUnloadableState
= false;
48 _dyld_register_for_image_loads(¬ify
);
50 // verify we were notified about already loaded images
51 if ( sCurrentImages
.count(&__dso_handle
) == 0 ) {
52 FAIL("did not notify us about main executable");
54 const mach_header
* libSysMH
= dyld_image_header_containing_address((void*)&printf
);
55 if ( sCurrentImages
.count(libSysMH
) == 0 ) {
56 FAIL("did not notify us about libsystem_c.dylib");
58 const mach_header
* libFoo
= dyld_image_header_containing_address((void*)&foo
);
59 if ( sCurrentImages
.count(libFoo
) == 0 ) {
60 FAIL("did not notify us about libfoo.dylib");
63 // These dlopen's can be unloaded
64 expectedUnloadableState
= true;
66 // verify we were notified about load of libfoo2.dylib
67 void* handle2
= dlopen(RUN_DIR
"/libfoo2.dylib", RTLD_FIRST
);
68 if ( handle2
== NULL
) {
69 FAIL("dlopen(\"%s\") failed with: %s", RUN_DIR
"/libfoo.dylib", dlerror());
71 const void* libfoo2Foo
= dlsym(handle2
, "foo");
72 const mach_header
* libfoo2MH
= dyld_image_header_containing_address(libfoo2Foo
);
73 if ( sCurrentImages
.count(libfoo2MH
) == 0 ) {
74 FAIL("did not notify us about libfoo2.dylib");
77 // verify we were notified about load of foo.bundle
78 void* handleB
= dlopen(RUN_DIR
"/foo.bundle", RTLD_FIRST
);
79 if ( handleB
== NULL
) {
80 FAIL("dlopen(\"%s\") failed with: %s", RUN_DIR
"/foo.bundle", dlerror());
82 const void* libfooBFoo
= dlsym(handle2
, "foo");
83 const mach_header
* libfooB
= dyld_image_header_containing_address(libfooBFoo
);
84 if ( sCurrentImages
.count(libfooB
) == 0 ) {
85 FAIL("_dyld_register_for_image_loads() did not notify us about foo.bundle");
88 // Upward linking with dlopen may confuse the notifier as we may try to notify twice on the upwardly linked image
90 // libbar upward links libup
91 // libbar also dlopens libbaz
93 // We should not get a duplicate notification on libup
94 void* handleBar
= dlopen(RUN_DIR
"/libbar.dylib", RTLD_FIRST
);
95 if ( handleBar
== NULL
) {
96 FAIL("dlopen(\"%s\") failed with: %s", RUN_DIR
"/libbar.dylib", dlerror());