summaryrefslogtreecommitdiff
path: root/ghc/interpreter/dynamic.c
blob: 1b416ecd7686543cc72edb1563e98726c2bdfff8 (plain)
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
167
168
169

/* --------------------------------------------------------------------------
 * Dynamic loading (of .dll or .so files) for Hugs
 *
 * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
 * Yale Haskell Group, and the Oregon Graduate Institute of Science and
 * Technology, 1994-1999, All rights reserved.  It is distributed as
 * free software under the license in the file "License", which is
 * included in the distribution.
 *
 * $RCSfile: dynamic.c,v $
 * $Revision: 1.13 $
 * $Date: 1999/11/25 10:19:15 $
 * ------------------------------------------------------------------------*/

#include "prelude.h"
#include "storage.h"
#include "errors.h"
#include "dynamic.h"
#include "connect.h"

#if HAVE_WINDOWS_H && !defined(__MSDOS__)

#include <windows.h>

void* getDLLSymbol(line,dll0,symbol0) /* load dll and lookup symbol */
Int    line;
String dll0;
String symbol0; {
    void*      sym;
    char       dll[1000];
    char       symbol[100];
    ObjectFile instance;

    if (strlen(dll0) > 996-strlen(installDir)) {
       ERRMSG(line) "Excessively long library name:\n%s\n",dll0
       EEND;
    }
    dll[0] = 0;
    if (strcmp("nHandle",dll0)==0) strcat(dll,installDir);
    strcat(dll,dll0);
    strcat(dll, ".dll");

    if (strlen(symbol0) > 96) {
       ERRMSG(line) "Excessively long symbol name:\n%s\n",symbol0
       EEND;
    }
    strcpy(&(symbol[1]),symbol0); 
    symbol[0] = '_';

    instance = LoadLibrary(dll);
    if (NULL == instance) {
        /* GetLastError allegedly provides more detail - in practice,
	 * it tells you nothing more.
         */
        ERRMSG(line) "Can't open library \"%s\"", dll
        EEND;
    }
    sym = GetProcAddress(instance,symbol0);
    return sym;
}

Bool stdcallAllowed ( void )
{
   return TRUE;
}






#elif HAVE_DLFCN_H /* eg LINUX, SOLARIS, ULTRIX */

#include <stdio.h>
#include <dlfcn.h>

void* getDLLSymbol(line,dll0,symbol)  /* load dll and lookup symbol */
Int    line;
String dll0;
String symbol; {
    void*      sym;
    char       dll[1000];
    ObjectFile instance;
    if (strlen(dll0) > 996-strlen(installDir)) {
       ERRMSG(line) "Excessively long library name:\n%s\n",dll0
       EEND;
    }
    dll[0] = 0;
    if (strcmp("nHandle",dll0)==0) strcat(dll,installDir);
    strcat(dll,dll0);
    strcat(dll, ".so");
#ifdef RTLD_NOW
    instance = dlopen(dll,RTLD_NOW);
#elif defined RTLD_LAZY /* eg SunOS4 doesn't have RTLD_NOW */
    instance = dlopen(dll,RTLD_LAZY);
#else /* eg FreeBSD doesn't have RTLD_LAZY */
    instance = dlopen(dll,1);
#endif

    if (NULL == instance) {
	ERRMSG(line) "Can't open library \"%s\":\n      %s\n",dll,dlerror()
        EEND;
    }
    if ((sym = dlsym(instance,symbol)))
        return sym;

    ERRMSG(line) "Can't find symbol \"%s\" in library \"%s\"",symbol,dll
    EEND;
}

Bool stdcallAllowed ( void )
{
   return FALSE;
}






#elif HAVE_DL_H /* eg HPUX */

#include <dl.h>

void* getDLLSymbol(line,dll0,symbol)  /* load dll and lookup symbol */
Int    line;
String dll0;
String symbol; {
    ObjectFile instance = shl_load(dll,BIND_IMMEDIATE,0L);
    void* r;
    if (NULL == instance) {
        ERRMSG(line) "Error while importing DLL \"%s\"", dll0
        EEND;
    }
    return (0 == shl_findsym(&instance,symbol,TYPE_PROCEDURE,&r)) ? r : 0;
}

Bool stdcallAllowed ( void )
{
   return FALSE;
}






#else /* Dynamic loading not available */

void* getDLLSymbol(line,dll0,symbol)  /* load dll and lookup symbol */
Int    line;
String dll0;
String symbol; {
#if 1 /* very little to choose between these options */
    return 0;
#else
    ERRMSG(line) "This Hugs build does not support dynamic loading\n"
    EEND;
#endif
}

Bool stdcallAllowed ( void )
{
   return FALSE;
}

#endif /* Dynamic loading not available */