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