[project @ 2002-07-17 09:21:48 by simonmar]
[ghc-hetmet.git] / ghc / rts / Printer.c
index e22e6ed..9277c72 100644 (file)
@@ -1,23 +1,35 @@
-/* -*- mode: hugs-c; -*- */
 /* -----------------------------------------------------------------------------
- * $Id: Printer.c,v 1.3 1999/01/15 17:57:09 simonm Exp $
+ * $Id: Printer.c,v 1.52 2002/07/17 09:21:50 simonmar Exp $
  *
- * Copyright (c) 1994-1998.
+ * (c) The GHC Team, 1994-2000.
  *
  * Heap printer
  * 
  * ---------------------------------------------------------------------------*/
 
+#include "PosixSource.h"
 #include "Rts.h"
+#include "Printer.h"
+
+#include <stdio.h>
 
 #ifdef DEBUG
 
 #include "RtsUtils.h"
 #include "RtsFlags.h"
+#include "MBlock.h"
+#include "Storage.h"
 #include "Bytecodes.h"  /* for InstrPtr */
 #include "Disassembler.h"
 
-#include "Printer.h"
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(GRAN) || defined(PAR)
+// HWL: explicit fixed header size to make debugging easier
+int fixed_hs = FIXED_HS, itbl_sz = sizeofW(StgInfoTable), 
+    uf_sz=sizeofW(StgUpdateFrame), sf_sz=sizeofW(StgSeqFrame); 
+#endif
 
 /* --------------------------------------------------------------------------
  * local function decls
@@ -32,127 +44,201 @@ static rtsBool lookup_name   ( char *name, unsigned *result );
 static void    enZcode       ( char *in, char *out );
 #endif
 static char    unZcode       ( char ch );
-rtsBool lookupGHCName ( StgPtr addr, const char **result );
+const char *   lookupGHCName ( void *addr );
 static void    printZcoded   ( const char *raw );
 
 /* --------------------------------------------------------------------------
  * Printer
  * ------------------------------------------------------------------------*/
 
-extern void printPtr( StgPtr p )
+void printPtr( StgPtr p )
 {
     const char *raw;
-    if (lookupGHCName( p, &raw )) {
+    raw = lookupGHCName(p);
+    if (raw != NULL) {
         printZcoded(raw);
-#ifdef INTERPRETER
-    } else if ((raw = lookupHugsName(p)) != 0) {
-        fprintf(stderr, "%s", raw);
-#endif
     } else {
-        fprintf(stderr, "%p", p);
+        fprintf(stdout, "%p", p);
     }
 }
   
 void printObj( StgClosure *obj )
 {
-    fprintf(stderr,"Object "); printPtr((StgPtr)obj); fprintf(stderr," = ");
+    fprintf(stdout,"Object "); printPtr((StgPtr)obj); fprintf(stdout," = ");
     printClosure(obj);
 }
 
-static void printStdObject( StgClosure *obj, char* tag )
+static inline void
+printStdObjHdr( StgClosure *obj, char* tag )
+{
+    fprintf(stdout,"%s(",tag);
+    printPtr((StgPtr)obj->header.info);
+#ifdef PROFILING
+    fprintf(stdout,", %s", obj->header.prof.ccs->cc->label);
+#endif
+}
+
+static void
+printStdObject( StgClosure *obj, char* tag )
 {
     StgWord i, j;
-    const StgInfoTable* info = get_itbl(obj);
-    fprintf(stderr,"%s(",tag);
-    printPtr((StgPtr)info);
+    const StgInfoTable* info;
+
+    printStdObjHdr( obj, tag );
+
+    info = get_itbl(obj);
     for (i = 0; i < info->layout.payload.ptrs; ++i) {
-        fprintf(stderr,", ");
-        printPtr(payloadPtr(obj,i));
+        fprintf(stdout,", ");
+        printPtr((StgPtr)obj->payload[i]);
     }
     for (j = 0; j < info->layout.payload.nptrs; ++j) {
-        fprintf(stderr,", %xd#",payloadWord(obj,i+j));
+        fprintf(stdout,", %pd#",obj->payload[i+j]);
     }
-    fprintf(stderr,")\n");
+    fprintf(stdout,")\n");
 }
 
-void printClosure( StgClosure *obj )
+void
+printClosure( StgClosure *obj )
 {
-    switch ( get_itbl(obj)->type ) {
+    StgInfoTable *info;
+    
+    info = get_itbl(obj);
+
+    switch ( info->type ) {
     case INVALID_OBJECT:
             barf("Invalid object");
-#ifdef INTERPRETER
     case BCO:
-            fprintf(stderr,"BCO\n");
-            disassemble(stgCast(StgBCO*,obj),"\t");
+            disassemble( (StgBCO*)obj );
             break;
-#endif
+
+    case MUT_VAR:
+        {
+         StgMutVar* mv = (StgMutVar*)obj;
+         fprintf(stdout,"MUT_VAR(var=%p, link=%p)\n", mv->var, mv->mut_link);
+          break;
+        }
+
     case AP_UPD:
         {
            StgAP_UPD* ap = stgCast(StgAP_UPD*,obj);
             StgWord i;
-            fprintf(stderr,"AP_UPD("); printPtr((StgPtr)ap->fun);
+            fprintf(stdout,"AP_UPD("); printPtr((StgPtr)ap->fun);
             for (i = 0; i < ap->n_args; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(ap,i));
+                fprintf(stdout,", ");
+                printPtr((P_)ap->payload[i]);
             }
-            fprintf(stderr,")\n");
+            fprintf(stdout,")\n");
             break;
         }
+
     case PAP:
         {
            StgPAP* pap = stgCast(StgPAP*,obj);
             StgWord i;
-            fprintf(stderr,"AP_NUPD("); printPtr((StgPtr)pap->fun);
+            fprintf(stdout,"PAP("); printPtr((StgPtr)pap->fun);
             for (i = 0; i < pap->n_args; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(pap,i));
+                fprintf(stdout,", ");
+                printPtr((StgPtr)pap->payload[i]);
             }
-            fprintf(stderr,")\n");
+            fprintf(stdout,")\n");
             break;
         }
+
+    case FOREIGN:
+            fprintf(stdout,"FOREIGN("); 
+            printPtr((StgPtr)( ((StgForeignObj*)obj)->data ));
+            fprintf(stdout,")\n"); 
+            break;
+
     case IND:
-            fprintf(stderr,"IND("); 
+            fprintf(stdout,"IND("); 
             printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,")\n"); 
             break;
-    case CAF_UNENTERED:
-        {
-           StgCAF* caf = stgCast(StgCAF*,obj);
-            fprintf(stderr,"CAF_UNENTERED("); 
-            printPtr((StgPtr)caf->body);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->value); /* should be null */
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->link);  /* should be null */
-            fprintf(stderr,")\n"); 
+
+    case IND_STATIC:
+            fprintf(stdout,"IND_STATIC("); 
+            printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
+            fprintf(stdout,")\n"); 
             break;
-        }
-    case CAF_ENTERED:
-        {
-           StgCAF* caf = stgCast(StgCAF*,obj);
-            fprintf(stderr,"CAF_ENTERED("); 
-            printPtr((StgPtr)caf->body);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->value);
-            fprintf(stderr,", ");
-            printPtr((StgPtr)caf->link);
-            fprintf(stderr,")\n"); 
+
+    case IND_OLDGEN:
+            fprintf(stdout,"IND_OLDGEN("); 
+            printPtr((StgPtr)stgCast(StgInd*,obj)->indirectee);
+            fprintf(stdout,")\n"); 
             break;
-        }
+
     case CAF_BLACKHOLE:
-            fprintf(stderr,"CAF_BH("); 
-            printPtr((StgPtr)stgCast(StgBlackHole*,obj)->blocking_queue);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,"CAF_BH("); 
+            printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue);
+            fprintf(stdout,")\n"); 
+            break;
+
+    case SE_BLACKHOLE:
+            fprintf(stdout,"SE_BH\n"); 
             break;
+
+    case SE_CAF_BLACKHOLE:
+            fprintf(stdout,"SE_CAF_BH\n"); 
+            break;
+
     case BLACKHOLE:
-            fprintf(stderr,"BH\n"); 
+            fprintf(stdout,"BH\n"); 
             break;
+
     case BLACKHOLE_BQ:
-            fprintf(stderr,"BQ("); 
-            printPtr((StgPtr)stgCast(StgBlackHole*,obj)->blocking_queue);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,"BQ("); 
+            printPtr((StgPtr)stgCast(StgBlockingQueue*,obj)->blocking_queue);
+            fprintf(stdout,")\n"); 
             break;
+
+    case TSO:
+      fprintf(stdout,"TSO("); 
+      fprintf(stdout,"%d (%p)",((StgTSO*)obj)->id, (StgTSO*)obj);
+      fprintf(stdout,")\n"); 
+      break;
+
+#if defined(PAR)
+    case BLOCKED_FETCH:
+      fprintf(stdout,"BLOCKED_FETCH("); 
+      printGA(&(stgCast(StgBlockedFetch*,obj)->ga));
+      printPtr((StgPtr)(stgCast(StgBlockedFetch*,obj)->node));
+      fprintf(stdout,")\n"); 
+      break;
+
+    case FETCH_ME:
+      fprintf(stdout,"FETCH_ME("); 
+      printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      fprintf(stdout,")\n"); 
+      break;
+
+#ifdef DIST      
+    case REMOTE_REF:
+      fprintf(stdout,"REMOTE_REF("); 
+      printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      fprintf(stdout,")\n"); 
+      break;
+#endif
+  
+    case FETCH_ME_BQ:
+      fprintf(stdout,"FETCH_ME_BQ("); 
+      // printGA((globalAddr *)stgCast(StgFetchMe*,obj)->ga);
+      printPtr((StgPtr)stgCast(StgFetchMeBlockingQueue*,obj)->blocking_queue);
+      fprintf(stdout,")\n"); 
+      break;
+#endif
+#if defined(GRAN) || defined(PAR)
+    case RBH:
+      fprintf(stdout,"RBH("); 
+      printPtr((StgPtr)stgCast(StgRBH*,obj)->blocking_queue);
+      fprintf(stdout,")\n"); 
+      break;
+
+#endif
+
     case CONSTR:
+    case CONSTR_1_0: case CONSTR_0_1:
+    case CONSTR_1_1: case CONSTR_0_2: case CONSTR_2_0:
     case CONSTR_INTLIKE:
     case CONSTR_CHARLIKE:
     case CONSTR_STATIC:
@@ -162,145 +248,180 @@ void printClosure( StgClosure *obj )
              * tag as well.
             */
             StgWord i, j;
-            const StgInfoTable* info = get_itbl(obj);
-            fprintf(stderr,"PACK(");
-            printPtr((StgPtr)info);
-            fprintf(stderr,"(tag=%d)",info->srt_len);
+#ifdef PROFILING
+           fprintf(stdout,"%s(", info->prof.closure_desc);
+           fprintf(stdout,"%s", obj->header.prof.ccs->cc->label);
+#else
+            fprintf(stdout,"CONSTR(");
+            printPtr((StgPtr)obj->header.info);
+            fprintf(stdout,"(tag=%d)",info->srt_len);
+#endif
             for (i = 0; i < info->layout.payload.ptrs; ++i) {
-                fprintf(stderr,", ");
-                printPtr(payloadPtr(obj,i));
+               fprintf(stdout,", ");
+                printPtr((StgPtr)obj->payload[i]);
             }
             for (j = 0; j < info->layout.payload.nptrs; ++j) {
-                fprintf(stderr,", %x#",payloadWord(obj,i+j));
+                fprintf(stdout,", %p#", obj->payload[i+j]);
             }
-            fprintf(stderr,")\n");
+            fprintf(stdout,")\n");
             break;
         }
+
+#ifdef XMLAMBDA
+/* rows are mutarrays in xmlambda, maybe we should make a new type: ROW */
+    case MUT_ARR_PTRS_FROZEN:
+          {
+            StgWord i;
+            StgMutArrPtrs* p = stgCast(StgMutArrPtrs*,obj);
+
+            fprintf(stdout,"Row<%i>(",p->ptrs);
+            for (i = 0; i < p->ptrs; ++i) {
+                if (i > 0) fprintf(stdout,", ");
+                printPtr((StgPtr)(p->payload[i]));
+            }
+            fprintf(stdout,")\n");
+            break;
+          }
+#endif  
+
     case FUN:
+    case FUN_1_0: case FUN_0_1: 
+    case FUN_1_1: case FUN_0_2: case FUN_2_0:
     case FUN_STATIC:
             printStdObject(obj,"FUN");
             break;
+
     case THUNK:
+    case THUNK_1_0: case THUNK_0_1:
+    case THUNK_1_1: case THUNK_0_2: case THUNK_2_0:
     case THUNK_STATIC:
             /* ToDo: will this work for THUNK_STATIC too? */
+#ifdef PROFILING
+           printStdObject(obj,info->prof.closure_desc);
+#else
             printStdObject(obj,"THUNK");
+#endif
             break;
-#if 0
+
+    case THUNK_SELECTOR:
+       printStdObjHdr(obj, "THUNK_SELECTOR");
+       fprintf(stdout, ", %p)\n", ((StgSelector *)obj)->selectee);
+       break;
+
     case ARR_WORDS:
         {
             StgWord i;
-            fprintf(stderr,"ARR_WORDS(\"");
-            /* ToDo: we can't safely assume that this is a string! */
+            fprintf(stdout,"ARR_WORDS(\"");
+            /* ToDo: we can't safely assume that this is a string! 
             for (i = 0; arrWordsGetChar(obj,i); ++i) {
                 putchar(arrWordsGetChar(obj,i));
-            }
-            fprintf(stderr,"\")\n");
+               } */
+           for (i=0; i<((StgArrWords *)obj)->words; i++)
+             fprintf(stdout, "%u", ((StgArrWords *)obj)->payload[i]);
+            fprintf(stdout,"\")\n");
             break;
         }
-#endif
+
     case UPDATE_FRAME:
         {
             StgUpdateFrame* u = stgCast(StgUpdateFrame*,obj);
-            fprintf(stderr,"UpdateFrame(");
+            fprintf(stdout,"UpdateFrame(");
             printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
+            fprintf(stdout,",");
             printPtr((StgPtr)u->updatee);
-            fprintf(stderr,",");
+            fprintf(stdout,",");
             printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,")\n"); 
             break;
         }
+
     case CATCH_FRAME:
         {
             StgCatchFrame* u = stgCast(StgCatchFrame*,obj);
-            fprintf(stderr,"CatchFrame(");
+            fprintf(stdout,"CatchFrame(");
             printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
+            fprintf(stdout,",");
             printPtr((StgPtr)u->handler);
-            fprintf(stderr,",");
+            fprintf(stdout,",");
             printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,")\n"); 
             break;
         }
+
     case SEQ_FRAME:
         {
             StgSeqFrame* u = stgCast(StgSeqFrame*,obj);
-            fprintf(stderr,"SeqFrame(");
+            fprintf(stdout,"SeqFrame(");
             printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,",");
+            fprintf(stdout,",");
             printPtr((StgPtr)u->link);
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,")\n"); 
             break;
         }
+
     case STOP_FRAME:
         {
             StgStopFrame* u = stgCast(StgStopFrame*,obj);
-            fprintf(stderr,"StopFrame(");
+            fprintf(stdout,"StopFrame(");
             printPtr((StgPtr)GET_INFO(u));
-            fprintf(stderr,")\n"); 
+            fprintf(stdout,")\n"); 
             break;
         }
     default:
+            //barf("printClosure %d",get_itbl(obj)->type);
+            fprintf(stdout, "*** printClosure: unknown type %d ****\n",
+                    get_itbl(obj)->type );
             barf("printClosure %d",get_itbl(obj)->type);
             return;
     }
 }
 
+/*
+void printGraph( StgClosure *obj )
+{
+ printClosure(obj);
+}
+*/
+
 StgPtr printStackObj( StgPtr sp )
 {
-    /*fprintf(stderr,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */
+    /*fprintf(stdout,"Stack[%d] = ", &stgStack[STACK_SIZE] - sp); */
 
     if (IS_ARG_TAG(*sp)) {
-
-#ifdef DEBUG_EXTRA
-        StackTag tag = (StackTag)*sp;
-        switch ( tag ) {
-        case ILLEGAL_TAG:
-                barf("printStackObj: ILLEGAL_TAG");
-                break;
-        case REALWORLD_TAG:
-                fprintf(stderr,"RealWorld#\n");
-                break;
-        case INT_TAG:
-                fprintf(stderr,"Int# %d\n", *(StgInt*)(sp+1));
-                break;
-        case INT64_TAG:
-                fprintf(stderr,"Int64# %lld\n", *(StgInt64*)(sp+1));
-                break;
-        case WORD_TAG:
-                fprintf(stderr,"Word# %d\n", *(StgWord*)(sp+1));
-                break;
-        case ADDR_TAG:
-                fprintf(stderr,"Addr# "); printPtr(*(StgAddr*)(sp+1)); fprintf(stderr,"\n");
-                break;
-        case CHAR_TAG:
-                fprintf(stderr,"Char# %d\n", *(StgChar*)(sp+1));
-                break;
-        case FLOAT_TAG:
-                fprintf(stderr,"Float# %f\n", PK_FLT(sp+1));
-                break;
-        case DOUBLE_TAG:
-                fprintf(stderr,"Double# %f\n", PK_DBL(sp+1));
-                break;
-        default:
-                barf("printStackObj: unrecognised ARGTAG %d",tag);
+        nat i;
+        StgWord tag = *sp++;
+        fprintf(stdout,"Tagged{");
+        for (i = 0; i < tag; i++) {
+            fprintf(stdout,"0x%x#", (unsigned)(*sp++));
+            if (i < tag-1) fprintf(stdout, ", ");
         }
-        sp += 1 + ARG_SIZE(tag);
-
-#else /* !DEBUG_EXTRA */
-       {
-           StgWord tag = *sp++;
-           nat i;
-           fprintf(stderr,"Tag: %d words\n", tag);
-           for (i = 0; i < tag; i++) {
-               fprintf(stderr,"Word# %d\n", *sp++);
-           }
-       }
-#endif
-
+        fprintf(stdout, "}\n");
     } else {
+        StgClosure* c = (StgClosure*)(*sp);
         printPtr((StgPtr)*sp);
-        fprintf(stderr,"\n");
+        if (c == (StgClosure*)&stg_ctoi_ret_R1p_info) {
+           fprintf(stdout, "\t\t\tstg_ctoi_ret_R1p_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_ret_R1n_info) {
+           fprintf(stdout, "\t\t\tstg_ctoi_ret_R1n_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_ret_F1_info) {
+           fprintf(stdout, "\t\t\tstg_ctoi_ret_F1_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_ret_D1_info) {
+           fprintf(stdout, "\t\t\tstg_ctoi_ret_D1_info\n" );
+       } else
+        if (c == (StgClosure*)&stg_ctoi_ret_V_info) {
+           fprintf(stdout, "\t\t\tstg_ctoi_ret_V_info\n" );
+       } else
+        if (get_itbl(c)->type == BCO) {
+           fprintf(stdout, "\t\t\t");
+           fprintf(stdout, "BCO(...)\n"); 
+        }
+        else {
+           fprintf(stdout, "\t\t\t");
+           printClosure ( (StgClosure*)(*sp));
+        }
         sp += 1;
     }
     return sp;
@@ -309,7 +430,7 @@ StgPtr printStackObj( StgPtr sp )
 
 void printStackChunk( StgPtr sp, StgPtr spBottom )
 {
-    StgNat32 bitmap;
+    StgWord bitmap;
     const StgInfoTable *info;
 
     ASSERT(sp <= spBottom);
@@ -339,25 +460,25 @@ void printStackChunk( StgPtr sp, StgPtr spBottom )
            continue;
 
        case RET_DYN:
-         fprintf(stderr, "RET_DYN (%p)\n", sp);
+         fprintf(stdout, "RET_DYN (%p)\n", sp);
          bitmap = *++sp;
          ++sp;
-         fprintf(stderr, "Bitmap: 0x%x\n", bitmap);
+         fprintf(stdout, "Bitmap: 0x%x\n", bitmap);
          goto small_bitmap;
 
        case RET_SMALL:
        case RET_VEC_SMALL:
-         fprintf(stderr, "RET_SMALL (%p)\n", sp);
+         fprintf(stdout, "RET_SMALL (%p)\n", sp);
          bitmap = info->layout.bitmap;
          sp++;
        small_bitmap:
          while (bitmap != 0) {
-           fprintf(stderr,"Stack[%d] (%p) = ", spBottom-sp, sp);
+           fprintf(stdout,"   stk[%ld] (%p) = ", spBottom-sp, sp);
            if ((bitmap & 1) == 0) {
              printPtr((P_)*sp);
-             fprintf(stderr,"\n");
+             fprintf(stdout,"\n");
            } else {
-             fprintf(stderr,"Word# %d\n", *sp++);
+             fprintf(stdout,"Word# %ld\n", *sp);
            }         
            sp++;
            bitmap = bitmap >> 1;
@@ -372,7 +493,7 @@ void printStackChunk( StgPtr sp, StgPtr spBottom )
          break;
        }
       }
-      fprintf(stderr,"Stack[%d] (%p) = ", spBottom-sp, sp);
+      fprintf(stdout,"Stack[%ld] (%p) = ", spBottom-sp, sp);
       sp = printStackObj(sp);
     }
 }
@@ -417,6 +538,94 @@ void printTSO( StgTSO *tso )
     /* printStackChunk( tso->sp, tso->stack+tso->stack_size); */
 }
 
+/* -----------------------------------------------------------------------------
+   Closure types
+   
+   NOTE: must be kept in sync with the closure types in includes/ClosureTypes.h
+   -------------------------------------------------------------------------- */
+
+static char *closure_type_names[] = {
+  "INVALID_OBJECT",            /* 0  */
+  "CONSTR",                    /* 1  */
+  "CONSTR_1_0",                        /* 2  */
+  "CONSTR_0_1",                        /* 3  */
+  "CONSTR_2_0",                        /* 4  */
+  "CONSTR_1_1",                        /* 5  */
+  "CONSTR_0_2",                        /* 6  */
+  "CONSTR_INTLIKE",            /* 7  */
+  "CONSTR_CHARLIKE",           /* 8  */
+  "CONSTR_STATIC",             /* 9  */
+  "CONSTR_NOCAF_STATIC",       /* 10 */
+  "FUN",                       /* 11 */
+  "FUN_1_0",                   /* 12 */
+  "FUN_0_1",                   /* 13 */
+  "FUN_2_0",                   /* 14 */
+  "FUN_1_1",                   /* 15 */
+  "FUN_0_2",                   /* 16 */
+  "FUN_STATIC",                        /* 17 */
+  "THUNK",                     /* 18 */
+  "THUNK_1_0",                 /* 19 */
+  "THUNK_0_1",                 /* 20 */
+  "THUNK_2_0",                 /* 21 */
+  "THUNK_1_1",                 /* 22 */
+  "THUNK_0_2",                 /* 23 */
+  "THUNK_STATIC",              /* 24 */
+  "THUNK_SELECTOR",            /* 25 */
+  "BCO",                       /* 26 */
+  "AP_UPD",                    /* 27 */
+  "PAP",                       /* 28 */
+  "IND",                       /* 29 */
+  "IND_OLDGEN",                        /* 30 */
+  "IND_PERM",                  /* 31 */
+  "IND_OLDGEN_PERM",           /* 32 */
+  "IND_STATIC",                        /* 33 */
+  "CAF_BLACKHOLE",             /* 36 */
+  "RET_BCO",                   /* 37 */
+  "RET_SMALL",                 /* 38 */
+  "RET_VEC_SMALL",             /* 39 */
+  "RET_BIG",                   /* 40 */
+  "RET_VEC_BIG",               /* 41 */
+  "RET_DYN",                   /* 42 */
+  "UPDATE_FRAME",              /* 43 */
+  "CATCH_FRAME",               /* 44 */
+  "STOP_FRAME",                        /* 45 */
+  "SEQ_FRAME",                 /* 46 */
+  "BLACKHOLE",                 /* 47 */
+  "BLACKHOLE_BQ",              /* 48 */
+  "SE_BLACKHOLE",              /* 49 */
+  "SE_CAF_BLACKHOLE",          /* 50 */
+  "MVAR",                      /* 51 */
+  "ARR_WORDS",                 /* 52 */
+  "MUT_ARR_PTRS",              /* 53 */
+  "MUT_ARR_PTRS_FROZEN",       /* 54 */
+  "MUT_VAR",                   /* 55 */
+  "WEAK",                      /* 56 */
+  "FOREIGN",                   /* 57 */
+  "STABLE_NAME",               /* 58 */
+  "TSO",                       /* 59 */
+  "BLOCKED_FETCH",             /* 60 */
+  "FETCH_ME",                   /* 61 */
+  "FETCH_ME_BQ",                /* 62 */
+  "RBH",                        /* 63 */
+  "EVACUATED",                  /* 64 */
+  "REMOTE_REF",                 /* 65 */
+  "N_CLOSURE_TYPES"            /* 66 */
+};
+
+char *
+info_type(StgClosure *closure){ 
+  return closure_type_names[get_itbl(closure)->type];
+}
+
+char *
+info_type_by_ip(StgInfoTable *ip){ 
+  return closure_type_names[ip->type];
+}
+
+void
+info_hdr_type(StgClosure *closure, char *res){ 
+  strcpy(res,closure_type_names[get_itbl(closure)->type]);
+}
 
 /* --------------------------------------------------------------------------
  * Address printing code
@@ -605,16 +814,15 @@ static void enZcode( char *in, char *out )
 }
 #endif
 
-rtsBool lookupGHCName( StgPtr addr, const char **result )
+const char *lookupGHCName( void *addr )
 {
     nat i;
     for( i = 0; i < table_size && table[i].value != (unsigned) addr; ++i ) {
     }
     if (i < table_size) {
-        *result = table[i].name;
-        return rtsTrue;
+        return table[i].name;
     } else {
-        return rtsFalse;
+        return NULL;
     }
 }
 
@@ -624,10 +832,10 @@ static void printZcoded( const char *raw )
     
     while ( raw[j] != '\0' ) {
         if (raw[j] == 'Z') {
-            fputc(unZcode(raw[j+1]),stderr);
+            fputc(unZcode(raw[j+1]),stdout);
             j = j + 2;
         } else {
-            fputc(raw[j],stderr);
+            fputc(raw[j],stdout);
             j = j + 1;
         }
     }
@@ -637,7 +845,10 @@ static void printZcoded( const char *raw )
  * Symbol table loading
  * ------------------------------------------------------------------------*/
 
-#ifdef HAVE_BFD_H
+/* Causing linking trouble on Win32 plats, so I'm
+   disabling this for now. 
+*/
+#ifdef USING_LIBBFD
 
 #include <bfd.h>
 
@@ -656,6 +867,7 @@ static rtsBool isReal( flagword flags, const char *name )
         return rtsFalse;
     }
 #else
+    (void)flags;   /* keep gcc -Wall happy */
     if (*name == '\0'  || 
        (name[0] == 'g' && name[1] == 'c' && name[2] == 'c') ||
        (name[0] == 'c' && name[1] == 'c' && name[2] == '.')) {
@@ -707,14 +919,14 @@ extern void DEBUG_LoadSymbols( char *name )
         for( i = 0; i != number_of_symbols; ++i ) {
             symbol_info info;
             bfd_get_symbol_info(abfd,symbol_table[i],&info);
-            /*fprintf(stderr,"\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
+            /*fprintf(stdout,"\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
             if (isReal(info.type, info.name)) {
                 num_real_syms += 1;
             }
         }
     
         IF_DEBUG(evaluator,
-                 fprintf(stderr,"Loaded %ld symbols. Of which %ld are real symbols\n", 
+                 fprintf(stdout,"Loaded %ld symbols. Of which %ld are real symbols\n", 
                          number_of_symbols, num_real_syms)
                  );
 
@@ -735,11 +947,67 @@ extern void DEBUG_LoadSymbols( char *name )
 
 #else /* HAVE_BFD_H */
 
-extern void DEBUG_LoadSymbols( char *name )
+extern void DEBUG_LoadSymbols( char *name STG_UNUSED )
 {
   /* nothing, yet */
 }
 
 #endif /* HAVE_BFD_H */
 
+#include "StoragePriv.h"
+
+void findPtr(P_ p, int);               /* keep gcc -Wall happy */
+
+void
+findPtr(P_ p, int follow)
+{
+  nat s, g;
+  P_ q, r;
+  bdescr *bd;
+  const int arr_size = 1024;
+  StgPtr arr[arr_size];
+  int i = 0;
+
+  for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+      for (s = 0; s < generations[g].n_steps; s++) {
+         if (RtsFlags.GcFlags.generations == 1) {
+             bd = generations[g].steps[s].to_blocks;
+         } else {
+             bd = generations[g].steps[s].blocks;
+         }
+         for (; bd; bd = bd->link) {
+             for (q = bd->start; q < bd->free; q++) {
+                 if (*q == (W_)p) {
+                     if (i < arr_size) {
+                         r = q;
+                         while (!LOOKS_LIKE_GHC_INFO(*r) || *r == NULL) {
+                             r--;
+                         }
+                         fprintf(stdout, "%p = ", r);
+                         printClosure((StgClosure *)r);
+                         arr[i++] = r;
+                     } else {
+                         return;
+                     }
+                 }
+             }
+         }
+      }
+  }
+  if (follow && i == 1) {
+      fprintf(stdout, "-->\n");
+      findPtr(arr[0], 1);
+  }
+}
+
+#else /* DEBUG */
+void printPtr( StgPtr p )
+{
+    fprintf(stdout, "ptr 0x%p (enable -DDEBUG for more info) " , p );
+}
+  
+void printObj( StgClosure *obj )
+{
+    fprintf(stdout, "obj 0x%p (enable -DDEBUG for more info) " , obj );
+}
 #endif /* DEBUG */