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