/* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.123 2003/06/26 20:48:59 panne Exp $
+ * $Id: Linker.c,v 1.134 2003/09/26 09:26:12 panne Exp $
*
* (c) The GHC Team, 2000-2003
*
#include <sys/mman.h>
#endif
-#if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS) || defined(netbsd_TARGET_OS)
+#if defined(linux_TARGET_OS) || defined(solaris2_TARGET_OS) || defined(freebsd_TARGET_OS) || defined(netbsd_TARGET_OS) || defined(openbsd_TARGET_OS)
# define OBJFORMAT_ELF
#elif defined(cygwin32_TARGET_OS) || defined (mingw32_TARGET_OS)
# define OBJFORMAT_PEi386
# include <mach-o/loader.h>
# include <mach-o/nlist.h>
# include <mach-o/reloc.h>
+# include <mach-o/dyld.h>
#endif
/* Hash table mapping symbol names to Symbol */
SymX(divModIntegerzh_fast) \
SymX(forkzh_fast) \
SymX(forkProcesszh_fast) \
+ SymX(forkOS_createThread) \
SymX(freeHaskellFunctionPtr) \
SymX(freeStablePtr) \
SymX(gcdIntegerzh_fast) \
SymX(gcdIntegerIntzh_fast) \
SymX(gcdIntzh_fast) \
+ SymX(genSymZh) \
SymX(getProgArgv) \
SymX(getStablePtr) \
SymX(int2Integerzh_fast) \
SymX(integer2Intzh_fast) \
SymX(integer2Wordzh_fast) \
+ SymX(isCurrentThreadBoundzh_fast) \
SymX(isDoubleDenormalized) \
SymX(isDoubleInfinite) \
SymX(isDoubleNaN) \
SymX(quotIntegerzh_fast) \
SymX(quotRemIntegerzh_fast) \
SymX(raisezh_fast) \
+ SymX(raiseIOzh_fast) \
SymX(remIntegerzh_fast) \
SymX(resetNonBlockingFd) \
SymX(resumeThread) \
SymX(rts_eval) \
SymX(rts_evalIO) \
SymX(rts_evalLazyIO) \
+ SymX(rts_evalStableIO) \
SymX(rts_eval_) \
SymX(rts_getBool) \
SymX(rts_getChar) \
SymX(rts_mkWord64) \
SymX(rts_mkWord8) \
SymX(rts_unlock) \
+ SymX(rtsSupportsBoundThreads) \
SymX(run_queue_hd) \
+ SymX(__hscore_get_saved_termios) \
+ SymX(__hscore_set_saved_termios) \
SymX(setProgArgv) \
SymX(startupHaskell) \
SymX(shutdownHaskell) \
SymX(stable_ptr_table) \
SymX(stackOverflow) \
SymX(stg_CAF_BLACKHOLE_info) \
+ SymX(stg_BLACKHOLE_BQ_info) \
+ SymX(awakenBlockedQueue) \
SymX(stg_CHARLIKE_closure) \
SymX(stg_EMPTY_MVAR_info) \
SymX(stg_IND_STATIC_info) \
initLinker();
+#if !defined(openbsd_TARGET_OS)
hdl= dlopen(dll_name, RTLD_NOW | RTLD_GLOBAL);
+#else
+ hdl= dlopen(dll_name, RTLD_LAZY);
+#endif
if (hdl == NULL) {
/* dlopen failed; return a ptr to the error msg. */
errmsg = dlerror();
val = lookupStrHashTable(symhash, lbl);
if (val == NULL) {
-# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
+# if defined(OBJFORMAT_ELF)
return dlsym(dl_prog_handle, lbl);
+# elif defined(OBJFORMAT_MACHO)
+ if(NSIsSymbolNameDefined(lbl)) {
+ NSSymbol symbol = NSLookupAndBindSymbol(lbl);
+ return NSAddressOfSymbol(symbol);
+ } else {
+ return NULL;
+ }
# elif defined(OBJFORMAT_PEi386)
OpenedDLL* o_dll;
void* sym;
# define ELF_TARGET_SPARC /* Used inside <elf.h> */
#elif defined(i386_TARGET_ARCH)
# define ELF_TARGET_386 /* Used inside <elf.h> */
+#elif defined(x86_64_TARGET_ARCH)
+# define ELF_TARGET_X64_64
+# define ELF_64BIT
#elif defined (ia64_TARGET_ARCH)
# define ELF_TARGET_IA64 /* Used inside <elf.h> */
# define ELF_64BIT
# define ELF_NEED_PLT /* needs Procedure Linkage Tables */
#endif
+#if !defined(openbsd_TARGET_OS)
#include <elf.h>
+#else
+/* openbsd elf has things in different places, with diff names */
+#include <elf_abi.h>
+#include <machine/reloc.h>
+#define R_386_32 RELOC_32
+#define R_386_PC32 RELOC_PC32
+#endif
/*
* Define a set of types which can be used for both ELF32 and ELF64
return 0;
}
ASSERT(addr);
+ checkProddableBlock(oc,((void**)(image + sect->offset)) + i);
((void**)(image + sect->offset))[i] = addr;
}
return 1;
}
-static int relocateSection(char *image,
+static int relocateSection(
+ ObjectCode* oc,
+ char *image,
struct symtab_command *symLC, struct nlist *nlist,
struct section* sections, struct section *sect)
{
{
unsigned long* word = (unsigned long*) (image + sect->offset + scat->r_address);
+ checkProddableBlock(oc,word);
*word = scat->r_value + sect->offset + ((long) image);
}
}
unsigned long word = 0;
unsigned long* wordPtr = (unsigned long*) (image + sect->offset + reloc->r_address);
+ checkProddableBlock(oc,wordPtr);
if(reloc->r_type == GENERIC_RELOC_VANILLA)
{
addSection(oc, SECTIONKIND_RWDATA,
(void*) (image + sections[i].offset),
(void*) (image + sections[i].offset + sections[i].size));
+
+ if(sections[i].size > 0) // size 0 segments do exist
+ addProddableBlock(oc, (void*) (image + sections[i].offset),
+ sections[i].size);
}
// count external symbols defined here
for(i=0;i<segLC->nsects;i++)
{
- if(!relocateSection(image,symLC,nlist,sections,§ions[i]))
+ if(!relocateSection(oc,image,symLC,nlist,sections,§ions[i]))
return 0;
}