dyld-733.8.tar.gz
[apple/dyld.git] / testing / test-cases / dlopen-indirect-groupNum.dtest / main.c
1 // BUILD_ONLY: MacOSX
2
3 // BUILD: $CC main.c -o $BUILD_DIR/dlopen-indirect-groupNum.exe -Wno-deprecated-declarations
4 // BUILD: $CC foo.c -o $BUILD_DIR/foo.bundle -bundle
5 // BUILD: $CC bar.c -dynamiclib -install_name $RUN_DIR/libbar.dylib -o $BUILD_DIR/libbar.dylib
6 // BUILD: $CC baz.c -dynamiclib -install_name $RUN_DIR/libbaz.dylib -o $BUILD_DIR/libbaz.dylib $BUILD_DIR/libbar.dylib
7
8 // RUN: ./dlopen-indirect-groupNum.exe $RUN_DIR/foo.bundle $RUN_DIR/libbar.dylib $RUN_DIR/libbaz.dylib
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <sys/mman.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <dlfcn.h>
19 #include <mach-o/dyld.h>
20
21
22 static void checkBundle(const char* path, bool unlinkBeforeDestroy)
23 {
24 int fd = open(path, O_RDONLY, 0);
25 if ( fd == -1 ) {
26 printf("[FAIL] open(%s) failed", path);
27 exit(0);
28 }
29
30 struct stat stat_buf;
31 if ( fstat(fd, &stat_buf) == -1) {
32 printf("[FAIL] fstat() failed\n");
33 exit(0);
34 }
35
36 void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
37 if ( loadAddress == ((void*)(-1)) ) {
38 printf("[FAIL] mmap() failed\n");
39 exit(0);
40 }
41
42 close(fd);
43
44 NSObjectFileImage ofi;
45 if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) {
46 printf("[FAIL] NSCreateObjectFileImageFromMemory failed\n");
47 exit(0);
48 }
49
50 NSModule mod = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_NONE);
51 if ( mod == NULL ) {
52 printf("[FAIL] NSLinkModule failed\n");
53 exit(0);
54 }
55
56 if ( !unlinkBeforeDestroy ) {
57 // API lets you destroy ofi and NSModule lives on
58 if ( !NSDestroyObjectFileImage(ofi) ) {
59 printf("[FAIL] NSDestroyObjectFileImage failed\n");
60 exit(0);
61 }
62 }
63
64 NSSymbol sym = NSLookupSymbolInModule(mod, "_fooInBundle");
65 if ( sym == NULL ) {
66 printf("[FAIL] NSLookupSymbolInModule failed\n");
67 exit(0);
68 }
69
70 void* func = NSAddressOfSymbol(sym);
71 if ( func == NULL ) {
72 printf("[FAIL] NSAddressOfSymbol failed\n");
73 exit(0);
74 }
75
76 Dl_info info;
77 if ( dladdr(func, &info) == 0 ) {
78 printf("[FAIL] dladdr(&p, xx) failed\n");
79 exit(0);
80 }
81 //printf("_fooInBundle found in %s\n", info.dli_fname);
82
83 if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) {
84 printf("[FAIL] NSUnLinkModule failed\n");
85 exit(0);
86 }
87
88 if ( dladdr(func, &info) != 0 ) {
89 printf("[FAIL] dladdr(&p, xx) found but should not have\n");
90 exit(0);
91 }
92
93 if ( unlinkBeforeDestroy ) {
94 if ( !NSDestroyObjectFileImage(ofi) ) {
95 printf("[FAIL] NSDestroyObjectFileImage failed\n");
96 exit(0);
97 }
98 }
99 }
100
101
102
103 static void tryImage(const char* path, const char* symbol)
104 {
105 void* handle = dlopen(path, RTLD_LAZY);
106 if ( handle == NULL ) {
107 printf("dlerror(): %s\n", dlerror());
108 printf("[FAIL] dlopen-indirect-groupNum %s\n", path);
109 exit(0);
110 }
111
112 void* sym = dlsym(handle, symbol);
113 if ( sym == NULL ) {
114 printf("dlerror(): %s\n", dlerror());
115 printf("[FAIL] dlopen-indirect-groupNum %s\n", path);
116 exit(0);
117 }
118
119 int result = dlclose(handle);
120 if ( result != 0 ) {
121 printf("dlclose() returned %c\n", result);
122 printf("[FAIL] dlopen-indirect-groupNum %s\n", path);
123 exit(0);
124 }
125 }
126
127
128 int main(int argc, const char* argv[])
129 {
130 printf("[BEGIN] dlopen-indirect-groupNum\n");
131
132 checkBundle(argv[1], true);
133 checkBundle(argv[1], false);
134
135 // Now go again enough times to flush out any limits in our dlopen encodings.
136 for (unsigned i = 0; i != 255; ++i)
137 checkBundle(argv[1], false);
138
139 // Open bar.dylib
140 tryImage(argv[2], "barInDylib");
141
142 // And now open baz.dylib which depends on bar.dylib
143 tryImage(argv[3], "bazInDylib");
144
145 printf("[PASS] dlopen-indirect-groupNum\n");
146 return 0;
147 }