[project @ 1999-10-22 10:00:19 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / dynamic.c
1
2 /* --------------------------------------------------------------------------
3  * Dynamic loading (of .dll or .so files) for Hugs
4  *
5  * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
6  * Yale Haskell Group, and the Oregon Graduate Institute of Science and
7  * Technology, 1994-1999, All rights reserved.  It is distributed as
8  * free software under the license in the file "License", which is
9  * included in the distribution.
10  *
11  * $RCSfile: dynamic.c,v $
12  * $Revision: 1.9 $
13  * $Date: 1999/10/22 10:00:19 $
14  * ------------------------------------------------------------------------*/
15
16 #include "prelude.h"
17 #include "storage.h"
18 #include "errors.h"
19 #include "dynamic.h"
20
21 #if HAVE_WINDOWS_H && !defined(__MSDOS__)
22
23 #include <windows.h>
24
25 ObjectFile loadLibrary(fn)
26 String fn; {
27     return LoadLibrary(fn);
28 }
29
30 void* lookupSymbol(file,symbol)
31 ObjectFile file;
32 String symbol; {
33     return GetProcAddress(file,symbol);
34 }
35
36 const char *dlerror(void)
37 {
38    return "<unknown>";
39 }
40
41 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
42 String dll;
43 String symbol; {
44     ObjectFile instance = LoadLibrary(dll);
45     if (NULL == instance) {
46         /* GetLastError allegedly provides more detail - in practice,
47          * it tells you nothing more.
48          */
49         ERRMSG(0) "Error while importing DLL \"%s\"", dll
50         EEND;
51     }
52     return GetProcAddress(instance,symbol);
53 }
54
55 #elif HAVE_DLFCN_H /* eg LINUX, SOLARIS, ULTRIX */
56
57 #include <stdio.h>
58 #include <dlfcn.h>
59
60 ObjectFile loadLibrary(fn)
61 String fn; {
62     return dlopen(fn,RTLD_NOW | RTLD_GLOBAL);
63 }
64
65 void* lookupSymbol(file,symbol)
66 ObjectFile file;
67 String symbol; {
68     return dlsym(file,symbol);
69 }
70
71 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
72 String dll;
73 String symbol; {
74 #ifdef RTLD_NOW
75     ObjectFile instance = dlopen(dll,RTLD_NOW);
76 #elif defined RTLD_LAZY /* eg SunOS4 doesn't have RTLD_NOW */
77     ObjectFile instance = dlopen(dll,RTLD_LAZY);
78 #else /* eg FreeBSD doesn't have RTLD_LAZY */
79     ObjectFile instance = dlopen(dll,1);
80 #endif
81     void *sym;
82
83     if (NULL == instance) {
84         ERRMSG(0) "Error while importing DLL \"%s\":\n%s\n", dll, dlerror()
85         EEND;
86     }
87     if ((sym = dlsym(instance,symbol)))
88         return sym;
89
90     ERRMSG(0) "Error loading sym:\n%s\n", dlerror()
91     EEND;
92 }
93
94 #elif HAVE_DL_H /* eg HPUX */
95
96 #include <dl.h>
97
98 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
99 String dll;
100 String symbol; {
101     ObjectFile instance = shl_load(dll,BIND_IMMEDIATE,0L);
102     void* r;
103     if (NULL == instance) {
104         ERRMSG(0) "Error while importing DLL \"%s\"", dll
105         EEND;
106     }
107     return (0 == shl_findsym(&instance,symbol,TYPE_PROCEDURE,&r)) ? r : 0;
108 }
109
110 #else /* Dynamic loading not available */
111
112 void* getDLLSymbol(dll,symbol)  /* load dll and lookup symbol */
113 String dll;
114 String symbol; {
115 #if 1 /* very little to choose between these options */
116     return 0;
117 #else
118     ERRMSG(0) "This Hugs build does not support dynamic loading\n"
119     EEND;
120 #endif
121 }
122
123 #endif /* Dynamic loading not available */
124