CVS: winex/dlls/dbghelp msc.c,1.5,1.6

[email protected] 30 Aug 2007 14:20:24 -0000
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/dlls/dbghelp msc.c,1.5,1.6Update of /var/lib/cvsd/cvsroot/winex/dlls/dbghelp
In directory agravaine:/tmp/cvs-serv19977/dlls/dbghelp

Modified Files:
	msc.c 
Log Message:
added all supported basic types to the PDB loader
#2034

- added support for all 219 basic types that can be stored in a PDB file
- added some #defines for the various basic type ID components
- reduced the memory footprint needed to store the basic type information
- added some more error checking and fixed a few compile warnings
- prevented some excessively long label names from being printed.



Index: msc.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/dbghelp/msc.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- msc.c	30 Aug 2007 14:17:49 -0000	1.5
+++ msc.c	30 Aug 2007 14:20:22 -0000	1.6
@@ -60,13 +60,15 @@
 
 #define MAX_PATHNAME_LEN 1024
 
+
+
 /*========================================================================
  * Debug file access helper routines
  */
 
 static void dump(const void* ptr, unsigned len)
 {
-    int         i, j;
+    unsigned int i, j;
     char        msg[128];
     const char* hexof = "0123456789abcdef";
     const BYTE* x = (const BYTE*)ptr;
@@ -93,10 +95,26 @@
  * Process CodeView type information.
  */
 
-#define MAX_BUILTIN_TYPES	0x0480
 #define FIRST_DEFINABLE_TYPE    0x1000
 
-static struct symt*     cv_basic_types[MAX_BUILTIN_TYPES];
+typedef struct{
+    struct symt *basic;         /* basic type (index < T_MAXBASICTYPE) */
+#ifdef USE_ALL_TYPES
+    struct symt *nearPtr;       /* near pointer to basic type (index & 0x0100) == 0x0100 */
+    struct symt *farPtr;        /* far pointer to basic type (index & 0x0200) == 0x0200 */
+    struct symt *hugePtr;       /* huge pointer to basic type (index & 0x0300) == 0x0300 */
+    struct symt *near32Ptr;     /* 32-bit near pointer to basic type (index & 0x0400) == 0x0400 */
+    struct symt *far32Ptr;      /* 48-bit far pointer to basic type (index & 0x0500) == 0x0500 */
+    struct symt *near64Ptr;     /* 64-bit near pointer to basic type (index & 0x0600) == 0x0600 */
+#else
+    struct symt *near32Ptr;     /* 32-bit near pointer to basic type (index & 0x0400) == 0x0400 */
+#endif
+} CV_BasicTypes;
+
+
+//static struct symt*     cv_basic_types[T_MAXPREDEFINEDTYPE];
+static CV_BasicTypes cv_basic_types[T_MAXBASICTYPE] = {{0}};
+
 
 struct cv_defined_module
 {
@@ -111,42 +129,100 @@
 
 static void codeview_init_basic_types(struct module* module)
 {
+#ifdef USE_ALL_TYPES
+    int i;
+#endif
+
     /*
      * These are the common builtin types that are used by VC++.
      */
-    cv_basic_types[T_NOTYPE] = NULL;
-    cv_basic_types[T_ABS]    = NULL;
-    cv_basic_types[T_VOID]   = &symt_new_basic(module, btVoid,  "void", 0)->symt;
-    cv_basic_types[T_CHAR]   = &symt_new_basic(module, btChar,  "char", 1)->symt;
-    cv_basic_types[T_SHORT]  = &symt_new_basic(module, btInt,   "short int", 2)->symt;
-    cv_basic_types[T_LONG]   = &symt_new_basic(module, btInt,   "long int", 4)->symt;
-    cv_basic_types[T_QUAD]   = &symt_new_basic(module, btInt,   "long long int", 8)->symt;
-    cv_basic_types[T_UCHAR]  = &symt_new_basic(module, btUInt,  "unsigned char", 1)->symt;
-    cv_basic_types[T_USHORT] = &symt_new_basic(module, btUInt,  "unsigned short", 2)->symt;
-    cv_basic_types[T_ULONG]  = &symt_new_basic(module, btUInt,  "unsigned long", 4)->symt;
-    cv_basic_types[T_UQUAD]  = &symt_new_basic(module, btUInt,  "unsigned long long", 8)->symt;
-    cv_basic_types[T_REAL32] = &symt_new_basic(module, btFloat, "float", 4)->symt;
-    cv_basic_types[T_REAL64] = &symt_new_basic(module, btFloat, "double", 8)->symt;
-    cv_basic_types[T_RCHAR]  = &symt_new_basic(module, btInt,   "signed char", 1)->symt;
-    cv_basic_types[T_WCHAR]  = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
-    cv_basic_types[T_INT4]   = &symt_new_basic(module, btInt,   "INT4", 4)->symt;
-    cv_basic_types[T_UINT4]  = &symt_new_basic(module, btUInt,  "UINT4", 4)->symt;
 
-    cv_basic_types[T_32PVOID]   = &symt_new_pointer(module, cv_basic_types[T_VOID])->symt;
-    cv_basic_types[T_32PCHAR]   = &symt_new_pointer(module, cv_basic_types[T_CHAR])->symt;
-    cv_basic_types[T_32PSHORT]  = &symt_new_pointer(module, cv_basic_types[T_SHORT])->symt;
-    cv_basic_types[T_32PLONG]   = &symt_new_pointer(module, cv_basic_types[T_LONG])->symt;
-    cv_basic_types[T_32PQUAD]   = &symt_new_pointer(module, cv_basic_types[T_QUAD])->symt;
-    cv_basic_types[T_32PUCHAR]  = &symt_new_pointer(module, cv_basic_types[T_UCHAR])->symt;
-    cv_basic_types[T_32PUSHORT] = &symt_new_pointer(module, cv_basic_types[T_USHORT])->symt;
-    cv_basic_types[T_32PULONG]  = &symt_new_pointer(module, cv_basic_types[T_ULONG])->symt;
-    cv_basic_types[T_32PUQUAD]  = &symt_new_pointer(module, cv_basic_types[T_UQUAD])->symt;
-    cv_basic_types[T_32PREAL32] = &symt_new_pointer(module, cv_basic_types[T_REAL32])->symt;
-    cv_basic_types[T_32PREAL64] = &symt_new_pointer(module, cv_basic_types[T_REAL64])->symt;
-    cv_basic_types[T_32PRCHAR]  = &symt_new_pointer(module, cv_basic_types[T_RCHAR])->symt;
-    cv_basic_types[T_32PWCHAR]  = &symt_new_pointer(module, cv_basic_types[T_WCHAR])->symt;
-    cv_basic_types[T_32PINT4]   = &symt_new_pointer(module, cv_basic_types[T_INT4])->symt;
-    cv_basic_types[T_32PUINT4]  = &symt_new_pointer(module, cv_basic_types[T_UINT4])->symt;
+    /* non-pointer basic types */
+    cv_basic_types[T_NOTYPE].basic    = NULL;
+    cv_basic_types[T_ABS].basic       = NULL;
+    cv_basic_types[T_SEGMENT].basic   = NULL;     /* fixme! */
+    cv_basic_types[T_VOID].basic      = &symt_new_basic(module, btVoid,  "void", 0)->symt;
+    cv_basic_types[T_CURRENCY].basic  = &symt_new_basic(module, btCurrency, "currency", 4)->symt; /* fixme!  This is a VB type... size and name are possibly incorrect */
+    cv_basic_types[T_NBASICSTR].basic = NULL;     /* fixme!  VB type */
+    cv_basic_types[T_FBASICSTR].basic = NULL;     /* fixme!  VB type */
+    cv_basic_types[T_NOTTRANS].basic  = NULL;     /* error type */
+    cv_basic_types[T_CHAR].basic      = &symt_new_basic(module, btChar,  "char", 1)->symt;
+    cv_basic_types[T_SHORT].basic     = &symt_new_basic(module, btInt,   "short int", 2)->symt;
+    cv_basic_types[T_LONG].basic      = &symt_new_basic(module, btInt,   "long int", 4)->symt;
+    cv_basic_types[T_QUAD].basic      = &symt_new_basic(module, btInt,   "long long int", 8)->symt;
+    cv_basic_types[T_UCHAR].basic     = &symt_new_basic(module, btUInt,  "unsigned char", 1)->symt;
+    cv_basic_types[T_USHORT].basic    = &symt_new_basic(module, btUInt,  "unsigned short", 2)->symt;
+    cv_basic_types[T_ULONG].basic     = &symt_new_basic(module, btUInt,  "unsigned long", 4)->symt;
+    cv_basic_types[T_UQUAD].basic     = &symt_new_basic(module, btUInt,  "unsigned long long", 8)->symt;
+    cv_basic_types[T_BOOL08].basic    = &symt_new_basic(module, btBool,  "bool", 1)->symt;
+    cv_basic_types[T_BOOL16].basic    = &symt_new_basic(module, btBool,  "bool16", 2)->symt;
+    cv_basic_types[T_BOOL32].basic    = &symt_new_basic(module, btBool,  "bool32", 4)->symt;
+    cv_basic_types[T_BOOL64].basic    = &symt_new_basic(module, btBool,  "bool64", 8)->symt;
+    cv_basic_types[T_REAL32].basic    = &symt_new_basic(module, btFloat, "float", 4)->symt;
+    cv_basic_types[T_REAL64].basic    = &symt_new_basic(module, btFloat, "double", 8)->symt;
+    cv_basic_types[T_REAL80].basic    = &symt_new_basic(module, btFloat, "long double", 10)->symt;
+    cv_basic_types[T_REAL128].basic   = &symt_new_basic(module, btFloat, "long long double", 16)->symt;
+    cv_basic_types[T_REAL48].basic    = &symt_new_basic(module, btFloat, "long float", 6)->symt;
+    cv_basic_types[T_CPLX32].basic    = &symt_new_basic(module, btComplex, "complex", 4)->symt;       /* fixme!  This is a VB type... name is possibly incorrect */
+    cv_basic_types[T_CPLX64].basic    = &symt_new_basic(module, btComplex, "complex64", 8)->symt;     /* fixme!  This is a VB type... name is possibly incorrect */
+    cv_basic_types[T_CPLX80].basic    = &symt_new_basic(module, btComplex, "complex80", 10)->symt;    /* fixme!  This is a VB type... name is possibly incorrect */
+    cv_basic_types[T_CPLX128].basic   = &symt_new_basic(module, btComplex, "complex128", 16)->symt;   /* fixme!  This is a VB type... name is possibly incorrect */
+    cv_basic_types[T_BIT].basic       = &symt_new_basic(module, btBit,    "Bit", 1)->symt;    /* fixme!  This is a VB type... size and name are possibly incorrect */
+    cv_basic_types[T_PASCHAR].basic   = NULL;     /* fixme! */
+    cv_basic_types[T_RCHAR].basic     = &symt_new_basic(module, btInt,   "signed char", 1)->symt;
+    cv_basic_types[T_WCHAR].basic     = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
+    cv_basic_types[T_INT2].basic      = &symt_new_basic(module, btInt,   "INT2", 2)->symt;
+    cv_basic_types[T_UINT2].basic     = &symt_new_basic(module, btUInt,  "UINT2", 2)->symt;
+    cv_basic_types[T_INT4].basic      = &symt_new_basic(module, btInt,   "INT4", 4)->symt;
+    cv_basic_types[T_UINT4].basic     = &symt_new_basic(module, btUInt,  "UINT4", 4)->symt;
+    cv_basic_types[T_INT8].basic      = &symt_new_basic(module, btInt,   "INT8", 8)->symt;
+    cv_basic_types[T_UINT8].basic     = &symt_new_basic(module, btUInt,  "UINT8", 8)->symt;
+
+
+    /* add 32-bit near pointers to basic types */
+    cv_basic_types[T_VOID].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_VOID].basic)->symt;
+    cv_basic_types[T_CHAR].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_CHAR].basic)->symt;
+    cv_basic_types[T_SHORT].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_SHORT].basic)->symt;
+    cv_basic_types[T_LONG].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_LONG].basic)->symt;
+    cv_basic_types[T_QUAD].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_QUAD].basic)->symt;
+    cv_basic_types[T_UCHAR].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_UCHAR].basic)->symt;
+    cv_basic_types[T_USHORT].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_USHORT].basic)->symt;
+    cv_basic_types[T_ULONG].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_ULONG].basic)->symt;
+    cv_basic_types[T_UQUAD].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_UQUAD].basic)->symt;
+    cv_basic_types[T_BOOL08].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_BOOL08].basic)->symt;
+    cv_basic_types[T_BOOL16].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_BOOL16].basic)->symt;
+    cv_basic_types[T_BOOL32].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_BOOL32].basic)->symt;
+    cv_basic_types[T_BOOL64].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_BOOL64].basic)->symt;
+    cv_basic_types[T_REAL32].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_REAL32].basic)->symt;
+    cv_basic_types[T_REAL64].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_REAL64].basic)->symt;
+    cv_basic_types[T_REAL80].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_REAL80].basic)->symt;
+    cv_basic_types[T_REAL128].near32Ptr = &symt_new_pointer(module, cv_basic_types[T_REAL128].basic)->symt;
+    cv_basic_types[T_REAL48].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_REAL48].basic)->symt;
+    cv_basic_types[T_CPLX32].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_CPLX32].basic)->symt;
+    cv_basic_types[T_CPLX64].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_CPLX64].basic)->symt;
+    cv_basic_types[T_CPLX80].near32Ptr  = &symt_new_pointer(module, cv_basic_types[T_CPLX80].basic)->symt;
+    cv_basic_types[T_CPLX128].near32Ptr = &symt_new_pointer(module, cv_basic_types[T_CPLX128].basic)->symt;
+    cv_basic_types[T_RCHAR].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_RCHAR].basic)->symt;
+    cv_basic_types[T_WCHAR].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_WCHAR].basic)->symt;
+    cv_basic_types[T_INT2].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_INT2].basic)->symt;
+    cv_basic_types[T_UINT2].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_UINT2].basic)->symt;
+    cv_basic_types[T_INT4].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_INT4].basic)->symt;
+    cv_basic_types[T_UINT4].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_UINT4].basic)->symt;
+    cv_basic_types[T_INT8].near32Ptr    = &symt_new_pointer(module, cv_basic_types[T_INT8].basic)->symt;
+    cv_basic_types[T_UINT8].near32Ptr   = &symt_new_pointer(module, cv_basic_types[T_UINT8].basic)->symt;
+
+#ifdef USE_ALL_TYPES
+    /* the representation of a pointer is independant of its size.  This means we can just reuse the same
+       symt object for the near, far, huge, and far32 pointers of each type.  This isn't really necessary,
+       it's just done for completeness. */
+    for (i = 0; i < T_MAXBASICTYPE; i++){
+        cv_basic_types[i].near64Ptr =   cv_basic_types[i].near32Ptr;
+        cv_basic_types[i].far32Ptr =    cv_basic_types[i].near32Ptr;
+        cv_basic_types[i].farPtr =      cv_basic_types[i].near32Ptr;
+        cv_basic_types[i].nearPtr =     cv_basic_types[i].near32Ptr;
+        cv_basic_types[i].hugePtr =     cv_basic_types[i].near32Ptr;
+    }
+#endif
 }
 
 static int numeric_leaf(int* value, const unsigned short int* leaf)
@@ -288,8 +364,35 @@
      */
     if (typeno < FIRST_DEFINABLE_TYPE)
     {
-        if (typeno < MAX_BUILTIN_TYPES)
-	    symt = cv_basic_types[typeno];
+        /* invalid type index => fail */
+        if (typeno >= T_MAXPREDEFINEDTYPE)
+            return NULL;
+
+        /* type potentially points to a basic type => check if any of the pointer flags are set on the type */
+        if ((typeno & T_BASICTYPE_MASK) < T_MAXBASICTYPE){
+#ifdef USE_ALL_TYPES
+            switch (typeno & T_MODE_MASK){
+                case 0:                 symt = cv_basic_types[typeno & T_BASICTYPE_MASK].basic;     break;
+                case T_NEARPTR_BITS:    symt = cv_basic_types[typeno & T_BASICTYPE_MASK].nearPtr;   break;
+                case T_FARPTR_BITS:     symt = cv_basic_types[typeno & T_BASICTYPE_MASK].farPtr;    break;
+                case T_HUGEPTR_BITS:    symt = cv_basic_types[typeno & T_BASICTYPE_MASK].hugePtr;   break;
+                case T_NEAR32PTR_BITS:  symt = cv_basic_types[typeno & T_BASICTYPE_MASK].near32Ptr; break;
+                case T_FAR32PTR_BITS:   symt = cv_basic_types[typeno & T_BASICTYPE_MASK].far32Ptr;  break;
+                case T_NEAR64PTR_BITS:  symt = cv_basic_types[typeno & T_BASICTYPE_MASK].near64Ptr; break;
+                default:
+                    FIXME("unknown type mode: 0x%04x\n", typeno & T_MODE_MASK);
+                    break;
+            }
+#else
+            /* type is a pointer => return the pointer to the basic type */
+            if (typeno & T_MODE_MASK)
+                symt = cv_basic_types[typeno & T_BASICTYPE_MASK].near32Ptr;
+
+            /* type is just a basic type */
+            else
+                symt = cv_basic_types[typeno & T_BASICTYPE_MASK].basic;
+#endif
+        }
     }
     else
     {
@@ -316,14 +419,28 @@
     struct module*      module;
     const BYTE*         table;
     const DWORD*        offset;
+    DWORD               first;
     DWORD               num;
 };
 
 static inline const void* codeview_jump_to_type(const struct codeview_type_parse* ctp, DWORD idx)
 {
-    if (idx < FIRST_DEFINABLE_TYPE) return NULL;
-    idx -= FIRST_DEFINABLE_TYPE;
-    return (idx >= ctp->num) ? NULL : (ctp->table + ctp->offset[idx]); 
+    if (idx < ctp->first){   /*FIRST_DEFINABLE_TYPE)*/
+        WARN("type 0x%08lx is potentially a built-in type.  Returning NULL\n", idx);
+
+        return NULL;
+    }
+
+
+    idx -= ctp->first;  /*FIRST_DEFINABLE_TYPE;*/
+
+    if (idx >= ctp->num){
+        ERR("out of range type number {idx = 0x%08lx, first = 0x%08lx, num = 0x%08lx}\n", idx, ctp->first, ctp->num);
+
+        return NULL;
+    }
+
+    return ctp->table + ctp->offset[idx]; 
 }
 
 static int codeview_add_type(unsigned int typeno, struct symt* dt)
@@ -406,7 +523,9 @@
         return NULL;
     }
     symt = codeview_parse_one_type(ctp, typeno, p, FALSE);
-    if (!symt) FIXME("Couldn't load forward type %x\n", typeno);
+    if (!symt)
+        FIXME("Couldn't load forward type %x\n", typeno);
+
     return symt;
 }
 
@@ -778,7 +897,7 @@
     sym->rettype = codeview_fetch_type(ctp, ret_type);
     if (args_list && (reftype = codeview_jump_to_type(ctp, args_list)))
     {
-        int i;
+        unsigned int i;
         switch (reftype->generic.id)
         {
         case LF_ARGLIST_V1:
@@ -815,7 +934,7 @@
         /* FIXME: we don't handle modifiers, 
          * but readd previous type on the curr_type 
          */
-        WARN("Modifier on %x: %s%s%s%s\n",
+        WARN("Modifier on 0x%04x: %s%s%s%s\n",
              type->modifier_v1.type,
              type->modifier_v1.attribute & 0x01 ? "const " : "",
              type->modifier_v1.attribute & 0x02 ? "volatile " : "",
@@ -827,7 +946,7 @@
         break;
     case LF_MODIFIER_V2:
         /* FIXME: we don't handle modifiers, but readd previous type on the curr_type */
-        WARN("Modifier on %x: %s%s%s%s\n",
+        WARN("Modifier on 0x%04x: %s%s%s%s\n",
              type->modifier_v2.type,
              type->modifier_v2.attribute & 0x01 ? "const " : "",
              type->modifier_v2.attribute & 0x02 ? "volatile " : "",
@@ -1050,10 +1169,10 @@
 
 static int codeview_parse_type_table(struct codeview_type_parse* ctp)
 {
-    unsigned int                curr_type = FIRST_DEFINABLE_TYPE;
+    unsigned int                curr_type;
     const union codeview_type*  type;
 
-    for (curr_type = FIRST_DEFINABLE_TYPE; curr_type < FIRST_DEFINABLE_TYPE + ctp->num; curr_type++)
+    for (curr_type = ctp->first; curr_type < ctp->first + ctp->num; curr_type++)
     {
         type = codeview_jump_to_type(ctp, curr_type);
 
@@ -1164,7 +1283,7 @@
             source = source_new(module, NULL, (const char*)(start + file_segcount));
         
         for (k = 0; k < file_segcount; k++, this_seg++)
-	{
+        {
             pnt2.uc = linetab + lt_ptr[k];
             lt_hdr[this_seg].start      = start[k].start;
             lt_hdr[this_seg].end        = start[k].end;
@@ -1173,7 +1292,7 @@
             lt_hdr[this_seg].nline      = *pnt2.s++;
             lt_hdr[this_seg].offtab     = pnt2.ui;
             lt_hdr[this_seg].linetab    = (const unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
-	}
+        }
     }
 
 leave:
@@ -1227,9 +1346,9 @@
     int			        nsect = msc_dbg->nsect;
     const IMAGE_SECTION_HEADER* sectp = msc_dbg->sectp;
 
-    if (!seg || seg > nsect) return 0;
-    return msc_dbg->module->module.BaseOfImage +
-        codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
+    if (!seg || seg > (unsigned)nsect) return 0;
+    return (unsigned int)(msc_dbg->module->module.BaseOfImage +
+        codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset));
 }
 
 static void codeview_add_func_linenum(struct module* module, 
@@ -1485,6 +1604,9 @@
             TRACE("S-Compiland-V2 %s\n", terminate_string(&sym->compiland_v2.p_name));
             if (TRACE_ON(dbghelp_msc))
             {
+                /* !! not sure what this is for since this will never print anything out.
+                        Note that *(str + strlen(str)) == 0 always. */
+
                 const char* ptr1 = sym->compiland_v2.p_name.name + sym->compiland_v2.p_name.namelen;
                 const char* ptr2;
                 while (*ptr1)
@@ -1499,6 +1621,9 @@
             TRACE("S-Compiland-V3 %s\n", sym->compiland_v3.name);
             if (TRACE_ON(dbghelp_msc))
             {
+                /* !! not sure what this is for since this will never print anything out.
+                        Note that *(str + strlen(str)) == 0 always. */
+
                 const char* ptr1 = sym->compiland_v3.name + strlen(sym->compiland_v3.name);
                 const char* ptr2;
                 while (*ptr1)
@@ -1525,9 +1650,14 @@
                 symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel, &loc,
                                         terminate_string(&sym->label_v1.p_name));
             }
-            else
-                FIXME("No current function for label %s\n",
-                      terminate_string(&sym->label_v1.p_name));
+            else{
+
+                /* this case doesn't need to be checked for length since the max length is 255 characters and
+                   the terminate_string() function takes that into account */
+                FIXME("No current function for V1 label %s\n",
+                        terminate_string(&sym->label_v1.p_name));
+            }
+
             break;
         case S_LABEL_V3:
             if (curr_func)
@@ -1537,8 +1667,17 @@
                 symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel, 
                                         &loc, sym->label_v3.name);
             }
-            else
-                FIXME("No current function for label %s\n", sym->label_v3.name);
+            else if (TRACE_ON(dbghelp_msc)){
+                const char *ehName = "__ehhandler$";
+
+
+                if (!strncmp(sym->label_v3.name, ehName, strlen(ehName)))
+                    TRACE("found a C++ EH wrapped function label\n");
+
+                else
+                    FIXME("No current function for V3 label %s.  Possibly a global initializer label\n", sym->label_v3.name);
+            }
+
             break;
 
         case S_CONSTANT_V1:
@@ -1661,6 +1800,12 @@
             break;
 
         case S_MSTOOL_V3: /* just to silence a few warnings */
+            /* compiler options and build settings 
+                This is a sequence of strings starting with "Microsoft (R) Optimizing Compiler".  After the
+                compiler string there is a sequence of string pairs.  The first string of each pair describes
+                the purpose (ie: 'cwd', 'cl', 'cmd', 'src', 'pdb').  The second string is the value for the
+                first string.  No real need to parse this block, just skip it.
+            */
             break;
 
         case S_SSEARCH_V1:
@@ -1970,6 +2115,15 @@
             ptr += ((const union codeview_type*)ptr)->generic.len + 2;
         }
         ctp.offset = offset;
+        ctp.first = types.first_index;
+
+        if (types.last_index != ctp.first + ctp.num)
+            FIXME("the type count doesn't match {first_index = 0x%08lx, last_index = 0x%08lx, num = 0x%08lx}\n", ctp.first, types.last_index, ctp.num);
+
+        /* sanity check -> there are still a number of places where we do not have access to a codeview_type_parse 
+            object so we can't actually use the <first> member for this value */
+        if (ctp.first != FIRST_DEFINABLE_TYPE)
+            FIXME("this PDB has a first UDT index that is different from FIRST_DEFINABLE_TYPE!  FIX IT FIX IT FIX IT FIX IT!\n");
 
         /* Read type table */
         codeview_parse_type_table(&ctp);
@@ -2049,6 +2203,8 @@
             ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
             return FALSE;
         }
+
+
         switch (root->Version)
         {
         case 20000404:
@@ -2254,12 +2410,17 @@
 
         /* Read global symbol table */
         TRACE("reading global symbol table\n");
-        modimage = pdb_read_file(image, pdb_lookup, symbols.gsym_file);
+        /* NOTE: only the low word of the gsym_file value is the file number for the symbols file.  On VC8
+                 PDBs the high word always seems to be 0x002a.  On VC7 PDBs the high word is 0x0000 (which
+                 is why this worked in those cases).  Similarly for the hash1_file and hash2_file values -
+                 VC7 always had the high word set to 0x38a0 and 0x0c05 respectively.  VC8 always had the
+                 high word set to 0x8800 and 0xc627 respectively. */
+        modimage = pdb_read_file(image, pdb_lookup, symbols.gsym_file & 0x0000ffff);
         if (modimage)
         {
             TRACE("dunno what this does\n");
             codeview_snarf(msc_dbg, modimage, 0, 
-                           pdb_get_file_size(pdb_lookup, symbols.gsym_file), NULL);
+                           pdb_get_file_size(pdb_lookup, symbols.gsym_file & 0x0000ffff), NULL);
 
             pdb_free(modimage);
         }
@@ -2267,7 +2428,7 @@
         /* Read per-module symbol / linenumber tables */
         TRACE("reading symbols and line numbers\n");
         file = symbols_image + header_size;
-        while (file - symbols_image < header_size + symbols.module_size)
+        while ((size_t)(file - symbols_image) < (size_t)(header_size + symbols.module_size))
         {
             PDB_SYMBOL_FILE_EX          sfile;
             const char*                 file_name;
@@ -2281,6 +2442,11 @@
             {
                 struct codeview_linetab*    linetab = NULL;
 
+                
+                TRACE("processing symbol file for '%s' {file = %d, symbolSize = %ld, lineNoSize = %ld, unknown2 = %ld, nSrcFiles = %ld}\n", 
+                        file + size, sfile.file, sfile.symbol_size, sfile.lineno_size, sfile.unknown2, sfile.nSrcFiles);
+
+
                 if (sfile.lineno_size)
                     linetab = codeview_snarf_linetab(msc_dbg->module, 
                                                      modimage + sfile.symbol_size,
@@ -2293,6 +2459,11 @@
 
                 pdb_free(modimage);
             }
+
+
+            if (sfile.unknown2 && sfile.lineno_size == 0)
+                FIXME("line number information is missing, but the mystery information block is present instead\n");
+
             file_name = (const char*)file + size;
             file_name += strlen(file_name) + 1;
             file = (BYTE*)((DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3);
@@ -2445,6 +2616,7 @@
                 ctp.module = msc_dbg->module;
                 ctp.offset = (const DWORD*)(types + 1);
                 ctp.num    = types->cTypes;
+                ctp.first  = FIRST_DEFINABLE_TYPE;
                 ctp.table  = (const BYTE*)(ctp.offset + types->cTypes);
 
                 cv_current_module = &cv_zmodules[0];