os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/unix/tclLoadDyld.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/unix/tclLoadDyld.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,580 @@
     1.4 +/*
     1.5 + * tclLoadDyld.c --
     1.6 + *
     1.7 + *	This procedure provides a version of the TclLoadFile that works with
     1.8 + *	Apple's dyld dynamic loading.
     1.9 + *	Original version of his file (now superseded long ago) provided by
    1.10 + *	Wilfredo Sanchez (wsanchez@apple.com).
    1.11 + *
    1.12 + * Copyright (c) 1995 Apple Computer, Inc.
    1.13 + * Copyright (c) 2001-2007 Daniel A. Steffen <das@users.sourceforge.net>
    1.14 + *
    1.15 + * See the file "license.terms" for information on usage and redistribution of
    1.16 + * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    1.17 + *
    1.18 + * RCS: @(#) $Id: tclLoadDyld.c,v 1.14.2.9 2007/04/29 02:20:16 das Exp $
    1.19 + */
    1.20 +
    1.21 +#include "tclInt.h"
    1.22 +#include "tclPort.h"
    1.23 +#include <mach-o/dyld.h>
    1.24 +#include <mach-o/fat.h>
    1.25 +#include <mach-o/swap.h>
    1.26 +#include <mach-o/arch.h>
    1.27 +#include <libkern/OSByteOrder.h>
    1.28 +#undef panic
    1.29 +#include <mach/mach.h>
    1.30 +
    1.31 +#ifndef MODULE_SCOPE
    1.32 +#define MODULE_SCOPE extern
    1.33 +#endif
    1.34 +
    1.35 +typedef struct Tcl_DyldModuleHandle {
    1.36 +    struct Tcl_DyldModuleHandle *nextPtr;
    1.37 +    NSModule module;
    1.38 +} Tcl_DyldModuleHandle;
    1.39 +
    1.40 +typedef struct Tcl_DyldLoadHandle {
    1.41 +    CONST struct mach_header *dyldLibHeader;
    1.42 +    Tcl_DyldModuleHandle *modulePtr;
    1.43 +} Tcl_DyldLoadHandle;
    1.44 +
    1.45 +#ifdef TCL_LOAD_FROM_MEMORY
    1.46 +MODULE_SCOPE long tclMacOSXDarwinRelease;
    1.47 +#endif
    1.48 +
    1.49 +/*
    1.50 + *----------------------------------------------------------------------
    1.51 + *
    1.52 + * DyldOFIErrorMsg --
    1.53 + *
    1.54 + *	Converts a numerical NSObjectFileImage error into an error message
    1.55 + *	string.
    1.56 + *
    1.57 + * Results:
    1.58 + *	Error message string.
    1.59 + *
    1.60 + * Side effects:
    1.61 + *	None.
    1.62 + *
    1.63 + *----------------------------------------------------------------------
    1.64 + */
    1.65 +
    1.66 +static CONST char*
    1.67 +DyldOFIErrorMsg(
    1.68 +    int err)
    1.69 +{
    1.70 +    switch(err) {
    1.71 +    case NSObjectFileImageSuccess:
    1.72 +	return NULL;
    1.73 +    case NSObjectFileImageFailure:
    1.74 +	return "object file setup failure";
    1.75 +    case NSObjectFileImageInappropriateFile:
    1.76 +	return "not a Mach-O MH_BUNDLE file";
    1.77 +    case NSObjectFileImageArch:
    1.78 +	return "no object for this architecture";
    1.79 +    case NSObjectFileImageFormat:
    1.80 +	return "bad object file format";
    1.81 +    case NSObjectFileImageAccess:
    1.82 +	return "can't read object file";
    1.83 +    default:
    1.84 +	return "unknown error";
    1.85 +    }
    1.86 +}
    1.87 +
    1.88 +/*
    1.89 + *----------------------------------------------------------------------
    1.90 + *
    1.91 + * TclpDlopen --
    1.92 + *
    1.93 + *	Dynamically loads a binary code file into memory and returns a handle
    1.94 + *	to the new code.
    1.95 + *
    1.96 + * Results:
    1.97 + *	A standard Tcl completion code. If an error occurs, an error message
    1.98 + *	is left in the interpreter's result.
    1.99 + *
   1.100 + * Side effects:
   1.101 + *	New code suddenly appears in memory.
   1.102 + *
   1.103 + *----------------------------------------------------------------------
   1.104 + */
   1.105 +
   1.106 +MODULE_SCOPE int
   1.107 +TclpDlopen(
   1.108 +    Tcl_Interp *interp,		/* Used for error reporting. */
   1.109 +    Tcl_Obj *pathPtr,		/* Name of the file containing the desired
   1.110 +				 * code (UTF-8). */
   1.111 +    Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded
   1.112 +				 * file which will be passed back to
   1.113 +				 * (*unloadProcPtr)() to unload the file. */
   1.114 +    Tcl_FSUnloadFileProc **unloadProcPtr)
   1.115 +				/* Filled with address of Tcl_FSUnloadFileProc
   1.116 +				 * function which should be used for this
   1.117 +				 * file. */
   1.118 +{
   1.119 +    Tcl_DyldLoadHandle *dyldLoadHandle;
   1.120 +    CONST struct mach_header *dyldLibHeader;
   1.121 +    NSObjectFileImage dyldObjFileImage = NULL;
   1.122 +    Tcl_DyldModuleHandle *modulePtr = NULL;
   1.123 +    CONST char *native;
   1.124 +
   1.125 +    /*
   1.126 +     * First try the full path the user gave us. This is particularly
   1.127 +     * important if the cwd is inside a vfs, and we are trying to load using a
   1.128 +     * relative path.
   1.129 +     */
   1.130 +
   1.131 +    native = Tcl_FSGetNativePath(pathPtr);
   1.132 +    dyldLibHeader = NSAddImage(native, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
   1.133 +
   1.134 +    if (!dyldLibHeader) {
   1.135 +	NSLinkEditErrors editError;
   1.136 +	int errorNumber;
   1.137 +	CONST char *name, *msg, *objFileImageErrMsg = NULL;
   1.138 +
   1.139 +	NSLinkEditError(&editError, &errorNumber, &name, &msg);
   1.140 +
   1.141 +	if (editError == NSLinkEditFileAccessError) {
   1.142 +	    /*
   1.143 +	     * The requested file was not found. Let the OS loader examine the
   1.144 +	     * binary search path for whatever string the user gave us which
   1.145 +	     * hopefully refers to a file on the binary path.
   1.146 +	     */
   1.147 +
   1.148 +	    Tcl_DString ds;
   1.149 +	    char *fileName = Tcl_GetString(pathPtr);
   1.150 +	    CONST char *native =
   1.151 +		    Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
   1.152 +
   1.153 +	    dyldLibHeader = NSAddImage(native, NSADDIMAGE_OPTION_WITH_SEARCHING
   1.154 +		    | NSADDIMAGE_OPTION_RETURN_ON_ERROR);
   1.155 +	    Tcl_DStringFree(&ds);
   1.156 +	    if (!dyldLibHeader) {
   1.157 +		NSLinkEditError(&editError, &errorNumber, &name, &msg);
   1.158 +	    }
   1.159 +	} else if ((editError == NSLinkEditFileFormatError
   1.160 +		&& errorNumber == EBADMACHO)
   1.161 +		|| editError == NSLinkEditOtherError){
   1.162 +	    /*
   1.163 +	     * The requested file was found but was not of type MH_DYLIB,
   1.164 +	     * attempt to load it as a MH_BUNDLE.
   1.165 +	     */
   1.166 +
   1.167 +	    NSObjectFileImageReturnCode err =
   1.168 +		    NSCreateObjectFileImageFromFile(native, &dyldObjFileImage);
   1.169 +	    objFileImageErrMsg = DyldOFIErrorMsg(err);
   1.170 +	}
   1.171 +
   1.172 +	if (!dyldLibHeader && !dyldObjFileImage) {
   1.173 +	    Tcl_AppendResult(interp, msg, NULL);
   1.174 +	    if (msg && *msg) {
   1.175 +		Tcl_AppendResult(interp, "\n", NULL);
   1.176 +	    }
   1.177 +	    if (objFileImageErrMsg) {
   1.178 +		Tcl_AppendResult(interp,
   1.179 +			"NSCreateObjectFileImageFromFile() error: ",
   1.180 +			objFileImageErrMsg, NULL);
   1.181 +	    }
   1.182 +	    return TCL_ERROR;
   1.183 +	}
   1.184 +    }
   1.185 +
   1.186 +    if (dyldObjFileImage) {
   1.187 +	NSModule module;
   1.188 +
   1.189 +	module = NSLinkModule(dyldObjFileImage, native,
   1.190 +		NSLINKMODULE_OPTION_BINDNOW
   1.191 +		| NSLINKMODULE_OPTION_RETURN_ON_ERROR);
   1.192 +	NSDestroyObjectFileImage(dyldObjFileImage);
   1.193 +
   1.194 +	if (!module) {
   1.195 +	    NSLinkEditErrors editError;
   1.196 +	    int errorNumber;
   1.197 +	    CONST char *name, *msg;
   1.198 +
   1.199 +	    NSLinkEditError(&editError, &errorNumber, &name, &msg);
   1.200 +	    Tcl_AppendResult(interp, msg, NULL);
   1.201 +	    return TCL_ERROR;
   1.202 +	}
   1.203 +
   1.204 +	modulePtr = (Tcl_DyldModuleHandle *)
   1.205 +		ckalloc(sizeof(Tcl_DyldModuleHandle));
   1.206 +	modulePtr->module = module;
   1.207 +	modulePtr->nextPtr = NULL;
   1.208 +    }
   1.209 +
   1.210 +    dyldLoadHandle = (Tcl_DyldLoadHandle *)
   1.211 +	    ckalloc(sizeof(Tcl_DyldLoadHandle));
   1.212 +    dyldLoadHandle->dyldLibHeader = dyldLibHeader;
   1.213 +    dyldLoadHandle->modulePtr = modulePtr;
   1.214 +    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle;
   1.215 +    *unloadProcPtr = &TclpUnloadFile;
   1.216 +    return TCL_OK;
   1.217 +}
   1.218 +
   1.219 +/*
   1.220 + *----------------------------------------------------------------------
   1.221 + *
   1.222 + * TclpFindSymbol --
   1.223 + *
   1.224 + *	Looks up a symbol, by name, through a handle associated with a
   1.225 + *	previously loaded piece of code (shared library).
   1.226 + *
   1.227 + * Results:
   1.228 + *	Returns a pointer to the function associated with 'symbol' if it is
   1.229 + *	found. Otherwise returns NULL and may leave an error message in the
   1.230 + *	interp's result.
   1.231 + *
   1.232 + *----------------------------------------------------------------------
   1.233 + */
   1.234 +
   1.235 +MODULE_SCOPE Tcl_PackageInitProc *
   1.236 +TclpFindSymbol(
   1.237 +    Tcl_Interp *interp,		/* For error reporting. */
   1.238 +    Tcl_LoadHandle loadHandle,	/* Handle from TclpDlopen. */
   1.239 +    CONST char *symbol)		/* Symbol name to look up. */
   1.240 +{
   1.241 +    NSSymbol nsSymbol;
   1.242 +    CONST char *native;
   1.243 +    Tcl_DString newName, ds;
   1.244 +    Tcl_PackageInitProc *proc = NULL;
   1.245 +    Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle;
   1.246 +
   1.247 +    /*
   1.248 +     * dyld adds an underscore to the beginning of symbol names.
   1.249 +     */
   1.250 +
   1.251 +    native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
   1.252 +    Tcl_DStringInit(&newName);
   1.253 +    Tcl_DStringAppend(&newName, "_", 1);
   1.254 +    native = Tcl_DStringAppend(&newName, native, -1);
   1.255 +
   1.256 +    if (dyldLoadHandle->dyldLibHeader) {
   1.257 +	nsSymbol = NSLookupSymbolInImage(dyldLoadHandle->dyldLibHeader, native,
   1.258 +		NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
   1.259 +		NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
   1.260 +	if (nsSymbol) {
   1.261 +	    /*
   1.262 +	     * Until dyld supports unloading of MY_DYLIB binaries, the
   1.263 +	     * following is not needed.
   1.264 +	     */
   1.265 +
   1.266 +#ifdef DYLD_SUPPORTS_DYLIB_UNLOADING
   1.267 +	    NSModule module = NSModuleForSymbol(nsSymbol);
   1.268 +	    Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;
   1.269 +
   1.270 +	    while (modulePtr != NULL) {
   1.271 +		if (module == modulePtr->module) {
   1.272 +		    break;
   1.273 +		}
   1.274 +		modulePtr = modulePtr->nextPtr;
   1.275 +	    }
   1.276 +	    if (modulePtr == NULL) {
   1.277 +		modulePtr = (Tcl_DyldModuleHandle *)
   1.278 +			ckalloc(sizeof(Tcl_DyldModuleHandle));
   1.279 +		modulePtr->module = module;
   1.280 +		modulePtr->nextPtr = dyldLoadHandle->modulePtr;
   1.281 +		dyldLoadHandle->modulePtr = modulePtr;
   1.282 +	    }
   1.283 +#endif /* DYLD_SUPPORTS_DYLIB_UNLOADING */
   1.284 +
   1.285 +	} else {
   1.286 +	    NSLinkEditErrors editError;
   1.287 +	    int errorNumber;
   1.288 +	    CONST char *name, *msg;
   1.289 +
   1.290 +	    NSLinkEditError(&editError, &errorNumber, &name, &msg);
   1.291 +	    Tcl_AppendResult(interp, msg, NULL);
   1.292 +	}
   1.293 +    } else {
   1.294 +	nsSymbol = NSLookupSymbolInModule(dyldLoadHandle->modulePtr->module,
   1.295 +		native);
   1.296 +    }
   1.297 +    if (nsSymbol) {
   1.298 +	proc = NSAddressOfSymbol(nsSymbol);
   1.299 +    }
   1.300 +    Tcl_DStringFree(&newName);
   1.301 +    Tcl_DStringFree(&ds);
   1.302 +
   1.303 +    return proc;
   1.304 +}
   1.305 +
   1.306 +/*
   1.307 + *----------------------------------------------------------------------
   1.308 + *
   1.309 + * TclpUnloadFile --
   1.310 + *
   1.311 + *	Unloads a dynamically loaded binary code file from memory. Code
   1.312 + *	pointers in the formerly loaded file are no longer valid after calling
   1.313 + *	this function.
   1.314 + *
   1.315 + * Results:
   1.316 + *	None.
   1.317 + *
   1.318 + * Side effects:
   1.319 + *	Code dissapears from memory. Note that dyld currently only supports
   1.320 + *	unloading of binaries of type MH_BUNDLE loaded with NSLinkModule() in
   1.321 + *	TclpDlopen() above.
   1.322 + *
   1.323 + *----------------------------------------------------------------------
   1.324 + */
   1.325 +
   1.326 +MODULE_SCOPE void
   1.327 +TclpUnloadFile(
   1.328 +    Tcl_LoadHandle loadHandle)	/* loadHandle returned by a previous call to
   1.329 +				 * TclpDlopen(). The loadHandle is a token
   1.330 +				 * that represents the loaded file. */
   1.331 +{
   1.332 +    Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) loadHandle;
   1.333 +    Tcl_DyldModuleHandle *modulePtr = dyldLoadHandle->modulePtr;
   1.334 +
   1.335 +    while (modulePtr != NULL) {
   1.336 +	void *ptr;
   1.337 +
   1.338 +	NSUnLinkModule(modulePtr->module,
   1.339 +		NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
   1.340 +	ptr = modulePtr;
   1.341 +	modulePtr = modulePtr->nextPtr;
   1.342 +	ckfree(ptr);
   1.343 +    }
   1.344 +    ckfree((char*) dyldLoadHandle);
   1.345 +}
   1.346 +
   1.347 +/*
   1.348 + *----------------------------------------------------------------------
   1.349 + *
   1.350 + * TclGuessPackageName --
   1.351 + *
   1.352 + *	If the "load" command is invoked without providing a package name,
   1.353 + *	this procedure is invoked to try to figure it out.
   1.354 + *
   1.355 + * Results:
   1.356 + *	Always returns 0 to indicate that we couldn't figure out a package
   1.357 + *	name; generic code will then try to guess the package from the file
   1.358 + *	name. A return value of 1 would have meant that we figured out the
   1.359 + *	package name and put it in bufPtr.
   1.360 + *
   1.361 + * Side effects:
   1.362 + *	None.
   1.363 + *
   1.364 + *----------------------------------------------------------------------
   1.365 + */
   1.366 +
   1.367 +int
   1.368 +TclGuessPackageName(
   1.369 +    CONST char *fileName,	/* Name of file containing package (already
   1.370 +				 * translated to local form if needed). */
   1.371 +    Tcl_DString *bufPtr)	/* Initialized empty dstring. Append package
   1.372 +				 * name to this if possible. */
   1.373 +{
   1.374 +    return 0;
   1.375 +}
   1.376 +
   1.377 +#ifdef TCL_LOAD_FROM_MEMORY
   1.378 +/*
   1.379 + *----------------------------------------------------------------------
   1.380 + *
   1.381 + * TclpLoadMemoryGetBuffer --
   1.382 + *
   1.383 + *	Allocate a buffer that can be used with TclpLoadMemory() below.
   1.384 + *
   1.385 + * Results:
   1.386 + *	Pointer to allocated buffer or NULL if an error occurs.
   1.387 + *
   1.388 + * Side effects:
   1.389 + *	Buffer is allocated.
   1.390 + *
   1.391 + *----------------------------------------------------------------------
   1.392 + */
   1.393 +
   1.394 +MODULE_SCOPE void *
   1.395 +TclpLoadMemoryGetBuffer(
   1.396 +    Tcl_Interp *interp,		/* Used for error reporting. */
   1.397 +    int size)			/* Size of desired buffer. */
   1.398 +{
   1.399 +    void *buffer = NULL;
   1.400 +
   1.401 +    /*
   1.402 +     * NSCreateObjectFileImageFromMemory is available but always fails
   1.403 +     * prior to Darwin 7.
   1.404 +     */
   1.405 +    if (tclMacOSXDarwinRelease >= 7) {
   1.406 +	/*
   1.407 +	 * We must allocate the buffer using vm_allocate, because
   1.408 +	 * NSCreateObjectFileImageFromMemory will dispose of it using
   1.409 +	 * vm_deallocate.
   1.410 +	 */
   1.411 +
   1.412 +	if (vm_allocate(mach_task_self(), (vm_address_t *) &buffer, size, 1)) {
   1.413 +	    buffer = NULL;
   1.414 +	}
   1.415 +    }
   1.416 +    return buffer;
   1.417 +}
   1.418 +
   1.419 +/*
   1.420 + *----------------------------------------------------------------------
   1.421 + *
   1.422 + * TclpLoadMemory --
   1.423 + *
   1.424 + *	Dynamically loads binary code file from memory and returns a handle to
   1.425 + *	the new code.
   1.426 + *
   1.427 + * Results:
   1.428 + *	A standard Tcl completion code. If an error occurs, an error message
   1.429 + *	is left in the interpreter's result.
   1.430 + *
   1.431 + * Side effects:
   1.432 + *	New code is loaded from memory.
   1.433 + *
   1.434 + *----------------------------------------------------------------------
   1.435 + */
   1.436 +
   1.437 +MODULE_SCOPE int
   1.438 +TclpLoadMemory(
   1.439 +    Tcl_Interp *interp,		/* Used for error reporting. */
   1.440 +    void *buffer,		/* Buffer containing the desired code
   1.441 +				 * (allocated with TclpLoadMemoryGetBuffer). */
   1.442 +    int size,			/* Allocation size of buffer. */
   1.443 +    int codeSize,		/* Size of code data read into buffer or -1 if
   1.444 +				 * an error occurred and the buffer should
   1.445 +				 * just be freed. */
   1.446 +    Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded
   1.447 +				 * file which will be passed back to
   1.448 +				 * (*unloadProcPtr)() to unload the file. */
   1.449 +    Tcl_FSUnloadFileProc **unloadProcPtr)
   1.450 +				/* Filled with address of Tcl_FSUnloadFileProc
   1.451 +				 * function which should be used for this
   1.452 +				 * file. */
   1.453 +{
   1.454 +    Tcl_DyldLoadHandle *dyldLoadHandle;
   1.455 +    NSObjectFileImage dyldObjFileImage = NULL;
   1.456 +    Tcl_DyldModuleHandle *modulePtr;
   1.457 +    NSModule module;
   1.458 +    CONST char *objFileImageErrMsg = NULL;
   1.459 +
   1.460 +    /*
   1.461 +     * Try to create an object file image that we can load from.
   1.462 +     */
   1.463 +
   1.464 +    if (codeSize >= 0) {
   1.465 +	NSObjectFileImageReturnCode err = NSObjectFileImageSuccess;
   1.466 +	CONST struct fat_header *fh = buffer;
   1.467 +	uint32_t ms = 0;
   1.468 +#ifndef __LP64__
   1.469 +	CONST struct mach_header *mh = NULL;
   1.470 +	#define mh_magic OSSwapHostToBigInt32(MH_MAGIC)
   1.471 +	#define mh_size  sizeof(struct mach_header)
   1.472 +#else
   1.473 +	CONST struct mach_header_64 *mh = NULL;
   1.474 +	#define mh_magic OSSwapHostToBigInt32(MH_MAGIC_64)
   1.475 +	#define mh_size  sizeof(struct mach_header_64)
   1.476 +#endif
   1.477 +	
   1.478 +	if ((size_t) codeSize >= sizeof(struct fat_header)
   1.479 +		&& fh->magic == OSSwapHostToBigInt32(FAT_MAGIC)) {
   1.480 +	    /*
   1.481 +	     * Fat binary, try to find mach_header for our architecture
   1.482 +	     */
   1.483 +	    uint32_t fh_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch);
   1.484 +	    
   1.485 +	    if ((size_t) codeSize >= sizeof(struct fat_header) + 
   1.486 +		    fh_nfat_arch * sizeof(struct fat_arch)) {
   1.487 +		void *fatarchs = (char*)buffer + sizeof(struct fat_header);
   1.488 +		CONST NXArchInfo *arch = NXGetLocalArchInfo();
   1.489 +		struct fat_arch *fa;
   1.490 +		
   1.491 +		if (fh->magic != FAT_MAGIC) {
   1.492 +		    swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);
   1.493 +		}
   1.494 +		fa = NXFindBestFatArch(arch->cputype, arch->cpusubtype,
   1.495 +			fatarchs, fh_nfat_arch);
   1.496 +		if (fa) {
   1.497 +		    mh = (void*)((char*)buffer + fa->offset);
   1.498 +		    ms = fa->size;
   1.499 +		} else {
   1.500 +		    err = NSObjectFileImageInappropriateFile;
   1.501 +		}
   1.502 +		if (fh->magic != FAT_MAGIC) {
   1.503 +		    swap_fat_arch(fatarchs, fh_nfat_arch, arch->byteorder);
   1.504 +		}
   1.505 +	    } else {
   1.506 +		err = NSObjectFileImageInappropriateFile;
   1.507 +	    }
   1.508 +	} else {
   1.509 +	    /*
   1.510 +	     * Thin binary
   1.511 +	     */
   1.512 +	    mh = buffer;
   1.513 +	    ms = codeSize;
   1.514 +	}
   1.515 +	if (ms && !(ms >= mh_size && mh->magic == mh_magic &&
   1.516 +		 mh->filetype == OSSwapHostToBigInt32(MH_BUNDLE))) {
   1.517 +	    err = NSObjectFileImageInappropriateFile;
   1.518 +	}
   1.519 +	if (err == NSObjectFileImageSuccess) {
   1.520 +	    err = NSCreateObjectFileImageFromMemory(buffer, codeSize,
   1.521 +		    &dyldObjFileImage);
   1.522 +	}
   1.523 +	objFileImageErrMsg = DyldOFIErrorMsg(err);
   1.524 +    }
   1.525 +
   1.526 +    /*
   1.527 +     * If it went wrong (or we were asked to just deallocate), get rid of the
   1.528 +     * memory block and create an error message.
   1.529 +     */
   1.530 +
   1.531 +    if (dyldObjFileImage == NULL) {
   1.532 +	vm_deallocate(mach_task_self(), (vm_address_t) buffer, size);
   1.533 +	if (objFileImageErrMsg != NULL) {
   1.534 +	    Tcl_AppendResult(interp,
   1.535 +		    "NSCreateObjectFileImageFromMemory() error: ",
   1.536 +		    objFileImageErrMsg, NULL);
   1.537 +	}
   1.538 +	return TCL_ERROR;
   1.539 +    }
   1.540 +
   1.541 +    /*
   1.542 +     * Extract the module we want from the image of the object file.
   1.543 +     */
   1.544 +
   1.545 +    module = NSLinkModule(dyldObjFileImage, "[Memory Based Bundle]",
   1.546 +	    NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
   1.547 +    NSDestroyObjectFileImage(dyldObjFileImage);
   1.548 +
   1.549 +    if (!module) {
   1.550 +	NSLinkEditErrors editError;
   1.551 +	int errorNumber;
   1.552 +	CONST char *name, *msg;
   1.553 +
   1.554 +	NSLinkEditError(&editError, &errorNumber, &name, &msg);
   1.555 +	Tcl_AppendResult(interp, msg, NULL);
   1.556 +	return TCL_ERROR;
   1.557 +    }
   1.558 +
   1.559 +    /*
   1.560 +     * Stash the module reference within the load handle we create and return.
   1.561 +     */
   1.562 +
   1.563 +    modulePtr = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle));
   1.564 +    modulePtr->module = module;
   1.565 +    modulePtr->nextPtr = NULL;
   1.566 +
   1.567 +    dyldLoadHandle = (Tcl_DyldLoadHandle *)
   1.568 +	    ckalloc(sizeof(Tcl_DyldLoadHandle));
   1.569 +    dyldLoadHandle->dyldLibHeader = NULL;
   1.570 +    dyldLoadHandle->modulePtr = modulePtr;
   1.571 +    *loadHandle = (Tcl_LoadHandle) dyldLoadHandle;
   1.572 +    *unloadProcPtr = &TclpUnloadFile;
   1.573 +    return TCL_OK;
   1.574 +}
   1.575 +#endif
   1.576 +
   1.577 +/*
   1.578 + * Local Variables:
   1.579 + * mode: c
   1.580 + * c-basic-offset: 4
   1.581 + * fill-column: 78
   1.582 + * End:
   1.583 + */