1/* 2 * tclLoadOSF.c -- 3 * 4 * This function provides a version of the TclLoadFile that works under 5 * OSF/1 1.0/1.1/1.2 and related systems, utilizing the old OSF/1 6 * /sbin/loader and /usr/include/loader.h. OSF/1 versions from 1.3 and on 7 * use ELF, rtld, and dlopen()[/usr/include/ldfcn.h]. 8 * 9 * This is useful for: 10 * OSF/1 1.0, 1.1, 1.2 (from OSF) 11 * includes: MK4 and AD1 (from OSF RI) 12 * OSF/1 1.3 (from OSF) using ROSE 13 * HP OSF/1 1.0 ("Acorn") using COFF 14 * 15 * This is likely to be useful for: 16 * Paragon OSF/1 (from Intel) 17 * HI-OSF/1 (from Hitachi) 18 * 19 * This is NOT to be used on: 20 * Digitial Alpha OSF/1 systems 21 * OSF/1 1.3 or later (from OSF) using ELF 22 * includes: MK6, MK7, AD2, AD3 (from OSF RI) 23 * 24 * This approach to things was utter @&^#; thankfully, OSF/1 eventually 25 * supported dlopen(). 26 * 27 * John Robert LoVerso <loverso@freebsd.osf.org> 28 * 29 * Copyright (c) 1995-1997 Sun Microsystems, Inc. 30 * 31 * See the file "license.terms" for information on usage and redistribution of 32 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 33 * 34 * RCS: @(#) $Id: tclLoadOSF.c,v 1.13 2005/11/11 23:46:34 dkf Exp $ 35 */ 36 37#include "tclInt.h" 38#include <sys/types.h> 39#include <loader.h> 40 41/* 42 *---------------------------------------------------------------------- 43 * 44 * TclpDlopen -- 45 * 46 * Dynamically loads a binary code file into memory and returns a handle 47 * to the new code. 48 * 49 * Results: 50 * A standard Tcl completion code. If an error occurs, an error message 51 * is left in the interp's result. 52 * 53 * Side effects: 54 * New code suddenly appears in memory. 55 * 56 *---------------------------------------------------------------------- 57 */ 58 59int 60TclpDlopen( 61 Tcl_Interp *interp, /* Used for error reporting. */ 62 Tcl_Obj *pathPtr, /* Name of the file containing the desired 63 * code (UTF-8). */ 64 Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded 65 * file which will be passed back to 66 * (*unloadProcPtr)() to unload the file. */ 67 Tcl_FSUnloadFileProc **unloadProcPtr) 68 /* Filled with address of Tcl_FSUnloadFileProc 69 * function which should be used for this 70 * file. */ 71{ 72 ldr_module_t lm; 73 char *pkg; 74 char *fileName = Tcl_GetString(pathPtr); 75 CONST char *native; 76 77 /* 78 * First try the full path the user gave us. This is particularly 79 * important if the cwd is inside a vfs, and we are trying to load using a 80 * relative path. 81 */ 82 83 native = Tcl_FSGetNativePath(pathPtr); 84 lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); 85 86 if (lm == LDR_NULL_MODULE) { 87 /* 88 * Let the OS loader examine the binary search path for whatever 89 * string the user gave us which hopefully refers to a file on the 90 * binary path 91 */ 92 93 Tcl_DString ds; 94 95 native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); 96 lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS); 97 Tcl_DStringFree(&ds); 98 } 99 100 if (lm == LDR_NULL_MODULE) { 101 Tcl_AppendResult(interp, "couldn't load file \"", fileName, "\": ", 102 Tcl_PosixError(interp), NULL); 103 return TCL_ERROR; 104 } 105 106 *clientDataPtr = NULL; 107 108 /* 109 * My convention is to use a [OSF loader] package name the same as shlib, 110 * since the idiots never implemented ldr_lookup() and it is otherwise 111 * impossible to get a package name given a module. 112 * 113 * I build loadable modules with a makefile rule like 114 * ld ... -export $@: -o $@ $(OBJS) 115 */ 116 117 if ((pkg = strrchr(fileName, '/')) == NULL) { 118 pkg = fileName; 119 } else { 120 pkg++; 121 } 122 *loadHandle = pkg; 123 *unloadProcPtr = &TclpUnloadFile; 124 return TCL_OK; 125} 126 127/* 128 *---------------------------------------------------------------------- 129 * 130 * TclpFindSymbol -- 131 * 132 * Looks up a symbol, by name, through a handle associated with a 133 * previously loaded piece of code (shared library). 134 * 135 * Results: 136 * Returns a pointer to the function associated with 'symbol' if it is 137 * found. Otherwise returns NULL and may leave an error message in the 138 * interp's result. 139 * 140 *---------------------------------------------------------------------- 141 */ 142 143Tcl_PackageInitProc * 144TclpFindSymbol( 145 Tcl_Interp *interp, 146 Tcl_LoadHandle loadHandle, 147 CONST char *symbol) 148{ 149 return ldr_lookup_package((char *)loadHandle, symbol); 150} 151 152/* 153 *---------------------------------------------------------------------- 154 * 155 * TclpUnloadFile -- 156 * 157 * Unloads a dynamically loaded binary code file from memory. Code 158 * pointers in the formerly loaded file are no longer valid after calling 159 * this function. 160 * 161 * Results: 162 * None. 163 * 164 * Side effects: 165 * Does nothing. Can anything be done? 166 * 167 *---------------------------------------------------------------------- 168 */ 169 170void 171TclpUnloadFile( 172 Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to 173 * TclpDlopen(). The loadHandle is a token 174 * that represents the loaded file. */ 175{ 176} 177 178/* 179 *---------------------------------------------------------------------- 180 * 181 * TclGuessPackageName -- 182 * 183 * If the "load" command is invoked without providing a package name, 184 * this function is invoked to try to figure it out. 185 * 186 * Results: 187 * Always returns 0 to indicate that we couldn't figure out a package 188 * name; generic code will then try to guess the package from the file 189 * name. A return value of 1 would have meant that we figured out the 190 * package name and put it in bufPtr. 191 * 192 * Side effects: 193 * None. 194 * 195 *---------------------------------------------------------------------- 196 */ 197 198int 199TclGuessPackageName( 200 CONST char *fileName, /* Name of file containing package (already 201 * translated to local form if needed). */ 202 Tcl_DString *bufPtr) /* Initialized empty dstring. Append package 203 * name to this if possible. */ 204{ 205 return 0; 206} 207 208/* 209 * Local Variables: 210 * mode: c 211 * c-basic-offset: 4 212 * fill-column: 78 213 * End: 214 */ 215