X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FLinker.c;h=933f4dd5d5aac84c73383ab3ea83a7fada3ca301;hb=52589e05f86d593bc3e6ea3f1a0b8f6ceae94fe6;hp=92d0106def244ff1cfeb60f55c9203363bcaac61;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1;p=ghc-hetmet.git diff --git a/rts/Linker.c b/rts/Linker.c index 92d0106..933f4dd 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -27,6 +27,7 @@ #include "Schedule.h" #include "Storage.h" #include "Sparks.h" +#include "RtsTypeable.h" #ifdef HAVE_SYS_TYPES_H #include @@ -92,6 +93,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 +334,7 @@ typedef struct _RtsSymbolVal { Sym(mktime) \ Sym(_imp___timezone) \ Sym(_imp___tzname) \ + Sym(_imp__tzname) \ Sym(_imp___iob) \ Sym(_imp___osver) \ Sym(localtime) \ @@ -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. */ @@ -852,6 +958,7 @@ initLinker( void ) linker_init_done = 1; } + stablehash = allocStrHashTable(); symhash = allocStrHashTable(); /* populate the symbol table with stuff from the RTS */ @@ -989,6 +1096,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 * @@ -2157,6 +2284,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; @@ -2785,6 +2914,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 +3266,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 +3286,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);