1 // BUILD(macos): $CC main.c -o $BUILD_DIR/NSCreateObjectFileImageFromMemory-basic.exe -Wno-deprecated-declarations
2 // BUILD(macos): $CC foo.c -o $BUILD_DIR/foo.bundle -bundle
4 // BUILD(ios,tvos,watchos,bridgeos):
6 // RUN: ./NSCreateObjectFileImageFromMemory-basic.exe $RUN_DIR/foo.bundle
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");
91 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
92 checkBundle(argv
[1], true);
93 checkBundle(argv
[1], false);
95 // Now go again enough times to flush out any limits in our dlopen encodings.
96 for (unsigned i
= 0; i
!= 255; ++i
)
97 checkBundle(argv
[1], false);