Eric Pouech : dbghelp: Add support for stream lookup by name in PDB files and use it for strings stream .

Alexandre Julliard julliard at winehq.org
Tue Jan 18 10:27:34 CST 2011


Module: wine
Branch: master
Commit: 8595f6c6520a2ad686bb4d17e00e249c11916fd3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8595f6c6520a2ad686bb4d17e00e249c11916fd3

Author: Eric Pouech <eric.pouech at orange.fr>
Date:   Mon Jan 17 21:54:04 2011 +0100

dbghelp: Add support for stream lookup by name in PDB files and use it for strings stream.

---

 dlls/dbghelp/msc.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 8ffbb6a..50dd6e6 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -62,12 +62,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_msc);
 
 #define MAX_PATHNAME_LEN 1024
 
+struct pdb_stream_name
+{
+    const char* name;
+    unsigned    index;
+};
+
 struct pdb_file_info
 {
     enum pdb_kind               kind;
     DWORD                       age;
     HANDLE                      hMap;
     const char*                 image;
+    struct pdb_stream_name*     stream_dict;
     union
     {
         struct
@@ -2159,21 +2166,73 @@ static void pdb_free_file(struct pdb_file_info* pdb_file)
         pdb_file->u.ds.toc = NULL;
         break;
     }
+    HeapFree(GetProcessHeap(), 0, pdb_file->stream_dict);
+}
+
+static BOOL pdb_load_stream_name_table(struct pdb_file_info* pdb_file, const char* str, unsigned cb)
+{
+    DWORD*      pdw;
+    DWORD*      ok_bits;
+    DWORD       count, numok;
+    unsigned    i, j;
+    char*       cpstr;
+
+    pdw = (DWORD*)(str + cb);
+    numok = *pdw++;
+    count = *pdw++;
+
+    pdb_file->stream_dict = HeapAlloc(GetProcessHeap(), 0, (numok + 1) * sizeof(struct pdb_stream_name) + cb);
+    if (!pdb_file->stream_dict) return FALSE;
+    cpstr = (char*)(pdb_file->stream_dict + numok + 1);
+    memcpy(cpstr, str, cb);
+
+    /* bitfield: first dword is len (in dword), then data */
+    ok_bits = pdw;
+    pdw += *ok_bits++ + 1;
+    if (*pdw++ != 0)
+    {
+        FIXME("unexpected value\n");
+        return -1;
+    }
+
+    for (i = j = 0; i < count; i++)
+    {
+        if (ok_bits[i / 32] & (1 << (i % 32)))
+        {
+            if (j >= numok) break;
+            pdb_file->stream_dict[j].name = &cpstr[*pdw++];
+            pdb_file->stream_dict[j].index = *pdw++;
+            j++;
+        }
+    }
+    /* add sentinel */
+    pdb_file->stream_dict[numok].name = NULL;
+    return j == numok && i == count;
+}
+
+static unsigned pdb_get_stream_by_name(const struct pdb_file_info* pdb_file, const char* name)
+{
+    struct pdb_stream_name*     psn;
+
+    for (psn = pdb_file->stream_dict; psn && psn->name; psn++)
+    {
+        if (!strcmp(psn->name, name)) return psn->index;
+    }
+    return -1;
 }
 
 static void* pdb_read_strings(const struct pdb_file_info* pdb_file)
 {
+    unsigned idx;
     void *ret;
 
-    /* FIXME: how to determine the correct file number? */
-    /* 4 and 12 have been observed, there may be others */
-
-    ret = pdb_read_file( pdb_file, 4 );
-    if (ret && *(const DWORD *)ret == 0xeffeeffe) return ret;
-    pdb_free( ret );
-    ret = pdb_read_file( pdb_file, 12 );
-    if (ret && *(const DWORD *)ret == 0xeffeeffe) return ret;
-    pdb_free( ret );
+    idx = pdb_get_stream_by_name(pdb_file, "/names");
+    if (idx != -1)
+    {
+        ret = pdb_read_file( pdb_file, idx );
+        if (ret && *(const DWORD *)ret == 0xeffeeffe) return ret;
+        pdb_free( ret );
+    }
     WARN("string table not found\n");
     return NULL;
 }
@@ -2411,6 +2470,8 @@ static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info*
                   pdb_lookup->filename, root->Age, pdb_lookup->age);
         TRACE("found JG for %s: age=%x timestamp=%x\n",
               pdb_lookup->filename, root->Age, root->TimeDateStamp);
+        pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
+
         pdb_free(root);
     }
     else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
@@ -2447,6 +2508,8 @@ static BOOL pdb_init(const struct pdb_lookup* pdb_lookup, struct pdb_file_info*
                   pdb_lookup->filename, root->Age, pdb_lookup->age);
         TRACE("found DS for %s: age=%x guid=%s\n",
               pdb_lookup->filename, root->Age, debugstr_guid(&root->guid));
+        pdb_load_stream_name_table(pdb_file, &root->names[0], root->cbNames);
+
         pdb_free(root);
     }
 




More information about the wine-cvs mailing list