summaryrefslogtreecommitdiffstats
path: root/unix/tclLoadDyld.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclLoadDyld.c')
-rw-r--r--unix/tclLoadDyld.c252
1 files changed, 78 insertions, 174 deletions
diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c
index 31d15b2..95735a4 100644
--- a/unix/tclLoadDyld.c
+++ b/unix/tclLoadDyld.c
@@ -16,42 +16,36 @@
#include "tclInt.h"
#ifndef MODULE_SCOPE
-#define MODULE_SCOPE extern
+# define MODULE_SCOPE extern
#endif
-#ifndef TCL_DYLD_USE_DLFCN
/*
* Use preferred dlfcn API on 10.4 and later
*/
-# if !defined(NO_DLFCN_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
-# define TCL_DYLD_USE_DLFCN 1
-# else
+
+#ifndef TCL_DYLD_USE_DLFCN
+# ifdef NO_DLFCN_H
# define TCL_DYLD_USE_DLFCN 0
+# else
+# define TCL_DYLD_USE_DLFCN 1
# endif
#endif
-#ifndef TCL_DYLD_USE_NSMODULE
+
/*
* Use deprecated NSModule API only to support 10.3 and earlier:
*/
-# if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
-# define TCL_DYLD_USE_NSMODULE 1
-# else
-# define TCL_DYLD_USE_NSMODULE 0
-# endif
+
+#ifndef TCL_DYLD_USE_NSMODULE
+# define TCL_DYLD_USE_NSMODULE 0
#endif
-#if TCL_DYLD_USE_DLFCN
-#include <dlfcn.h>
-#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
/*
- * Support for weakly importing dlfcn API.
+ * Use includes for the API we're using.
*/
-extern void *dlopen(const char *path, int mode) WEAK_IMPORT_ATTRIBUTE;
-extern void *dlsym(void *handle, const char *symbol) WEAK_IMPORT_ATTRIBUTE;
-extern int dlclose(void *handle) WEAK_IMPORT_ATTRIBUTE;
-extern char *dlerror(void) WEAK_IMPORT_ATTRIBUTE;
-#endif
-#endif
+
+#if TCL_DYLD_USE_DLFCN
+# include <dlfcn.h>
+#endif /* TCL_DYLD_USE_DLFCN */
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
#include <mach-o/dyld.h>
@@ -60,38 +54,23 @@ extern char *dlerror(void) WEAK_IMPORT_ATTRIBUTE;
#include <mach-o/arch.h>
#include <libkern/OSByteOrder.h>
#include <mach/mach.h>
-#include <stdbool.h>
typedef struct Tcl_DyldModuleHandle {
struct Tcl_DyldModuleHandle *nextPtr;
NSModule module;
} Tcl_DyldModuleHandle;
-#endif /* TCL_DYLD_USE_NSMODULE */
+#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */
-typedef struct Tcl_DyldLoadHandle {
-#if TCL_DYLD_USE_DLFCN
+typedef struct {
void *dlHandle;
-#endif
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
const struct mach_header *dyldLibHeader;
Tcl_DyldModuleHandle *modulePtr;
#endif
} Tcl_DyldLoadHandle;
-#if (TCL_DYLD_USE_DLFCN && MAC_OS_X_VERSION_MIN_REQUIRED < 1040) || \
- defined(TCL_LOAD_FROM_MEMORY)
-MODULE_SCOPE long tclMacOSXDarwinRelease;
-#endif
-
-#ifdef TCL_DEBUG_LOAD
-#define TclLoadDbgMsg(m, ...) \
- do { \
- fprintf(stderr, "%s:%d: %s(): " m ".\n", \
- strrchr(__FILE__, '/')+1, __LINE__, __func__, \
- ##__VA_ARGS__); \
- } while (0)
-#else
-#define TclLoadDbgMsg(m, ...)
+#if TCL_DYLD_USE_DLFCN || defined(TCL_LOAD_FROM_MEMORY)
+MODULE_SCOPE long tclMacOSXDarwinRelease;
#endif
/*
@@ -102,7 +81,6 @@ static void * FindSymbol(Tcl_Interp *interp,
Tcl_LoadHandle loadHandle, const char *symbol);
static void UnloadFile(Tcl_LoadHandle handle);
-#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
/*
*----------------------------------------------------------------------
*
@@ -120,6 +98,7 @@ static void UnloadFile(Tcl_LoadHandle handle);
*----------------------------------------------------------------------
*/
+#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
static const char *
DyldOFIErrorMsg(
int err)
@@ -141,7 +120,7 @@ DyldOFIErrorMsg(
return "unknown error";
}
}
-#endif /* TCL_DYLD_USE_NSMODULE */
+#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */
/*
*----------------------------------------------------------------------
@@ -176,9 +155,7 @@ TclpDlopen(
{
Tcl_DyldLoadHandle *dyldLoadHandle;
Tcl_LoadHandle newHandle;
-#if TCL_DYLD_USE_DLFCN
void *dlHandle = NULL;
-#endif
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
const struct mach_header *dyldLibHeader = NULL;
Tcl_DyldModuleHandle *modulePtr = NULL;
@@ -187,11 +164,10 @@ TclpDlopen(
NSLinkEditErrors editError;
int errorNumber;
const char *errorName, *objFileImageErrMsg = NULL;
-#endif
+#endif /* TCL_DYLD_USE_NSMODULE */
const char *errMsg = NULL;
int result;
Tcl_DString ds;
- char *fileName = NULL;
const char *nativePath, *nativeFileName = NULL;
/*
@@ -201,46 +177,36 @@ TclpDlopen(
*/
nativePath = Tcl_FSGetNativePath(pathPtr);
+ nativeFileName = Tcl_UtfToExternalDString(NULL, Tcl_GetString(pathPtr),
+ -1, &ds);
#if TCL_DYLD_USE_DLFCN
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
- if (tclMacOSXDarwinRelease >= 8)
-#endif
- {
/*
* Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070]
*/
- dlHandle = dlopen(nativePath, RTLD_NOW | RTLD_LOCAL);
- if (!dlHandle) {
- /*
- * Let the OS loader examine the binary search path for whatever
- * string the user gave us which hopefully refers to a file on the
- * binary path.
- */
- fileName = Tcl_GetString(pathPtr);
- nativeFileName = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
- /*
- * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070]
- */
- dlHandle = dlopen(nativeFileName, RTLD_NOW | RTLD_LOCAL);
- }
- if (dlHandle) {
- TclLoadDbgMsg("dlopen() successful");
- } else {
+ dlHandle = dlopen(nativePath, RTLD_NOW | RTLD_LOCAL);
+ if (!dlHandle) {
+ /*
+ * Let the OS loader examine the binary search path for whatever string
+ * the user gave us which hopefully refers to a file on the binary
+ * path.
+ *
+ * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070]
+ */
+
+ dlHandle = dlopen(nativeFileName, RTLD_NOW | RTLD_LOCAL);
+ if (!dlHandle) {
errMsg = dlerror();
- TclLoadDbgMsg("dlopen() failed: %s", errMsg);
}
}
- if (!dlHandle)
#endif /* TCL_DYLD_USE_DLFCN */
- {
+
+ if (!dlHandle) {
#if TCL_DYLD_USE_NSMODULE
dyldLibHeader = NSAddImage(nativePath,
NSADDIMAGE_OPTION_RETURN_ON_ERROR);
- if (dyldLibHeader) {
- TclLoadDbgMsg("NSAddImage() successful");
- } else {
+ if (!dyldLibHeader) {
NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
if (editError == NSLinkEditFileAccessError) {
/*
@@ -249,20 +215,12 @@ TclpDlopen(
* which hopefully refers to a file on the binary path.
*/
- if (!fileName) {
- fileName = Tcl_GetString(pathPtr);
- nativeFileName = Tcl_UtfToExternalDString(NULL, fileName,
- -1, &ds);
- }
dyldLibHeader = NSAddImage(nativeFileName,
NSADDIMAGE_OPTION_WITH_SEARCHING |
NSADDIMAGE_OPTION_RETURN_ON_ERROR);
- if (dyldLibHeader) {
- TclLoadDbgMsg("NSAddImage() successful");
- } else {
+ if (!dyldLibHeader) {
NSLinkEditError(&editError, &errorNumber, &errorName,
&errMsg);
- TclLoadDbgMsg("NSAddImage() failed: %s", errMsg);
}
} else if ((editError == NSLinkEditFileFormatError
&& errorNumber == EBADMACHO)
@@ -279,8 +237,6 @@ TclpDlopen(
err = NSCreateObjectFileImageFromFile(nativePath,
&dyldObjFileImage);
if (err == NSObjectFileImageSuccess && dyldObjFileImage) {
- TclLoadDbgMsg("NSCreateObjectFileImageFromFile() "
- "successful");
module = NSLinkModule(dyldObjFileImage, nativePath,
NSLINKMODULE_OPTION_BINDNOW
| NSLINKMODULE_OPTION_RETURN_ON_ERROR);
@@ -289,37 +245,29 @@ TclpDlopen(
modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle));
modulePtr->module = module;
modulePtr->nextPtr = NULL;
- TclLoadDbgMsg("NSLinkModule() successful");
} else {
NSLinkEditError(&editError, &errorNumber, &errorName,
&errMsg);
- TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg);
}
} else {
objFileImageErrMsg = DyldOFIErrorMsg(err);
- TclLoadDbgMsg("NSCreateObjectFileImageFromFile() failed: "
- "%s", objFileImageErrMsg);
}
}
}
#endif /* TCL_DYLD_USE_NSMODULE */
}
- if (0
-#if TCL_DYLD_USE_DLFCN
- || dlHandle
-#endif
+
+ if (dlHandle
#if TCL_DYLD_USE_NSMODULE
|| dyldLibHeader || modulePtr
-#endif
+#endif /* TCL_DYLD_USE_NSMODULE */
) {
dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle));
-#if TCL_DYLD_USE_DLFCN
dyldLoadHandle->dlHandle = dlHandle;
-#endif
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
dyldLoadHandle->dyldLibHeader = dyldLibHeader;
dyldLoadHandle->modulePtr = modulePtr;
-#endif
+#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */
newHandle = ckalloc(sizeof(*newHandle));
newHandle->clientData = dyldLoadHandle;
newHandle->findSymbolProcPtr = &FindSymbol;
@@ -328,18 +276,23 @@ TclpDlopen(
*loadHandle = newHandle;
result = TCL_OK;
} else {
- Tcl_AppendResult(interp, errMsg, NULL);
+ Tcl_Obj *errObj = Tcl_NewObj();
+
+ if (errMsg != NULL) {
+ Tcl_AppendToObj(errObj, errMsg, -1);
+ }
#if TCL_DYLD_USE_NSMODULE
if (objFileImageErrMsg) {
- Tcl_AppendResult(interp, "\nNSCreateObjectFileImageFromFile() "
- "error: ", objFileImageErrMsg, NULL);
+ Tcl_AppendPrintfToObj(errObj,
+ "\nNSCreateObjectFileImageFromFile() error: %s",
+ objFileImageErrMsg);
}
-#endif
+#endif /* TCL_DYLD_USE_NSMODULE */
+ Tcl_SetObjResult(interp, errObj);
result = TCL_ERROR;
}
- if(fileName) {
- Tcl_DStringFree(&ds);
- }
+
+ Tcl_DStringFree(&ds);
return result;
}
@@ -372,18 +325,14 @@ FindSymbol(
const char *native;
native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
-#if TCL_DYLD_USE_DLFCN
if (dyldLoadHandle->dlHandle) {
+#if TCL_DYLD_USE_DLFCN
proc = dlsym(dyldLoadHandle->dlHandle, native);
- if (proc) {
- TclLoadDbgMsg("dlsym() successful");
- } else {
+ if (!proc) {
errMsg = dlerror();
- TclLoadDbgMsg("dlsym() failed: %s", errMsg);
}
- } else
#endif /* TCL_DYLD_USE_DLFCN */
- {
+ } else {
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
NSSymbol nsSymbol = NULL;
Tcl_DString newName;
@@ -400,13 +349,12 @@ FindSymbol(
native, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
if (nsSymbol) {
- TclLoadDbgMsg("NSLookupSymbolInImage() successful");
-#ifdef DYLD_SUPPORTS_DYLIB_UNLOADING
/*
* Until dyld supports unloading of MY_DYLIB binaries, the
* following is not needed.
*/
+#ifdef DYLD_SUPPORTS_DYLIB_UNLOADING
NSModule module = NSModuleForSymbol(nsSymbol);
Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;
@@ -429,32 +377,21 @@ FindSymbol(
const char *errorName;
NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
- TclLoadDbgMsg("NSLookupSymbolInImage() failed: %s", errMsg);
}
} else if (dyldLoadHandle->modulePtr) {
nsSymbol = NSLookupSymbolInModule(
dyldLoadHandle->modulePtr->module, native);
- if (nsSymbol) {
- TclLoadDbgMsg("NSLookupSymbolInModule() successful");
- } else {
- TclLoadDbgMsg("NSLookupSymbolInModule() failed");
- }
}
if (nsSymbol) {
proc = NSAddressOfSymbol(nsSymbol);
- if (proc) {
- TclLoadDbgMsg("NSAddressOfSymbol() successful");
- } else {
- TclLoadDbgMsg("NSAddressOfSymbol() failed");
- }
}
Tcl_DStringFree(&newName);
#endif /* TCL_DYLD_USE_NSMODULE */
}
Tcl_DStringFree(&ds);
if (errMsg && (interp != NULL)) {
- Tcl_AppendResult(interp, "cannot find symbol \"", symbol, "\": ",
- errMsg, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "cannot find symbol \"%s\": %s", symbol, errMsg));
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol,
NULL);
}
@@ -489,34 +426,19 @@ UnloadFile(
{
Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData;
-#if TCL_DYLD_USE_DLFCN
if (dyldLoadHandle->dlHandle) {
- int result;
-
- result = dlclose(dyldLoadHandle->dlHandle);
- if (!result) {
- TclLoadDbgMsg("dlclose() successful");
- } else {
- TclLoadDbgMsg("dlclose() failed: %s", dlerror());
- }
- } else
+#if TCL_DYLD_USE_DLFCN
+ (void) dlclose(dyldLoadHandle->dlHandle);
#endif /* TCL_DYLD_USE_DLFCN */
- {
+ } else {
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;
while (modulePtr != NULL) {
- void *ptr;
- bool result;
+ void *ptr = modulePtr;
- result = NSUnLinkModule(modulePtr->module,
+ (void) NSUnLinkModule(modulePtr->module,
NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
- if (result) {
- TclLoadDbgMsg("NSUnLinkModule() successful");
- } else {
- TclLoadDbgMsg("NSUnLinkModule() failed");
- }
- ptr = modulePtr;
modulePtr = modulePtr->nextPtr;
ckfree(ptr);
}
@@ -556,7 +478,6 @@ TclGuessPackageName(
return 0;
}
-#ifdef TCL_LOAD_FROM_MEMORY
/*
*----------------------------------------------------------------------
*
@@ -573,6 +494,7 @@ TclGuessPackageName(
*----------------------------------------------------------------------
*/
+#ifdef TCL_LOAD_FROM_MEMORY
MODULE_SCOPE void *
TclpLoadMemoryGetBuffer(
Tcl_Interp *interp, /* Used for error reporting. */
@@ -597,6 +519,7 @@ TclpLoadMemoryGetBuffer(
}
return buffer;
}
+#endif /* TCL_LOAD_FROM_MEMORY */
/*
*----------------------------------------------------------------------
@@ -616,6 +539,7 @@ TclpLoadMemoryGetBuffer(
*----------------------------------------------------------------------
*/
+#ifdef TCL_LOAD_FROM_MEMORY
MODULE_SCOPE int
TclpLoadMemory(
Tcl_Interp *interp, /* Used for error reporting. */
@@ -658,7 +582,7 @@ TclpLoadMemory(
# define mh_size sizeof(struct mach_header_64)
# define mh_magic MH_MAGIC_64
# define arch_abi CPU_ARCH_ABI64
-#endif
+#endif /* __LP64__ */
if ((size_t) codeSize >= sizeof(struct fat_header)
&& fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) {
@@ -668,7 +592,6 @@ TclpLoadMemory(
* Fat binary, try to find mach_header for our architecture
*/
- TclLoadDbgMsg("Fat binary, %d archs", fh_nfat_arch);
if ((size_t) codeSize >= sizeof(struct fat_header) +
fh_nfat_arch * sizeof(struct fat_arch)) {
void *fatarchs = (char*)buffer + sizeof(struct fat_header);
@@ -681,22 +604,15 @@ TclpLoadMemory(
fa = NXFindBestFatArch(arch->cputype | arch_abi,
arch->cpusubtype, fatarchs, fh_nfat_arch);
if (fa) {
- TclLoadDbgMsg("NXFindBestFatArch() successful: "
- "local cputype %d subtype %d, "
- "fat cputype %d subtype %d",
- arch->cputype | arch_abi, arch->cpusubtype,
- fa->cputype, fa->cpusubtype);
- mh = (void*)((char*)buffer + fa->offset);
+ mh = (void *)((char *) buffer + fa->offset);
ms = fa->size;
} else {
- TclLoadDbgMsg("NXFindBestFatArch() failed");
err = NSObjectFileImageInappropriateFile;
}
if (fh->magic != FAT_MAGIC) {
swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);
}
} else {
- TclLoadDbgMsg("Fat binary header failure");
err = NSObjectFileImageInappropriateFile;
}
} else {
@@ -704,26 +620,18 @@ TclpLoadMemory(
* Thin binary
*/
- TclLoadDbgMsg("Thin binary");
mh = buffer;
ms = codeSize;
}
if (ms && !(ms >= mh_size && mh->magic == mh_magic &&
mh->filetype == MH_BUNDLE)) {
- TclLoadDbgMsg("Inappropriate file: magic %x filetype %d",
- mh->magic, mh->filetype);
err = NSObjectFileImageInappropriateFile;
}
if (err == NSObjectFileImageSuccess) {
err = NSCreateObjectFileImageFromMemory(buffer, codeSize,
&dyldObjFileImage);
- if (err == NSObjectFileImageSuccess) {
- TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() "
- "successful");
- } else {
+ if (err != NSObjectFileImageSuccess) {
objFileImageErrMsg = DyldOFIErrorMsg(err);
- TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s",
- objFileImageErrMsg);
}
} else {
objFileImageErrMsg = DyldOFIErrorMsg(err);
@@ -738,8 +646,9 @@ TclpLoadMemory(
if (dyldObjFileImage == NULL) {
vm_deallocate(mach_task_self(), (vm_address_t) buffer, size);
if (objFileImageErrMsg != NULL) {
- Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() "
- "error: ", objFileImageErrMsg, NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "NSCreateObjectFileImageFromMemory() error: ",
+ objFileImageErrMsg));
}
return TCL_ERROR;
}
@@ -751,16 +660,13 @@ TclpLoadMemory(
module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]",
NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
NSDestroyObjectFileImage(dyldObjFileImage);
- if (module) {
- TclLoadDbgMsg("NSLinkModule() successful");
- } else {
+ if (!module) {
NSLinkEditErrors editError;
int errorNumber;
const char *errorName, *errMsg;
NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
- TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg);
- Tcl_AppendResult(interp, errMsg, NULL);
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1));
return TCL_ERROR;
}
@@ -772,9 +678,7 @@ TclpLoadMemory(
modulePtr->module = module;
modulePtr->nextPtr = NULL;
dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle));
-#if TCL_DYLD_USE_DLFCN
dyldLoadHandle->dlHandle = NULL;
-#endif
dyldLoadHandle->dyldLibHeader = NULL;
dyldLoadHandle->modulePtr = modulePtr;
newHandle = ckalloc(sizeof(*newHandle));