diff --git a/debugger/msc.c b/debugger/msc.c
index a998709f0a4194892e6856095f35866639448cda..a7967ab0759b97f9615991748d43cb950230b2d1 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -3,6 +3,7 @@
  * from PDB files.
  *
  * Copyright (C) 1996, Eric Youngdale.
+ * Copyright (C) 1999, Ulrich Weigand.
  *
  * Note - this handles reading debug information for 32 bit applications
  * that run under Windows-NT for example.  I doubt that this would work well
@@ -122,6 +123,17 @@ union codeview_symbol
 	unsigned char	name[1];
   } data;
 
+  struct
+  {
+	short int	len;
+	short int	id;
+	unsigned int	symtype;
+	unsigned int	offset;
+	unsigned short	seg;
+	unsigned char	namelen;
+	unsigned char	name[1];
+  } data32;
+
   struct
   {
 	short int	len;
@@ -136,6 +148,7 @@ union codeview_symbol
 	unsigned char	namelen;
 	unsigned char	name[1];
   } thunk;
+
   struct
   {
 	short int	len;
@@ -153,6 +166,25 @@ union codeview_symbol
 	unsigned char	namelen;
 	unsigned char	name[1];
   } proc;
+
+  struct
+  {
+	short int	len;
+	short int	id;
+	unsigned int	pparent;
+	unsigned int	pend;
+	unsigned int	next;
+	unsigned int	proc_len;
+	unsigned int	debug_start;
+	unsigned int	debug_end;
+	unsigned int	proctype;
+	unsigned int	offset;
+	unsigned short	segment;
+	unsigned char	flags;
+	unsigned char	namelen;
+	unsigned char	name[1];
+  } proc32;
+
   struct
   {
 	short int	len;	/* Total length of this entry */
@@ -162,6 +194,17 @@ union codeview_symbol
 	unsigned char	namelen;
 	unsigned char	name[1];
   } stack;
+
+  struct
+  {
+	short int	len;	/* Total length of this entry */
+	short int	id;		/* Always S_BPREL32 */
+	unsigned int	offset;	/* Stack offset relative to BP */
+	unsigned int	symtype;
+	unsigned char	namelen;
+	unsigned char	name[1];
+  } stack32;
+
 };
 
 union codeview_type
@@ -181,6 +224,15 @@ union codeview_type
     unsigned char	variant[1];
   } pointer;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    unsigned int	datatype;
+    unsigned int	attribute;
+    unsigned char	variant[1];
+  } pointer32;
+
   struct
   {
     short int		len;
@@ -190,6 +242,15 @@ union codeview_type
     unsigned short	type;
   } bitfield;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    unsigned int	type;
+    unsigned char	nbits;
+    unsigned char	bitoff;
+  } bitfield32;
+
   struct
   {
     short int		len;
@@ -201,6 +262,17 @@ union codeview_type
     unsigned char	name[1];
   } array;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    unsigned int	elemtype;
+    unsigned int	idxtype;
+    unsigned char	arrlen;
+    unsigned char	namelen;
+    unsigned char	name[1];
+  } array32;
+
   struct
   {
     short int		len;
@@ -215,6 +287,20 @@ union codeview_type
     unsigned char	name[1];
   } structure;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    short int		n_element;
+    short int		property;
+    unsigned int	fieldlist;
+    unsigned int	derived;
+    unsigned int	vshape;
+    unsigned short	structlen;
+    unsigned char	namelen;
+    unsigned char	name[1];
+  } structure32;
+
   struct
   {
     short int		len;
@@ -227,6 +313,18 @@ union codeview_type
     unsigned char	name[1];
   } t_union;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    short int		count;
+    short int		property;
+    unsigned int	field;
+    unsigned short	un_len;
+    unsigned char	namelen;
+    unsigned char	name[1];
+  } t_union32;
+
   struct
   {
     short int		len;
@@ -239,6 +337,18 @@ union codeview_type
     unsigned char	name[1];
   } enumeration;
 
+  struct
+  {
+    short int		len;
+    short int		id;
+    short int		count;
+    short int		property;
+    unsigned int	type;
+    unsigned int	field;
+    unsigned char	namelen;
+    unsigned char	name[1];
+  } enumeration32;
+
   struct
   {
     short int		id;
@@ -260,33 +370,68 @@ union codeview_type
 
   struct
   {
-    short int		len;
     short int		id;
-    short int		count;
-    short int		type;
-    short int		field;
-    short int		property;
+    short int		attribute;
+    unsigned int	type;
+    unsigned short int	offset;
     unsigned char	namelen;
     unsigned char	name[1];
-  } fieldlist;
-
+  } member32;
 };
 
-#define S_BPREL	0x200
-#define S_LDATA	0x201
-#define S_GDATA	0x202
-#define S_PUB		0x203
-#define S_LPROC	0x204
-#define S_GPROC	0x205
-#define S_THUNK	0x206
-#define S_BLOCK	0x207
-#define S_WITH	0x208
-#define S_LABEL	0x209
-
-#define S_PROCREF	0x400
-#define S_DATAREF	0x401
-#define S_ALIGN		0x402
-#define S_UNKNOWN	0x403
+#define S_COMPILE       0x0001
+#define S_REGISTER      0x0002
+#define S_CONSTANT      0x0003
+#define S_UDT           0x0004
+#define S_SSEARCH       0x0005
+#define S_END           0x0006
+#define S_SKIP          0x0007
+#define S_CVRESERVE     0x0008
+#define S_OBJNAME       0x0009
+#define S_ENDARG        0x000a
+#define S_COBOLUDT      0x000b
+#define S_MANYREG       0x000c
+#define S_RETURN        0x000d
+#define S_ENTRYTHIS     0x000e
+
+#define S_BPREL         0x0200
+#define S_LDATA         0x0201
+#define S_GDATA         0x0202
+#define S_PUB           0x0203
+#define S_LPROC         0x0204
+#define S_GPROC         0x0205
+#define S_THUNK         0x0206
+#define S_BLOCK         0x0207
+#define S_WITH          0x0208
+#define S_LABEL         0x0209
+#define S_CEXMODEL      0x020a
+#define S_VFTPATH       0x020b
+#define S_REGREL        0x020c
+#define S_LTHREAD       0x020d
+#define S_GTHREAD       0x020e
+
+#define S_PROCREF       0x0400
+#define S_DATAREF       0x0401
+#define S_ALIGN         0x0402
+#define S_LPROCREF      0x0403
+
+#define S_REGISTER_32   0x1001 /* Variants with new 32-bit type indices */
+#define S_CONSTANT_32   0x1002
+#define S_UDT_32        0x1003
+#define S_COBOLUDT_32   0x1004
+#define S_MANYREG_32    0x1005
+
+#define S_BPREL_32      0x1006
+#define S_LDATA_32      0x1007
+#define S_GDATA_32      0x1008
+#define S_PUB_32        0x1009
+#define S_LPROC_32      0x100a
+#define S_GPROC_32      0x100b
+#define S_VFTTABLE_32   0x100c
+#define S_REGREL_32     0x100d
+#define S_LTHREAD_32    0x100e
+#define S_GTHREAD_32    0x100f
+
 
 /*
  * This covers the basic datatypes that VC++ seems to be using these days.
@@ -329,40 +474,105 @@ union codeview_type
 #define T_32PINT4	0x0474	/* 16:32 near pointer to int */
 #define T_32PUINT4	0x0475  /* 16:32 near pointer to unsigned int */
 
-#define LF_MODIFIER	0x1
-#define LF_POINTER	0x2
-#define LF_ARRAY	0x3
-#define LF_CLASS	0x4
-#define LF_STRUCTURE	0x5
-#define LF_UNION	0x6
-#define LF_ENUMERATION	0x7
-#define LF_PROCEDURE	0x8
-#define LF_MFUNCTION	0x9
-#define LF_VTSHAPE	0xa
-#define LF_BARRAY	0xd
-#define LF_DIMARRAY	0x11
-#define LF_VFTPATH	0x12
-
-#define LF_SKIP		0x200
-#define LF_ARGLIST	0x201
-#define LF_FIELDLIST	0x204
-#define LF_DERIVED	0x205
-#define LF_BITFIELD	0x206
-
-#define LF_BCLASS	0x400
-#define LF_VBCLASS	0x401
-#define LF_IVBCLASS	0x402
-#define LF_ENUMERATE	0x403
-#define LF_FRIENDFCN	0x404
-#define LF_INDEX	0x405
-#define LF_MEMBER	0x406
-#define LF_STMEMBER	0x407
-#define LF_METHOD	0x408
-#define LF_NESTEDTYPE	0x409
-#define LF_VFUNCTAB	0x40a
-#define LF_FRIENDCLS	0x40b
-#define LF_ONEMETHOD	0x40c
-#define LF_FUNCOFF	0x40d
+#define LF_MODIFIER     0x0001
+#define LF_POINTER      0x0002
+#define LF_ARRAY        0x0003
+#define LF_CLASS        0x0004
+#define LF_STRUCTURE    0x0005
+#define LF_UNION        0x0006
+#define LF_ENUM         0x0007
+#define LF_PROCEDURE    0x0008
+#define LF_MFUNCTION    0x0009
+#define LF_VTSHAPE      0x000a
+#define LF_COBOL0       0x000b
+#define LF_COBOL1       0x000c
+#define LF_BARRAY       0x000d
+#define LF_LABEL        0x000e
+#define LF_NULL         0x000f
+#define LF_NOTTRAN      0x0010
+#define LF_DIMARRAY     0x0011
+#define LF_VFTPATH      0x0012
+#define LF_PRECOMP      0x0013
+#define LF_ENDPRECOMP   0x0014
+#define LF_OEM          0x0015
+#define LF_TYPESERVER   0x0016
+
+#define LF_MODIFIER_32  0x1001     /* variants with new 32-bit type indices */
+#define LF_POINTER_32   0x1002
+#define LF_ARRAY_32     0x1003
+#define LF_CLASS_32     0x1004
+#define LF_STRUCTURE_32 0x1005
+#define LF_UNION_32     0x1006
+#define LF_ENUM_32      0x1007
+#define LF_PROCEDURE_32 0x1008
+#define LF_MFUNCTION_32 0x1009
+#define LF_COBOL0_32    0x100a
+#define LF_BARRAY_32    0x100b
+#define LF_DIMARRAY_32  0x100c
+#define LF_VFTPATH_32   0x100d
+#define LF_PRECOMP_32   0x100e
+#define LF_OEM_32       0x100f
+
+#define LF_SKIP         0x0200
+#define LF_ARGLIST      0x0201
+#define LF_DEFARG       0x0202
+#define LF_LIST         0x0203
+#define LF_FIELDLIST    0x0204
+#define LF_DERIVED      0x0205
+#define LF_BITFIELD     0x0206
+#define LF_METHODLIST   0x0207
+#define LF_DIMCONU      0x0208
+#define LF_DIMCONLU     0x0209
+#define LF_DIMVARU      0x020a
+#define LF_DIMVARLU     0x020b
+#define LF_REFSYM       0x020c
+
+#define LF_SKIP_32      0x1200    /* variants with new 32-bit type indices */
+#define LF_ARGLIST_32   0x1201
+#define LF_DEFARG_32    0x1202
+#define LF_FIELDLIST_32 0x1203
+#define LF_DERIVED_32   0x1204
+#define LF_BITFIELD_32  0x1205
+#define LF_METHODLIST_32 0x1206
+#define LF_DIMCONU_32   0x1207
+#define LF_DIMCONLU_32  0x1208
+#define LF_DIMVARU_32   0x1209
+#define LF_DIMVARLU_32  0x120a
+
+#define LF_BCLASS       0x0400
+#define LF_VBCLASS      0x0401
+#define LF_IVBCLASS     0x0402
+#define LF_ENUMERATE    0x0403
+#define LF_FRIENDFCN    0x0404
+#define LF_INDEX        0x0405
+#define LF_MEMBER       0x0406
+#define LF_STMEMBER     0x0407
+#define LF_METHOD       0x0408
+#define LF_NESTTYPE     0x0409
+#define LF_VFUNCTAB     0x040a
+#define LF_FRIENDCLS    0x040b
+#define LF_ONEMETHOD    0x040c
+#define LF_VFUNCOFF     0x040d
+#define LF_NESTTYPEEX   0x040e
+#define LF_MEMBERMODIFY 0x040f
+
+#define LF_BCLASS_32    0x1400    /* variants with new 32-bit type indices */
+#define LF_VBCLASS_32   0x1401
+#define LF_IVBCLASS_32  0x1402
+#define LF_FRIENDFCN_32 0x1403
+#define LF_INDEX_32     0x1404
+#define LF_MEMBER_32    0x1405
+#define LF_STMEMBER_32  0x1406
+#define LF_METHOD_32    0x1407
+#define LF_NESTTYPE_32  0x1408
+#define LF_VFUNCTAB_32  0x1409
+#define LF_FRIENDCLS_32 0x140a
+#define LF_ONEMETHOD_32 0x140b
+#define LF_VFUNCOFF_32  0x140c
+#define LF_NESTTYPEEX_32 0x140d
+
+
+
 
 #define MAX_BUILTIN_TYPES	0x480
 static struct datatype * cv_basic_types[MAX_BUILTIN_TYPES];
@@ -478,65 +688,6 @@ struct codeview_linetab_hdr
   unsigned int		 * offtab;
 };
 
-struct codeview_pdb_hdr
-{
-  char		ident[44];
-  unsigned int	blocksize;	   /* Extent size */
-  unsigned short loc_freelist;   /* freelist. */
-  unsigned short alloc_filesize; /* # extents allocated. */
-  unsigned int	toc_len;
-  unsigned int	unknown;
-  unsigned short toc_ext[1];	   /* array of extent #'s for toc. */
-};
-
-/*
- * This is our own structure that we use to keep track of the contents
- * of a PDB file.
- */
-struct file_list
-{
-	int		record_len;
-	int		nextents;
-	short int     * extent_list;
-	unsigned int	linetab_offset;
-	unsigned int	linetab_len;
-};
-
-/*
- * These are the structures that represent how the file table is set up
- * within the PDB file.
- */
-struct filetab_hdr
-{
-  unsigned short	tab1_file;
-  unsigned short	tab2_file;
-  unsigned short	gsym_file;
-  unsigned short	padding;
-  unsigned int		ftab_len;
-  unsigned int		fofftab_len;
-  unsigned int		hash_len;
-  unsigned int		strtab_len;
-};
-
-struct file_ent
-{
-  unsigned int		reserved1;
-  unsigned short	datasect_segment;
-  unsigned short	reserved2;
-  unsigned int		datasect_offset;
-  unsigned int		datasect_size;
-  unsigned int		datasect_flags;
-  unsigned short	reserved3;
-  unsigned short	index;
-  unsigned short	num6a;
-  unsigned short	file_number;
-  unsigned int		linetab_offset;
-  unsigned int		linetab_len;
-  unsigned int		num9;
-  unsigned int		num10;
-  unsigned int		num11;
-  unsigned char		filename[1];
-};
 
 /*
  ********************************************************************
@@ -580,7 +731,7 @@ struct deferred_debug_info * dbglist = NULL;
 #define IMAGE_SYM_CLASS_FILE                0x67
 
 static 
-struct datatype * DEBUG_GetCVType(int typeno)
+struct datatype * DEBUG_GetCVType(unsigned int typeno)
 {
   struct datatype * dt = NULL;
 
@@ -624,7 +775,6 @@ DEBUG_ParseTypeTable(char * table, int len)
 
   curr_type = 0x1000;
 
-  ptr.c = (table + 16);
   while( ptr.c - table < len )
     {
       type = (union codeview_type *) ptr.c;
@@ -649,6 +799,10 @@ DEBUG_ParseTypeTable(char * table, int len)
 	  cv_defined_types[curr_type - 0x1000] = 
 	    DEBUG_FindOrMakePointerType(DEBUG_GetCVType(type->pointer.datatype));
 	  break;
+	case LF_POINTER_32:
+	  cv_defined_types[curr_type - 0x1000] = 
+	    DEBUG_FindOrMakePointerType(DEBUG_GetCVType(type->pointer32.datatype));
+	  break;
 	case LF_ARRAY:
 	  if( type->array.arrlen >= 0x8000 )
 	    {
@@ -682,6 +836,41 @@ DEBUG_ParseTypeTable(char * table, int len)
 	      arr_max = type->array.arrlen / DEBUG_GetObjectSize(subtype);
 	    }
 
+	  DEBUG_SetArrayParams(typeptr, 0, arr_max, subtype);
+	  break;
+	case LF_ARRAY_32:
+	  if( type->array32.arrlen >= 0x8000 )
+	    {
+	      /*
+	       * This is a numeric leaf, I am too lazy to handle this right
+	       * now.
+	       */
+	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      break;
+	    }
+	  if( type->array32.namelen != 0 )
+	    {
+	      memset(symname, 0, sizeof(symname));
+	      memcpy(symname, type->array32.name, type->array32.namelen);
+	      typeptr = DEBUG_NewDataType(DT_ARRAY, symname);
+	    }
+	  else
+	    {
+	      typeptr = DEBUG_NewDataType(DT_ARRAY, NULL);
+	    }
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+
+	  subtype = DEBUG_GetCVType(type->array32.elemtype);
+	  if(    (subtype == NULL)
+	      || (elem_size = DEBUG_GetObjectSize(subtype)) == 0 )
+	    {
+	      arr_max = 0;
+	    }
+	  else
+	    {
+	      arr_max = type->array32.arrlen / DEBUG_GetObjectSize(subtype);
+	    }
+
 	  DEBUG_SetArrayParams(typeptr, 0, arr_max, subtype);
 	  break;
 	case LF_FIELDLIST:
@@ -774,6 +963,96 @@ DEBUG_ParseTypeTable(char * table, int len)
 	      ptr2.c += ((type2->member.namelen + 9 + 3) & ~3);
 	    }
 	  break;
+	case LF_FIELDLIST_32:
+	  /*
+	   * This is where the basic list of fields is defined for
+	   * structures and classes.
+	   *
+	   * First, we need to look ahead and see whether we are building
+	   * a fieldlist for an enum or a struct.
+	   */
+	  ptr2.i = ptr.i + 1;
+	  type2 = (union codeview_type *) ptr2.c;
+	  if( type2->member32.id == LF_MEMBER_32 )
+	    {
+	      typeptr = DEBUG_NewDataType(DT_STRUCT, NULL);
+	      fieldtype = DT_STRUCT;
+	    }
+	  else if( type2->member32.id == LF_ENUMERATE )
+	    {
+	      typeptr = DEBUG_NewDataType(DT_ENUM, NULL);
+	      fieldtype = DT_ENUM;
+	    }
+	  else
+	    {
+	      break;
+	    }
+
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+	  while( ptr2.c < (ptr.c + ((type->generic.len + 3) & ~3)) )
+	    {
+	      type2 = (union codeview_type *) ptr2.c;
+	      if( type2->member.id == LF_MEMBER_32 && fieldtype == DT_STRUCT )
+		{
+		  memset(symname, 0, sizeof(symname));
+		  memcpy(symname, type2->member32.name, type2->member32.namelen);
+		  
+		  subtype = DEBUG_GetCVType(type2->member32.type);
+		  elem_size = 0;
+		  if( subtype != NULL )
+		    {
+		      elem_size = DEBUG_GetObjectSize(subtype);
+		    }
+		  
+		  if( type2->member32.offset >= 0x8000 )
+		    {
+		      /*
+		       * This is a numeric leaf, I am too lazy to handle this right
+		       * now.
+		       */
+		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		    }
+		  else
+		    {
+		      DEBUG_AddStructElement(typeptr, symname, subtype, 
+					     type2->member32.offset << 3,
+					     elem_size << 3);
+		    }
+		}
+	      else if( type2->member32.id == LF_ENUMERATE && fieldtype == DT_ENUM )
+		{
+		  memset(symname, 0, sizeof(symname));
+		  memcpy(symname, type2->enumerate.name, type2->enumerate.namelen);
+		  
+		  if( type2->enumerate.value >= 0x8000 )
+		    {
+		      /*
+		       * This is a numeric leaf, I am too lazy to handle this right
+		       * now.
+		       */
+		      fprintf(stderr, "Ignoring large numberic leaf.\n");
+		    }
+		  else
+		    {
+		      DEBUG_AddStructElement(typeptr, symname, NULL, 
+					     type2->enumerate.value, 0);
+		    }
+		}
+	      else
+		{
+		  /*
+		   * Something else I have never seen before.  Either wrong type of
+		   * object in the fieldlist, or some other problem which I wouldn't
+		   * really know how to handle until it came up.
+		   */
+		  fprintf(stderr, "Unexpected entry in fieldlist\n");
+		  break;
+		}
+
+
+	      ptr2.c += ((type2->member32.namelen + 9 + 3) & ~3);
+	    }
+	  break;
 	case LF_STRUCTURE:
 	case LF_CLASS:
 	  if( type->structure.structlen >= 0x8000 )
@@ -808,6 +1087,40 @@ DEBUG_ParseTypeTable(char * table, int len)
 	      DEBUG_CopyFieldlist(typeptr, subtype);
 	    }
 	  break;
+	case LF_STRUCTURE_32:
+	case LF_CLASS_32:
+	  if( type->structure32.structlen >= 0x8000 )
+	    {
+	      /*
+	       * This is a numeric leaf, I am too lazy to handle this right
+	       * now.
+	       */
+	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      break;
+	    }
+	  memset(symname, 0, sizeof(symname));
+	  memcpy(symname, type->structure32.name, type->structure32.namelen);
+	  if( strcmp(symname, "__unnamed") == 0 )
+	    {
+	      typeptr = DEBUG_NewDataType(DT_STRUCT, NULL);
+	    }
+	  else
+	    {
+	      typeptr = DEBUG_NewDataType(DT_STRUCT, symname);
+	    }
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+
+	  /*
+	   * Now copy the relevant bits from the fieldlist that we specified.
+	   */
+	  subtype = DEBUG_GetCVType(type->structure32.fieldlist);
+
+	  if( subtype != NULL )
+	    {
+	      DEBUG_SetStructSize(typeptr, type->structure32.structlen);
+	      DEBUG_CopyFieldlist(typeptr, subtype);
+	    }
+	  break;
 	case LF_UNION:
 	  if( type->t_union.un_len >= 0x8000 )
 	    {
@@ -843,14 +1156,56 @@ DEBUG_ParseTypeTable(char * table, int len)
 	      DEBUG_CopyFieldlist(typeptr, subtype);
 	    }
 	  break;
-	case LF_BITFIELD:
-	  typeptr = DEBUG_NewDataType(DT_BITFIELD, NULL);
-	  cv_defined_types[curr_type - 0x1000] = typeptr;
-	  DEBUG_SetBitfieldParams(typeptr, type->bitfield.bitoff,
+	case LF_UNION_32:
+	  if( type->t_union32.un_len >= 0x8000 )
+	    {
+	      /*
+	       * This is a numeric leaf, I am too lazy to handle this right
+	       * now.
+	       */
+	      fprintf(stderr, "Ignoring large numberic leaf.\n");
+	      break;
+	    }
+	  memset(symname, 0, sizeof(symname));
+	  memcpy(symname, type->t_union32.name, type->t_union32.namelen);
+
+	  if( strcmp(symname, "__unnamed") == 0 )
+	    {
+	      typeptr = DEBUG_NewDataType(DT_STRUCT, NULL);
+	    }
+	  else
+	    {
+	      typeptr = DEBUG_NewDataType(DT_STRUCT, symname);
+	    }
+
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+
+	  /*
+	   * Now copy the relevant bits from the fieldlist that we specified.
+	   */
+	  subtype = DEBUG_GetCVType(type->t_union32.field);
+
+	  if( subtype != NULL )
+	    {
+	      DEBUG_SetStructSize(typeptr, type->t_union32.un_len);
+	      DEBUG_CopyFieldlist(typeptr, subtype);
+	    }
+	  break;
+	case LF_BITFIELD:
+	  typeptr = DEBUG_NewDataType(DT_BITFIELD, NULL);
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+	  DEBUG_SetBitfieldParams(typeptr, type->bitfield.bitoff,
 				  type->bitfield.nbits, 
 				  DEBUG_GetCVType(type->bitfield.type));
 	  break;
-	case LF_ENUMERATION:
+	case LF_BITFIELD_32:
+	  typeptr = DEBUG_NewDataType(DT_BITFIELD, NULL);
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+	  DEBUG_SetBitfieldParams(typeptr, type->bitfield32.bitoff,
+				  type->bitfield32.nbits, 
+				  DEBUG_GetCVType(type->bitfield32.type));
+	  break;
+	case LF_ENUM:
 	  memset(symname, 0, sizeof(symname));
 	  memcpy(symname, type->enumeration.name, type->enumeration.namelen);
 	  typeptr = DEBUG_NewDataType(DT_ENUM, symname);
@@ -866,7 +1221,22 @@ DEBUG_ParseTypeTable(char * table, int len)
 	      DEBUG_CopyFieldlist(typeptr, subtype);
 	    }
 	  break;
-	case LF_DIMARRAY:
+	case LF_ENUM_32:
+	  memset(symname, 0, sizeof(symname));
+	  memcpy(symname, type->enumeration32.name, type->enumeration32.namelen);
+	  typeptr = DEBUG_NewDataType(DT_ENUM, symname);
+	  cv_defined_types[curr_type - 0x1000] = typeptr;
+
+	  /*
+	   * Now copy the relevant bits from the fieldlist that we specified.
+	   */
+	  subtype = DEBUG_GetCVType(type->enumeration32.field);
+
+	  if( subtype != NULL )
+	    {
+	      DEBUG_CopyFieldlist(typeptr, subtype);
+	    }
+	  break;
 	default:
 	  break;
 	}
@@ -1654,12 +2024,6 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
   nsect = deefer->nsect;
   sectp = deefer->sectp;
 
-  /*
-   * Skip over the first word.  Don't really know what it means, but
-   * it is useless.
-   */
-  ptr.ui++;
-
   /*
    * Loop over the different types of records and whenever we
    * find something we are interested in, record it and move on.
@@ -1712,6 +2076,35 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
 	    sym->data.offset;
 	  DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA );
 	  break;
+	case S_GDATA_32:
+	case S_LDATA_32:
+	case S_PUB_32:
+	  /*
+	   * First, a couple of sanity checks.
+	   */
+	  if( sym->data32.namelen == 0 )
+	    {
+	      break;
+	    }
+
+	  if( sym->data32.seg == 0 || sym->data32.seg > nsect )
+	    {
+	      break;
+	    }
+
+	  /*
+	   * Global and local data symbols.  We don't associate these
+	   * with any given source file.
+	   */
+
+	  memcpy(symname, sym->data32.name, sym->data32.namelen);
+	  new_addr.seg = 0;
+	  new_addr.type = DEBUG_GetCVType(sym->data32.symtype);
+	  new_addr.off = (unsigned int) deefer->load_addr + 
+	    sectp[sym->data32.seg - 1].VirtualAddress + 
+	    sym->data32.offset;
+	  DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA );
+	  break;
 	case S_THUNK:
 	  /*
 	   * Sort of like a global function, but it just points
@@ -1793,6 +2186,71 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
 	  DEBUG_SetSymbolBPOff(curr_func, sym->proc.debug_start);
 	  DEBUG_SetSymbolSize(curr_func, sym->proc.proc_len);
 	  break;
+	case S_GPROC_32:
+	case S_LPROC_32:
+	  /*
+	   * Global and static functions.
+	   */
+	  memcpy(symname, sym->proc32.name, sym->proc32.namelen);
+	  new_addr.seg = 0;
+	  new_addr.type = DEBUG_GetCVType(sym->proc32.proctype);
+	  new_addr.off = (unsigned int) deefer->load_addr + 
+	    sectp[sym->proc32.segment - 1].VirtualAddress + 
+	    sym->proc32.offset;
+	  /*
+	   * See if we can find a segment that this goes with.  If so,
+	   * it means that we also may have line number information
+	   * for this function.
+	   */
+	  for(i=0; linetab[i].linetab != NULL; i++)
+	    {
+	      if(     ((unsigned int) deefer->load_addr 
+		       + sectp[linetab[i].segno - 1].VirtualAddress 
+		       + linetab[i].start <= new_addr.off)
+		  &&  ((unsigned int) deefer->load_addr 
+		       + sectp[linetab[i].segno - 1].VirtualAddress 
+		       + linetab[i].end > new_addr.off) )
+		{
+		  break;
+		}
+	    }
+
+ 	  DEBUG_Normalize(curr_func);
+	  if( linetab[i].linetab == NULL )
+	    {
+	      curr_func = DEBUG_AddSymbol( symname, &new_addr, NULL,
+					   SYM_WIN32 | SYM_FUNC);
+	    }
+	  else
+	    {
+	      /*
+	       * First, create the entry.  Then dig through the linetab
+	       * and add whatever line numbers are appropriate for this
+	       * function.
+	       */
+	      curr_func = DEBUG_AddSymbol( symname, &new_addr, 
+					   linetab[i].sourcefile,
+					   SYM_WIN32 | SYM_FUNC);
+	      for(j=0; j < linetab[i].nline; j++)
+		{
+		  if( linetab[i].offtab[j] >= sym->proc32.offset 
+		      && linetab[i].offtab[j] < sym->proc32.offset 
+		      + sym->proc32.proc_len )
+		    {
+		      DEBUG_AddLineNumber(curr_func, linetab[i].linetab[j],
+					  linetab[i].offtab[j] - sym->proc32.offset);
+		    }
+		}
+
+	    }
+
+	  /*
+	   * Add information about where we should set breakpoints
+	   * in this function.
+	   */
+	  DEBUG_SetSymbolBPOff(curr_func, sym->proc32.debug_start);
+	  DEBUG_SetSymbolSize(curr_func, sym->proc32.proc_len);
+	  break;
 	case S_BPREL:
 	  /*
 	   * Function parameters and stack variables.
@@ -1806,6 +2264,20 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
 			 symname);
 	  DEBUG_SetLocalSymbolType(curr_sym, DEBUG_GetCVType(sym->stack.symtype));
 	  
+	  break;
+	case S_BPREL_32:
+	  /*
+	   * Function parameters and stack variables.
+	   */
+	  memcpy(symname, sym->stack32.name, sym->stack32.namelen);
+	  curr_sym = DEBUG_AddLocal(curr_func, 
+			 0, 
+			 sym->stack32.offset, 
+			 0, 
+			 0, 
+			 symname);
+	  DEBUG_SetLocalSymbolType(curr_sym, DEBUG_GetCVType(sym->stack32.symtype));
+	  
 	  break;
 	default:
 	  break;
@@ -1818,7 +2290,7 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
        */
       if( sym->generic.id == S_PROCREF
 	  || sym->generic.id == S_DATAREF
-	  || sym->generic.id == S_UNKNOWN )
+	  || sym->generic.id == S_LPROCREF )
 	{
 	  len = (sym->generic.len + 3) & ~3;
 	  len += ptr.c[16] + 1;
@@ -1841,361 +2313,475 @@ DEBUG_SnarfCodeView(      struct deferred_debug_info * deefer,
 
 /*
  * Process PDB file which contains debug information.
- *
- * These are really weird beasts.  They are intended to be incrementally
- * updated by the incremental linker, and this means that you need to 
- * be able to remove and add information.  Thus the PDB file is sort of
- * like a block structured device, with a freelist and lists of extent numbers
- * that are used to get the relevant pieces.  In all cases seen so far, the
- * blocksize is always 0x400 bytes.  The header has a field which apparently
- * holds the blocksize, so if it ever changes we are safe.
- *
- * In general, every time we need to extract something from the pdb file,
- * it is easier to copy it into another buffer so we have the information
- * in one contiguous block rather than attempt to try and keep track of when
- * we need to grab another extent from the pdb file.
- *
- * The thing that is a real pain about some MS stuff is that they choose
- * data structures which are not representable in C.  Thus we have to
- * hack around and diddle pointers.
  */
-/* static */
-int
-DEBUG_ProcessPDBFile(struct deferred_debug_info * deefer, char * full_filename)
+
+#pragma pack(1)
+typedef struct _PDB_FILE
 {
-  char			      * addr = (char *) 0xffffffff;
-  unsigned int			blocksize;
-  unsigned int			bufflen = 0;
-  char			      * buffer = NULL;
-  unsigned short	      * extent_table;
-  int				fd = -1;
-  struct file_ent	      * fent;
-  char			        filename[MAX_PATHNAME_LEN];
-  struct file_list	      * filelist = NULL;
-  unsigned int			gsym_record = 0;
-  char			      * gsymtab = NULL;
-  struct filetab_hdr	      * hd;
-  int				i;
-  int				j;
-  unsigned int			last_extent;
-  struct codeview_linetab_hdr * linetab;
-  unsigned int			nblocks;
-  unsigned int			npair;
-  unsigned int			offset;
-  struct codeview_pdb_hdr     * pdbhdr;
-  unsigned int		      * pnt;
-  struct stat			statbuf;
-  int				status;
-  unsigned short	      * table;
-  char			      * toc;
-  unsigned int			toc_blocks;
+    DWORD size;
+    DWORD unknown;
 
-  LocateDebugInfoFile(full_filename, filename);
-  status = stat(filename, &statbuf);
-  if( status == -1 )
-    {
-      fprintf(stderr, "-Unable to open .PDB file %s\n", filename);
-      goto leave;
-    }
+} PDB_FILE, *PPDB_FILE;
 
-  /*
-   * Now open the file, so that we can mmap() it.
-   */
-  fd = open(filename, O_RDONLY);
-  if( fd == -1 )
-    {
-      fprintf(stderr, "-Unable to open .DBG file %s\n", filename);
-      goto leave;
-    }
+typedef struct _PDB_HEADER
+{
+    CHAR     ident[40];
+    DWORD    signature;
+    DWORD    blocksize;
+    WORD     freelist;
+    WORD     total_alloc;
+    PDB_FILE toc;
+    WORD     toc_block[ 1 ];
 
+} PDB_HEADER, *PPDB_HEADER;
 
-  /*
-   * Now mmap() the file.
-   */
-  addr = mmap(0, statbuf.st_size, PROT_READ, 
-	      MAP_PRIVATE, fd, 0);
-  if( addr == (char *) 0xffffffff )
-    {
-      fprintf(stderr, "-Unable to mmap .DBG file %s\n", filename);
-      goto leave;
-    }
+typedef struct _PDB_TOC
+{
+    DWORD    nFiles;
+    PDB_FILE file[ 1 ];
 
-  /*
-   * Now that we have the formalities over and done with, we need
-   * to find the table of contents for the PDB file.
-   */
-  pdbhdr = (struct codeview_pdb_hdr *) addr;
-  blocksize = pdbhdr->blocksize;
-  last_extent = (statbuf.st_size + blocksize - 1) / blocksize;
+} PDB_TOC, *PPDB_TOC;
 
-  /*
-   * The TOC itself isn't always contiguous, so we need to extract a few
-   * extents from the file to form the TOC.
-   */
-  toc_blocks = (pdbhdr->toc_len + blocksize - 1) / blocksize;
-  toc = (char *) DBG_alloc(toc_blocks * blocksize);
-  table = pdbhdr->toc_ext;
-  for(i=0; i < toc_blocks; i++)
-    {
-      memcpy(toc + blocksize*i, addr + table[i]*blocksize, blocksize);
-    }
+typedef struct _PDB_ROOT
+{
+    DWORD  version;
+    DWORD  TimeDateStamp;
+    DWORD  unknown;
+    DWORD  cbNames;
+    CHAR   names[ 1 ];
 
-  /*
-   * Next build our own table which will have the size and extent block
-   * list for each record in the PDB file.
-   *
-   * The TOC starts out with the number of files.  Then it is followed by
-   * (npair * 2*sizeof(int)) bytes of information, which are pairs of ints.
-   * The first one is the size of the record (in bytes), and the second one
-   * is something else which I haven't figured out yet.
-   */
-  pnt = (unsigned int *) toc;
-  npair = *pnt++;
-  extent_table = (unsigned short *) ((unsigned int) toc +
-				     npair * 2 * sizeof(int) + sizeof(int));
+} PDB_ROOT, *PPDB_ROOT;
 
-  /*
-   * Sanity check.
-   */
-  if( sizeof(int) + 2*sizeof(int)*npair > pdbhdr->toc_len )
-    {
-      goto leave;
-    }
-  
-  filelist = (struct file_list *) DBG_alloc(npair * sizeof(*filelist));
-  if( filelist == NULL )
-    {
-      goto leave;
-    }
-  memset(filelist, 0, npair * sizeof(*filelist));
+typedef struct _PDB_TYPES_OLD
+{
+    DWORD  version;
+    WORD   first_index;
+    WORD   last_index;
+    DWORD  type_size;
+    WORD   file;
+    WORD   pad;
 
-  nblocks = 0;
-  for(i=0; i < npair; i++)
-    {
-      filelist[i].record_len = pnt[i*2];
-      filelist[i].nextents   = (filelist[i].record_len + blocksize - 1) 
-	/ blocksize;
-      filelist[i].extent_list = extent_table + nblocks;
-      nblocks += filelist[i].nextents;
+} PDB_TYPES_OLD, *PPDB_TYPES_OLD;
 
-      /*
-       * These get filled in later when we parse one of the records.
-       */
-      filelist[i].linetab_offset = 0;
-      filelist[i].linetab_len = 0;
-    }
+typedef struct _PDB_TYPES
+{
+    DWORD  version;
+    DWORD  type_offset;
+    DWORD  first_index;
+    DWORD  last_index;
+    DWORD  type_size;
+    WORD   file;
+    WORD   pad;
+    DWORD  hash_size;
+    DWORD  hash_base;
+    DWORD  hash_offset;
+    DWORD  hash_len;
+    DWORD  search_offset;
+    DWORD  search_len;
+    DWORD  unknown_offset;
+    DWORD  unknown_len;
+
+} PDB_TYPES, *PPDB_TYPES;
+
+typedef struct _PDB_SYMBOL_RANGE
+{
+    WORD   segment;
+    WORD   pad1;
+    DWORD  offset;
+    DWORD  size;
+    DWORD  characteristics;
+    WORD   index;
+    WORD   pad2;
 
-  /*
-   * OK, now walk through the various records and pick out the bits we
-   * really want to see.  Some of the records are extra special, and
-   * we need to handle these a little bit differently.
-   */
-  for(i=0; i < npair; i++)
-    {
-      if( filelist[i].record_len == 0xffffffff )
-	{
-	  continue;
-	}
+} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
 
-      /*
-       * Make sure our buffer is large enough to hold the record.
-       */
-      if( bufflen < filelist[i].nextents * blocksize )
-	{
-	  bufflen = filelist[i].nextents * blocksize;
-	  buffer = (char *) DBG_realloc(buffer, bufflen);
-	}
+typedef struct _PDB_SYMBOL_RANGE_EX
+{
+    WORD   segment;
+    WORD   pad1;
+    DWORD  offset;
+    DWORD  size;
+    DWORD  characteristics;
+    WORD   index;
+    WORD   pad2;
+    DWORD  timestamp;
+    DWORD  unknown;
+
+} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
+
+typedef struct _PDB_SYMBOL_FILE
+{
+    DWORD  unknown1;
+    PDB_SYMBOL_RANGE range;
+    WORD   flag;
+    WORD   file;
+    DWORD  symbol_size;
+    DWORD  lineno_size;
+    DWORD  unknown2;
+    DWORD  nSrcFiles;
+    DWORD  attribute;
+    CHAR   filename[ 1 ];
+
+} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
+
+typedef struct _PDB_SYMBOL_FILE_EX
+{
+    DWORD  unknown1;
+    PDB_SYMBOL_RANGE_EX range;
+    WORD   flag;
+    WORD   file;
+    DWORD  symbol_size;
+    DWORD  lineno_size;
+    DWORD  unknown2;
+    DWORD  nSrcFiles;
+    DWORD  attribute;
+    DWORD  reserved[ 2 ];
+    CHAR   filename[ 1 ];
+
+} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
+
+typedef struct _PDB_SYMBOL_SOURCE
+{
+    WORD   nModules;
+    WORD   nSrcFiles;
+    WORD   table[ 1 ];
 
-      /*
-       * Do this just for completeness.  It makes debugging easier
-       * if we have a clean indication of where the record ends.
-       */
-      memset(buffer, 0, filelist[i].nextents * blocksize);
+} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
 
-      /*
-       * Next, build the record using the extent list.
-       */
-      for(j=0; j < filelist[i].nextents; j++)
-	{
-	  memcpy(buffer + j * blocksize,
-		 addr + filelist[i].extent_list[j] * blocksize,
-		 blocksize);
-	}
+typedef struct _PDB_SYMBOL_IMPORT
+{
+    DWORD  unknown1;
+    DWORD  unknown2;
+    DWORD  TimeDateStamp;
+    DWORD  nRequests;
+    CHAR   filename[ 1 ];
 
-      pnt = (unsigned int *) buffer;
+} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
 
-      /*
-       * OK, now figure out what to do with it.
-       */
+typedef struct _PDB_SYMBOLS_OLD
+{
+    WORD   hash1_file;
+    WORD   hash2_file;
+    WORD   gsym_file;
+    WORD   pad;
+    DWORD  module_size;
+    DWORD  offset_size;
+    DWORD  hash_size;
+    DWORD  srcmodule_size;
+
+} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
+
+typedef struct _PDB_SYMBOLS
+{
+    DWORD  signature;
+    DWORD  version;
+    DWORD  extended_format;
+    DWORD  hash1_file;
+    DWORD  hash2_file;
+    DWORD  gsym_file;
+    DWORD  module_size;
+    DWORD  offset_size;
+    DWORD  hash_size;
+    DWORD  srcmodule_size;
+    DWORD  pdbimport_size;
+    DWORD  resvd[ 5 ];
+
+} PDB_SYMBOLS, *PPDB_SYMBOLS;
+#pragma pack()
+
+
+static void *pdb_read( LPBYTE image, WORD *block_list, int size )
+{
+    PPDB_HEADER pdb = (PPDB_HEADER)image;
+    int i, nBlocks;
+    LPBYTE buffer;
 
-      /*
-       * Always ignore the first entry.  It seems to contain a backup copy
-       * of the TOC (the last time the file was modified??)
-       */
-      if( i == 0 )
-	{
-	  continue;
-	}
+    if ( !size ) return NULL;
 
-      /* 
-       * The second entry as a id block.  It contains a magic number
-       * to identify the compiler, plus it also contains the timestamp
-       * which must match the timestamp in the executable.  
-       */
-      if( i == 1 )
-	{
+    nBlocks = (size + pdb->blocksize-1) / pdb->blocksize;
+    buffer = DBG_alloc( nBlocks * pdb->blocksize );
 
-	  if( ((*pnt != 19950623) && (*pnt != 19950814))
-	      || (filelist[i].record_len != 0x24)
-	      || (pnt[1] != ((struct CodeViewDebug *)(deefer->dbg_info))->cv_timestamp) )
-	    {
-	      goto leave;
-	    }
-	}
+    for ( i = 0; i < nBlocks; i++ )
+        memcpy( buffer + i*pdb->blocksize,
+                image + block_list[i]*pdb->blocksize, pdb->blocksize );
 
-      /*
-       * The third entry contains pointers to the global symbol table,
-       * plus it also contains additional information about each record
-       * in the PDB file.
-       */
-      if( i == 3 )
-	{
-	  hd = (struct filetab_hdr *) buffer;
+    return buffer;
+}
 
-	  gsym_record = hd->gsym_file;
-	  gsymtab = (char *) DBG_alloc(filelist[gsym_record].nextents 
-				      * blocksize);
-	  memset(gsymtab, 0, filelist[gsym_record].nextents * blocksize);
-	  
-	  for(j=0; j < filelist[gsym_record].nextents; j++)
-	    {
-	      memcpy(gsymtab + j * blocksize,
-		     addr + filelist[gsym_record].extent_list[j] * blocksize,
-		     blocksize);
-	    }
+static void *pdb_read_file( LPBYTE image, PPDB_TOC toc, int fileNr )
+{
+    PPDB_HEADER pdb = (PPDB_HEADER)image;
+    WORD *block_list;
+    int i;
 
-	  /*
-	   * This record also contains information about where in the
-	   * remaining records we will be able to find the start of the
-	   * line number table.  We could locate that bit using heuristics,
-	   * but since we have the info handy, we might as well use it.
-	   */
-	  offset = sizeof(*hd);
-	  while(1==1)
-	    {
-	      fent = (struct file_ent *) (buffer + offset);
-	      if( offset > hd->ftab_len )
-		{
-		  break;
-		}
+    if ( !toc || fileNr >= toc->nFiles )
+        return NULL;
 
-	      if( fent->file_number == 0 || fent->file_number >= npair )
-		{
- 		  break;
-		}
+    block_list = (WORD *) &toc->file[ toc->nFiles ];
+    for ( i = 0; i < fileNr; i++ )
+        block_list += (toc->file[i].size + pdb->blocksize-1) / pdb->blocksize;
 
-	      filelist[fent->file_number].linetab_offset = 
-		fent->linetab_offset;
-	      filelist[fent->file_number].linetab_len = 
-		fent->linetab_len;
-	      /*
-	       * Figure out the offset of the next entry.
-	       * There is a fixed part of the record and a variable
-	       * length filename which we must also skip past.
-	       */
-	      offset += ((unsigned int) &fent->filename - (unsigned int) fent)
-		+ strlen(fent->filename) + 1;
-	      offset += strlen(buffer+offset) + 1;
-	      offset = (offset + 3) & ~3;
-	    }
-	}
-      
+    return pdb_read( image, block_list, toc->file[fileNr].size );
+}
 
-      /*
-       * Two different magic numbers used as dates.
-       * These indicate the 'type' table.
-       */
-      if(       *pnt == 19950410
-	     || *pnt == 19951122 )
-	{
-	  DEBUG_ParseTypeTable(buffer, filelist[i].record_len);
-	  continue;
-	}
+static void pdb_free( void *buffer )
+{
+    DBG_free( buffer );
+}
 
-      /*
-       * This is something we really want to look at, since it contains
-       * real debug info.  Anything that doesn't match this can be
-       * ignored for now.
-       */
-      if( *pnt == 1 )
-	{
-	  /*
-	   * First, snag the line table, if we have one.  This always
-	   * occurs at the end of the record, so we take the linetab
-	   * offset as the end of the normal part of the record.
-	   */
-	  linetab = NULL;
-	  if( filelist[i].linetab_len != 0 )
-	    {
-	      linetab = DEBUG_SnarfLinetab(buffer + filelist[i].linetab_offset,
-					   filelist[i].linetab_len);
-	      DEBUG_SnarfCodeView(deefer, buffer,
-				  filelist[i].linetab_offset,
-				  linetab);
-	    }
-	  else
-	    {
-	      DEBUG_SnarfCodeView(deefer, buffer,
-				  filelist[i].record_len,
-				  linetab);
-	    }
-	  continue;
-	}
+static void pdb_convert_types_header( PDB_TYPES *types, char *image )
+{
+    memset( types, 0, sizeof(PDB_TYPES) );
+    if ( !image ) return;
+
+    if ( *(DWORD *)image < 19960000 )   /* FIXME: correct version? */
+    {
+        /* Old version of the types record header */
+        PDB_TYPES_OLD *old = (PDB_TYPES_OLD *)image;
+        types->version     = old->version;
+        types->type_offset = sizeof(PDB_TYPES_OLD);
+        types->type_size   = old->type_size;
+        types->first_index = old->first_index;
+        types->last_index  = old->last_index;
+        types->file        = old->file;
+    }
+    else
+    {
+        /* New version of the types record header */
+        *types = *(PDB_TYPES *)image;
     }
+}
 
-  /*
-   * Finally, process the global symbol table itself.  There isn't
-   * a line number component to this, so we just toss everything
-   * into the mix and it all should work out.
-   */
-  if( gsym_record != 0 )
+static void pdb_convert_symbols_header( PDB_SYMBOLS *symbols, 
+                                        int *header_size, char *image )
+{
+    memset( symbols, 0, sizeof(PDB_SYMBOLS) );
+    if ( !image ) return;
+
+    if ( *(DWORD *)image != 0xffffffff )
     {
-      DEBUG_SnarfCodeView(deefer, gsymtab - sizeof(int), 
-			  filelist[gsym_record].record_len,
-			  NULL);
+        /* Old version of the symbols record header */
+        PDB_SYMBOLS_OLD *old     = (PDB_SYMBOLS_OLD *)image;
+        symbols->version         = 0;
+        symbols->extended_format = 0;
+        symbols->module_size     = old->module_size;
+        symbols->offset_size     = old->offset_size;
+        symbols->hash_size       = old->hash_size;
+        symbols->srcmodule_size  = old->srcmodule_size;
+        symbols->pdbimport_size  = 0;
+        symbols->hash1_file      = old->hash1_file;
+        symbols->hash2_file      = old->hash2_file;
+        symbols->gsym_file       = old->gsym_file;
+
+        *header_size = sizeof(PDB_SYMBOLS_OLD);
     }
-  
-leave:
+    else
+    {
+        /* New version of the symbols record header */
+        *symbols = *(PDB_SYMBOLS *)image;
 
-  if( gsymtab != NULL )
+        *header_size = sizeof(PDB_SYMBOLS);
+    }
+}
+
+int DEBUG_ProcessPDBFile( struct deferred_debug_info *deefer, char *full_filename )
+{
+    char filename[MAX_PATHNAME_LEN];
+    struct stat	statbuf;
+    int	fd = -1;
+    char *image = (char *) 0xffffffff;
+    PDB_HEADER *pdb = NULL;
+    PDB_TOC *toc = NULL;
+    PDB_ROOT *root = NULL;
+    char *types_image = NULL;
+    char *symbols_image = NULL;
+    PDB_TYPES types;
+    PDB_SYMBOLS symbols;
+    int header_size = 0;
+    char *modimage, *file;
+
+
+    /*
+     * Open and mmap() .PDB file
+     */
+
+    LocateDebugInfoFile( full_filename, filename );
+
+    if ( stat( filename, &statbuf ) == -1 )
     {
-      DBG_free(gsymtab);
-      gsymtab = NULL;
+        fprintf( stderr, "-Unable to open .PDB file %s\n", filename );
+        goto leave;
     }
 
-  if( buffer != NULL )
+    fd = open(filename, O_RDONLY);
+    if ( fd == -1 )
     {
-      DBG_free(buffer);
+        fprintf( stderr, "-Unable to open .PDB file %s\n", filename );
+        goto leave;
     }
 
-  if( filelist != NULL )
+    image = mmap( 0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0 );
+    if ( image == (char *) 0xffffffff )
     {
-      DBG_free(filelist);
+        fprintf(stderr, "-Unable to mmap .PDB file %s\n", filename);
+        goto leave;
     }
 
-  if( addr != (char *) 0xffffffff )
+    /*
+     * Read in TOC and well-known files
+     */
+
+    pdb = (PPDB_HEADER)image;
+    toc = pdb_read( image, pdb->toc_block, pdb->toc.size );
+    root = pdb_read_file( image, toc, 1 );
+    types_image = pdb_read_file( image, toc, 2 );
+    symbols_image = pdb_read_file( image, toc, 3 );
+
+    pdb_convert_types_header( &types, types_image );
+    pdb_convert_symbols_header( &symbols, &header_size, symbols_image );
+
+    /*
+     * Check for unknown versions
+     */
+
+    switch ( root->version )
     {
-      munmap(addr, statbuf.st_size);
+        case 19950623:      /* VC 4.0 */
+        case 19950814:
+        case 19960307:      /* VC 5.0 */
+        case 19970604:      /* VC 6.0 */
+            break;
+        default:
+            fprintf( stderr, "-Unknown root block version %ld\n", root->version );
     }
 
-  if( fd != -1 )
+    switch ( types.version )
     {
-      close(fd);
+        case 19950410:      /* VC 4.0 */
+        case 19951122:
+        case 19961031:      /* VC 5.0 / 6.0 */
+            break;
+        default:
+            fprintf( stderr, "-Unknown type info version %ld\n", types.version );
     }
 
-  return TRUE;
+    switch ( symbols.version )
+    {
+        case 0:            /* VC 4.0 */
+        case 19960307:     /* VC 5.0 */
+        case 19970606:     /* VC 6.0 */
+            break;
+        default:
+            fprintf( stderr, "-Unknown symbol info version %ld\n", symbols.version );
+    }
+
+
+    /* 
+     * Check .PDB time stamp
+     */
+
+    if (      root->TimeDateStamp 
+         != ((struct CodeViewDebug *)deefer->dbg_info)->cv_timestamp ) 
+    {
+        fprintf(stderr, "-Wrong time stamp of .PDB file %s\n", filename);
+        goto leave;
+    }
+
+    /* 
+     * Read type table
+     */
+
+    DEBUG_ParseTypeTable( types_image + types.type_offset, types.type_size );
+    
+    /*
+     * Read type-server .PDB imports
+     */
+
+    if ( symbols.pdbimport_size )
+    {   
+        /* FIXME */
+        fprintf(stderr, "-Type server .PDB imports ignored!\n" );
+    }
+
+    /* 
+     * Read global symbol table
+     */
+
+    modimage = pdb_read_file( image, toc, symbols.gsym_file );
+    if ( modimage )
+    {
+        DEBUG_SnarfCodeView( deefer, modimage, 
+                             toc->file[symbols.gsym_file].size, NULL );
+        pdb_free( modimage );
+    }
+
+    /*
+     * Read per-module symbol / linenumber tables
+     */
+
+    file = symbols_image + header_size;
+    while ( file - symbols_image < header_size + symbols.module_size )
+    {
+        int file_nr, file_index, symbol_size, lineno_size;
+        char *file_name;
+
+        if ( !symbols.extended_format )
+        {
+            PDB_SYMBOL_FILE *sym_file = (PDB_SYMBOL_FILE *) file;
+            file_nr     = sym_file->file;
+            file_name   = sym_file->filename;
+            file_index  = sym_file->range.index;
+            symbol_size = sym_file->symbol_size;
+            lineno_size = sym_file->lineno_size;
+        }
+        else
+        {
+            PDB_SYMBOL_FILE_EX *sym_file = (PDB_SYMBOL_FILE_EX *) file;
+            file_nr     = sym_file->file;
+            file_name   = sym_file->filename;
+            file_index  = sym_file->range.index;
+            symbol_size = sym_file->symbol_size;
+            lineno_size = sym_file->lineno_size;
+        }
+
+        modimage = pdb_read_file( image, toc, file_nr );
+        if ( modimage )
+        {
+            struct codeview_linetab_hdr *linetab = NULL;
+
+            if ( lineno_size )
+                linetab = DEBUG_SnarfLinetab( modimage + symbol_size, lineno_size );
+
+            if ( symbol_size )
+                DEBUG_SnarfCodeView( deefer, modimage + sizeof(DWORD),
+                                     symbol_size - sizeof(DWORD), linetab );
+
+            pdb_free( modimage );
+        }
+
+        file_name += strlen(file_name) + 1;
+        file = (char *)( (DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3 );
+    }
+    
+
+ leave:    
+
+    /*
+     * Cleanup
+     */
+
+    if ( symbols_image ) pdb_free( symbols_image );
+    if ( types_image ) pdb_free( types_image );
+    if ( root ) pdb_free( root );
+    if ( toc ) pdb_free( toc );
+
+    if ( image != (char *) 0xffffffff ) munmap( image, statbuf.st_size );
+    if ( fd != -1 ) close( fd );
+
+    return TRUE;
 }
 
+
 /*
  * Process DBG file which contains debug information.
  */
@@ -2356,8 +2942,8 @@ DEBUG_ProcessDBGFile(struct deferred_debug_info * deefer, char * filename)
 			   * Now process the CV stuff.
 			   */
 			  DEBUG_SnarfCodeView(deefer, 
-					      codeview + codeview_dent->offset,
-					      codeview_dent->size,
+					      codeview + codeview_dent->offset + sizeof(DWORD),
+					      codeview_dent->size - sizeof(DWORD),
 					      linetab);
 			}
 		    }
diff --git a/debugger/source.c b/debugger/source.c
index b372d705eee5e5948a8833313f066023aaa0da00..6ce1aee6c3200aec4f6e4d6bdb3b42610e36a84a 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -107,6 +107,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
   int				i;
   struct open_filelist	      * ol;
   int				nlines;
+  char			      * basename;
   char			      * pnt;
   int				rtn;
   struct searchlist	      * sl;
@@ -131,10 +132,17 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
       /*
        * Try again, stripping the path from the opened file.
        */
+      basename = strrchr(sourcefile, '\\' );
+      if ( !basename )
+          basename = strrchr(sourcefile, '/' );
+      if ( !basename )
+          basename = sourcefile;
+      else
+          basename++;
+
       for(ol = ofiles; ol; ol = ol->next)
 	{
-	  pnt = strrchr(ol->path, '/');
-	  if( pnt != NULL && strcmp(pnt + 1, sourcefile) == 0 )
+          if( strcmp(ol->path, basename) == 0 )
 	    {
 	      break;
 	    }
@@ -144,19 +152,6 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
 
   if( ol == NULL )
     {
-      /*
-       * See if this is a DOS style name or not.
-       */
-      pnt = strchr(sourcefile, '\\' );
-      if( pnt == NULL )
-	{
-	  pnt = strchr(sourcefile, '/' );
-	  if( pnt == NULL )
-	    {
-	      pnt = sourcefile;
-	    }
-	}
-
       /*
        * Crapola.  We need to try and open the file.
        */
@@ -165,6 +160,10 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
 	{
 	  strcpy(tmppath, sourcefile);
 	}
+      else if( (status = stat(basename, &statbuf)) != -1 )
+	{
+	  strcpy(tmppath, basename);
+	}
       else
 	{
 	  for(sl = listhead; sl; sl = sl->next)
@@ -177,7 +176,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
 	      /*
 	       * Now append the base file name.
 	       */
-	      strcat(tmppath, pnt);
+	      strcat(tmppath, basename);
 	      
 	      status = stat(tmppath, &statbuf);
 	      if( status != -1 )
@@ -206,7 +205,7 @@ DEBUG_DisplaySource(char * sourcefile, int start, int end)
 	      /*
 	       * Now append the base file name.
 	       */
-	      strcat(tmppath, pnt);
+	      strcat(tmppath, basename);
 	      
 	      status = stat(tmppath, &statbuf);
 	      if( status == -1 )