Beispiel #1
0
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 = (Tcl_DyldLoadHandle *) loadHandle;

#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
#endif /* TCL_DYLD_USE_DLFCN */
    {
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
	Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;

	while (modulePtr != NULL) {
	    void *ptr;
	    bool result;

	    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((char*) dyldLoadHandle);
}
Beispiel #2
0
static short
OpenResourceMap(
    CFBundleRef bundleRef)
{
    static int initialized = FALSE;
    static short (*openresourcemap)(CFBundleRef) = NULL;

    if (!initialized) {
#if TCL_DYLD_USE_DLFCN
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
	if (tclMacOSXDarwinRelease >= 8)
#endif
	{
	    openresourcemap = dlsym(RTLD_NEXT,
		    "CFBundleOpenBundleResourceMap");
#ifdef TCL_DEBUG_LOAD
	    if (!openresourcemap) {
		const char *errMsg = dlerror();

		TclLoadDbgMsg("dlsym() failed: %s", errMsg);
	    }
#endif /* TCL_DEBUG_LOAD */
	}
	if (!openresourcemap)
#endif /* TCL_DYLD_USE_DLFCN */
	{
#if TCL_DYLD_USE_NSMODULE
	    if (NSIsSymbolNameDefinedWithHint(
		    "_CFBundleOpenBundleResourceMap", "CoreFoundation")) {
		NSSymbol nsSymbol = NSLookupAndBindSymbolWithHint(
			"_CFBundleOpenBundleResourceMap", "CoreFoundation");

		if (nsSymbol) {
		    openresourcemap = NSAddressOfSymbol(nsSymbol);
		}
	    }
#endif /* TCL_DYLD_USE_NSMODULE */
	}
	initialized = TRUE;
    }

    if (openresourcemap) {
	return openresourcemap(bundleRef);
    }
    return -1;
}
Beispiel #3
0
int
Tcl_MacOSXOpenVersionedBundleResources(
    Tcl_Interp *interp,
    const char *bundleName,
    const char *bundleVersion,
    int hasResourceFile,
    int maxPathLen,
    char *libraryPath)
{
#ifdef HAVE_COREFOUNDATION
    CFBundleRef bundleRef, versionedBundleRef = NULL;
    CFStringRef bundleNameRef;
    CFURLRef libURL;

    libraryPath[0] = '\0';

    bundleNameRef = CFStringCreateWithCString(NULL, bundleName,
	    kCFStringEncodingUTF8);

    bundleRef = CFBundleGetBundleWithIdentifier(bundleNameRef);
    CFRelease(bundleNameRef);

    if (bundleVersion && bundleRef) {
	/*
	 * Create bundle from bundleVersion subdirectory of 'Versions'.
	 */

	CFURLRef bundleURL = CFBundleCopyBundleURL(bundleRef);

	if (bundleURL) {
	    CFStringRef bundleVersionRef = CFStringCreateWithCString(NULL,
		    bundleVersion, kCFStringEncodingUTF8);

	    if (bundleVersionRef) {
		CFStringRef bundleTailRef = CFURLCopyLastPathComponent(
			bundleURL);

		if (bundleTailRef) {
		    if (CFStringCompare(bundleTailRef, bundleVersionRef, 0) ==
			    kCFCompareEqualTo) {
			versionedBundleRef = (CFBundleRef) CFRetain(bundleRef);
		    }
		    CFRelease(bundleTailRef);
		}
		if (!versionedBundleRef) {
		    CFURLRef versURL = CFURLCreateCopyAppendingPathComponent(
			    NULL, bundleURL, CFSTR("Versions"), TRUE);

		    if (versURL) {
			CFURLRef versionedBundleURL =
				CFURLCreateCopyAppendingPathComponent(
				NULL, versURL, bundleVersionRef, TRUE);
			if (versionedBundleURL) {
			    versionedBundleRef = CFBundleCreate(NULL,
				    versionedBundleURL);
			    CFRelease(versionedBundleURL);
			}
			CFRelease(versURL);
		    }
		}
		CFRelease(bundleVersionRef);
	    }
	    CFRelease(bundleURL);
	}
	if (versionedBundleRef) {
	    bundleRef = versionedBundleRef;
	}
    }

    if (bundleRef) {
	if (hasResourceFile) {
	    /*
	     * Dynamically acquire address for CFBundleOpenBundleResourceMap
	     * symbol, since it is only present in full CoreFoundation on Mac
	     * OS X and not in CFLite on pure Darwin.
	     */

	    static int initialized = FALSE;
	    static short (*openresourcemap)(CFBundleRef) = NULL;

	    if (!initialized) {
#if TCL_DYLD_USE_DLFCN
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
		if (tclMacOSXDarwinRelease >= 8)
#endif
		{
		    const char *errMsg = nil;
		    openresourcemap = dlsym(RTLD_NEXT,
			    "CFBundleOpenBundleResourceMap");
		    if (!openresourcemap) {
			errMsg = dlerror();
			TclLoadDbgMsg("dlsym() failed: %s", errMsg);
		    }
		}
		if (!openresourcemap)
#endif
		{
#if TCL_DYLD_USE_NSMODULE
		    NSSymbol nsSymbol = NULL;
		    if (NSIsSymbolNameDefinedWithHint(
			    "_CFBundleOpenBundleResourceMap",
			    "CoreFoundation")) {
			nsSymbol = NSLookupAndBindSymbolWithHint(
				"_CFBundleOpenBundleResourceMap",
				"CoreFoundation");
			if (nsSymbol) {
			    openresourcemap = NSAddressOfSymbol(nsSymbol);
			}
		    }
#endif
		}
		initialized = TRUE;
	    }

	    if (openresourcemap) {
		short refNum;

		refNum = openresourcemap(bundleRef);
	    }
	}

	libURL = CFBundleCopyResourceURL(bundleRef, CFSTR("Scripts"),
		NULL, NULL);

	if (libURL) {
	    /*
	     * FIXME: This is a quick fix, it is probably not right for
	     * internationalization.
	     */

	    CFURLGetFileSystemRepresentation(libURL, TRUE,
		    (unsigned char*) libraryPath, maxPathLen);
	    CFRelease(libURL);
	}
	if (versionedBundleRef) {
	    CFRelease(versionedBundleRef);
	}
    }

    if (libraryPath[0]) {
	return TCL_OK;
    } else {
	return TCL_ERROR;
    }
#else  /* HAVE_COREFOUNDATION */
    return TCL_ERROR;
#endif /* HAVE_COREFOUNDATION */
}
Beispiel #4
0
MODULE_SCOPE int
TclpLoadMemory(
    Tcl_Interp *interp,		/* Used for error reporting. */
    void *buffer,		/* Buffer containing the desired code
				 * (allocated with TclpLoadMemoryGetBuffer). */
    int size,			/* Allocation size of buffer. */
    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
				 * file which will be passed back to
				 * (*unloadProcPtr)() to unload the file. */
    Tcl_FSUnloadFileProc **unloadProcPtr)
				/* Filled with address of Tcl_FSUnloadFileProc
				 * function which should be used for this
				 * file. */
{
    Tcl_DyldLoadHandle *dyldLoadHandle;
    NSObjectFileImage dyldObjFileImage = NULL;
    Tcl_DyldModuleHandle *modulePtr;
    NSModule module;
    const char *objFileImageErrMsg = NULL;

    /*
     * Try to create an object file image that we can load from.
     */

    if (codeSize >= 0) {
	NSObjectFileImageReturnCode err = NSObjectFileImageSuccess;
	const struct fat_header *fh = buffer;
	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
#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

	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
	     */

	    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);
		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_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);
		    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 {
	    /*
	     * 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 {
		objFileImageErrMsg = DyldOFIErrorMsg(err);
		TclLoadDbgMsg("NSCreateObjectFileImageFromMemory() failed: %s",
			objFileImageErrMsg);
	    }
	} else {
	    objFileImageErrMsg = DyldOFIErrorMsg(err);
	}
    }

    /*
     * If it went wrong (or we were asked to just deallocate), get rid of the
     * memory block and create an error message.
     */

    if (dyldObjFileImage == NULL) {
	vm_deallocate(mach_task_self(), (vm_address_t) buffer, size);
	if (objFileImageErrMsg != NULL) {
	    Tcl_AppendResult(interp, "NSCreateObjectFileImageFromMemory() "
		    "error: ", objFileImageErrMsg, NULL);
	}
	return TCL_ERROR;
    }

    /*
     * 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);
    NSDestroyObjectFileImage(dyldObjFileImage);
    if (module) {
	TclLoadDbgMsg("NSLinkModule() successful");
    } else {
	NSLinkEditErrors editError;
	int errorNumber;
	const char *errorName, *errMsg;

	NSLinkEditError(&editError, &errorNumber, &errorName, &errMsg);
	TclLoadDbgMsg("NSLinkModule() failed: %s", errMsg);
	Tcl_AppendResult(interp, errMsg, NULL);
	return TCL_ERROR;
    }

    /*
     * Stash the module reference within the load handle we create and return.
     */

    modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle));
    modulePtr->module = module;
    modulePtr->nextPtr = NULL;
    dyldLoadHandle = (Tcl_DyldLoadHandle *)
	    ckalloc(sizeof(Tcl_DyldLoadHandle));
#if TCL_DYLD_USE_DLFCN
    dyldLoadHandle->dlHandle = NULL;
#endif
    dyldLoadHandle->dyldLibHeader = NULL;
    dyldLoadHandle->modulePtr = modulePtr;
    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle;
    *unloadProcPtr = &TclpUnloadFile;
    return TCL_OK;
}
Beispiel #5
0
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. */
{
    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 TCL_DYLD_USE_DLFCN
    if (dyldLoadHandle->dlHandle) {
	proc = dlsym(dyldLoadHandle->dlHandle, native);
	if (proc) {
	    TclLoadDbgMsg("dlsym() successful");
	} else {
	    errMsg = dlerror();
	    TclLoadDbgMsg("dlsym() failed: %s", errMsg);
	}
    } else
#endif /* TCL_DYLD_USE_DLFCN */
    {
#if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY)
	NSSymbol nsSymbol = NULL;
	Tcl_DString newName;

	/*
	 * dyld adds an underscore to the beginning of symbol names.
	 */

	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) {
		TclLoadDbgMsg("NSLookupSymbolInImage() successful");
#ifdef DYLD_SUPPORTS_DYLIB_UNLOADING
		/*
		 * Until dyld supports unloading of MY_DYLIB binaries, the
		 * following is not needed.
		 */

		NSModule module = NSModuleForSymbol(nsSymbol);
		Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;

		while (modulePtr != NULL) {
		    if (module == modulePtr->module) {
			break;
		    }
		    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;

		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) {
	Tcl_AppendResult(interp, errMsg, NULL);
    }
    return proc;
}
Beispiel #6
0
MODULE_SCOPE int
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
				 * file which will be passed back to
				 * (*unloadProcPtr)() to unload the file. */
    Tcl_FSUnloadFileProc **unloadProcPtr)
				/* Filled with address of Tcl_FSUnloadFileProc
				 * function which should be used for this
				 * file. */
{
    Tcl_DyldLoadHandle *dyldLoadHandle;
#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;
#endif
#if TCL_DYLD_USE_NSMODULE
    NSLinkEditErrors editError;
    int errorNumber;
    const char *errorName, *objFileImageErrMsg = NULL;
#endif
    const char *errMsg = NULL;
    int result;
    Tcl_DString ds;
    char *fileName = NULL;
    const char *nativePath, *nativeFileName = NULL;

    /*
     * First try the full path the user gave us. This is particularly
     * important if the cwd is inside a vfs, and we are trying to load using a
     * relative path.
     */

    nativePath = Tcl_FSGetNativePath(pathPtr);

#if TCL_DYLD_USE_DLFCN
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
    if (tclMacOSXDarwinRelease >= 8)
#endif
    {
	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);
	    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 TCL_DYLD_USE_NSMODULE
	dyldLibHeader = NSAddImage(nativePath,
		NSADDIMAGE_OPTION_RETURN_ON_ERROR);
	if (dyldLibHeader) {
	    TclLoadDbgMsg("NSAddImage() successful");
	} else {
	    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.
		 */

		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 {
		    NSLinkEditError(&editError, &errorNumber, &errorName,
			    &errMsg);
		    TclLoadDbgMsg("NSAddImage() failed: %s", 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) {
		    TclLoadDbgMsg("NSCreateObjectFileImageFromFile() "
			    "successful");
		    module = NSLinkModule(dyldObjFileImage, nativePath,
			    NSLINKMODULE_OPTION_BINDNOW
			    | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
		    NSDestroyObjectFileImage(dyldObjFileImage);
		    if (module) {
			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 (0
#if TCL_DYLD_USE_DLFCN
	    || dlHandle
#endif
#if TCL_DYLD_USE_NSMODULE
	    || dyldLibHeader || modulePtr
#endif
    ) {
	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
	*loadHandle = (Tcl_LoadHandle) dyldLoadHandle;
	*unloadProcPtr = &TclpUnloadFile;
	result = TCL_OK;
    } else {
	Tcl_AppendResult(interp, errMsg, NULL);
#if TCL_DYLD_USE_NSMODULE
	if (objFileImageErrMsg) {
	    Tcl_AppendResult(interp, "\nNSCreateObjectFileImageFromFile() "
		    "error: ", objFileImageErrMsg, NULL);
	}
#endif
	result = TCL_ERROR;
    }
    if(fileName) {
	Tcl_DStringFree(&ds);
    }
    return result;
}