1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/*
* tclLoadDyld.c --
*
* This procedure provides a version of the TclLoadFile that
* works with Apple's dyld dynamic loading. This file
* provided by Wilfredo Sanchez (wsanchez@apple.com).
* This works on Mac OS X.
*
* Copyright (c) 1995 Apple Computer, Inc.
*
* 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.1 2005/07/25 20:52:00 andreas_kupries Exp $
*/
#include <mach-o/dyld.h>
#include <errno.h>
#include "tcl.h"
typedef struct Tcl_DyldModuleHandle {
struct Tcl_DyldModuleHandle *nextModuleHandle;
NSModule module;
} Tcl_DyldModuleHandle;
typedef struct Tcl_DyldLoadHandle {
const struct mach_header *dyld_lib;
Tcl_DyldModuleHandle *firstModuleHandle;
} Tcl_DyldLoadHandle;
/*
*----------------------------------------------------------------------
*
* TclpDlopen --
*
* Dynamically loads a binary code file into memory and returns
* a handle to the new code.
*
* Results:
* A standard Tcl completion code. If an error occurs, an error
* message is left in the interpreter's result.
*
* Side effects:
* New code suddenly appears in memory.
*
*----------------------------------------------------------------------
*/
VOID *
dlopen(path, flags)
CONST char *path;
int flags;
{
Tcl_DyldLoadHandle *dyldLoadHandle;
const struct mach_header *dyld_lib;
dyld_lib = NSAddImage(path,
NSADDIMAGE_OPTION_WITH_SEARCHING |
NSADDIMAGE_OPTION_RETURN_ON_ERROR);
if (!dyld_lib) {
return NULL;
}
dyldLoadHandle = (Tcl_DyldLoadHandle *) ckalloc(sizeof(Tcl_DyldLoadHandle));
if (!dyldLoadHandle) return NULL;
dyldLoadHandle->dyld_lib = dyld_lib;
dyldLoadHandle->firstModuleHandle = NULL;
return (Tcl_LoadHandle) dyldLoadHandle;
}
char *
dlerror()
{
NSLinkEditErrors editError;
char *name, *msg;
NSLinkEditError(&editError, &errno, &name, &msg);
return msg;
}
/*
*----------------------------------------------------------------------
*
* TclpFindSymbol --
*
* Looks up a symbol, by name, through a handle associated with
* a previously loaded piece of code (shared library).
*
* Results:
* Returns a pointer to the function associated with 'symbol' if
* it is found. Otherwise returns NULL and may leave an error
* message in the interp's result.
*
*----------------------------------------------------------------------
*/
VOID *dlsym(handle, symbol)
VOID *handle;
CONST char *symbol;
{
NSSymbol nsSymbol;
CONST char *native;
Tcl_DString newName, ds;
Tcl_PackageInitProc* proc = NULL;
Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) handle;
/*
* dyld adds an underscore to the beginning of symbol names.
*/
native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
Tcl_DStringInit(&newName);
Tcl_DStringAppend(&newName, "_", 1);
native = Tcl_DStringAppend(&newName, native, -1);
nsSymbol = NSLookupSymbolInImage(dyldLoadHandle->dyld_lib, native,
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW |
NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
if(nsSymbol) {
Tcl_DyldModuleHandle *dyldModuleHandle;
proc = NSAddressOfSymbol(nsSymbol);
dyldModuleHandle = (Tcl_DyldModuleHandle *) ckalloc(sizeof(Tcl_DyldModuleHandle));
if (dyldModuleHandle) {
dyldModuleHandle->module = NSModuleForSymbol(nsSymbol);
dyldModuleHandle->nextModuleHandle = dyldLoadHandle->firstModuleHandle;
dyldLoadHandle->firstModuleHandle = dyldModuleHandle;
}
}
Tcl_DStringFree(&newName);
Tcl_DStringFree(&ds);
return proc;
}
/*
*----------------------------------------------------------------------
*
* TclpUnloadFile --
*
* Unloads a dynamically loaded binary code file from memory.
* Code pointers in the formerly loaded file are no longer valid
* after calling this function.
*
* Results:
* None.
*
* Side effects:
* Code dissapears from memory.
* Note that this is a no-op on older (OpenStep) versions of dyld.
*
*----------------------------------------------------------------------
*/
int
dlclose(handle)
VOID *handle;
{
Tcl_DyldLoadHandle *dyldLoadHandle = (Tcl_DyldLoadHandle *) handle;
Tcl_DyldModuleHandle *dyldModuleHandle = dyldLoadHandle->firstModuleHandle;
void *ptr;
while (dyldModuleHandle) {
NSUnLinkModule(dyldModuleHandle->module, NSUNLINKMODULE_OPTION_NONE);
ptr = dyldModuleHandle;
dyldModuleHandle = dyldModuleHandle->nextModuleHandle;
ckfree(ptr);
}
ckfree(dyldLoadHandle);
}
|