2 // BUILD: $CXX main.cxx -o $BUILD_DIR/dyld_register_test.exe -DRUN_DIR="$RUN_DIR"
3 // BUILD: $CC foo.c -dynamiclib -install_name $RUN_DIR/libfoo.dylib -o $BUILD_DIR/libfoo.dylib
5 // RUN: ./dyld_register_test.exe
10 #include <mach-o/dyld.h>
11 #include <mach-o/dyld_priv.h>
13 #include <unordered_set>
15 #include "test_support.h"
17 extern mach_header __dso_handle
;
19 static std
::unordered_set
<const mach_header
*> sCurrentImages
;
21 static void notify(const mach_header
* mh
, intptr_t vmaddr_slide
)
24 if ( sCurrentImages
.count(mh
) != 0 ) {
25 FAIL("notified twice about %p", mh
);
27 sCurrentImages
.insert(mh
);
31 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
32 _dyld_register_func_for_add_image(¬ify
);
34 // verify we were notified about already loaded images
35 if ( sCurrentImages
.count(&__dso_handle
) == 0 ) {
36 FAIL("did not notify us about main executable");
38 const mach_header
* libSysMH
= dyld_image_header_containing_address((void*)&printf
);
39 if ( sCurrentImages
.count(libSysMH
) == 0 ) {
40 FAIL("did not notify us about libsystem_c.dylib"); }
42 void* handle
= dlopen(RUN_DIR
"/libfoo.dylib", RTLD_FIRST
);
43 if ( handle
== NULL
) {
44 FAIL("dlopen(\"%s\") failed with: %s", RUN_DIR
"/libfoo.dylib", dlerror());
47 void* sym
= dlsym(handle
, "foo");
49 FAIL("dlsym(handle, \"foo\") failed");
52 // verify we were notified about load of libfoo.dylib
53 const mach_header
* libfooMH
= dyld_image_header_containing_address(sym
);
54 if ( sCurrentImages
.count(libfooMH
) == 0 ) {
55 FAIL("_dyld_register_func_for_add_image() did not notify us about libfoo.dylib");
58 int result
= dlclose(handle
);
60 FAIL("dlclose(handle) returned %d", result
);
63 PASS("_dyld_register_func_for_add_image");