/* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.40 2001/05/15 15:29:03 sewardj Exp $
+ * $Id: Linker.c,v 1.47 2001/06/28 14:26:58 sewardj Exp $
*
* (c) The GHC Team, 2000
*
#else
#define RTS_POSIX_ONLY_SYMBOLS
+
+/* These are statically linked from the mingw libraries into the ghc
+ executable, so we have to employ this hack. */
#define RTS_MINGW_ONLY_SYMBOLS \
- Sym(mktime) \
- Sym(gmtime) \
- Sym(strftime) \
- Sym(localtime) \
- SymX(getenv) \
- SymX(rename) \
- Sym(opendir) \
- Sym(readdir) \
- Sym(closedir) \
- Sym(PrelHandle_stderr_closure) \
- Sym(Main_main_closure) \
- Sym(__init_Main) \
+ SymX(inet_ntoa) \
+ SymX(inet_addr) \
+ SymX(htonl) \
+ SymX(recvfrom) \
+ SymX(listen) \
+ SymX(bind) \
+ SymX(shutdown) \
+ SymX(connect) \
+ SymX(htons) \
+ SymX(ntohs) \
+ SymX(getservbyname) \
+ SymX(getservbyport) \
+ SymX(getprotobynumber) \
+ SymX(getprotobyname) \
+ SymX(gethostbyname) \
+ SymX(gethostbyaddr) \
+ SymX(gethostname) \
+ SymX(strcpy) \
+ SymX(strncpy) \
+ SymX(abort) \
+ Sym(_alloca) \
+ Sym(isxdigit) \
+ Sym(isupper) \
+ Sym(ispunct) \
+ Sym(islower) \
+ Sym(isspace) \
+ Sym(isprint) \
+ Sym(isdigit) \
+ Sym(iscntrl) \
+ Sym(isalpha) \
+ Sym(isalnum) \
+ SymX(strcmp) \
+ SymX(memmove) \
+ SymX(realloc) \
+ SymX(malloc) \
SymX(pow) \
SymX(tanh) \
SymX(cosh) \
SymX(exp) \
SymX(log) \
SymX(sqrt) \
- SymX(Sleep) \
- SymX(system) \
- SymX(memchr) \
SymX(memcpy) \
- SymX(memmove) \
- SymX(fprintf) \
- Sym(_imp___iob) \
- Sym(_imp___tzname) \
+ Sym(mktime) \
Sym(_imp___timezone) \
- Sym(__udivdi3) \
- SymX(GetProcessTimes) \
- SymX(GetCurrentProcess) \
- SymX(send) \
- SymX(recv) \
- SymX(malloc) \
+ Sym(_imp___tzname) \
+ Sym(localtime) \
+ Sym(gmtime) \
+ SymX(getenv) \
SymX(free) \
- SymX(realloc) \
- SymX(_errno) \
- SymX(closesocket)
+ SymX(rename) \
+ Sym(opendir) \
+ Sym(readdir) \
+ Sym(closedir) \
+ SymX(GetCurrentProcess) \
+ SymX(GetProcessTimes) \
+ SymX(CloseHandle) \
+ SymX(GetExitCodeProcess) \
+ SymX(WaitForSingleObject) \
+ SymX(CreateProcessA) \
+ SymX(_errno)
#endif
Sym(stg_gc_f1) \
Sym(stg_gc_ut_1_0) \
Sym(stg_gc_ut_0_1) \
+ Sym(stg_gc_unpt_r1) \
Sym(stg_gc_unbx_r1) \
Sym(stg_chk_0) \
Sym(stg_chk_1) \
typedef
struct _OpenedDLL {
+ char* name;
struct _OpenedDLL* next;
HINSTANCE instance;
}
char*
-addDLL ( char* dll_name )
+addDLL ( char* path, char* dll_name )
{
# if defined(OBJFORMAT_ELF)
void *hdl;
char *buf;
char *errmsg;
- buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
- sprintf(buf, "lib%s.so", dll_name);
+ if (path == NULL || strlen(path) == 0) {
+ buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
+ sprintf(buf, "lib%s.so", dll_name);
+ } else {
+ buf = stgMallocBytes(strlen(path) + 1 + strlen(dll_name) + 10, "addDll");
+ sprintf(buf, "%s/lib%s.so", path, dll_name);
+ }
hdl = dlopen(buf, RTLD_NOW | RTLD_GLOBAL );
free(buf);
if (hdl == NULL) {
} else {
return NULL;
}
- ASSERT(0); /*NOTREACHED*/
+ /*NOTREACHED*/
+
# elif defined(OBJFORMAT_PEi386)
- HINSTANCE instance;
- char* buf;
- char* errmsg;
+ /* Add this DLL to the list of DLLs in which to search for symbols.
+ The path argument is ignored. */
+ char* buf;
OpenedDLL* o_dll;
+ HINSTANCE instance;
- /* fprintf(stderr, "addDLL %s\n", dll_name ); */
- buf = stgMallocBytes(strlen(dll_name) + 10, "addDll");
+ /* fprintf(stderr, "\naddDLL; path=`%s', dll_name = `%s'\n", path, dll_name); */
+
+ /* See if we've already got it, and ignore if so. */
+ for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
+ if (0 == strcmp(o_dll->name, dll_name))
+ return NULL;
+ }
+
+ buf = stgMallocBytes(strlen(dll_name) + 10, "addDLL");
sprintf(buf, "%s.DLL", dll_name);
instance = LoadLibrary(buf);
free(buf);
if (instance == NULL) {
/* LoadLibrary failed; return a ptr to the error msg. */
- errmsg = "addDLL: unknown error";
- return errmsg;
+ return "addDLL: unknown error";
}
o_dll = stgMallocBytes( sizeof(OpenedDLL), "addDLL" );
+ o_dll->name = stgMallocBytes(1+strlen(dll_name), "addDLL");
+ strcpy(o_dll->name, dll_name);
o_dll->instance = instance;
- o_dll->next = opened_dlls;
- opened_dlls = o_dll;
+ o_dll->next = opened_dlls;
+ opened_dlls = o_dll;
return NULL;
# else
# elif defined(OBJFORMAT_PEi386)
OpenedDLL* o_dll;
void* sym;
- ASSERT(2+2 == 5);
for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
+ /* fprintf(stderr, "look in %s for %s\n", o_dll->name, lbl); */
sym = GetProcAddress(o_dll->instance, lbl);
if (sym != NULL) return sym;
}
COFF_section* sectab;
COFF_symbol* symtab;
UChar* strtab;
-
+ /* fprintf(stderr, "\nLOADING %s\n", oc->fileName); */
hdr = (COFF_header*)(oc->image);
sectab = (COFF_section*) (
((UChar*)(oc->image))
addr = ((UChar*)(oc->image))
+ (sectabent->PointerToRawData
+ symtab_i->Value);
+ /* fprintf(stderr,"addSymbol %p `%s'\n", addr,sname); */
IF_DEBUG(linker, belch("addSymbol %p `%s'\n", addr,sname);)
ASSERT(i >= 0 && i < oc->n_symbols);
oc->symbols[i] = sname;
COFF_section* sectab_i
= (COFF_section*)
myindex ( sizeof_COFF_section, sectab, i );
- IF_DEBUG(linker, belchf("section name = %s\n", sectab_i->Name ));
+ IF_DEBUG(linker, belch("section name = %s\n", sectab_i->Name ));
#if 0
/* I'm sure this is the Right Way to do it. However, the