diff options
Diffstat (limited to 'unix/tclLoadDyld.c')
| -rw-r--r-- | unix/tclLoadDyld.c | 542 | 
1 files changed, 343 insertions, 199 deletions
| diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c index 332c6c1..50c283d 100644 --- a/unix/tclLoadDyld.c +++ b/unix/tclLoadDyld.c @@ -3,19 +3,51 @@   *   *	This procedure provides a version of the TclLoadFile that works with   *	Apple's dyld dynamic loading. - *	Original version of his file (now superseded long ago) provided by + *	Original version of his file (superseded long ago) provided by   *	Wilfredo Sanchez (wsanchez@apple.com).   *   * Copyright (c) 1995 Apple Computer, Inc. - * Copyright (c) 2005 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2001-2007 Daniel A. Steffen <das@users.sourceforge.net>   *   * See the file "license.terms" for information on usage and redistribution of   * this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclLoadDyld.c,v 1.24 2006/07/20 06:18:38 das Exp $   */  #include "tclInt.h" + +#ifndef MODULE_SCOPE +#   define MODULE_SCOPE extern +#endif + +/* + * 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 +#	define TCL_DYLD_USE_DLFCN 1 +#   endif +#endif + +/* + * Use deprecated NSModule API only to support 10.3 and earlier: + */ + +#ifndef TCL_DYLD_USE_NSMODULE +#   define TCL_DYLD_USE_NSMODULE 0 +#endif + +/* + * Use includes for the API we're using. + */ + +#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>  #include <mach-o/fat.h>  #include <mach-o/swap.h> @@ -27,15 +59,27 @@ typedef struct Tcl_DyldModuleHandle {      struct Tcl_DyldModuleHandle *nextPtr;      NSModule module;  } Tcl_DyldModuleHandle; +#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */ -typedef struct Tcl_DyldLoadHandle { -    CONST struct mach_header *dyldLibHeader; +typedef struct { +    void *dlHandle; +#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) +    const struct mach_header *dyldLibHeader;      Tcl_DyldModuleHandle *modulePtr; +#endif  } Tcl_DyldLoadHandle; -#ifdef TCL_LOAD_FROM_MEMORY -MODULE_SCOPE long tclMacOSXDarwinRelease; +#if TCL_DYLD_USE_DLFCN || 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);  /*   *---------------------------------------------------------------------- @@ -54,8 +98,11 @@ MODULE_SCOPE long tclMacOSXDarwinRelease;   *----------------------------------------------------------------------   */ -static CONST char* -DyldOFIErrorMsg(int err) { +#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) +static const char * +DyldOFIErrorMsg( +    int err) +{      switch(err) {      case NSObjectFileImageSuccess:  	return NULL; @@ -73,6 +120,7 @@ DyldOFIErrorMsg(int err) {  	return "unknown error";      }  } +#endif /* TCL_DYLD_USE_NSMODULE || TCL_LOAD_FROM_MEMORY */  /*   *---------------------------------------------------------------------- @@ -97,19 +145,34 @@ TclpDlopen(      Tcl_Interp *interp,		/* Used for error reporting. */      Tcl_Obj *pathPtr,		/* Name of the file containing the desired  				 * code (UTF-8). */ -    Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded +    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; -    CONST struct mach_header *dyldLibHeader; -    NSObjectFileImage dyldObjFileImage = NULL; +    Tcl_LoadHandle newHandle; +    void *dlHandle = NULL; +#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) +    const struct mach_header *dyldLibHeader = NULL;      Tcl_DyldModuleHandle *modulePtr = NULL; -    CONST char *native; +#endif +#if TCL_DYLD_USE_NSMODULE +    NSLinkEditErrors editError; +    int errorNumber; +    const char *errorName, *objFileImageErrMsg = NULL; +#endif /* TCL_DYLD_USE_NSMODULE */ +    const char *errMsg = NULL; +    int result; +    Tcl_DString ds; +    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 @@ -117,98 +180,139 @@ TclpDlopen(       * relative path.       */ -    native = Tcl_FSGetNativePath(pathPtr); -    dyldLibHeader = NSAddImage(native, NSADDIMAGE_OPTION_RETURN_ON_ERROR); +    nativePath = Tcl_FSGetNativePath(pathPtr); +    nativeFileName = Tcl_UtfToExternalDString(NULL, Tcl_GetString(pathPtr), +	    -1, &ds); -    if (!dyldLibHeader) { -	NSLinkEditErrors editError; -	int errorNumber; -	CONST char *name, *msg, *objFileImageErrMsg = NULL; - -	NSLinkEditError(&editError, &errorNumber, &name, &msg); - -	if (editError == NSLinkEditFileAccessError) { -	    /* -	     * The requested file was not found. 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. -	     */ - -	    Tcl_DString ds; -	    char *fileName = Tcl_GetString(pathPtr); -	    CONST char *native = -		    Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); +#if TCL_DYLD_USE_DLFCN +    /* +     * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070] +     */ -	    dyldLibHeader = NSAddImage(native, NSADDIMAGE_OPTION_WITH_SEARCHING -		    | NSADDIMAGE_OPTION_RETURN_ON_ERROR); -	    Tcl_DStringFree(&ds); -	    if (!dyldLibHeader) { -		NSLinkEditError(&editError, &errorNumber, &name, &msg); -	    } -	} else if ((editError == NSLinkEditFileFormatError -		&& errorNumber == EBADMACHO) -		|| editError == NSLinkEditOtherError){ -	    /* -	     * The requested file was found but was not of type MH_DYLIB, -	     * attempt to load it as a MH_BUNDLE. -	     */ +    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. +	 */ -	    NSObjectFileImageReturnCode err = -		    NSCreateObjectFileImageFromFile(native, &dyldObjFileImage); -	    objFileImageErrMsg = DyldOFIErrorMsg(err); +	dlHandle = dlopen(nativeFileName, dlopenflags); +	if (!dlHandle) { +	    errMsg = dlerror();  	} - -	if (!dyldLibHeader && !dyldObjFileImage) { -	    Tcl_AppendResult(interp, msg, NULL); -	    if (msg && *msg) { -		Tcl_AppendResult(interp, "\n", NULL); -	    } -	    if (objFileImageErrMsg) { -		Tcl_AppendResult(interp, -			"NSCreateObjectFileImageFromFile() error: ", -			objFileImageErrMsg, NULL); +    } +#endif /* TCL_DYLD_USE_DLFCN */ + +    if (!dlHandle) { +#if TCL_DYLD_USE_NSMODULE +	dyldLibHeader = NSAddImage(nativePath, +		NSADDIMAGE_OPTION_RETURN_ON_ERROR); +	if (!dyldLibHeader) { +	    NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); +	    if (editError == NSLinkEditFileAccessError) { +		/* +		 * The requested file was not found. 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. +		 */ + +		dyldLibHeader = NSAddImage(nativeFileName, +			NSADDIMAGE_OPTION_WITH_SEARCHING | +			NSADDIMAGE_OPTION_RETURN_ON_ERROR); +		if (!dyldLibHeader) { +		    NSLinkEditError(&editError, &errorNumber, &errorName, +			    &errMsg); +		} +	    } else if ((editError == NSLinkEditFileFormatError +		    && errorNumber == EBADMACHO) +		    || editError == NSLinkEditOtherError){ +		NSObjectFileImageReturnCode err; +		NSObjectFileImage dyldObjFileImage; +		NSModule module; + +		/* +		 * The requested file was found but was not of type MH_DYLIB, +		 * attempt to load it as a MH_BUNDLE. +		 */ + +		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); +		    NSDestroyObjectFileImage(dyldObjFileImage); +		    if (module) { +			modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); +			modulePtr->module = module; +			modulePtr->nextPtr = NULL; +		    } else { +			NSLinkEditError(&editError, &errorNumber, &errorName, +				&errMsg); +		    } +		} else { +		    objFileImageErrMsg = DyldOFIErrorMsg(err); +		}  	    } -	    return TCL_ERROR;  	} +#endif /* TCL_DYLD_USE_NSMODULE */      } -    if (dyldObjFileImage) { -	NSModule module; - -	module = NSLinkModule(dyldObjFileImage, native, -		NSLINKMODULE_OPTION_BINDNOW -		| NSLINKMODULE_OPTION_RETURN_ON_ERROR); -	NSDestroyObjectFileImage(dyldObjFileImage); - -	if (!module) { -	    NSLinkEditErrors editError; -	    int errorNumber; -	    CONST char *name, *msg; +    if (dlHandle +#if TCL_DYLD_USE_NSMODULE +	    || dyldLibHeader || modulePtr +#endif /* TCL_DYLD_USE_NSMODULE */ +    ) { +	dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); +	dyldLoadHandle->dlHandle = dlHandle; +#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; +	result = TCL_OK; +    } else { +	Tcl_Obj *errObj = Tcl_NewObj(); -	    NSLinkEditError(&editError, &errorNumber, &name, &msg); -	    Tcl_AppendResult(interp, msg, NULL); -	    return TCL_ERROR; +	if (errMsg != NULL) { +	    Tcl_AppendToObj(errObj, errMsg, -1);  	} - -	modulePtr = (Tcl_DyldModuleHandle *) -		ckalloc(sizeof(Tcl_DyldModuleHandle)); -	modulePtr->module = module; -	modulePtr->nextPtr = NULL; +#if TCL_DYLD_USE_NSMODULE +	if (objFileImageErrMsg) { +	    Tcl_AppendPrintfToObj(errObj, +		    "\nNSCreateObjectFileImageFromFile() error: %s", +		    objFileImageErrMsg); +	} +#endif /* TCL_DYLD_USE_NSMODULE */ +	Tcl_SetObjResult(interp, errObj); +	result = TCL_ERROR;      } -    dyldLoadHandle = (Tcl_DyldLoadHandle *) -	    ckalloc(sizeof(Tcl_DyldLoadHandle)); -    dyldLoadHandle->dyldLibHeader = dyldLibHeader; -    dyldLoadHandle->modulePtr = modulePtr; -    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; -    *unloadProcPtr = &TclpUnloadFile; -    return TCL_OK; +    Tcl_DStringFree(&ds); +    return result;  }  /*   *----------------------------------------------------------------------   * - * TclpFindSymbol -- + * FindSymbol --   *   *	Looks up a symbol, by name, through a handle associated with a   *	previously loaded piece of code (shared library). @@ -221,81 +325,96 @@ TclpDlopen(   *----------------------------------------------------------------------   */ -MODULE_SCOPE Tcl_PackageInitProc * -TclpFindSymbol( +static void * +FindSymbol(      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. */  { -    NSSymbol nsSymbol; -    CONST char *native; -    Tcl_DString newName, ds; +    Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData;      Tcl_PackageInitProc *proc = NULL; -    Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle; - -    /* -     * dyld adds an underscore to the beginning of symbol names. -     */ +    const char *errMsg = NULL; +    Tcl_DString ds; +    const char *native;      native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); -    Tcl_DStringInit(&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) { -	    /* -	     * Until dyld supports unloading of MY_DYLIB binaries, the -	     * following is not needed. -	     */ +    if (dyldLoadHandle->dlHandle) { +#if TCL_DYLD_USE_DLFCN +	proc = dlsym(dyldLoadHandle->dlHandle, native); +	if (!proc) { +	    errMsg = dlerror(); +	} +#endif /* TCL_DYLD_USE_DLFCN */ +    } else { +#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) +	NSSymbol nsSymbol = NULL; +	Tcl_DString newName; -#ifdef DYLD_SUPPORTS_DYLIB_UNLOADING -	    NSModule module = NSModuleForSymbol(nsSymbol); -	    Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr; +	/* +	 * dyld adds an underscore to the beginning of symbol names. +	 */ -	    while (modulePtr != NULL) { -		if (module == modulePtr->module) { -		    break; +	Tcl_DStringInit(&newName); +	TclDStringAppendLiteral(&newName, "_"); +	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) { +		/* +		 * 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; + +		while (modulePtr != NULL) { +		    if (module == modulePtr->module) { +			break; +		    } +		    modulePtr = modulePtr->nextPtr; +		} +		if (modulePtr == NULL) { +		    modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle)); +		    modulePtr->module = module; +		    modulePtr->nextPtr = dyldLoadHandle->modulePtr; +		    dyldLoadHandle->modulePtr = modulePtr;  		} -		modulePtr = modulePtr->nextPtr; -	    } -	    if (modulePtr == NULL) { -		modulePtr = (Tcl_DyldModuleHandle *) -			ckalloc(sizeof(Tcl_DyldModuleHandle)); -		modulePtr->module = module; -		modulePtr->nextPtr = dyldLoadHandle->modulePtr; -		dyldLoadHandle->modulePtr = modulePtr; -	    }  #endif /* DYLD_SUPPORTS_DYLIB_UNLOADING */ +	    } else { +		NSLinkEditErrors editError; +		int errorNumber; +		const char *errorName; -	} else { -	    NSLinkEditErrors editError; -	    int errorNumber; -	    CONST char *name, *msg; - -	    NSLinkEditError(&editError, &errorNumber, &name, &msg); -	    Tcl_AppendResult(interp, msg, NULL); +		NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); +	    } +	} else if (dyldLoadHandle->modulePtr) { +	    nsSymbol = NSLookupSymbolInModule( +		    dyldLoadHandle->modulePtr->module, native);  	} -    } else { -	nsSymbol = NSLookupSymbolInModule(dyldLoadHandle->modulePtr->module, -		native); -    } -    if (nsSymbol) { -	proc = NSAddressOfSymbol(nsSymbol); +	if (nsSymbol) { +	    proc = NSAddressOfSymbol(nsSymbol); +	} +	Tcl_DStringFree(&newName); +#endif /* TCL_DYLD_USE_NSMODULE */      } -    Tcl_DStringFree(&newName);      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); +    }      return proc;  }  /*   *----------------------------------------------------------------------   * - * TclpUnloadFile -- + * UnloadFile --   *   *	Unloads a dynamically loaded binary code file from memory. Code   *	pointers in the formerly loaded file are no longer valid after calling @@ -312,25 +431,34 @@ TclpFindSymbol(   *----------------------------------------------------------------------   */ -MODULE_SCOPE void -TclpUnloadFile( +static void +UnloadFile(      Tcl_LoadHandle loadHandle)	/* loadHandle returned by a previous call to  				 * TclpDlopen(). The loadHandle is a token  				 * that represents the loaded file. */  { -    Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle; -    Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr; +    Tcl_DyldLoadHandle *dyldLoadHandle = loadHandle->clientData; -    while (modulePtr != NULL) { -	void *ptr; +    if (dyldLoadHandle->dlHandle) { +#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; -	NSUnLinkModule(modulePtr->module, -		NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); -	ptr = modulePtr; -	modulePtr = modulePtr->nextPtr; -	ckfree(ptr); +	while (modulePtr != NULL) { +	    void *ptr = modulePtr; + +	    (void) NSUnLinkModule(modulePtr->module, +		    NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +	    modulePtr = modulePtr->nextPtr; +	    ckfree(ptr); +	} +#endif /* TCL_DYLD_USE_NSMODULE */      } -    ckfree((char*) dyldLoadHandle); +    ckfree(dyldLoadHandle); +    ckfree(loadHandle);  }  /* @@ -355,7 +483,7 @@ TclpUnloadFile(  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. */ @@ -363,7 +491,6 @@ TclGuessPackageName(      return 0;  } -#ifdef TCL_LOAD_FROM_MEMORY  /*   *----------------------------------------------------------------------   * @@ -380,6 +507,7 @@ TclGuessPackageName(   *----------------------------------------------------------------------   */ +#ifdef TCL_LOAD_FROM_MEMORY  MODULE_SCOPE void *  TclpLoadMemoryGetBuffer(      Tcl_Interp *interp,		/* Used for error reporting. */ @@ -404,6 +532,7 @@ TclpLoadMemoryGetBuffer(      }      return buffer;  } +#endif /* TCL_LOAD_FROM_MEMORY */  /*   *---------------------------------------------------------------------- @@ -423,6 +552,7 @@ TclpLoadMemoryGetBuffer(   *----------------------------------------------------------------------   */ +#ifdef TCL_LOAD_FROM_MEMORY  MODULE_SCOPE int  TclpLoadMemory(      Tcl_Interp *interp,		/* Used for error reporting. */ @@ -432,19 +562,22 @@ TclpLoadMemory(      int codeSize,		/* Size of code data read into buffer or -1 if  				 * an error occurred and the buffer should  				 * just be freed. */ -    Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded +    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; +    const char *objFileImageErrMsg = NULL; +    int nsflags = NSLINKMODULE_OPTION_RETURN_ON_ERROR;      /*       * Try to create an object file image that we can load from. @@ -452,38 +585,41 @@ TclpLoadMemory(      if (codeSize >= 0) {  	NSObjectFileImageReturnCode err = NSObjectFileImageSuccess; -	CONST struct fat_header *fh = buffer; +	const struct fat_header *fh = buffer;  	uint32_t ms = 0;  #ifndef __LP64__ -	CONST struct mach_header *mh = NULL; -	#define mh_magic OSSwapHostToBigInt32(MH_MAGIC) -	#define mh_size  sizeof(struct mach_header) +	const struct mach_header *mh = NULL; +#	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_magic OSSwapHostToBigInt32(MH_MAGIC_64) -	#define mh_size  sizeof(struct mach_header_64) -#endif -	 +	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__ */ +  	if ((size_t) codeSize >= sizeof(struct fat_header)  		&& fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) { +	    uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); +  	    /*  	     * Fat binary, try to find mach_header for our architecture  	     */ -	    uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); -	     -	    if ((size_t) codeSize >= sizeof(struct fat_header) +  + +	    if ((size_t) codeSize >= sizeof(struct fat_header) +  		    fh_nfat_arch * sizeof(struct fat_arch)) { -		void *fatarchs = buffer + sizeof(struct fat_header); -		CONST NXArchInfo *arch = NXGetLocalArchInfo(); +		void *fatarchs = (char*)buffer + sizeof(struct fat_header); +		const NXArchInfo *arch = NXGetLocalArchInfo();  		struct fat_arch *fa; -		 +  		if (fh->magic != FAT_MAGIC) {  		    swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);  		} -		fa = NXFindBestFatArch(arch->cputype, arch->cpusubtype, -			fatarchs, fh_nfat_arch); +		fa = NXFindBestFatArch(arch->cputype | arch_abi, +			arch->cpusubtype, fatarchs, fh_nfat_arch);  		if (fa) { -		    mh = buffer + fa->offset; +		    mh = (void *)((char *) buffer + fa->offset);  		    ms = fa->size;  		} else {  		    err = NSObjectFileImageInappropriateFile; @@ -498,18 +634,23 @@ TclpLoadMemory(  	    /*  	     * Thin binary  	     */ +  	    mh = buffer;  	    ms = codeSize;  	}  	if (ms && !(ms >= mh_size && mh->magic == mh_magic && -		 mh->filetype == OSSwapHostToBigInt32(MH_BUNDLE))) { +		 mh->filetype == MH_BUNDLE)) {  	    err = NSObjectFileImageInappropriateFile;  	}  	if (err == NSObjectFileImageSuccess) {  	    err = NSCreateObjectFileImageFromMemory(buffer, codeSize,  		    &dyldObjFileImage); +	    if (err != NSObjectFileImageSuccess) { +		objFileImageErrMsg = DyldOFIErrorMsg(err); +	    } +	} else { +	    objFileImageErrMsg = DyldOFIErrorMsg(err);  	} -	objFileImageErrMsg = DyldOFIErrorMsg(err);      }      /* @@ -520,9 +661,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: %s", +		    objFileImageErrMsg));  	}  	return TCL_ERROR;      } @@ -531,17 +672,17 @@ TclpLoadMemory(       * Extract the module we want from the image of the object file.       */ -    module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", -	    NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR); +    if (!(flags & 1)) nsflags |= NSLINKMODULE_OPTION_PRIVATE; +    if (!(flags & 2)) nsflags |= NSLINKMODULE_OPTION_BINDNOW; +    module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]", nsflags);      NSDestroyObjectFileImage(dyldObjFileImage); -      if (!module) {  	NSLinkEditErrors editError;  	int errorNumber; -	CONST char *name, *msg; +	const char *errorName, *errMsg; -	NSLinkEditError(&editError, &errorNumber, &name, &msg); -	Tcl_AppendResult(interp, msg, NULL); +	NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg); +	Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1));  	return TCL_ERROR;      } @@ -549,24 +690,27 @@ TclpLoadMemory(       * Stash the module reference within the load handle we create and return.       */ -    modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle)); +    modulePtr = ckalloc(sizeof(Tcl_DyldModuleHandle));      modulePtr->module = module;      modulePtr->nextPtr = NULL; - -    dyldLoadHandle = (Tcl_DyldLoadHandle *) -	    ckalloc(sizeof(Tcl_DyldLoadHandle)); +    dyldLoadHandle = ckalloc(sizeof(Tcl_DyldLoadHandle)); +    dyldLoadHandle->dlHandle = NULL;      dyldLoadHandle->dyldLibHeader = NULL;      dyldLoadHandle->modulePtr = modulePtr; -    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle; -    *unloadProcPtr = &TclpUnloadFile; +    newHandle = ckalloc(sizeof(*newHandle)); +    newHandle->clientData = dyldLoadHandle; +    newHandle->findSymbolProcPtr = &FindSymbol; +    newHandle->unloadFileProcPtr = &UnloadFile; +    *loadHandle = newHandle; +    *unloadProcPtr = &UnloadFile;      return TCL_OK;  } -#endif +#endif /* TCL_LOAD_FROM_MEMORY */  /*   * Local Variables:   * mode: c   * c-basic-offset: 4 - * fill-column: 78 + * fill-column: 79   * End:   */ | 
