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
8 // RUN: ./dlopen-indirect-groupNum.exe $RUN_DIR/foo.bundle $RUN_DIR/libbar.dylib $RUN_DIR/libbaz.dylib
13 #include <sys/types.h>
19 #include <mach-o/dyld.h>
21 #include "test_support.h"
23 static void checkBundle(const char* path
, bool unlinkBeforeDestroy
)
25 int fd
= open(path
, O_RDONLY
, 0);
27 FAIL("open(%s) failed", path
);
31 if ( fstat(fd
, &stat_buf
) == -1) {
32 FAIL("fstat() failed");
35 void* loadAddress
= mmap(NULL
, stat_buf
.st_size
, PROT_READ
, MAP_FILE
| MAP_PRIVATE
, fd
, 0);
36 if ( loadAddress
== ((void*)(-1)) ) {
37 FAIL("mmap() failed");
42 NSObjectFileImage ofi
;
43 if ( NSCreateObjectFileImageFromMemory(loadAddress
, stat_buf
.st_size
, &ofi
) != NSObjectFileImageSuccess
) {
44 FAIL("NSCreateObjectFileImageFromMemory failed");
47 NSModule mod
= NSLinkModule(ofi
, path
, NSLINKMODULE_OPTION_NONE
);
49 FAIL("NSLinkModule failed");
52 if ( !unlinkBeforeDestroy
) {
53 // API lets you destroy ofi and NSModule lives on
54 if ( !NSDestroyObjectFileImage(ofi
) ) {
55 FAIL("NSDestroyObjectFileImage failed");
59 NSSymbol sym
= NSLookupSymbolInModule(mod
, "_fooInBundle");
61 FAIL("NSLookupSymbolInModule failed");
64 void* func
= NSAddressOfSymbol(sym
);
66 FAIL("NSAddressOfSymbol failed");
70 if ( dladdr(func
, &info
) == 0 ) {
71 FAIL("dladdr(&p, xx) failed");
73 LOG("_fooInBundle found in %s", info
.dli_fname
);
75 if ( !NSUnLinkModule(mod
, NSUNLINKMODULE_OPTION_NONE
) ) {
76 FAIL("NSUnLinkModule failed");
79 if ( dladdr(func
, &info
) != 0 ) {
80 FAIL("dladdr(&p, xx) found but should not have");
83 if ( unlinkBeforeDestroy
) {
84 if ( !NSDestroyObjectFileImage(ofi
) ) {
85 FAIL("NSDestroyObjectFileImage failed");
92 static void tryImage(const char* path
, const char* symbol
)
94 void* handle
= dlopen(path
, RTLD_LAZY
);
95 if ( handle
== NULL
) {
96 FAIL("dlopen(%s) error: %s", path
, dlerror());
99 void* sym
= dlsym(handle
, symbol
);
101 FAIL("dlsym(%s) error: %s", symbol
, dlerror());
104 int result
= dlclose(handle
);
106 FAIL("dlclose(%s) returned %c", path
, result
);
111 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
112 checkBundle(argv
[1], true);
113 checkBundle(argv
[1], false);
115 // Now go again enough times to flush out any limits in our dlopen encodings.
116 for (unsigned i
= 0; i
!= 255; ++i
)
117 checkBundle(argv
[1], false);
120 tryImage(argv
[2], "barInDylib");
122 // And now open baz.dylib which depends on bar.dylib
123 tryImage(argv
[3], "bazInDylib");