Fixed uninitialised FunBind fun_tick field
[ghc-hetmet.git] / rts / Linker.c
index 3cfd2a8..d0c120b 100644 (file)
@@ -10,7 +10,7 @@
 #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__
@@ -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 <sys/types.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 */
@@ -333,6 +330,7 @@ typedef struct _RtsSymbolVal {
       Sym(mktime)                               \
       Sym(_imp___timezone)                      \
       Sym(_imp___tzname)                        \
+      Sym(_imp__tzname)                         \
       Sym(_imp___iob)                           \
       Sym(_imp___osver)                         \
       Sym(localtime)                            \
@@ -404,7 +402,11 @@ typedef struct _RtsSymbolVal {
 #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
@@ -486,6 +488,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)                  \
@@ -507,6 +510,7 @@ typedef struct _RtsSymbolVal {
       SymX(forkOS_createThread)                        \
       SymX(freeHaskellFunctionPtr)             \
       SymX(freeStablePtr)                      \
+      SymX(getOrSetTypeableStore)              \
       SymX(gcdIntegerzh_fast)                  \
       SymX(gcdIntegerIntzh_fast)               \
       SymX(gcdIntzh_fast)                      \
@@ -522,6 +526,8 @@ typedef struct _RtsSymbolVal {
       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)                        \
@@ -540,6 +546,7 @@ typedef struct _RtsSymbolVal {
       SymX(insertStableSymbol)                         \
       SymX(insertSymbol)                       \
       SymX(lookupSymbol)                       \
+      SymX(lookupDataCon)                      \
       SymX(makeStablePtrzh_fast)               \
       SymX(minusIntegerzh_fast)                        \
       SymX(mkApUpd0zh_fast)                    \
@@ -794,6 +801,7 @@ static RtsSymbolVal rtsSyms[] = {
       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,
@@ -805,97 +813,12 @@ static RtsSymbolVal rtsSyms[] = {
 };
 
 
-/* -----------------------------------------------------------------------------
- * 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;
-}
-
-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);
-}
-
-
-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,
@@ -905,6 +828,15 @@ static void ghciInsertStrHashTable ( char* obj_name,
    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(
@@ -925,8 +857,6 @@ static void ghciInsertStrHashTable ( char* obj_name,
    );
    exit(1);
 }
-
-
 /* -----------------------------------------------------------------------------
  * initialize the object linker
  */
@@ -938,11 +868,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 )
 {
@@ -957,6 +882,9 @@ initLinker( void )
 
     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++) {
@@ -972,9 +900,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
 }
@@ -1125,10 +1050,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;
@@ -1138,7 +1060,7 @@ lookupSymbol( char *lbl )
        } else {
            return val;
        }
-#      else /* not openbsd */
+#      else
        return dlsym(dl_prog_handle, lbl);
 #      endif
 #       elif defined(OBJFORMAT_MACHO)
@@ -1181,6 +1103,24 @@ lookupSymbol( char *lbl )
     }
 }
 
+#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 *
@@ -1258,13 +1198,12 @@ loadObj( char *path )
    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;
@@ -1354,7 +1293,7 @@ loadObj( char *path )
 #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);
@@ -1368,7 +1307,12 @@ loadObj( char *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
@@ -1378,15 +1322,12 @@ loadObj( char *path )
     // 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);
@@ -1499,9 +1440,13 @@ unloadObj( char *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);
@@ -1576,7 +1521,7 @@ static void addSection ( ObjectCode* oc, SectionKind kind,
 
 /*
   ocAllocateJumpIslands
-  
+
   Allocate additional space at the end of the object file image to make room
   for jump islands.
   
@@ -2281,6 +2226,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;
@@ -2498,14 +2445,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);
@@ -3289,7 +3236,6 @@ do_Elf_Rel_relocations ( ObjectCode* oc, char* ehdrC,
               S = (Elf_Addr)S_tmp;
             } else {
               stableVal = deRefStablePtr( stablePtr );
-              addRootObject((void*)P);
               S_tmp = stableVal;
               S = (Elf_Addr)S_tmp;
             }
@@ -4450,3 +4396,18 @@ static int machoGetMisalignment( FILE * f )
 }
 
 #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;
+  }