diff --git a/makefile b/makefile index 9cdd151cdb..e4d31bfe01 100644 --- a/makefile +++ b/makefile @@ -82,7 +82,7 @@ endif ifeq ($(platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ -I$(JAVA_HOME)/include/linux -I$(src) - lflags = $(common-lflags) -ldl + lflags = $(common-lflags) -ldl -framework CoreFoundation strip-all = -S -x binaryToMacho = $(native-build)/binaryToMacho endif diff --git a/src/posix.cpp b/src/posix.cpp index 4f3b46857a..dbc4bd5886 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -1,3 +1,6 @@ +#ifdef __APPLE__ +#include "CoreFoundation/CoreFoundation.h" +#endif #include "sys/mman.h" #include "sys/types.h" #include "sys/stat.h" @@ -116,6 +119,27 @@ allocate(System* s, unsigned size) return p; } +void +pathOfExecutable(System* s, const char** retBuf, unsigned* size) +{ +#ifdef __APPLE__ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFURLRef url = CFBundleCopyExecutableURL(bundle); + CFStringRef path = CFURLCopyPath(url); + CFIndex pathSize = CFStringGetMaximumSizeOfFileSystemRepresentation(path); + char* buffer = reinterpret_cast(allocate(s, pathSize)); + if (CFStringGetFileSystemRepresentation(path, buffer, pathSize)) { + *size = pathSize; + *retBuf = buffer; + } else { + abort(); + } +#else + *size = 0; + *retBuf = NULL; +#endif +} + const bool Verbose = false; const unsigned Waiting = 1 << 0; @@ -646,6 +670,7 @@ class MySystem: public System { bool mapName) { void* p; + bool alreadyAllocated = false; unsigned nameLength = (name ? strlen(name) : 0); if (mapName) { unsigned size = nameLength + 3 + sizeof(SO_SUFFIX); @@ -653,6 +678,10 @@ class MySystem: public System { snprintf(buffer, size, "lib%s" SO_SUFFIX, name); p = dlopen(buffer, RTLD_LAZY); } else { + if (!name) { + pathOfExecutable(this, &name, &nameLength); + alreadyAllocated = true; + } p = dlopen(name, RTLD_LAZY); } @@ -665,6 +694,9 @@ class MySystem: public System { if (name) { n = static_cast(allocate(this, nameLength + 1)); memcpy(n, name, nameLength + 1); + if (alreadyAllocated) { + free(name, nameLength, false); + } } else { n = 0; } diff --git a/src/system.h b/src/system.h index 2f06357cbf..bb53cdc407 100644 --- a/src/system.h +++ b/src/system.h @@ -134,6 +134,7 @@ expect(System* s, bool v) #ifdef NDEBUG +# undef assert # define assert(a, b) #else // not NDEBUG