[project @ 2000-05-12 13:34:06 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / interface.c
index d0e753c..0da2db3 100644 (file)
@@ -7,25 +7,22 @@
  * Hugs version 1.4, December 1997
  *
  * $RCSfile: interface.c,v $
- * $Revision: 1.33 $
- * $Date: 2000/03/02 10:10:33 $
+ * $Revision: 1.58 $
+ * $Date: 2000/05/12 13:34:07 $
  * ------------------------------------------------------------------------*/
 
-#include "prelude.h"
+#include "hugsbasictypes.h"
 #include "storage.h"
-#include "backend.h"
 #include "connect.h"
 #include "errors.h"
-#include "link.h"
-#include "Assembler.h"  /* for wrapping GHC objects */
 #include "object.h"
 
+#include "Rts.h"       /* to make StgPtr visible in Assembler.h */
+#include "Assembler.h"  /* for wrapping GHC objects */
 
 /*#define DEBUG_IFACE*/
 #define VERBOSE FALSE
 
-extern void print ( Cell, Int );
-
 /* --------------------------------------------------------------------------
  * (This comment is now out of date.  JRS, 991216).
  * The "addGHC*" functions act as "impedence matchers" between GHC
@@ -121,54 +118,51 @@ viz, the entire Prelude at once:
  * local function prototypes:
  * ------------------------------------------------------------------------*/
 
-static Void startGHCValue       Args((Int,VarId,Type));
-static Void finishGHCValue      Args((VarId));
+static Void startGHCValue       ( Int,VarId,Type );
+static Void finishGHCValue      ( VarId );
 
-static Void startGHCSynonym     Args((Int,Cell,List,Type));
-static Void finishGHCSynonym    Args((Tycon)); 
+static Void startGHCSynonym     ( Int,Cell,List,Type );
+static Void finishGHCSynonym    ( Tycon ); 
 
-static Void  startGHCClass      Args((Int,List,Cell,List,List));
-static Class finishGHCClass     Args((Class)); 
+static Void  startGHCClass      ( Int,List,Cell,List,List );
+static Class finishGHCClass     ( Class ); 
 
-static Inst startGHCInstance    Args((Int,List,Pair,VarId));
-static Void finishGHCInstance   Args((Inst));
+static Inst startGHCInstance    ( Int,List,Pair,VarId );
+static Void finishGHCInstance   ( Inst );
 
-static Void startGHCImports     Args((ConId,List));
-static Void finishGHCImports    Args((ConId,List));
+static Void startGHCImports     ( ConId,List );
+static Void finishGHCImports    ( ConId,List );
 
-static Void startGHCExports     Args((ConId,List));
-static Void finishGHCExports    Args((ConId,List));
+static Void startGHCExports     ( ConId,List );
+static Void finishGHCExports    ( ConId,List );
 
 static Void finishGHCFixdecl    ( Cell prec, Cell assoc, ConVarId name );
 
-static Void finishGHCModule     Args((Cell));
-static Void startGHCModule      Args((Text, Int, Text));
+static Void finishGHCModule     ( Cell );
+static Void startGHCModule      ( Text );
 
-static Void startGHCDataDecl    Args((Int,List,Cell,List,List));
+static Void startGHCDataDecl    ( Int,List,Cell,List,List );
 static List finishGHCDataDecl   ( ConId tyc );
+/* Supporting stuff for {start|finish}GHCDataDecl */
+static List startGHCConstrs     ( Int,List,List );
+static Name startGHCSel         ( Int,Pair );
+static Name startGHCConstr      ( Int,Int,Triple );
 
-static Void startGHCNewType     Args((Int,List,Cell,List,Cell));
+static Void startGHCNewType     ( Int,List,Cell,List,Cell );
 static Void finishGHCNewType    ( ConId tyc );
 
 
-/* Supporting stuff for {start|finish}GHCDataDecl */
-static List startGHCConstrs Args((Int,List,List));
-static Name startGHCSel     Args((Int,Pair));
-static Name startGHCConstr  Args((Int,Int,Triple));
-
-
 
-static Kinds tvsToKind             Args((List));
-static Int   arityFromType         Args((Type));
-static Int   arityInclDictParams   Args((Type));
-static Bool  allTypesKnown ( Type type, List aktys /* [QualId] */, ConId thisMod );
+static Kinds tvsToKind             ( List );
+static Int   arityFromType         ( Type );
+static Int   arityInclDictParams   ( Type );
+static Bool  allTypesKnown         ( Type type, 
+                                     List aktys /* [QualId] */,
+                                     ConId thisMod );
                                          
-static List       ifTyvarsIn       Args((Type));
-
-static Type       tvsToOffsets       Args((Int,Type,List));
-static Type       conidcellsToTycons Args((Int,Type));
-
-static void*      lookupObjName ( char* );
+static List  ifTyvarsIn            ( Type );
+static Type  tvsToOffsets          ( Int,Type,List );
+static Type  conidcellsToTycons    ( Int,Type );
 
 
 
@@ -249,12 +243,10 @@ static Cell filterInterface ( Cell root,
 }
 
 
-ZPair readInterface(String fname, Long fileSize)
+List /* of CONID */ getInterfaceImports ( Cell iface )
 {
     List  tops;
     List  imports = NIL;
-    ZPair iface   = parseInterface(fname,fileSize);
-    assert (whatIs(iface)==I_INTERFACE);
 
     for (tops = zsnd(unap(I_INTERFACE,iface)); nonNull(tops); tops=tl(tops))
        if (whatIs(hd(tops)) == I_IMPORT) {
@@ -262,10 +254,13 @@ ZPair readInterface(String fname, Long fileSize)
           ConId m_to_imp = zfst(imp_decl);
           if (textOf(m_to_imp) != findText("PrelGHC")) {
              imports = cons(m_to_imp,imports);
-             /* fprintf(stderr, "add iface %s\n", textToStr(textOf(m_to_imp))); */
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "add iface %s\n", 
+                     textToStr(textOf(m_to_imp)));
+#            endif
           }
        }
-    return zpair(iface,imports);
+    return imports;
 }
 
 
@@ -330,11 +325,15 @@ static Bool isExportedIFaceEntity ( Cell ife, List exlist_list )
       }
 
    }
+#  ifdef DEBUG_IFACE
    fprintf ( stderr, "     dump %s\n", textToStr(tnm) );
+#  endif
    return FALSE;
 
  retain:
+#  ifdef DEBUG_IFACE
    fprintf ( stderr, "   retain %s\n", textToStr(tnm) );
+#  endif
    return TRUE;
 }
 
@@ -380,7 +379,9 @@ static Cell deleteUnexportedIFaceEntities ( Cell root )
    List  exlist_list = NIL;
    List  t;
 
+#  ifdef DEBUG_IFACE
    fprintf(stderr, "\ncleanIFace: %s\n", textToStr(textOf(iname)));
+#  endif
 
    exlist_list = getExportDeclsInIFace ( root );
    /* exlist_list :: [I_EXPORT] */
@@ -389,10 +390,12 @@ static Cell deleteUnexportedIFaceEntities ( Cell root )
       hd(t) = zsnd(unap(I_EXPORT,hd(t)));
    /* exlist_list :: [[ ConVarId | ((ConId, [ConVarId])) ]] */
 
+#if 0
    if (isNull(exlist_list)) {
       ERRMSG(0) "Can't find any export lists in interface file"
       EEND;
    }
+#endif
 
    return filterInterface ( root, isExportedIFaceEntity, 
                             exlist_list, NULL );
@@ -422,9 +425,11 @@ static List addTyconsAndClassesFromIFace ( Cell root, List aktys )
 static Void ifentityAllTypesKnown_dumpmsg ( Cell entity )
 {
    ConVarId id = getIEntityName ( entity );
+#  ifdef DEBUG_IFACE
    fprintf ( stderr, 
              "dumping %s because of unknown type(s)\n",
              isNull(id) ? "(nameless entity?!)" : textToStr(textOf(id)) );
+#  endif
 }
 
 
@@ -517,9 +522,11 @@ static Void ifTypeDoesntRefUnknownTycon_dumpmsg ( Cell entity )
    ConVarId id = getIEntityName ( entity );
    assert (whatIs(entity)==I_TYPE);
    assert (isCon(id));
+#  ifdef DEBUG_IFACE
    fprintf ( stderr, 
              "dumping type %s because of unknown tycon(s)\n",
              textToStr(textOf(id)) );
+#  endif
 }
 
 
@@ -545,9 +552,11 @@ static List abstractifyExDecl ( Cell root, ConId toabs )
 
 static Void ppModule ( Text modt )
 {
+#  ifdef DEBUG_IFACE
    fflush(stderr); fflush(stdout);
    fprintf(stderr, "---------------- MODULE %s ----------------\n", 
                    textToStr(modt) );
+#  endif
 }
 
 
@@ -562,7 +571,7 @@ static void* ifFindItblFor ( Name n )
    char  buf[1000];
    Text  t;
 
-   sprintf ( buf, "%s_%s_con_info", 
+   sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_con_info"), 
                   textToStr( module(name(n).mod).text ),
                   textToStr( name(n).text ) );
    t = enZcodeThenFindText(buf);
@@ -571,7 +580,7 @@ static void* ifFindItblFor ( Name n )
    if (p) return p;
 
    if (name(n).arity == 0) {
-      sprintf ( buf, "%s_%s_static_info", 
+      sprintf ( buf, MAYBE_LEADING_UNDERSCORE_STR("%s_%s_static_info"), 
                      textToStr( module(name(n).mod).text ),
                      textToStr( name(n).text ) );
       t = enZcodeThenFindText(buf);
@@ -661,13 +670,7 @@ static void ifSetClassDefaultsAndDCon ( Class c )
 }
 
 
-/* ifaces_outstanding holds a list of parsed interfaces
-   for which we need to load objects and create symbol
-   table entries.
-
-   Return TRUE if Prelude `elem` ifaces_outstanding, else FALSE.
-*/
-Bool processInterfaces ( void )
+void processInterfaces ( List /* of CONID */ iface_modnames )
 {
     List    tmp;
     List    xs;
@@ -680,30 +683,26 @@ Bool processInterfaces ( void )
     Module  mod;
     List    all_known_types;
     Int     num_known_types;
-    Bool    didPrelude;
     List    cls_list;         /* :: List Class */
     List    constructor_list; /* :: List Name */
 
     List ifaces       = NIL;  /* :: List I_INTERFACE */
-    List iface_sizes  = NIL;  /* :: List Int         */
-    List iface_onames = NIL;  /* :: List Text        */
 
-    if (isNull(ifaces_outstanding)) return FALSE;
+    if (isNull(iface_modnames)) return;
 
+#   ifdef DEBUG_IFACE
     fprintf ( stderr, 
               "processInterfaces: %d interfaces to process\n", 
               length(ifaces_outstanding) );
+#   endif
 
-    /* unzip3 ifaces_outstanding into ifaces, iface_sizes, iface_onames */
-    for (xs = ifaces_outstanding; nonNull(xs); xs=tl(xs)) {
-       ifaces       = cons ( zfst3(hd(xs)), ifaces       );
-       iface_onames = cons ( zsnd3(hd(xs)), iface_onames );
-       iface_sizes  = cons ( zthd3(hd(xs)), iface_sizes  );
+    for (xs = iface_modnames; nonNull(xs); xs=tl(xs)) {
+       mod = findModule(textOf(hd(xs)));
+       assert(nonNull(mod));
+       assert(module(mod).mode == FM_OBJECT);
+       ifaces = cons ( module(mod).tree, ifaces );
     }
-
-    ifaces       = reverse(ifaces);
-    iface_onames = reverse(iface_onames);
-    iface_sizes  = reverse(iface_sizes);
+    ifaces = reverse(ifaces);
 
     /* Clean up interfaces -- dump non-exported value, class, type decls */
     for (xs = ifaces; nonNull(xs); xs = tl(xs))
@@ -724,11 +723,15 @@ Bool processInterfaces ( void )
        */
        all_known_types = getAllKnownTyconsAndClasses();
        for (xs = ifaces; nonNull(xs); xs=tl(xs))
-          all_known_types = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
+          all_known_types 
+             = addTyconsAndClassesFromIFace ( hd(xs), all_known_types );
 
        /* Have we reached a fixed point? */
        i = length(all_known_types);
-       printf ( "\n============= %d known types =============\n", i );
+#      ifdef DEBUG_IFACE
+       fprintf ( stderr,
+                 "\n============= %d known types =============\n", i );
+#      endif
        if (num_known_types == i) break;
        num_known_types = i;
 
@@ -782,9 +785,11 @@ Bool processInterfaces ( void )
 
           if (!allKnown) {
              absify = cons ( getIEntityName(ent), absify );
+#            ifdef DEBUG_IFACE
              fprintf ( stderr, 
                        "abstractifying %s because it uses an unknown type\n",
                        textToStr(textOf(getIEntityName(ent))) );
+#            endif
           }
        }
 
@@ -818,7 +823,10 @@ Bool processInterfaces ( void )
              data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
                             zsel45(data), NIL /* the constr list */ );
              hd(es) = ap(I_DATA,data);
-fprintf(stderr, "abstractify data %s\n", textToStr(textOf(getIEntityName(ent))) );
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "abstractify data %s\n", 
+                     textToStr(textOf(getIEntityName(ent))) );
+#            endif
          }
           else if (whatIs(ent)==I_NEWTYPE
               && isExportedAbstractly ( getIEntityName(ent), 
@@ -827,7 +835,10 @@ fprintf(stderr, "abstractify data %s\n", textToStr(textOf(getIEntityName(ent)))
              data = z5ble ( zsel15(data), zsel25(data), zsel35(data),
                             zsel45(data), NIL /* the constr-type pair */ );
              hd(es) = ap(I_NEWTYPE,data);
-fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent))) );
+#            ifdef DEBUG_IFACE
+             fprintf(stderr, "abstractify newtype %s\n", 
+                     textToStr(textOf(getIEntityName(ent))) );
+#            endif
           }
        }
 
@@ -841,8 +852,9 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
        be value defns, classes and instances which refer to unknown types.
        Delete iteratively until a fixed point is reached.
     */
-    printf("\n");
-
+#   ifdef DEBUG_IFACE
+    fprintf(stderr,"\n");
+#   endif
     num_known_types = 999999999;
     while (TRUE) {
        Int i;
@@ -858,7 +870,10 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
 
        /* Have we reached a fixed point? */
        i = length(all_known_types);
-       printf ( "\n------------- %d known types -------------\n", i );
+#      ifdef DEBUG_IFACE
+       fprintf ( stderr,
+                 "\n------------- %d known types -------------\n", i );
+#      endif
        if (num_known_types == i) break;
        num_known_types = i;
 
@@ -876,15 +891,8 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
 
 
     /* Allocate module table entries and read in object code. */
-    for (xs=ifaces; 
-         nonNull(xs);
-         xs=tl(xs), iface_sizes=tl(iface_sizes), iface_onames=tl(iface_onames)) {
-       startGHCModule ( textOf(zfst(unap(I_INTERFACE,hd(xs)))),
-                        intOf(hd(iface_sizes)),
-                        hd(iface_onames) );
-    }
-    assert (isNull(iface_sizes));
-    assert (isNull(iface_onames));
+    for (xs=ifaces; nonNull(xs); xs=tl(xs))
+       startGHCModule ( textOf(zfst(unap(I_INTERFACE,hd(xs)))) );
 
 
     /* Now work through the decl lists of the modules, and call the
@@ -966,14 +974,17 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
        }       
     }
 
-    fprintf(stderr, "\n=========================================================\n");
-    fprintf(stderr, "=========================================================\n");
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\n============================"
+                    "=============================\n");
+    fprintf(stderr, "=============================="
+                    "===========================\n");
+#   endif
 
     /* Traverse again the decl lists of the modules, this time 
        calling the finishGHC* functions.  But don't process
        the export lists; those must wait for later.
     */
-    didPrelude       = FALSE;
     cls_list         = NIL;
     constructor_list = NIL;
     for (xs = ifaces; nonNull(xs); xs = tl(xs)) {
@@ -984,8 +995,6 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
        setCurrModule(mod);
        ppModule ( module(mod).text );
 
-       if (mname == textPrelude) didPrelude = TRUE;
-
        for (decls = zsnd(iface); nonNull(decls); decls = tl(decls)) {
           Cell decl = hd(decls);
           switch(whatIs(decl)) {
@@ -1013,7 +1022,7 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
              case I_DATA: {
                 Cell ddecl   = unap(I_DATA,decl);
                 List constrs = finishGHCDataDecl ( zsel35(ddecl) );
-                constructor_list = appendOnto ( constrs, constructor_list );
+                constructor_list = dupOnto ( constrs, constructor_list );
                 break;
              }
              case I_NEWTYPE: {
@@ -1037,8 +1046,12 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
           }
        }       
     }
-    fprintf(stderr, "\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-    fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+#   ifdef DEBUG_IFACE
+    fprintf(stderr, "\n+++++++++++++++++++++++++++++"
+                    "++++++++++++++++++++++++++++\n");
+    fprintf(stderr, "+++++++++++++++++++++++++++++++"
+                    "++++++++++++++++++++++++++\n");
+#   endif
 
     /* Build the module(m).export lists for each module, by running
        through the export lists in the iface.  Also, do the implicit
@@ -1054,8 +1067,6 @@ fprintf(stderr, "abstractify newtype %s\n", textToStr(textOf(getIEntityName(ent)
 
     /* Finished! */
     ifaces_outstanding = NIL;
-
-    return didPrelude;
 }
 
 
@@ -1070,15 +1081,24 @@ static void startGHCModule_errMsg ( char* msg )
 
 static void* startGHCModule_clientLookup ( char* sym )
 {
+#  ifdef DEBUG_IFACE
    /* fprintf ( stderr, "CLIENTLOOKUP %s\n", sym ); */
+#  endif
    return lookupObjName ( sym );
 }
 
+static int /*Bool*/ startGHCModule_clientWantsSymbol ( char* sym )
+{
+   if (strcmp(sym,"ghc_cc_ID")==0) return 0;
+   return 1;
+}
+
 static ObjectCode* startGHCModule_partial_load ( String objNm, Int objSz )
 {
    ObjectCode* oc
       = ocNew ( startGHCModule_errMsg,
                 startGHCModule_clientLookup,
+                startGHCModule_clientWantsSymbol,
                 objNm, objSz );
     
     if (!oc) {
@@ -1100,36 +1120,34 @@ static ObjectCode* startGHCModule_partial_load ( String objNm, Int objSz )
     return oc;
 }
 
-static Void startGHCModule ( Text mname, Int sizeObj, Text nameObj )
+static Void startGHCModule ( Text mname )
 {
    List   xts;
    Module m = findModule(mname);
+   assert(nonNull(m));
 
-   if (isNull(m)) {
-      m = newModule(mname);
-      fprintf ( stderr, "startGHCIface: name %16s   objsize %d\n", 
-                         textToStr(mname), sizeObj );
-   } else {
-      if (module(m).fake) {
-         module(m).fake = FALSE;
-      } else {
-         ERRMSG(0) "Module \"%s\" already loaded", textToStr(mname)
-         EEND;
-      }
-   }
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr, "startGHCIface: name %16s   objsize %d\n", 
+                      textToStr(mname), module(m).objSize );
+#  endif
+   if (module(m).fake)
+      module(m).fake = FALSE;
 
    /* Get hold of the primary object for the module. */
    module(m).object
-      = startGHCModule_partial_load ( textToStr(nameObj), sizeObj );
+      = startGHCModule_partial_load ( textToStr(module(m).objName), 
+                                      module(m).objSize );
 
    /* and any extras ... */
    for (xts = module(m).objectExtraNames; nonNull(xts); xts=tl(xts)) {
       Int         size;
       ObjectCode* oc;
       Text        xtt = hd(xts);
-      String      nm  = getExtraObjectInfo ( textToStr(nameObj),
-                                             textToStr(xtt),
-                                             &size );
+      String      nm  = getExtraObjectInfo (
+                           textToStr(module(m).objName),
+                           textToStr(xtt),
+                           &size
+                        );
       if (size == -1) {
          ERRMSG(0) "Can't find extra object file \"%s\"", nm
          EEND;
@@ -1176,7 +1194,9 @@ static Void finishGHCModule ( Cell root )
    List        t;
    ObjectCode* oc;
 
+#  ifdef DEBUG_IFACE
    fprintf(stderr, "begin finishGHCModule %s\n", textToStr(textOf(iname)));
+#  endif
 
    if (isNull(mod)) internal("finishExports(1)");
    setCurrModule(mod);
@@ -1203,7 +1223,9 @@ static Void finishGHCModule ( Cell root )
                q = mkQualId(exmod,ex);
                c = findQualNameWithoutConsultingExportList ( q );
                if (isNull(c)) goto notfound;
+#              ifdef DEBUG_IFACE
                fprintf(stderr, "   var %s\n", textToStr(textOf(ex)) );
+#              endif
                module(mod).exports = cons(c, module(mod).exports);
                addName(c);
                break;
@@ -1212,7 +1234,9 @@ static Void finishGHCModule ( Cell root )
                q = mkQualId(exmod,ex);
                c = findQualTyconWithoutConsultingExportList ( q );
                if (isNull(c)) goto notfound;
+#              ifdef DEBUG_IFACE
                fprintf(stderr, "   type %s\n", textToStr(textOf(ex)) );
+#              endif
                module(mod).exports = cons(pair(c,NIL), module(mod).exports);
                addTycon(c);
                break;
@@ -1224,7 +1248,10 @@ static Void finishGHCModule ( Cell root )
                c       = findQualTyconWithoutConsultingExportList ( q );
 
                if (nonNull(c)) { /* data */
-                  fprintf(stderr, "   data/newtype %s = { ", textToStr(textOf(ex)) );
+#                 ifdef DEBUG_IFACE
+                  fprintf(stderr, "   data/newtype %s = { ", 
+                          textToStr(textOf(ex)) );
+#                 endif
                   assert(tycon(c).what == DATATYPE || tycon(c).what==NEWTYPE);
                   abstract = isNull(tycon(c).defn);
                   /* This data/newtype could be abstract even tho the export list
@@ -1236,7 +1263,9 @@ static Void finishGHCModule ( Cell root )
                   if (abstract) {
                      module(mod).exports = cons(pair(c,NIL), module(mod).exports);
                      addTycon(c);
+#                    ifdef DEBUG_IFACE
                      fprintf ( stderr, "(abstract) ");
+#                    endif
                  } else {
                      module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
                      addTycon(c);
@@ -1246,18 +1275,24 @@ static Void finishGHCModule ( Cell root )
                                               /* isVar since could be a field name */
                         q = mkQualId(exmod,ent2);
                         c = findQualNameWithoutConsultingExportList ( q );
+#                       ifdef DEBUG_IFACE
                         fprintf(stderr, "%s ", textToStr(name(c).text));
+#                       endif
                         assert(nonNull(c));
                         /* module(mod).exports = cons(c, module(mod).exports); */
                         addName(c);
                      }
                   }
+#                 ifdef DEBUG_IFACE
                   fprintf(stderr, "}\n" );
+#                 endif
                } else { /* class */
                   q = mkQualId(exmod,ex);
                   c = findQualClassWithoutConsultingExportList ( q );
                   if (isNull(c)) goto notfound;
+#                 ifdef DEBUG_IFACE
                   fprintf(stderr, "   class %s { ", textToStr(textOf(ex)) );
+#                 endif
                   module(mod).exports = cons(pair(c,DOTDOT), module(mod).exports);
                   addClass(c);
                   for (; nonNull(subents); subents = tl(subents)) {
@@ -1265,12 +1300,16 @@ static Void finishGHCModule ( Cell root )
                      assert(isVar(ent2));
                      q = mkQualId(exmod,ent2);
                      c = findQualNameWithoutConsultingExportList ( q );
+#                    ifdef DEBUG_IFACE
                      fprintf(stderr, "%s ", textToStr(name(c).text));
+#                    endif
                      if (isNull(c)) goto notfound;
                      /* module(mod).exports = cons(c, module(mod).exports); */
                      addName(c);
                   }
+#                 ifdef DEBUG_IFACE
                   fprintf(stderr, "}\n" );
+#                 endif
                }
                break;
 
@@ -1283,8 +1322,10 @@ static Void finishGHCModule ( Cell root )
         notfound:
          /* q holds what ain't found */
          assert(whatIs(q)==QUALIDENT);
+#        ifdef DEBUG_IFACE
          fprintf( stderr, "   ------ IGNORED: %s.%s\n",
                   textToStr(qmodOf(q)), textToStr(qtextOf(q)) );
+#        endif
          continue;
       }
    }
@@ -1336,7 +1377,7 @@ static Void finishGHCModule ( Cell root )
 static Void startGHCExports ( ConId mn, List exlist )
 {
 #   ifdef DEBUG_IFACE
-    printf("startGHCExports %s\n", textToStr(textOf(mn)) );
+    fprintf(stderr,"startGHCExports %s\n", textToStr(textOf(mn)) );
 #   endif
    /* Nothing to do. */
 }
@@ -1344,7 +1385,7 @@ static Void startGHCExports ( ConId mn, List exlist )
 static Void finishGHCExports ( ConId mn, List exlist )
 {
 #   ifdef DEBUG_IFACE
-    printf("finishGHCExports %s\n", textToStr(textOf(mn)) );
+    fprintf(stderr,"finishGHCExports %s\n", textToStr(textOf(mn)) );
 #   endif
    /* Nothing to do. */
 }
@@ -1359,7 +1400,7 @@ static Void startGHCImports ( ConId mn, List syms )
 /* syms   [ConId | VarId] -- the names to import */
 {
 #  ifdef DEBUG_IFACE
-   printf("startGHCImports %s\n", textToStr(textOf(mn)) );
+   fprintf(stderr,"startGHCImports %s\n", textToStr(textOf(mn)) );
 #  endif
    /* Nothing to do. */
 }
@@ -1370,7 +1411,7 @@ static Void finishGHCImports ( ConId nm, List syms )
 /* syms   [ConId | VarId] -- the names to import */
 {
 #  ifdef DEBUG_IFACE
-   printf("finishGHCImports %s\n", textToStr(textOf(nm)) );
+   fprintf(stderr,"finishGHCImports %s\n", textToStr(textOf(nm)) );
 #  endif
   /* Nothing to do. */
 }
@@ -1447,7 +1488,7 @@ static void startGHCValue ( Int line, VarId vid, Type ty )
     Text   v = textOf(vid);
 
 #   ifdef DEBUG_IFACE
-    printf("begin startGHCValue %s\n", textToStr(v));
+    fprintf(stderr,"begin startGHCValue %s\n", textToStr(v));
 #   endif
 
     line = intOf(line);
@@ -1559,6 +1600,37 @@ static Void  finishGHCSynonym ( ConId tyc )
  * Data declarations
  * ------------------------------------------------------------------------*/
 
+static Type qualifyIfaceType ( Type unqual, List ctx )
+{
+   /* ctx :: [((QConId,VarId))] */
+   /* ctx is a list of (class name, tyvar) pairs.  
+      Attach to unqual qualifiers taken from ctx
+      for each tyvar which appears in unqual.
+   */
+   List tyvarsMentioned; /* :: [VarId] */
+   List ctx2  = NIL;
+   Cell kinds = NIL;
+
+   if (isPolyType(unqual)) {
+      kinds  = polySigOf(unqual);
+      unqual = monotypeOf(unqual);
+   }
+
+   assert(!isQualType(unqual));
+   tyvarsMentioned = ifTyvarsIn ( unqual );
+   for (; nonNull(ctx); ctx=tl(ctx)) {
+      ZPair ctxElem = hd(ctx); /* :: ((QConId, VarId)) */
+      if (nonNull(varIsMember(textOf(zsnd(ctxElem)),tyvarsMentioned)))
+         ctx2 = cons(ctxElem, ctx2);
+   }
+   if (nonNull(ctx2))
+      unqual = ap(QUAL,pair(reverse(ctx2),unqual));
+   if (nonNull(kinds))
+      unqual = mkPolyType(kinds,unqual);
+   return unqual;
+}
+
+
 static Void startGHCDataDecl(line,ctx0,tycon,ktyvars,constrs0)
 Int   line;
 List  ctx0;      /* [((QConId,VarId))]                */
@@ -1572,13 +1644,13 @@ List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
      */
 {
     Type    ty, resTy, selTy, conArgTy;
-    List    tmp, conArgs, sels, constrs, fields, tyvarsMentioned;
-    List    ctx, ctx2;
+    List    tmp, conArgs, sels, constrs, fields;
     Triple  constr;
     Cell    conid;
     Pair    conArg, ctxElem;
     Text    conArgNm;
     Int     conArgStrictness;
+    Int     conStrictCompCount;
 
     Text t = textOf(tycon);
 #   ifdef DEBUG_IFACE
@@ -1612,48 +1684,34 @@ List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
            conid  = zfst(constr);
            fields = zsnd(constr);
 
-           /* Build type of constr and handle any selectors found.
-              Also collect up tyvars occurring in the constr's arg
-              types, so we can throw away irrelevant parts of the
-              context later.
-           */
+           /* Build type of constr and handle any selectors found. */
            ty = resTy;
-           tyvarsMentioned = NIL;  
-           /* tyvarsMentioned :: [VarId] */
 
+           conStrictCompCount = 0;
            conArgs = reverse(fields);
            for (; nonNull(conArgs); conArgs=tl(conArgs)) {
               conArg           = hd(conArgs); /* (Type,Text) */
               conArgTy         = zfst3(conArg);
               conArgNm         = zsnd3(conArg);
               conArgStrictness = intOf(zthd3(conArg));
-              tyvarsMentioned = dupListOnto(ifTyvarsIn(conArgTy),
-                                            tyvarsMentioned);
-              if (conArgStrictness > 0) conArgTy = bang(conArgTy);
+              if (conArgStrictness > 0) conStrictCompCount++;
               ty = fn(conArgTy,ty);
               if (nonNull(conArgNm)) {
                  /* a field name is mentioned too */
                  selTy = fn(resTy,conArgTy);
                  if (whatIs(tycon(tc).kind) != STAR)
                     selTy = pair(POLYTYPE,pair(tycon(tc).kind, selTy));
+                 selTy = qualifyIfaceType ( selTy, ctx0 );
                  selTy = tvsToOffsets(line,selTy, ktyvars);
                  sels = cons( zpair(conArgNm,selTy), sels);
               }
            }
 
            /* Now ty is the constructor's type, not including context.
-              Throw away any parts of the context not mentioned in 
-              tyvarsMentioned, and use it to qualify ty.
+              Throw away any parts of the context not mentioned in ty,
+              and use it to qualify ty.
           */
-           ctx2 = NIL;
-           for (ctx=ctx0; nonNull(ctx); ctx=tl(ctx)) {
-              ctxElem = hd(ctx);     
-              /* ctxElem :: ((QConId,VarId)) */
-              if (nonNull(cellIsMember(textOf(zsnd(ctxElem)),tyvarsMentioned)))
-                 ctx2 = cons(ctxElem, ctx2);
-           }
-           if (nonNull(ctx2))
-              ty = ap(QUAL,pair(ctx2,ty));
+           ty = qualifyIfaceType ( ty, ctx0 );
 
            /* stick the tycon's kind on, if not simply STAR */
            if (whatIs(tycon(tc).kind) != STAR)
@@ -1662,12 +1720,12 @@ List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
            ty = tvsToOffsets(line,ty, ktyvars);
 
            /* Finally, stick the constructor's type onto it. */
-           hd(constrs) = ztriple(conid,fields,ty);
+           hd(constrs) = z4ble(conid,fields,ty,mkInt(conStrictCompCount));
         }
 
         /* Final result is that 
-           constrs :: [((ConId,[((Type,Text))],Type))]   
-                      lists the constructors and their types
+           constrs :: [((ConId,[((Type,Text))],Type,Int))]   
+                      lists the constructors, their types and # strict comps
            sels :: [((VarId,Type))]
                    lists the selectors and their types
        */
@@ -1678,9 +1736,9 @@ List  constrs0;  /* [((ConId,[((Type,VarId,Int))]))]  */
 
 static List startGHCConstrs ( Int line, List cons, List sels )
 {
-    /* cons :: [((ConId,[((Type,Text,Int))],Type))] */
-    /* sels :: [((VarId,Type))]                     */
-    /* returns [Name]                               */
+    /* cons :: [((ConId,[((Type,Text,Int))],Type,Int))] */
+    /* sels :: [((VarId,Type))]                         */
+    /* returns [Name]                                   */
     List cs, ss;
     Int  conNo = length(cons)>1 ? 1 : 0;
     for(cs=cons; nonNull(cs); cs=tl(cs), conNo++) {
@@ -1720,15 +1778,16 @@ static Name startGHCSel ( Int line, ZPair sel )
 }
 
 
-static Name startGHCConstr ( Int line, Int conNo, ZTriple constr )
+static Name startGHCConstr ( Int line, Int conNo, Z4Ble constr )
 {
-    /* constr :: ((ConId,[((Type,Text,Int))],Type)) */
+    /* constr :: ((ConId,[((Type,Text,Int))],Type,Int)) */
     /* (ADR) ToDo: add rank2 annotation and existential annotation
      * these affect how constr can be used.
      */
-    Text con   = textOf(zfst3(constr));
-    Type type  = zthd3(constr);
-    Int  arity = arityFromType(type);
+    Text con     = textOf(zsel14(constr));
+    Type type    = zsel34(constr);
+    Int  arity   = arityFromType(type);
+    Int  nStrict = intOf(zsel44(constr));
     Name n = findName(con);     /* Allocate constructor fun name   */
     if (isNull(n)) {
         n = newName(con,NIL);
@@ -1737,10 +1796,11 @@ static Name startGHCConstr ( Int line, Int conNo, ZTriple constr )
             textToStr(con)
         EEND;
     }
-    name(n).arity  = arity;     /* Save constructor fun details    */
-    name(n).line   = line;
-    name(n).number = cfunNo(conNo);
-    name(n).type   = type;
+    name(n).arity     = arity;     /* Save constructor fun details    */
+    name(n).line      = line;
+    name(n).number    = cfunNo(conNo);
+    name(n).type      = type;
+    name(n).hasStrict = nStrict > 0;
     return n;
 }
 
@@ -1750,7 +1810,8 @@ static List finishGHCDataDecl ( ConId tyc )
     List  nms;
     Tycon tc = findTycon(textOf(tyc));
 #   ifdef DEBUG_IFACE
-    printf ( "begin finishGHCDataDecl %s\n", textToStr(textOf(tyc)) );
+    fprintf ( stderr, "begin finishGHCDataDecl %s\n", 
+              textToStr(textOf(tyc)) );
 #   endif
     if (isNull(tc)) internal("finishGHCDataDecl");
     
@@ -1836,7 +1897,8 @@ static Void finishGHCNewType ( ConId tyc )
 {
     Tycon tc = findTycon(textOf(tyc));
 #   ifdef DEBUG_IFACE
-    printf ( "begin finishGHCNewType %s\n", textToStr(textOf(tyc)) );
+    fprintf ( stderr, "begin finishGHCNewType %s\n", 
+              textToStr(textOf(tyc)) );
 #   endif
  
     if (isNull(tc)) internal("finishGHCNewType");
@@ -1877,7 +1939,7 @@ List  mems0; {    /* [((VarId, Type))]     */
     Text ct         = textOf(tc_name);
     Pair newCtx     = pair(tc_name, zfst(kinded_tv));
 #   ifdef DEBUG_IFACE
-    printf ( "begin startGHCClass %s\n", textToStr(ct) );
+    fprintf ( stderr, "begin startGHCClass %s\n", textToStr(ct) );
 #   endif
 
     line = intOf(line);
@@ -1983,7 +2045,7 @@ static Class finishGHCClass ( Tycon cls_tyc )
     Int   ctr;
     Class nw = findClass ( textOf(cls_tyc) );
 #   ifdef DEBUG_IFACE
-    printf ( "begin finishGHCClass %s\n", textToStr(cclass(nw).text) );
+    fprintf ( stderr, "begin finishGHCClass %s\n", textToStr(cclass(nw).text) );
 #   endif
     if (isNull(nw)) internal("finishGHCClass");
 
@@ -2031,7 +2093,7 @@ VarId var; {   /* VarId */
 
     Inst in = newInst();
 #   ifdef DEBUG_IFACE
-    printf ( "begin startGHCInstance\n" );
+    fprintf ( stderr, "begin startGHCInstance\n" );
 #   endif
 
     line = intOf(line);
@@ -2098,7 +2160,7 @@ static Void finishGHCInstance ( Inst in )
     Type   cls;
 
 #   ifdef DEBUG_IFACE
-    printf ( "begin finishGHCInstance\n" );
+    fprintf ( stderr, "begin finishGHCInstance\n" );
 #   endif
 
     assert (nonNull(in));
@@ -2334,7 +2396,10 @@ static Bool allTypesKnown ( Type  type,
          return TRUE; /*notreached*/
    }
   missing:
-   printf ( "allTypesKnown: unknown " ); print(type,10); printf("\n");
+#  ifdef DEBUG_IFACE
+   fprintf ( stderr,"allTypesKnown: unknown " ); print(type,10); 
+   fprintf(stderr,"\n");
+#  endif
    return FALSE;
 }
 
@@ -2420,7 +2485,8 @@ Type type; {
  * General object symbol query stuff
  * ------------------------------------------------------------------------*/
 
-#define EXTERN_SYMS                  \
+#define EXTERN_SYMS_ALLPLATFORMS     \
+      SymX(MainRegTable)              \
       Sym(stg_gc_enter_1)            \
       Sym(stg_gc_noregs)             \
       Sym(stg_gc_seq_1)              \
@@ -2429,107 +2495,110 @@ Type type; {
       Sym(stg_chk_0)                 \
       Sym(stg_chk_1)                 \
       Sym(stg_gen_chk)               \
-      Sym(stg_exit)                  \
-      Sym(stg_update_PAP)            \
-      Sym(stg_error_entry)           \
-      Sym(__ap_2_upd_info)           \
-      Sym(__ap_3_upd_info)           \
-      Sym(__ap_4_upd_info)           \
-      Sym(__ap_5_upd_info)           \
-      Sym(__ap_6_upd_info)           \
-      Sym(__ap_7_upd_info)           \
-      Sym(__ap_8_upd_info)           \
-      Sym(__sel_0_upd_info)          \
-      Sym(__sel_1_upd_info)          \
-      Sym(__sel_2_upd_info)          \
-      Sym(__sel_3_upd_info)          \
-      Sym(__sel_4_upd_info)          \
-      Sym(__sel_5_upd_info)          \
-      Sym(__sel_6_upd_info)          \
-      Sym(__sel_7_upd_info)          \
-      Sym(__sel_8_upd_info)          \
-      Sym(__sel_9_upd_info)          \
-      Sym(__sel_10_upd_info)         \
-      Sym(__sel_11_upd_info)         \
-      Sym(__sel_12_upd_info)         \
-      Sym(MainRegTable)              \
-      Sym(Upd_frame_info)            \
-      Sym(seq_frame_info)            \
-      Sym(CAF_BLACKHOLE_info)        \
-      Sym(IND_STATIC_info)           \
-      Sym(EMPTY_MVAR_info)           \
-      Sym(MUT_ARR_PTRS_FROZEN_info)  \
-      Sym(newCAF)                    \
-      Sym(putMVarzh_fast)            \
-      Sym(newMVarzh_fast)            \
-      Sym(takeMVarzh_fast)           \
-      Sym(catchzh_fast)              \
-      Sym(raisezh_fast)              \
-      Sym(delayzh_fast)              \
-      Sym(yieldzh_fast)              \
-      Sym(killThreadzh_fast)         \
-      Sym(waitReadzh_fast)           \
-      Sym(waitWritezh_fast)          \
-      Sym(CHARLIKE_closure)          \
-      Sym(INTLIKE_closure)           \
-      Sym(suspendThread)             \
-      Sym(resumeThread)              \
+      SymX(stg_exit)                  \
+      SymX(stg_update_PAP)            \
+      SymX(stg_error_entry)           \
+      SymX(__ap_2_upd_info)           \
+      SymX(__ap_3_upd_info)           \
+      SymX(__ap_4_upd_info)           \
+      SymX(__ap_5_upd_info)           \
+      SymX(__ap_6_upd_info)           \
+      SymX(__ap_7_upd_info)           \
+      SymX(__ap_8_upd_info)           \
+      SymX(__sel_0_upd_info)          \
+      SymX(__sel_1_upd_info)          \
+      SymX(__sel_2_upd_info)          \
+      SymX(__sel_3_upd_info)          \
+      SymX(__sel_4_upd_info)          \
+      SymX(__sel_5_upd_info)          \
+      SymX(__sel_6_upd_info)          \
+      SymX(__sel_7_upd_info)          \
+      SymX(__sel_8_upd_info)          \
+      SymX(__sel_9_upd_info)          \
+      SymX(__sel_10_upd_info)         \
+      SymX(__sel_11_upd_info)         \
+      SymX(__sel_12_upd_info)         \
+      SymX(Upd_frame_info)            \
+      SymX(seq_frame_info)            \
+      SymX(CAF_BLACKHOLE_info)        \
+      SymX(IND_STATIC_info)           \
+      SymX(EMPTY_MVAR_info)           \
+      SymX(MUT_ARR_PTRS_FROZEN_info)  \
+      SymX(newCAF)                    \
+      SymX(putMVarzh_fast)            \
+      SymX(newMVarzh_fast)            \
+      SymX(takeMVarzh_fast)           \
+      SymX(catchzh_fast)              \
+      SymX(raisezh_fast)              \
+      SymX(delayzh_fast)              \
+      SymX(yieldzh_fast)              \
+      SymX(killThreadzh_fast)         \
+      SymX(waitReadzh_fast)           \
+      SymX(waitWritezh_fast)          \
+      SymX(CHARLIKE_closure)          \
+      SymX(INTLIKE_closure)           \
+      SymX(suspendThread)             \
+      SymX(resumeThread)              \
       Sym(stackOverflow)             \
-      Sym(int2Integerzh_fast)        \
+      SymX(int2Integerzh_fast)        \
       Sym(stg_gc_unbx_r1)            \
-      Sym(ErrorHdrHook)              \
-      Sym(makeForeignObjzh_fast)     \
-      Sym(__encodeDouble)            \
-      Sym(decodeDoublezh_fast)       \
-      Sym(isDoubleNaN)               \
-      Sym(isDoubleInfinite)          \
-      Sym(isDoubleDenormalized)      \
-      Sym(isDoubleNegativeZero)      \
-      Sym(__encodeFloat)             \
-      Sym(decodeFloatzh_fast)        \
-      Sym(isFloatNaN)                \
-      Sym(isFloatInfinite)           \
-      Sym(isFloatDenormalized)       \
-      Sym(isFloatNegativeZero)       \
-      Sym(__int_encodeFloat)         \
-      Sym(__int_encodeDouble)        \
-      Sym(mpz_cmp_si)                \
-      Sym(mpz_cmp)                   \
-      Sym(__mpn_gcd_1)               \
-      Sym(gcdIntegerzh_fast)         \
-      Sym(newArrayzh_fast)           \
-      Sym(unsafeThawArrayzh_fast)    \
-      Sym(newDoubleArrayzh_fast)     \
-      Sym(newFloatArrayzh_fast)      \
-      Sym(newAddrArrayzh_fast)       \
-      Sym(newWordArrayzh_fast)       \
-      Sym(newIntArrayzh_fast)        \
-      Sym(newCharArrayzh_fast)       \
-      Sym(newMutVarzh_fast)          \
-      Sym(quotRemIntegerzh_fast)     \
-      Sym(quotIntegerzh_fast)        \
-      Sym(remIntegerzh_fast)         \
-      Sym(divExactIntegerzh_fast)    \
-      Sym(divModIntegerzh_fast)      \
-      Sym(timesIntegerzh_fast)       \
-      Sym(minusIntegerzh_fast)       \
-      Sym(plusIntegerzh_fast)        \
-      Sym(addr2Integerzh_fast)       \
-      Sym(mkWeakzh_fast)             \
-      Sym(prog_argv)                 \
-      Sym(prog_argc)                 \
+      SymX(ErrorHdrHook)              \
+      SymX(mkForeignObjzh_fast)       \
+      SymX(__encodeDouble)            \
+      SymX(decodeDoublezh_fast)       \
+      SymX(isDoubleNaN)               \
+      SymX(isDoubleInfinite)          \
+      SymX(isDoubleDenormalized)      \
+      SymX(isDoubleNegativeZero)      \
+      SymX(__encodeFloat)             \
+      SymX(decodeFloatzh_fast)        \
+      SymX(isFloatNaN)                \
+      SymX(isFloatInfinite)           \
+      SymX(isFloatDenormalized)       \
+      SymX(isFloatNegativeZero)       \
+      SymX(__int_encodeFloat)         \
+      SymX(__int_encodeDouble)        \
+      SymX(mpz_cmp_si)                \
+      SymX(mpz_cmp)                   \
+      SymX(__mpn_gcd_1)               \
+      SymX(gcdIntegerzh_fast)         \
+      SymX(newArrayzh_fast)           \
+      SymX(unsafeThawArrayzh_fast)    \
+      SymX(newDoubleArrayzh_fast)     \
+      SymX(newFloatArrayzh_fast)      \
+      SymX(newAddrArrayzh_fast)       \
+      SymX(newWordArrayzh_fast)       \
+      SymX(newIntArrayzh_fast)        \
+      SymX(newCharArrayzh_fast)       \
+      SymX(newMutVarzh_fast)          \
+      SymX(quotRemIntegerzh_fast)     \
+      SymX(quotIntegerzh_fast)        \
+      SymX(remIntegerzh_fast)         \
+      SymX(divExactIntegerzh_fast)    \
+      SymX(divModIntegerzh_fast)      \
+      SymX(timesIntegerzh_fast)       \
+      SymX(minusIntegerzh_fast)       \
+      SymX(plusIntegerzh_fast)        \
+      SymX(addr2Integerzh_fast)       \
+      SymX(mkWeakzh_fast)             \
+      SymX(prog_argv)                 \
+      SymX(prog_argc)                 \
       Sym(resetNonBlockingFd)        \
-      Sym(getStablePtr)              \
-      Sym(stable_ptr_table)          \
+      SymX(getStablePtr)              \
+      SymX(stable_ptr_table)          \
       Sym(createAdjThunk)            \
+      SymX(shutdownHaskellAndExit)    \
+      Sym(stg_enterStackTop)         \
+      SymX(CAF_UNENTERED_entry)       \
+      Sym(stg_yield_to_Hugs)         \
+      Sym(StgReturn)                 \
+      Sym(init_stack)                \
+      SymX(blockAsyncExceptionszh_fast)    \
+      SymX(unblockAsyncExceptionszh_fast)  \
                                      \
       /* needed by libHS_cbits */    \
       SymX(malloc)                   \
-      Sym(__errno_location)          \
       SymX(close)                    \
-      Sym(__xstat)                   \
-      Sym(__fxstat)                  \
-      Sym(__lxstat)                  \
       Sym(mkdir)                     \
       SymX(close)                    \
       Sym(opendir)                   \
@@ -2542,14 +2611,11 @@ Type type; {
       SymX(lseek)                    \
       SymX(write)                    \
       Sym(getrusage)                 \
-      Sym(gettimeofday)              \
       SymX(realloc)                  \
       SymX(getcwd)                   \
       SymX(free)                     \
       SymX(strcpy)                   \
-      SymX(select)                   \
       Sym(fcntl)                     \
-      SymX(stderr)                   \
       SymX(fprintf)                  \
       SymX(exit)                     \
       Sym(open)                      \
@@ -2559,44 +2625,114 @@ Type type; {
       SymX(rmdir)                    \
       SymX(rename)                   \
       SymX(chdir)                    \
-      Sym(localtime)                 \
-      Sym(strftime)                  \
-      SymX(vfork)                    \
       SymX(execl)                    \
-      SymX(_exit)                    \
       Sym(waitpid)                   \
-      Sym(tzname)                    \
-      Sym(timezone)                  \
-      Sym(mktime)                    \
-      Sym(gmtime)                    \
       SymX(getenv)                   \
-      Sym(shutdownHaskellAndExit)    \
+
+#define EXTERN_SYMS_cygwin32         \
+      SymX(GetCurrentProcess)        \
+      SymX(GetProcessTimes)          \
+      Sym(__udivdi3)                 \
+      SymX(bzero)                    \
+      Sym(select)                    \
+      SymX(_impure_ptr)              \
+      Sym(lstat)                     \
+      Sym(setmode)                   \
+      SymX(system)                   \
+      SymX(sleep)                    \
+      SymX(__imp__tzname)            \
+      SymX(__imp__timezone)          \
+      SymX(tzset)                    \
+      SymX(log)                      \
+      SymX(exp)                      \
+      Sym(sqrt)                      \
+      Sym(sin)                       \
+      Sym(cos)                       \
+      SymX(pow)                      \
+      SymX(__errno)                  \
+      Sym(stat)                      \
+      Sym(fstat)                     \
+      Sym(gettimeofday)              \
+      SymX(localtime)                \
+      SymX(strftime)                 \
+      SymX(mktime)                   \
+      SymX(gmtime)
 
 
-/* AJG Hack; for the moment, make EXTERN_SYMS vanish on Win32 */
-#ifdef _WIN32
-#undef EXTERN_SYMS
-#define EXTERN_SYMS
+#define EXTERN_SYMS_linux            \
+      SymX(__errno_location)         \
+      Sym(__xstat)                   \
+      Sym(__fxstat)                  \
+      Sym(__lxstat)                  \
+      SymX(select)                   \
+      SymX(stderr)                   \
+      SymX(vfork)                    \
+      SymX(_exit)                    \
+      SymX(tzname)                   \
+      SymX(localtime)                \
+      SymX(strftime)                 \
+      SymX(timezone)                 \
+      SymX(mktime)                   \
+      SymX(gmtime)                   \
+      Sym(setitimer)                 \
+      Sym(chmod)                     \
+      Sym(gettimeofday)              \
+
+#define EXTERN_SYMS_solaris2         \
+      SymX(gettimeofday)             \
+
+
+#if defined(linux_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_linux
+#endif
+
+#if defined(solaris2_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_solaris2
+#endif
+
+#if defined(cygwin32_TARGET_OS)
+#define EXTERN_SYMS_THISPLATFORM EXTERN_SYMS_cygwin32
 #endif
 
+
+
 /* entirely bogus claims about types of these symbols */
-#define Sym(vvv)  extern int vvv;
-#define SymX(vvv) /* nothing */
-EXTERN_SYMS
+#define Sym(vvv)  extern void (vvv);
+#define SymX(vvv) /**/
+EXTERN_SYMS_ALLPLATFORMS
+EXTERN_SYMS_THISPLATFORM
 #undef Sym
 #undef SymX
 
-#define Sym(vvv) { #vvv, &vvv },
-#define SymX(vvv) { #vvv, &vvv },
+
+#define Sym(vvv)  { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+                    (void*)(&(vvv)) },
+#define SymX(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+                    (void*)(&(vvv)) },
 OSym rtsTab[] 
    = { 
-       EXTERN_SYMS
+       EXTERN_SYMS_ALLPLATFORMS
+       EXTERN_SYMS_THISPLATFORM
        {0,0} 
      };
 #undef Sym
 #undef SymX
 
-static void* lookupObjName ( char* nm )
+
+
+
+/* A kludge to assist Win32 debugging. */
+char* nameFromStaticOPtr ( void* ptr )
+{
+   int k;
+   for (k = 0; rtsTab[k].nm; k++)
+      if (ptr == rtsTab[k].ad)
+         return rtsTab[k].nm;
+   return NULL;
+}
+
+
+void* lookupObjName ( char* nm )
 {
    int    k;
    char*  pp;
@@ -2604,6 +2740,7 @@ static void* lookupObjName ( char* nm )
    Text   t;
    Module m;
    char   nm2[200];
+   int    first_real_char;
 
    nm2[199] = 0;
    strncpy(nm2,nm,200);
@@ -2617,24 +2754,46 @@ static void* lookupObjName ( char* nm )
    a = lookupOExtraTabName ( nm );
    if (a) return a;
 
+#  if LEADING_UNDERSCORE
+   first_real_char = 1;
+#  else
+   first_real_char = 0;
+#  endif
+
+   /* Maybe it's an __init_Module thing? */
+   if (strlen(nm2+first_real_char) > 7
+       && strncmp(nm2+first_real_char, "__init_", 7)==0) {
+      t = unZcodeThenFindText(nm2+first_real_char+7);
+      if (t == findText("PrelGHC")) return (4+NULL); /* kludge */
+      m = findModule(t);
+      if (isNull(m)) goto dire_straits;
+      a = lookupOTabName ( m, nm );
+      if (a) return a;
+      goto dire_straits;
+   }
+
    /* if not an RTS name, look in the 
       relevant module's object symbol table
    */
-   pp = strchr(nm2, '_');
-   if (!pp || !isupper(nm2[0])) goto not_found;
+   pp = strchr(nm2+first_real_char, '_');
+   if (!pp || !isupper(nm2[first_real_char])) goto dire_straits;
    *pp = 0;
-   t = unZcodeThenFindText(nm2);
+   t = unZcodeThenFindText(nm2+first_real_char);
    m = findModule(t);
-   if (isNull(m)) goto not_found;
+   if (isNull(m)) goto dire_straits;
 
    a = lookupOTabName ( m, nm );  /* RATIONALISE */
    if (a) return a;
 
-  not_found:
+  dire_straits:
+   /* make a desperate, last-ditch attempt to find it */
+   a = lookupOTabNameAbsolutelyEverywhere ( nm );
+   if (a) return a;
+
    fprintf ( stderr, 
              "lookupObjName: can't resolve name `%s'\n", 
              nm );
-assert(4-4);
+   assert(0);
    return NULL;
 }