#include "PosixSource.h"
#endif
-/* Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h> and
+/* Linux needs _GNU_SOURCE to get RTLD_DEFAULT from <dlfcn.h> and
MREMAP_MAYMOVE from <sys/mman.h>.
*/
#ifdef __linux__
#include "LinkerInternals.h"
#include "RtsUtils.h"
#include "Schedule.h"
-#include "Storage.h"
#include "Sparks.h"
#include "RtsTypeable.h"
/* 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;
+#if defined(DEBUGGER)
+/* Hash table mapping info table ptrs to DataCon names */
+static HashTable *dchash;
+#endif
/* List of currently loaded objects */
ObjectCode *objects = NULL; /* initially empty */
#define RTS_USER_SIGNALS_SYMBOLS \
SymX(setIOManagerPipe)
#else
-#define RTS_USER_SIGNALS_SYMBOLS /* nothing */
+#define RTS_USER_SIGNALS_SYMBOLS \
+ SymX(sendIOManagerEvent) \
+ SymX(readIOManagerEvent) \
+ SymX(getIOManagerEvent) \
+ SymX(console_handler)
#endif
#ifdef TABLES_NEXT_TO_CODE
SymX(catchzh_fast) \
SymX(catchRetryzh_fast) \
SymX(catchSTMzh_fast) \
+ SymX(checkzh_fast) \
SymX(closure_flags) \
SymX(cmp_thread) \
SymX(cmpIntegerzh_fast) \
SymX(hs_free_stable_ptr) \
SymX(hs_free_fun_ptr) \
SymX(initLinker) \
+ SymX(infoPtrzh_fast) \
+ SymX(closurePayloadzh_fast) \
SymX(int2Integerzh_fast) \
SymX(integer2Intzh_fast) \
SymX(integer2Wordzh_fast) \
SymX(insertStableSymbol) \
SymX(insertSymbol) \
SymX(lookupSymbol) \
+ SymX(lookupDataCon) \
SymX(makeStablePtrzh_fast) \
SymX(minusIntegerzh_fast) \
SymX(mkApUpd0zh_fast) \
RTS_POSIX_ONLY_SYMBOLS
RTS_MINGW_ONLY_SYMBOLS
RTS_CYGWIN_ONLY_SYMBOLS
+ RTS_DARWIN_ONLY_SYMBOLS
RTS_LIBGCC_SYMBOLS
#if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
// dyld stub code contains references to this,
};
-/* -----------------------------------------------------------------------------
- * 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.
*/
+int isSuffixOf(char* x, char* suffix);
+
static void ghciInsertStrHashTable ( char* obj_name,
HashTable *table,
char* key,
if (lookupHashTable(table, (StgWord)key) == NULL)
{
insertStrHashTable(table, (StgWord)key, data);
+#if defined(DEBUGGER)
+ // Insert the reverse pair in the datacon hash if it is a closure
+ {
+ if(isSuffixOf(key, "static_info") || isSuffixOf(key, "con_info")) {
+ insertHashTable(dchash, (StgWord)data, key);
+ // debugBelch("DChash addSymbol: %s (%p)\n", key, data);
+ }
+ }
+#endif
return;
}
debugBelch(
);
exit(1);
}
-
-
/* -----------------------------------------------------------------------------
* initialize the object linker
*/
stablehash = allocStrHashTable();
symhash = allocStrHashTable();
+#if defined(DEBUGGER)
+ dchash = allocHashTable();
+#endif
/* populate the symbol table with stuff from the RTS */
for (sym = rtsSyms; sym->lbl != NULL; sym++) {
}
}
+#if defined(DEBUGGER)
+char *
+lookupDataCon( StgWord addr )
+{
+ void *val;
+ initLinker() ;
+ ASSERT(dchash != NULL);
+ val = lookupHashTable(dchash, addr);
+
+ return val;
+}
+#else
+char* lookupDataCon( StgWord addr )
+{
+ return NULL;
+}
+#endif
+
static
__attribute((unused))
void *
void *map_addr = NULL;
#else
FILE *f;
- int misalignment;
#endif
initLinker();
/* debugBelch("loadObj %s\n", path ); */
- /* Check that we haven't already loaded this object.
+ /* Check that we haven't already loaded this object.
Ignore requests to load multiple times */
{
ObjectCode *o;
#define EXTRA_MAP_FLAGS 0
#endif
- oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
+ oc->image = mmap(map_addr, n, PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_PRIVATE|EXTRA_MAP_FLAGS, fd, 0);
if (oc->image == MAP_FAILED)
barf("loadObj: can't map `%s'", path);
if (!f)
barf("loadObj: can't read `%s'", path);
-#ifdef darwin_HOST_OS
+# if defined(mingw32_HOST_OS)
+ // TODO: We would like to use allocateExec here, but allocateExec
+ // cannot currently allocate blocks large enough.
+ oc->image = VirtualAlloc(NULL, oc->fileSize, MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+# elif defined(darwin_HOST_OS)
// In a Mach-O .o file, all sections can and will be misaligned
// if the total size of the headers is not a multiple of the
// desired alignment. This is fine for .o files that only serve
// We calculate the correct alignment from the header before
// reading the file, and then we misalign oc->image on purpose so
// that the actual sections end up aligned again.
- misalignment = machoGetMisalignment(f);
- oc->misalignment = misalignment;
-#else
- misalignment = 0;
-#endif
+ oc->misalignment = machoGetMisalignment(f);
+ oc->image = stgMallocBytes(oc->fileSize + oc->misalignment, "loadObj(image)");
+# else
+ oc->image = stgMallocBytes(oc->fileSize, "loadObj(image)");
+# endif
- oc->image = stgMallocBytes(oc->fileSize + misalignment, "loadObj(image)");
- oc->image += misalignment;
-
n = fread ( oc->image, 1, oc->fileSize, f );
if (n != oc->fileSize)
barf("loadObj: error whilst reading `%s'", path);
prev->next = oc->next;
}
- /* We're going to leave this in place, in case there are
- any pointers from the heap into it: */
- /* stgFree(oc->image); */
+ // We're going to leave this in place, in case there are
+ // any pointers from the heap into it:
+ // #ifdef mingw32_HOST_OS
+ // VirtualFree(oc->image);
+ // #else
+ // stgFree(oc->image);
+ // #endif
stgFree(oc->fileName);
stgFree(oc->symbols);
stgFree(oc->sections);
/*
ocAllocateJumpIslands
-
+
Allocate additional space at the end of the object file image to make room
for jump islands.
S = (Elf_Addr)S_tmp;
} else {
stableVal = deRefStablePtr( stablePtr );
- addRootObject((void*)P);
S_tmp = stableVal;
S = (Elf_Addr)S_tmp;
}
}
#endif
+
+int isSuffixOf(char* x, char* suffix) {
+ int suffix_len = strlen (suffix);
+ int x_len = strlen (x);
+
+ if (x_len == 0)
+ return 0;
+ if (suffix_len > x_len)
+ return 0;
+ if (suffix_len == 0)
+ return 1;
+
+ char* x_suffix = &x[strlen(x)-strlen(suffix)];
+ return strcmp(x_suffix, suffix) == 0;
+ }