]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/_dyld_register_func_for_add_image.dtest/main.cxx
905a1533ef7a66ed61712d4d4d02442ec9cac542
[apple/dyld.git] / testing / test-cases / _dyld_register_func_for_add_image.dtest / main.cxx
1
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
4
5 // RUN: ./dyld_register_test.exe
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <dlfcn.h>
10 #include <mach-o/dyld.h>
11 #include <mach-o/dyld_priv.h>
12
13 #include <unordered_set>
14
15 extern mach_header __dso_handle;
16
17 static std::unordered_set<const mach_header*> sCurrentImages;
18
19 static void notify(const mach_header* mh, intptr_t vmaddr_slide)
20 {
21 //fprintf(stderr, "mh=%p\n", mh);
22 if ( sCurrentImages.count(mh) != 0 ) {
23 printf("[FAIL] _dyld_register_func_for_add_image: notified twice about %p\n", mh);
24 exit(0);
25 }
26 sCurrentImages.insert(mh);
27 }
28
29
30 int main()
31 {
32 printf("[BEGIN] _dyld_register_func_for_add_image\n");
33
34 _dyld_register_func_for_add_image(&notify);
35
36 // verify we were notified about already loaded images
37 if ( sCurrentImages.count(&__dso_handle) == 0 ) {
38 printf("[FAIL] _dyld_register_func_for_add_image() did not notify us about main executable");
39 exit(0);
40 }
41 const mach_header* libSysMH = dyld_image_header_containing_address((void*)&printf);
42 if ( sCurrentImages.count(libSysMH) == 0 ) {
43 printf("[FAIL] _dyld_register_func_for_add_image() did not notify us about libsystem_c.dylib");
44 exit(0);
45 }
46
47 void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_FIRST);
48 if ( handle == NULL ) {
49 printf("[FAIL] dlopen(\"%s\") failed with: %s", RUN_DIR "/libfoo.dylib", dlerror());
50 exit(0);
51 }
52
53 void* sym = dlsym(handle, "foo");
54 if ( sym == NULL ) {
55 printf("[FAIL] dlsym(handle, \"foo\") failed");
56 exit(0);
57 }
58
59 // verify we were notified about load of libfoo.dylib
60 const mach_header* libfooMH = dyld_image_header_containing_address(sym);
61 if ( sCurrentImages.count(libfooMH) == 0 ) {
62 printf("[FAIL] _dyld_register_func_for_add_image() did not notify us about libfoo.dylib");
63 exit(0);
64 }
65
66
67 int result = dlclose(handle);
68 if ( result != 0 ) {
69 printf("[FAIL] dlclose(handle) returned %d", result);
70 exit(0);
71 }
72
73
74 printf("[PASS] _dyld_register_func_for_add_image\n");
75 return 0;
76 }
77