X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FLinker.c;h=53def900f0800b89239e50f7c7ebbde53206d4d0;hb=fe07f054d7ae5e10b14d5fed730fe4424dabd587;hp=92d0106def244ff1cfeb60f55c9203363bcaac61;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/rts/Linker.c b/rts/Linker.c index 92d0106..53def90 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -25,8 +25,8 @@ #include "LinkerInternals.h" #include "RtsUtils.h" #include "Schedule.h" -#include "Storage.h" #include "Sparks.h" +#include "RtsTypeable.h" #ifdef HAVE_SYS_TYPES_H #include @@ -92,6 +92,17 @@ /* Hash table mapping symbol names to Symbol */ static /*Str*/HashTable *symhash; +typedef struct { + void *addr; +} rootEntry; + +/* Hash table mapping symbol names to StgStablePtr */ +static /*Str*/HashTable *stablehash; +rootEntry *root_ptr_table = NULL; +static rootEntry *root_ptr_free = NULL; + +static unsigned int RPT_size = 0; + /* List of currently loaded objects */ ObjectCode *objects = NULL; /* initially empty */ @@ -322,6 +333,7 @@ typedef struct _RtsSymbolVal { Sym(mktime) \ Sym(_imp___timezone) \ Sym(_imp___tzname) \ + Sym(_imp__tzname) \ Sym(_imp___iob) \ Sym(_imp___osver) \ Sym(localtime) \ @@ -475,6 +487,7 @@ typedef struct _RtsSymbolVal { SymX(catchzh_fast) \ SymX(catchRetryzh_fast) \ SymX(catchSTMzh_fast) \ + SymX(checkzh_fast) \ SymX(closure_flags) \ SymX(cmp_thread) \ SymX(cmpIntegerzh_fast) \ @@ -496,6 +509,7 @@ typedef struct _RtsSymbolVal { SymX(forkOS_createThread) \ SymX(freeHaskellFunctionPtr) \ SymX(freeStablePtr) \ + SymX(getOrSetTypeableStore) \ SymX(gcdIntegerzh_fast) \ SymX(gcdIntegerIntzh_fast) \ SymX(gcdIntzh_fast) \ @@ -526,6 +540,8 @@ typedef struct _RtsSymbolVal { SymX(isFloatNegativeZero) \ SymX(killThreadzh_fast) \ SymX(loadObj) \ + SymX(insertStableSymbol) \ + SymX(insertSymbol) \ SymX(lookupSymbol) \ SymX(makeStablePtrzh_fast) \ SymX(minusIntegerzh_fast) \ @@ -694,7 +710,8 @@ typedef struct _RtsSymbolVal { SymX(stg_interp_constr6_entry) \ SymX(stg_interp_constr7_entry) \ SymX(stg_interp_constr8_entry) \ - SymX(stgMallocBytesRWX) \ + SymX(allocateExec) \ + SymX(freeExec) \ SymX(getAllocations) \ SymX(revertCAFs) \ SymX(RtsFlags) \ @@ -790,6 +807,95 @@ static RtsSymbolVal rtsSyms[] = { { 0, 0 } /* sentinel */ }; + +/* ----------------------------------------------------------------------------- + * Utilities for handling root pointers. + * -------------------------------------------------------------------------- */ + + +#define INIT_RPT_SIZE 64 + +STATIC_INLINE void +initFreeList(rootEntry *table, nat n, rootEntry *free) +{ + rootEntry *p; + + for (p = table + n - 1; p >= table; p--) { + p->addr = (P_)free; + free = p; + } + root_ptr_free = table; +} + +static void +initRootPtrTable(void) +{ + if (RPT_size > 0) + return; + + RPT_size = INIT_RPT_SIZE; + root_ptr_table = stgMallocBytes(RPT_size * sizeof(rootEntry), + "initRootPtrTable"); + + initFreeList(root_ptr_table,INIT_RPT_SIZE,NULL); +} + + +static void +enlargeRootPtrTable(void) +{ + nat old_RPT_size = RPT_size; + + // 2nd and subsequent times + RPT_size *= 2; + root_ptr_table = + stgReallocBytes(root_ptr_table, + RPT_size * sizeof(rootEntry), + "enlargeRootPtrTable"); + + initFreeList(root_ptr_table + old_RPT_size, old_RPT_size, NULL); +} + +static void +addRootObject(void *addr) +{ + StgWord rt; + initRootPtrTable(); + if (root_ptr_free == NULL) { + enlargeRootPtrTable(); + } + + rt = root_ptr_free - root_ptr_table; + root_ptr_free = (rootEntry*)(root_ptr_free->addr); + root_ptr_table[rt].addr = addr; +} + +/* ----------------------------------------------------------------------------- + * Treat root pointers as roots for the garbage collector. + * -------------------------------------------------------------------------- */ + +void +markRootPtrTable(evac_fn evac) +{ + rootEntry *p, *end_root_ptr_table; + StgPtr q; + + end_root_ptr_table = &root_ptr_table[RPT_size]; + + for (p = root_ptr_table; p < end_root_ptr_table; p++) { + q = p->addr; + + if (q && (q < (P_)root_ptr_table || q >= (P_)end_root_ptr_table)) { + evac((StgClosure **)p->addr); + } + } +} + +/* ----------------------------------------------------------------------------- + * End of utilities for handling root pointers. + * -------------------------------------------------------------------------- */ + + /* ----------------------------------------------------------------------------- * Insert symbols into hash tables, checking for duplicates. */ @@ -835,11 +941,6 @@ static int linker_init_done = 0 ; static void *dl_prog_handle; #endif -/* dlopen(NULL,..) doesn't work so we grab libc explicitly */ -#if defined(openbsd_HOST_OS) -static void *dl_libc_handle; -#endif - void initLinker( void ) { @@ -852,6 +953,7 @@ initLinker( void ) linker_init_done = 1; } + stablehash = allocStrHashTable(); symhash = allocStrHashTable(); /* populate the symbol table with stuff from the RTS */ @@ -868,9 +970,6 @@ initLinker( void ) dl_prog_handle = RTLD_DEFAULT; # else dl_prog_handle = dlopen(NULL, RTLD_LAZY); -# if defined(openbsd_HOST_OS) - dl_libc_handle = dlopen("libc.so", RTLD_LAZY); -# endif # endif /* RTLD_DEFAULT */ # endif } @@ -989,6 +1088,26 @@ addDLL( char *dll_name ) } /* ----------------------------------------------------------------------------- + * insert a stable symbol in the hash table + */ + +void +insertStableSymbol(char* obj_name, char* key, StgPtr p) +{ + ghciInsertStrHashTable(obj_name, stablehash, key, getStablePtr(p)); +} + + +/* ----------------------------------------------------------------------------- + * insert a symbol in the hash table + */ +void +insertSymbol(char* obj_name, char* key, void* data) +{ + ghciInsertStrHashTable(obj_name, symhash, key, data); +} + +/* ----------------------------------------------------------------------------- * lookup a symbol in the hash table */ void * @@ -1001,10 +1120,7 @@ lookupSymbol( char *lbl ) if (val == NULL) { # if defined(OBJFORMAT_ELF) -# if defined(openbsd_HOST_OS) - val = dlsym(dl_prog_handle, lbl); - return (val != NULL) ? val : dlsym(dl_libc_handle,lbl); -# elif defined(x86_64_HOST_ARCH) +# if defined(x86_64_HOST_ARCH) val = dlsym(dl_prog_handle, lbl); if (val >= (void *)0x80000000) { void *new_val; @@ -1014,7 +1130,7 @@ lookupSymbol( char *lbl ) } else { return val; } -# else /* not openbsd */ +# else return dlsym(dl_prog_handle, lbl); # endif # elif defined(OBJFORMAT_MACHO) @@ -2157,6 +2273,8 @@ ocGetNames_PEi386 ( ObjectCode* oc ) && 0 != strcmp(".stabstr", sectab_i->Name) /* ignore constructor section for now */ && 0 != strcmp(".ctors", sectab_i->Name) + /* ignore section generated from .ident */ + && 0!= strcmp("/4", sectab_i->Name) ) { errorBelch("Unknown PEi386 section name `%s' (while processing: %s)", sectab_i->Name, oc->fileName); return 0; @@ -2374,14 +2492,14 @@ ocResolve_PEi386 ( ObjectCode* oc ) + sym->Value); } else { copyName ( sym->Name, strtab, symbol, 1000-1 ); - (void*)S = lookupLocalSymbol( oc, symbol ); + S = (UInt32) lookupLocalSymbol( oc, symbol ); if ((void*)S != NULL) goto foundit; - (void*)S = lookupSymbol( symbol ); + S = (UInt32) lookupSymbol( symbol ); if ((void*)S != NULL) goto foundit; zapTrailingAtSign ( symbol ); - (void*)S = lookupLocalSymbol( oc, symbol ); + S = (UInt32) lookupLocalSymbol( oc, symbol ); if ((void*)S != NULL) goto foundit; - (void*)S = lookupSymbol( symbol ); + S = (UInt32) lookupSymbol( symbol ); if ((void*)S != NULL) goto foundit; /* Newline first because the interactive linker has printed "linking..." */ errorBelch("\n%s: unknown symbol `%s'", oc->fileName, symbol); @@ -2785,6 +2903,9 @@ ocVerifyImage_ELF ( ObjectCode* oc ) IF_DEBUG(linker,debugBelch( "Architecture is " )); switch (ehdr->e_machine) { case EM_386: IF_DEBUG(linker,debugBelch( "x86" )); break; +#ifdef EM_SPARC32PLUS + case EM_SPARC32PLUS: +#endif case EM_SPARC: IF_DEBUG(linker,debugBelch( "sparc" )); break; #ifdef EM_IA_64 case EM_IA_64: IF_DEBUG(linker,debugBelch( "ia64" )); break; @@ -3134,6 +3255,8 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, Elf_Addr S; void* S_tmp; Elf_Addr value; + StgStablePtr stablePtr; + StgPtr stableVal; IF_DEBUG(linker,debugBelch( "Rel entry %3d is raw(%6p %6p)", j, (void*)offset, (void*)info )); @@ -3152,10 +3275,18 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC, + stab[ELF_R_SYM(info)].st_value); } else { - /* No, so look up the name in our global table. */ symbol = strtab + sym.st_name; - S_tmp = lookupSymbol( symbol ); - S = (Elf_Addr)S_tmp; + stablePtr = (StgStablePtr)lookupHashTable(stablehash, (StgWord)symbol); + if (NULL == stablePtr) { + /* No, so look up the name in our global table. */ + S_tmp = lookupSymbol( symbol ); + S = (Elf_Addr)S_tmp; + } else { + stableVal = deRefStablePtr( stablePtr ); + addRootObject((void*)P); + S_tmp = stableVal; + S = (Elf_Addr)S_tmp; + } } if (!S) { errorBelch("%s: unknown symbol `%s'", oc->fileName, symbol);