diff --git a/NT/init_nt b/NT/init_nt
index 849a2d195a754faacb64b019c727b4637da74058..b5d02d47b22f4cac453f3d08840180a5b9edfc74 100755
--- a/NT/init_nt
+++ b/NT/init_nt
@@ -64,6 +64,16 @@ path=$MSVC\\bin;
 include=$MSVC\\Include;$local\\include
 lib=$MSVC\\Lib;$local\\lib
 "
+
+      # This variable is used by pntld to find
+      # the libraries (*.lib) on the UNIX system.
+      #
+      # If your library directory is not available on the unix system you
+      # will need to make a copy. -Hubbe
+      #
+      NTLD_LIBRARY_PATH='/net/cytocin/winshare/vc98/Lib:/net/cytocin/winshare/local/lib'
+
+      export NTLD_LIBRARY_PATH
       export REMOTE_VARIABLES
     else
       echo "We are not Hubbe."
diff --git a/NT/tools/pntld b/NT/tools/pntld
index 11401612cc70ecfa032c83aad64b0f13033036a2..c81b65672e9f4567d205e0c82fca577dc748e1c7 100755
--- a/NT/tools/pntld
+++ b/NT/tools/pntld
@@ -1,6 +1,12 @@
 #!/usr/local/bin/pike
 
-/* Partial linker for COFF files, written by Fredrik Hubinette 2000 */
+// Partial linker for COFF files, written by Fredrik Hubinette 2000
+// 
+// Things left to do:
+//   Merge sections
+//   Test if resulting files work with cl.exe
+//   Support line number information
+//   Support 64 bit architechtures
 
 class Reloc
 {
@@ -35,6 +41,8 @@ class Symbol
 mapping(string:Symbol) global_symbols=([]);
 array(Section) global_sections=({});
 array(string) global_directives=({});
+array(string) libpath=({});
+array(string) libraries=({});
 
 class Linker
 {
@@ -637,29 +645,75 @@ class dumpfile
 
   void dumpArchive(int pos)
     {
+      string name;
+      int num;
+      int longnames;
       while(pos < strlen(data))
       {
-	string name=range(pos,16);
+	num++;
 	int size = (int) range(pos+48,10);
-
+	name=range(pos,16);
+	if(name[0]=='/')
+	{
+	  if(num == 3)
+	  {
+	    longnames=pos+60;
+	  }
+	  else if(longnames && sscanf(name,"/%d",int longnamenum))
+	  {
+	    name=nulltermstring(longnames + longnamenum);
+	  }
+	}else{
+	  if(sscanf(reverse(name),"%*s/%s",name))
+	    name=reverse(name);
+	}
 #ifdef DEBUG
 	write("\n");
 	write("# name: %s\n",name);
-	write("# date: %s\n",ctime( (int) range(pos+16,12) ) );
+	write("# date: %s",ctime( (int) range(pos+16,12) ) );
 	write("# uid : %s\n",range(pos+28,6));
 	write("# gid : %s\n",range(pos+34,6));
 	write("# mode: %s\n",range(pos+40,8));
 	write("# size: %s\n",range(pos+48,10));
 #endif
-
 	if(name[0]!='/')
-	  dumpfile(data, pos+60,0,name);
-
+	{
+	  dumpfile(data, pos+60, 0, name);
+	}
 	pos+=60;
 	pos+=(size+1)&~1;
       }
     }
 
+  void dumpImportLib()
+    {
+      string name= ( filename/"/" )[-1];
+#if 0
+      sscanf(range(0,20),
+	     "%-2c%-2c%-2c%-2c%-4c%-4c%-2c%-2c",
+	     int sig1,
+	     int sig2,
+	     int version,
+	     int machine,
+	     int timestamp,
+	     int size_of_data,
+	     int ordinal,
+	     int type);
+      write("Sig1      : %x\n",sig1);
+      write("Sig2      : %x\n",sig2);
+      write("version   : %x\n",version);
+      write("Machine   : %x\n", machine);
+      write("Time      : %s",ctime(timestamp));
+      write("Ordinal   : %x\n",ordinal);
+      write("Type:     : %x\n",type);
+      write("Name      : %s\n",nulltermstring(20));
+
+     write("Importing library: %O\n",name);
+#endif
+  
+      global_directives|=({ "-LIB:"+name });
+    }
+
   void create(string d, void|int p, void|int len, void|string f)
     {
       base=p;
@@ -674,21 +728,24 @@ class dumpfile
 #endif
 	dumpArchive(8);
       }else{
-	if(len >=0x40 && !dumpPE(i4(0x3c)))
+	if(i2(0) == 0 && i2(2) == 0xffff)
 	{
+	  dumpImportLib();
+	}else{
 	  dumpCOFF(0);
-	}   
+	}
       }
     }
 }
 
 int main(int argc, array(string) argv)
 {
+  int err;
   int strip=0;
   string output="a.out";
 //  werror("%O\n",argv);
   werror("Pike Win32 partial linker.\n"
-	 "$Id: pntld,v 1.1 2000/12/23 07:19:49 hubbe Exp $\n"
+	 "$Id: pntld,v 1.2 2000/12/27 07:55:09 hubbe Exp $\n"
 	 "Written by Fredrik Hubinette 2000\n");
 
   foreach(Getopt.find_all_options(argv,aggregate(
@@ -704,8 +761,11 @@ int main(int argc, array(string) argv)
       {
 	case "S": strip++; break;
 	  
-	case "R":
 	case "L":
+	  libpath|=({opt[1]});
+	  break;
+
+	case "R":
 	  global_directives|=({ "-?rpath:"+opt[1] });
 	  break;
 
@@ -714,11 +774,7 @@ int main(int argc, array(string) argv)
 	  {
 	    case "c": case "m": break;
 	    default:
-	      /* FIXME:
-	       * search for *.lib files and link them 'statically'
-	       * if found.
-	       */
-	      global_directives|=({ "-lib:"+opt[1] });
+	      libraries|=({opt[1]});
 	  }
 	  break;
 	  
@@ -728,6 +784,49 @@ int main(int argc, array(string) argv)
       }
     }
 
+  if(getenv("NTLD_LIBRARY_PATH"))
+    libpath|=getenv("NTLD_LIBRARY_PATH")/":";
+
+  if(getenv("NTLD_RUN_PATH"))
+    foreach(getenv("NTLD_RUN_PATH")/":",string p)
+      global_directives|=({"-?rpath:"+p});
+
+  libpath|=({"."});
+
+  foreach(libraries, string lib)
+    {
+      int found;
+      foreach(libpath, string path)
+	{
+	  string filename=combine_path(path,lib+".lib");
+#ifdef DEBUG
+	  werror("Looking for %s\n",filename);
+#endif
+	  if(string file=Stdio.read_file(filename))
+	  {
+	    dumpfile(file, 0, 0, filename);
+	    found=1;
+	    break;
+	  }
+
+	  filename=combine_path(path,upper_case(lib+".lib"));
+#ifdef DEBUG
+	  werror("Looking for %s\n",filename);
+#endif
+	  if(string file=Stdio.read_file(filename))
+	  {
+	    dumpfile(file, 0, 0, filename);
+	    found=1;
+	    break;
+	  }
+	}
+      if(!found)
+      {
+	werror("Failed to find library: %s\n",lib);
+	err++;
+      }
+    }
+
   argv=Getopt.get_args(argv);
 
   foreach(argv[1..],string file)
@@ -753,9 +852,10 @@ int main(int argc, array(string) argv)
     global_sections= ({s}) + global_sections;
   }
 
+  if(err) exit(err);
   rm(output);
   Stdio.write_file(output,
 		   Linker()->out(global_sections,
 				 values(global_symbols)));
-  exit(0);
+  exit(err);
 }
diff --git a/src/dlopen.c b/src/dlopen.c
index f5871faba3865bc646df148fe61cbcbdb6c4dfa2..25319fdac58c9b111e3a21b08657dcbf62442b21 100644
--- a/src/dlopen.c
+++ b/src/dlopen.c
@@ -20,13 +20,21 @@
 #include <sys/stat.h>
 #include <assert.h>
 
+/* Todo:
+ *  Make image debugable if possible
+ *  Support Win64
+ *  Separate RWX, RW and R memory sections.
+ */
 
-#define DLDEBUG 1
+/* #define DLDEBUG 1 */
 #define DL_VERBOSE 1
 
+
 #ifdef DLDEBUG
+#define FLUSH() do{ fflush(stderr); Sleep(500); }while(0)
 #define DO_IF_DLDEBUG(X) X
 #else
+#define FLUSH()
 #define DO_IF_DLDEBUG(X)
 #endif
 
@@ -67,7 +75,7 @@ size_t STRNLEN(char *s, size_t maxlen)
 
 #else /* PIKE_CONCAT */
 
-RCSID("$Id: dlopen.c,v 1.2 2000/12/23 16:18:14 grubba Exp $");
+RCSID("$Id: dlopen.c,v 1.3 2000/12/27 07:55:09 hubbe Exp $");
 
 #endif
 
@@ -94,6 +102,7 @@ static struct Htable *alloc_htable(size_t size)
   struct Htable *ret;
 #ifdef DLDEBUG
   fprintf(stderr,"alloc_htable(%d)\n",size);
+  FLUSH();
 #endif
   ret=(struct Htable *)malloc(sizeof(struct Htable) +
 			      sizeof(void *)*(size-1));
@@ -248,6 +257,9 @@ static void htable_free(struct Htable *h, void(*hfree)(void *))
 static int filesize(char *filename)
 {
   struct stat st;
+#ifdef DLDEBUG
+  fprintf(stderr,"filesize(%s)\n",filename);
+#endif
   if(stat(filename, &st)<0) return -1;
   return st.st_size;
 }
@@ -291,6 +303,8 @@ static char *read_file(char *name, size_t *len)
   while(fd_close(fd) < 0 && errno==EINTR);
 #ifdef DLDEBUG
   fprintf(stderr,"Done reading\n");
+  fflush(stderr);
+  Sleep(500);
 #endif
   return buffer;
 }
@@ -347,12 +361,18 @@ static int append_dlllist(struct DLLList **l,
 			  char *name)
 {
   struct DLLList *n;
-  HINSTANCE tmp=LoadLibrary(name);
+  HINSTANCE tmp;
+#ifdef DLDEBUG
+  fprintf(stderr,"append_dlllist(%s)\n",name);
+  FLUSH();
+#endif
+  tmp=LoadLibrary(name);
   if(!tmp) return 0;
   n=(struct DLLList *)malloc(sizeof(struct DLLList));
   n->dll=tmp;
 #ifdef DLDEBUG
   fprintf(stderr,"append_dlllist(%s)->%p\n",name,n->dll);
+  FLUSH();
 #endif
   n->next=0;
   while( *l ) l= & (*l)->next;
@@ -506,7 +526,9 @@ static void *low_dlsym(struct DLHandle *handle,
   }
 #ifdef DL_VERBOSE
   if(!ptr)
+  {
     fprintf(stderr,"Failed to find identifier %s\n",tmp);
+  }
 #endif
   return ptr;
 }
@@ -535,6 +557,7 @@ static parse_link_info(struct DLHandle *ret,
     fprintf(stderr,"DLINFO(%d): ",len);
     for(z=0;z<len;z++) fprintf(stderr,"%c",info[z]);
     fprintf(stderr,"\n");
+    FLUSH();
   }
 #endif
 
@@ -545,6 +568,7 @@ static parse_link_info(struct DLHandle *ret,
 
 #ifdef DLDEBUG    
     fprintf(stderr,"Parse link info ptr=%d\n",ptr,l);
+    FLUSH();
 #endif
 
     end=MEMCHR(info+ptr,' ',len-ptr);
@@ -554,7 +578,17 @@ static parse_link_info(struct DLHandle *ret,
       l=len-ptr;
 
 #ifdef DLDEBUG    
-    fprintf(stderr,"Parse link info ptr=%d len=%d\n",ptr,l);
+    fprintf(stderr,"Parse link info ptr=%d len=%d '%c%c%c%c%c%c%c%c'\n",
+	    ptr,l,
+	    info[x],
+	    info[x+1],
+	    info[x+2],
+	    info[x+3],
+	    info[x+4],
+	    info[x+5],
+	    info[x+6],
+	    info[x+7]);
+    FLUSH();
 #endif
 
     if(info[x] == '-')
@@ -564,13 +598,31 @@ static parse_link_info(struct DLHandle *ret,
       if(!memcmp(info+x,"lib:",4) || !memcmp(info+x,"LIB:",4))
       {
 	x+=4;
-	memcpy(buffer,info+x,l-x);
-	buffer[l-x]=0;
+#ifdef DLDEBUG    
+	fprintf(stderr,"Found lib: ptr=%d len=%d '%c%c%c%c%c%c%c%c'\n",
+		x,
+		l-(x-ptr),
+		info[x],
+		info[x+1],
+		info[x+2],
+		info[x+3],
+		info[x+4],
+		info[x+5],
+		info[x+6],
+		info[x+7]);
+	FLUSH();
+#endif
+	memcpy(buffer,info+x,l-(x-ptr));
+	buffer[l-(x-ptr)]=0;
 	append_dlllist(&ret->dlls, buffer);
       }
     }
     ptr+=l+1;
   }
+#ifdef DLDEBUG    
+  fprintf(stderr,"Parse link info done.\n");
+  FLUSH();
+#endif
 }
 
 static int dl_load_coff_files(struct DLHandle *ret,
@@ -586,6 +638,7 @@ static int dl_load_coff_files(struct DLHandle *ret,
 
 #ifdef DLDEBUG
   fprintf(stderr,"dl_load_coff_files(%p,%p,%d)\n",ret,tmp,num);
+  FLUSH();
 #endif
 
   if(!num) return 0;
@@ -689,6 +742,7 @@ static int dl_load_coff_files(struct DLHandle *ret,
 
 #ifdef DLDEBUG
   fprintf(stderr,"DL: moving code\n");
+  FLUSH();
 #endif
 
   /* Copy code into executable memory */
@@ -797,6 +851,7 @@ static int dl_load_coff_files(struct DLHandle *ret,
 
 #ifdef DLDEBUG
   fprintf(stderr,"DL: resolving\n");
+  FLUSH();
 #endif
 
   /* Do resolve and relocations */
@@ -893,21 +948,17 @@ static int dl_load_coff_files(struct DLHandle *ret,
 
 	    /* We may need to support more types here */
 	  case COFFReloc_type_dir32:
-	    if(SYMBOLS(sym).type >> 4 == 2)
+	    if( (SYMBOLS(sym).type >> 4) == 2 && !SYMBOLS(sym).secnum)
 	    {
-	      /* Indirect function pointer (#&$#*&#$ */
-	      ((char **)loc)[0]=(char *)(data->symbol_addresses + sym);
 #ifdef DLDEBUG
-	    fprintf(stderr,"DL: reloc indirect: loc %p = %p, *%p = %p + %d\n",
-		    loc,ptr,
-		    *(char **)loc,data->symbol_addresses,sym);
+	      fprintf(stderr,"DL: Indirect *%p = %d secnum=%d!!!\n", loc, *(INT32 *)loc,SYMBOLS(sym).secnum);
 #endif
-	    }else{
-	      ((INT32 *)loc)[0]+=(INT32)ptr;
+	      ptr=(char *)(data->symbol_addresses + sym);
+	    }
+	    ((INT32 *)loc)[0]+=(INT32)ptr;
 #ifdef DLDEBUG
 	    fprintf(stderr,"DL: reloc absolute: loc %p = %p\n", loc,ptr);
 #endif
-	    }
 	       
 	    break;
 
@@ -948,6 +999,7 @@ static int dl_loadarchive(struct DLHandle *ret,
 
 #ifdef DLDEBUG
   fprintf(stderr,"dl_loadarchive\n");
+  FLUSH();
 #endif
 
   /* Count how many object files there are in the loop */
@@ -991,6 +1043,7 @@ static int dl_loadcoff(struct DLHandle *ret,
 
 #ifdef DLDEBUG
   fprintf(stderr,"dl_loadcoff\n");
+  FLUSH();
 #endif
 
   tmp.buflen=data->buflen;
@@ -1012,6 +1065,7 @@ static int dl_load_file(struct DLHandle *ret,
   INT32 tmp;
 #ifdef DLDEBUG
   fprintf(stderr,"dl_load_file\n");
+  FLUSH();
 #endif
 
   if(data->buflen > 8 && ! memcmp(data->buffer,"!<arch>\n",8))
@@ -1033,12 +1087,11 @@ struct DLHandle *dlopen(char *name, int flags)
   int retcode;
   tmpdata.flags=flags;
 
-  if(!global_symbols) init_dlopen();
-
 #ifdef DLDEBUG
   fprintf(stderr,"dlopen(%s,%d)\n",name,flags);
 #endif
-  abort();
+
+  if(!global_symbols) init_dlopen();
 
   for(ret=first;ret;ret=ret->next)
   {
@@ -1065,7 +1118,6 @@ struct DLHandle *dlopen(char *name, int flags)
     dlclose(ret);
     return 0;
   }
-
   
   retcode=dl_load_file(ret, &tmpdata);
   free(tmpdata.buffer);
@@ -1244,6 +1296,10 @@ static void init_dlopen(void)
     EXPORT(abort);
     EXPORT(rand);
     EXPORT(srand);
+    EXPORT(getc);
+    EXPORT(ungetc);
+    EXPORT(printf);
+    EXPORT(perror);
   }
 
 #ifdef DLDEBUG