diff options
Diffstat (limited to 'unix/tclLoadDyld.c')
-rw-r--r-- | unix/tclLoadDyld.c | 362 |
1 files changed, 211 insertions, 151 deletions
diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c index 50c283d..0a36215 100644 --- a/unix/tclLoadDyld.c +++ b/unix/tclLoadDyld.c @@ -16,36 +16,42 @@ #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 */ - -#ifndef TCL_DYLD_USE_DLFCN -# ifdef NO_DLFCN_H -# define TCL_DYLD_USE_DLFCN 0 -# else +# if !defined(NO_DLFCN_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 # define TCL_DYLD_USE_DLFCN 1 +# else +# define TCL_DYLD_USE_DLFCN 0 # endif #endif - +#ifndef TCL_DYLD_USE_NSMODULE /* * Use deprecated NSModule API only to support 10.3 and earlier: */ - -#ifndef TCL_DYLD_USE_NSMODULE -# define TCL_DYLD_USE_NSMODULE 0 +# if MAC_OS_X_VERSION_MIN_REQUIRED < 1040 +# define TCL_DYLD_USE_NSMODULE 1 +# else +# define TCL_DYLD_USE_NSMODULE 0 +# endif #endif +#if TCL_DYLD_USE_DLFCN +#include <dlfcn.h> +#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040 /* - * Use includes for the API we're using. + * Support for weakly importing dlfcn API. */ - -#if TCL_DYLD_USE_DLFCN -# include <dlfcn.h> -#endif /* TCL_DYLD_USE_DLFCN */ +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_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) #include <mach-o/dyld.h> @@ -54,33 +60,39 @@ #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 || TCL_LOAD_FROM_MEMORY */ +#endif /* TCL_DYLD_USE_NSMODULE */ -typedef struct { +typedef struct Tcl_DyldLoadHandle { +#if TCL_DYLD_USE_DLFCN 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 || defined(TCL_LOAD_FROM_MEMORY) -MODULE_SCOPE long tclMacOSXDarwinRelease; +#if (TCL_DYLD_USE_DLFCN && MAC_OS_X_VERSION_MIN_REQUIRED < 1040) || \ + defined(TCL_LOAD_FROM_MEMORY) +MODULE_SCOPE long tclMacOSXDarwinRelease; #endif -/* - * Static functions defined in this file. - */ - -static void * FindSymbol(Tcl_Interp *interp, - Tcl_LoadHandle loadHandle, const char *symbol); -static void UnloadFile(Tcl_LoadHandle handle); +#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, ...) +#endif +#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) /* *---------------------------------------------------------------------- * @@ -98,8 +110,7 @@ static void UnloadFile(Tcl_LoadHandle handle); *---------------------------------------------------------------------- */ -#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) -static const char * +static CONST char* DyldOFIErrorMsg( int err) { @@ -120,7 +131,7 @@ DyldOFIErrorMsg( return "unknown error"; } } -#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ +#endif /* TCL_DYLD_USE_NSMODULE */ /* *---------------------------------------------------------------------- @@ -148,15 +159,15 @@ TclpDlopen( Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ - Tcl_FSUnloadFileProc **unloadProcPtr, + Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ - int flags) { 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; @@ -165,14 +176,12 @@ TclpDlopen( NSLinkEditErrors editError; int errorNumber; const char *errorName, *objFileImageErrMsg = NULL; -#endif /* TCL_DYLD_USE_NSMODULE */ +#endif const char *errMsg = NULL; int result; Tcl_DString ds; + char *fileName = NULL; const char *nativePath, *nativeFileName = NULL; -#if TCL_DYLD_USE_DLFCN - int dlopenflags = 0; -#endif /* TCL_DYLD_USE_DLFCN */ /* * First try the full path the user gave us. This is particularly @@ -181,44 +190,46 @@ 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) as default, see [Bug #3216070] + * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070] */ - - if (flags & TCL_LOAD_GLOBAL) { - dlopenflags |= RTLD_GLOBAL; - } else { - dlopenflags |= RTLD_LOCAL; - } - if (flags & TCL_LOAD_LAZY) { - dlopenflags |= RTLD_LAZY; - } else { - dlopenflags |= RTLD_NOW; - } - dlHandle = dlopen(nativePath, dlopenflags); - 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. - */ - - dlHandle = dlopen(nativeFileName, dlopenflags); + 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 { 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) { + if (dyldLibHeader) { + TclLoadDbgMsg("NSAddImage() successful"); + } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); if (editError == NSLinkEditFileAccessError) { /* @@ -227,12 +238,20 @@ 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) { + if (dyldLibHeader) { + TclLoadDbgMsg("NSAddImage() successful"); + } else { NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); + TclLoadDbgMsg("NSAddImage() failed: %s", errMsg); } } else if ((editError == NSLinkEditFileFormatError && errorNumber == EBADMACHO) @@ -249,70 +268,72 @@ TclpDlopen( err = NSCreateObjectFileImageFromFile(nativePath, &dyldObjFileImage); if (err == NSObjectFileImageSuccess && dyldObjFileImage) { - int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; - if (!(flags & 1)) nsflags |= NSLINKMODULE_OPTION_PRIVATE; - if (!(flags & 2)) nsflags |= NSLINKMODULE_OPTION_BINDNOW; - module = NSLinkModule(dyldObjFileImage, nativePath, nsflags); + TclLoadDbgMsg("NSCreateObjectFileImageFromFile() " + "successful"); + module = NSLinkModule(dyldObjFileImage, nativePath, + NSLINKMODULE_OPTION_BINDNOW + | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); if (module) { - modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); + modulePtr = (Tcl_DyldModuleHandle *) + 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 (dlHandle + if (0 +#if TCL_DYLD_USE_DLFCN + || dlHandle +#endif #if TCL_DYLD_USE_NSMODULE || dyldLibHeader || modulePtr -#endif /* TCL_DYLD_USE_NSMODULE */ +#endif ) { - dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); + dyldLoadHandle = (Tcl_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 /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ - newHandle = ckalloc(sizeof(*newHandle)); - newHandle->clientData = dyldLoadHandle; - newHandle->findSymbolProcPtr = &FindSymbol; - newHandle->unloadFileProcPtr = &UnloadFile; - *unloadProcPtr = &UnloadFile; - *loadHandle = newHandle; +#endif + *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; + *unloadProcPtr = &TclpUnloadFile; result = TCL_OK; } else { - Tcl_Obj *errObj = Tcl_NewObj(); - - if (errMsg != NULL) { - Tcl_AppendToObj(errObj, errMsg, -1); - } + Tcl_AppendResult(interp, errMsg, NULL); #if TCL_DYLD_USE_NSMODULE if (objFileImageErrMsg) { - Tcl_AppendPrintfToObj(errObj, - "\nNSCreateObjectFileImageFromFile() error: %s", - objFileImageErrMsg); + Tcl_AppendResult(interp, "\nNSCreateObjectFileImageFromFile() " + "error: ", objFileImageErrMsg, NULL); } -#endif /* TCL_DYLD_USE_NSMODULE */ - Tcl_SetObjResult(interp, errObj); +#endif result = TCL_ERROR; } - - Tcl_DStringFree(&ds); + if(fileName) { + Tcl_DStringFree(&ds); + } return result; } /* *---------------------------------------------------------------------- * - * FindSymbol -- + * TclpFindSymbol -- * * Looks up a symbol, by name, through a handle associated with a * previously loaded piece of code (shared library). @@ -325,27 +346,31 @@ TclpDlopen( *---------------------------------------------------------------------- */ -static void * -FindSymbol( +MODULE_SCOPE Tcl_PackageInitProc * +TclpFindSymbol( Tcl_Interp *interp, /* For error reporting. */ Tcl_LoadHandle loadHandle, /* Handle from TclpDlopen. */ - const char *symbol) /* Symbol name to look up. */ + CONST char *symbol) /* Symbol name to look up. */ { - Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; + Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle; Tcl_PackageInitProc *proc = NULL; const char *errMsg = NULL; Tcl_DString ds; const char *native; native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); - if (dyldLoadHandle->dlHandle) { #if TCL_DYLD_USE_DLFCN + if (dyldLoadHandle->dlHandle) { proc = dlsym(dyldLoadHandle->dlHandle, native); - if (!proc) { + if (proc) { + TclLoadDbgMsg("dlsym() successful"); + } else { 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; @@ -355,19 +380,20 @@ FindSymbol( */ Tcl_DStringInit(&newName); - TclDStringAppendLiteral(&newName, "_"); + Tcl_DStringAppend(&newName, "_", 1); native = Tcl_DStringAppend(&newName, native, -1); if (dyldLoadHandle->dyldLibHeader) { nsSymbol = NSLookupSymbolInImage(dyldLoadHandle->dyldLibHeader, 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; @@ -378,7 +404,8 @@ FindSymbol( modulePtr = modulePtr->nextPtr; } if (modulePtr == NULL) { - modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); + modulePtr = (Tcl_DyldModuleHandle *) + ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = dyldLoadHandle->modulePtr; dyldLoadHandle->modulePtr = modulePtr; @@ -390,23 +417,31 @@ 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_SetObjResult(interp, Tcl_ObjPrintf( - "cannot find symbol \"%s\": %s", symbol, errMsg)); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol, - NULL); + if (errMsg) { + Tcl_AppendResult(interp, errMsg, NULL); } return proc; } @@ -414,7 +449,7 @@ FindSymbol( /* *---------------------------------------------------------------------- * - * UnloadFile -- + * TclpUnloadFile -- * * Unloads a dynamically loaded binary code file from memory. Code * pointers in the formerly loaded file are no longer valid after calling @@ -431,34 +466,48 @@ FindSymbol( *---------------------------------------------------------------------- */ -static void -UnloadFile( +MODULE_SCOPE void +TclpUnloadFile( Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to * TclpDlopen(). The loadHandle is a token * that represents the loaded file. */ { - Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; + Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle; - if (dyldLoadHandle->dlHandle) { #if TCL_DYLD_USE_DLFCN - (void) dlclose(dyldLoadHandle->dlHandle); + if (dyldLoadHandle->dlHandle) { + int result; + + result = dlclose(dyldLoadHandle->dlHandle); + if (!result) { + TclLoadDbgMsg("dlclose() successful"); + } else { + TclLoadDbgMsg("dlclose() failed: %s", dlerror()); + } + } else #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 = modulePtr; + void *ptr; + bool result; - (void) NSUnLinkModule(modulePtr->module, + result = NSUnLinkModule(modulePtr->module, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); + if (result) { + TclLoadDbgMsg("NSUnLinkModule() successful"); + } else { + TclLoadDbgMsg("NSUnLinkModule() failed"); + } + ptr = modulePtr; modulePtr = modulePtr->nextPtr; ckfree(ptr); } #endif /* TCL_DYLD_USE_NSMODULE */ } - ckfree(dyldLoadHandle); - ckfree(loadHandle); + ckfree((char*) dyldLoadHandle); } /* @@ -483,7 +532,7 @@ UnloadFile( int TclGuessPackageName( - const char *fileName, /* Name of file containing package (already + CONST char *fileName, /* Name of file containing package (already * translated to local form if needed). */ Tcl_DString *bufPtr) /* Initialized empty dstring. Append package * name to this if possible. */ @@ -491,6 +540,7 @@ TclGuessPackageName( return 0; } +#ifdef TCL_LOAD_FROM_MEMORY /* *---------------------------------------------------------------------- * @@ -507,7 +557,6 @@ TclGuessPackageName( *---------------------------------------------------------------------- */ -#ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE void * TclpLoadMemoryGetBuffer( Tcl_Interp *interp, /* Used for error reporting. */ @@ -532,7 +581,6 @@ TclpLoadMemoryGetBuffer( } return buffer; } -#endif /* TCL_LOAD_FROM_MEMORY */ /* *---------------------------------------------------------------------- @@ -552,7 +600,6 @@ TclpLoadMemoryGetBuffer( *---------------------------------------------------------------------- */ -#ifdef TCL_LOAD_FROM_MEMORY MODULE_SCOPE int TclpLoadMemory( Tcl_Interp *interp, /* Used for error reporting. */ @@ -565,19 +612,16 @@ TclpLoadMemory( Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded * file which will be passed back to * (*unloadProcPtr)() to unload the file. */ - Tcl_FSUnloadFileProc **unloadProcPtr, + Tcl_FSUnloadFileProc **unloadProcPtr) /* Filled with address of Tcl_FSUnloadFileProc * function which should be used for this * file. */ - int flags) { - Tcl_LoadHandle newHandle; Tcl_DyldLoadHandle *dyldLoadHandle; NSObjectFileImage dyldObjFileImage = NULL; Tcl_DyldModuleHandle *modulePtr; NSModule module; const char *objFileImageErrMsg = NULL; - int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR; /* * Try to create an object file image that we can load from. @@ -589,15 +633,15 @@ TclpLoadMemory( uint32_t ms = 0; #ifndef __LP64__ const struct mach_header *mh = NULL; -# define mh_size sizeof(struct mach_header) -# define mh_magic MH_MAGIC -# define arch_abi 0 + #define mh_size sizeof(struct mach_header) + #define mh_magic MH_MAGIC + #define arch_abi 0 #else const struct mach_header_64 *mh = NULL; -# define mh_size sizeof(struct mach_header_64) -# define mh_magic MH_MAGIC_64 -# define arch_abi CPU_ARCH_ABI64 -#endif /* __LP64__ */ + #define mh_size sizeof(struct mach_header_64) + #define mh_magic MH_MAGIC_64 + #define arch_abi CPU_ARCH_ABI64 +#endif if ((size_t) codeSize >= sizeof(struct fat_header) && fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) { @@ -607,6 +651,7 @@ 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); @@ -619,15 +664,22 @@ TclpLoadMemory( fa = NXFindBestFatArch(arch->cputype | arch_abi, arch->cpusubtype, fatarchs, fh_nfat_arch); if (fa) { - mh = (void *)((char *) buffer + fa->offset); + 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); 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 { @@ -635,18 +687,26 @@ 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) { + if (err == NSObjectFileImageSuccess) { + TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() " + "successful"); + } else { objFileImageErrMsg = DyldOFIErrorMsg(err); + TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s", + objFileImageErrMsg); } } else { objFileImageErrMsg = DyldOFIErrorMsg(err); @@ -661,9 +721,8 @@ TclpLoadMemory( if (dyldObjFileImage == NULL) { vm_deallocate(mach_task_self(), (vm_address_t) buffer, size); if (objFileImageErrMsg != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "NSCreateObjectFileImageFromMemory() error: %s", - objFileImageErrMsg)); + Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() " + "error: ", objFileImageErrMsg, NULL); } return TCL_ERROR; } @@ -672,17 +731,19 @@ TclpLoadMemory( * Extract the module we want from the image of the object file. */ - if (!(flags & 1)) nsflags |= NSLINKMODULE_OPTION_PRIVATE; - if (!(flags & 2)) nsflags |= NSLINKMODULE_OPTION_BINDNOW; - module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", nsflags); + module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", + NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(dyldObjFileImage); - if (!module) { + if (module) { + TclLoadDbgMsg("NSLinkModule() successful"); + } else { NSLinkEditErrors editError; int errorNumber; const char *errorName, *errMsg; NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); - Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); + TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg); + Tcl_AppendResult(interp, errMsg, NULL); return TCL_ERROR; } @@ -690,19 +751,18 @@ TclpLoadMemory( * Stash the module reference within the load handle we create and return. */ - modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); + modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); modulePtr->module = module; modulePtr->nextPtr = NULL; - dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); + dyldLoadHandle = (Tcl_DyldLoadHandle *) + ckalloc(sizeof(Tcl_DyldLoadHandle)); +#if TCL_DYLD_USE_DLFCN dyldLoadHandle->dlHandle = NULL; +#endif dyldLoadHandle->dyldLibHeader = NULL; dyldLoadHandle->modulePtr = modulePtr; - newHandle = ckalloc(sizeof(*newHandle)); - newHandle->clientData = dyldLoadHandle; - newHandle->findSymbolProcPtr = &FindSymbol; - newHandle->unloadFileProcPtr = &UnloadFile; - *loadHandle = newHandle; - *unloadProcPtr = &UnloadFile; + *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; + *unloadProcPtr = &TclpUnloadFile; return TCL_OK; } #endif /* TCL_LOAD_FROM_MEMORY */ |