dbghelp: Return matched information for path_find_symbol_file.
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
f824a72c7f
commit
ad921b3c56
5 changed files with 132 additions and 133 deletions
|
@ -758,9 +758,9 @@ extern DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW*
|
||||||
extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info);
|
extern DWORD dbg_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info);
|
||||||
|
|
||||||
/* path.c */
|
/* path.c */
|
||||||
extern BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
|
extern BOOL path_find_symbol_file(const struct process *pcs, const struct module *module,
|
||||||
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
||||||
WCHAR *buffer, BOOL* is_unmatched);
|
SYMSRV_INDEX_INFOW *info, BOOL *unmatched);
|
||||||
extern WCHAR *get_dos_file_name(const WCHAR *filename) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
extern WCHAR *get_dos_file_name(const WCHAR *filename) __WINE_DEALLOC(HeapFree, 3) __WINE_MALLOC;
|
||||||
extern BOOL search_dll_path(const struct process* process, const WCHAR *name, WORD machine,
|
extern BOOL search_dll_path(const struct process* process, const WCHAR *name, WORD machine,
|
||||||
BOOL (*match)(void*, HANDLE, const WCHAR*), void *param);
|
BOOL (*match)(void*, HANDLE, const WCHAR*), void *param);
|
||||||
|
|
|
@ -60,7 +60,6 @@ enum pdb_kind {PDB_JG, PDB_DS};
|
||||||
struct pdb_file_info
|
struct pdb_file_info
|
||||||
{
|
{
|
||||||
enum pdb_kind kind;
|
enum pdb_kind kind;
|
||||||
DWORD age;
|
|
||||||
HANDLE hMap;
|
HANDLE hMap;
|
||||||
const char* image;
|
const char* image;
|
||||||
struct pdb_stream_name* stream_dict;
|
struct pdb_stream_name* stream_dict;
|
||||||
|
@ -69,12 +68,10 @@ struct pdb_file_info
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
DWORD timestamp;
|
|
||||||
struct PDB_JG_TOC* toc;
|
struct PDB_JG_TOC* toc;
|
||||||
} jg;
|
} jg;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GUID guid;
|
|
||||||
struct PDB_DS_TOC* toc;
|
struct PDB_DS_TOC* toc;
|
||||||
} ds;
|
} ds;
|
||||||
} u;
|
} u;
|
||||||
|
@ -3306,30 +3303,6 @@ static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE map_pdb_file(const struct process* pcs,
|
|
||||||
const char *filename, const GUID *guid, DWORD timestamp, DWORD age,
|
|
||||||
struct module* module)
|
|
||||||
{
|
|
||||||
HANDLE hFile, hMap = NULL;
|
|
||||||
WCHAR dbg_file_path[MAX_PATH];
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
|
||||||
ret = path_find_symbol_file(pcs, module, filename, TRUE, guid, timestamp, age,
|
|
||||||
dbg_file_path, &module->module.PdbUnmatched);
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
WARN("\tCouldn't find %s\n", filename);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if ((hFile = CreateFileW(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
||||||
CloseHandle(hFile);
|
|
||||||
}
|
|
||||||
return hMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pdb_dispose_type_parse(struct codeview_type_parse* ctp)
|
static void pdb_dispose_type_parse(struct codeview_type_parse* ctp)
|
||||||
{
|
{
|
||||||
pdb_free(ctp->hash_stream);
|
pdb_free(ctp->hash_stream);
|
||||||
|
@ -3479,13 +3452,8 @@ static const char PDB_DS_IDENT[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0";
|
||||||
* pdb_init
|
* pdb_init
|
||||||
*
|
*
|
||||||
* Tries to load a pdb file
|
* Tries to load a pdb file
|
||||||
* 'matched' is filled with the number of correct matches for this file:
|
|
||||||
* - age counts for one
|
|
||||||
* - timestamp or guid depending on kind counts for one
|
|
||||||
* a wrong kind of file returns FALSE (FIXME ?)
|
|
||||||
*/
|
*/
|
||||||
static BOOL pdb_init(struct pdb_file_info* pdb_file,
|
static BOOL pdb_init(struct pdb_file_info* pdb_file, const char* image)
|
||||||
const char* image)
|
|
||||||
{
|
{
|
||||||
/* check the file header, and if ok, load the TOC */
|
/* check the file header, and if ok, load the TOC */
|
||||||
TRACE("PDB: %.40s\n", debugstr_an(image, 40));
|
TRACE("PDB: %.40s\n", debugstr_an(image, 40));
|
||||||
|
@ -3494,12 +3462,19 @@ static BOOL pdb_init(struct pdb_file_info* pdb_file,
|
||||||
{
|
{
|
||||||
const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
|
const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
|
||||||
struct PDB_JG_ROOT* root;
|
struct PDB_JG_ROOT* root;
|
||||||
|
struct PDB_JG_TOC* jg_toc;
|
||||||
|
|
||||||
pdb_file->u.jg.toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
jg_toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
||||||
root = pdb_read_jg_stream(pdb, pdb_file->u.jg.toc, 1);
|
if (!jg_toc)
|
||||||
|
{
|
||||||
|
ERR("-Unable to get TOC from .PDB\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
root = pdb_read_jg_stream(pdb, jg_toc, 1);
|
||||||
if (!root)
|
if (!root)
|
||||||
{
|
{
|
||||||
ERR("-Unable to get root from .PDB\n");
|
ERR("-Unable to get root from .PDB\n");
|
||||||
|
pdb_free(jg_toc);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch (root->Version)
|
switch (root->Version)
|
||||||
|
@ -3513,25 +3488,31 @@ static BOOL pdb_init(struct pdb_file_info* pdb_file,
|
||||||
ERR("-Unknown root block version %d\n", root->Version);
|
ERR("-Unknown root block version %d\n", root->Version);
|
||||||
}
|
}
|
||||||
pdb_file->kind = PDB_JG;
|
pdb_file->kind = PDB_JG;
|
||||||
pdb_file->u.jg.timestamp = root->TimeDateStamp;
|
pdb_file->u.jg.toc = jg_toc;
|
||||||
pdb_file->age = root->Age;
|
|
||||||
TRACE("found JG: age=%x timestamp=%x\n", root->Age, root->TimeDateStamp);
|
TRACE("found JG: age=%x timestamp=%x\n", root->Age, root->TimeDateStamp);
|
||||||
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
||||||
pdb_file->fpoext_stream = -1;
|
pdb_file->fpoext_stream = -1;
|
||||||
|
|
||||||
pdb_free(root);
|
pdb_free(root);
|
||||||
}
|
}
|
||||||
else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
|
else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
|
||||||
{
|
{
|
||||||
const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
|
const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
|
||||||
struct PDB_DS_ROOT* root;
|
struct PDB_DS_ROOT* root;
|
||||||
|
struct PDB_DS_TOC* ds_toc;
|
||||||
|
|
||||||
pdb_file->u.ds.toc =
|
ds_toc = pdb_ds_read(pdb, (const UINT*)((const char*)pdb + pdb->toc_block * pdb->block_size),
|
||||||
pdb_ds_read(pdb, (const UINT*)((const char*)pdb + pdb->toc_block * pdb->block_size),
|
pdb->toc_size);
|
||||||
pdb->toc_size);
|
if (!ds_toc)
|
||||||
root = pdb_read_ds_stream(pdb, pdb_file->u.ds.toc, 1);
|
{
|
||||||
|
ERR("-Unable to get TOC from .PDB\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
root = pdb_read_ds_stream(pdb, ds_toc, 1);
|
||||||
if (!root)
|
if (!root)
|
||||||
{
|
{
|
||||||
ERR("-Unable to get root from .PDB\n");
|
ERR("-Unable to get root from .PDB\n");
|
||||||
|
pdb_free(ds_toc);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch (root->Version)
|
switch (root->Version)
|
||||||
|
@ -3542,9 +3523,8 @@ static BOOL pdb_init(struct pdb_file_info* pdb_file,
|
||||||
ERR("-Unknown root block version %u\n", root->Version);
|
ERR("-Unknown root block version %u\n", root->Version);
|
||||||
}
|
}
|
||||||
pdb_file->kind = PDB_DS;
|
pdb_file->kind = PDB_DS;
|
||||||
pdb_file->u.ds.guid = root->guid;
|
pdb_file->u.ds.toc = ds_toc;
|
||||||
pdb_file->age = root->Age;
|
TRACE("found DS for: age=%x guid=%s\n", root->Age, debugstr_guid(&root->guid));
|
||||||
TRACE("found DS: age=%x guid=%s\n", root->Age, debugstr_guid(&root->guid));
|
|
||||||
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
pdb_file->stream_dict = pdb_load_stream_name_table(&root->names[0], root->cbNames);
|
||||||
pdb_file->fpoext_stream = -1;
|
pdb_file->fpoext_stream = -1;
|
||||||
|
|
||||||
|
@ -3574,9 +3554,9 @@ static BOOL pdb_init(struct pdb_file_info* pdb_file,
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL pdb_process_internal(const struct process *pcs,
|
static BOOL pdb_process_internal(const struct process *pcs,
|
||||||
const struct msc_debug_info* msc_dbg,
|
const struct msc_debug_info *msc_dbg,
|
||||||
const char *filename, const GUID *guid, DWORD timestamp, DWORD age,
|
const WCHAR *filename,
|
||||||
struct pdb_module_info* pdb_module_info,
|
struct pdb_module_info *pdb_module_info,
|
||||||
unsigned module_index);
|
unsigned module_index);
|
||||||
|
|
||||||
DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
DWORD pdb_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||||
|
@ -3711,11 +3691,15 @@ static void pdb_process_symbol_imports(const struct process *pcs,
|
||||||
last = (const char*)imp + symbols->pdbimport_size;
|
last = (const char*)imp + symbols->pdbimport_size;
|
||||||
while (imp < (const PDB_SYMBOL_IMPORT*)last)
|
while (imp < (const PDB_SYMBOL_IMPORT*)last)
|
||||||
{
|
{
|
||||||
|
SYMSRV_INDEX_INFOW info;
|
||||||
|
|
||||||
ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename);
|
ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename);
|
||||||
if (i >= CV_MAX_MODULES) FIXME("Out of bounds!!!\n");
|
if (i >= CV_MAX_MODULES) FIXME("Out of bounds!!!\n");
|
||||||
TRACE("got for %s: age=%u ts=%x\n",
|
TRACE("got for %s: age=%u ts=%x\n",
|
||||||
imp->filename, imp->Age, imp->TimeDateStamp);
|
imp->filename, imp->Age, imp->TimeDateStamp);
|
||||||
pdb_process_internal(pcs, msc_dbg, imp->filename, NULL, imp->TimeDateStamp, imp->Age, pdb_module_info, i);
|
if (path_find_symbol_file(pcs, msc_dbg->module, imp->filename, TRUE, NULL, imp->TimeDateStamp, imp->Age, &info,
|
||||||
|
&msc_dbg->module->module.PdbUnmatched))
|
||||||
|
pdb_process_internal(pcs, msc_dbg, info.pdbfile, pdb_module_info, i);
|
||||||
i++;
|
i++;
|
||||||
imp = (const PDB_SYMBOL_IMPORT*)((const char*)first + ((ptr - (const char*)first + strlen(ptr) + 1 + 3) & ~3));
|
imp = (const PDB_SYMBOL_IMPORT*)((const char*)first + ((ptr - (const char*)first + strlen(ptr) + 1 + 3) & ~3));
|
||||||
}
|
}
|
||||||
|
@ -3733,27 +3717,31 @@ static void pdb_process_symbol_imports(const struct process *pcs,
|
||||||
|
|
||||||
static BOOL pdb_process_internal(const struct process *pcs,
|
static BOOL pdb_process_internal(const struct process *pcs,
|
||||||
const struct msc_debug_info *msc_dbg,
|
const struct msc_debug_info *msc_dbg,
|
||||||
const char *filename, const GUID *guid, DWORD timestamp, DWORD age,
|
const WCHAR *filename,
|
||||||
struct pdb_module_info *pdb_module_info,
|
struct pdb_module_info *pdb_module_info,
|
||||||
unsigned module_index)
|
unsigned module_index)
|
||||||
{
|
{
|
||||||
HANDLE hMap = NULL;
|
HANDLE hFile = NULL, hMap = NULL;
|
||||||
char* image = NULL;
|
char* image = NULL;
|
||||||
BYTE* symbols_image = NULL;
|
BYTE* symbols_image = NULL;
|
||||||
PDB_STRING_TABLE* files_image = NULL;
|
PDB_STRING_TABLE* files_image = NULL;
|
||||||
struct pdb_file_info* pdb_file;
|
struct pdb_file_info* pdb_file;
|
||||||
|
|
||||||
TRACE("Processing PDB file %s\n", filename);
|
TRACE("Processing PDB file %ls\n", filename);
|
||||||
|
|
||||||
pdb_file = &pdb_module_info->pdb_files[module_index == -1 ? 0 : module_index];
|
pdb_file = &pdb_module_info->pdb_files[module_index == -1 ? 0 : module_index];
|
||||||
/* Open and map() .PDB file */
|
/* Open and map() .PDB file */
|
||||||
if ((hMap = map_pdb_file(pcs, filename, guid, timestamp, age, msc_dbg->module)) == NULL ||
|
if ((hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ||
|
||||||
|
(hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL ||
|
||||||
|
(image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL)
|
||||||
{
|
{
|
||||||
WARN("Unable to open .PDB file: %s\n", filename);
|
WARN("Unable to open .PDB file: %ls\n", filename);
|
||||||
CloseHandle(hMap);
|
CloseHandle(hMap);
|
||||||
|
CloseHandle(hFile);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
if (!pdb_init(pdb_file, image))
|
if (!pdb_init(pdb_file, image))
|
||||||
{
|
{
|
||||||
CloseHandle(hMap);
|
CloseHandle(hMap);
|
||||||
|
@ -3902,48 +3890,53 @@ static BOOL pdb_process_file(const struct process *pcs,
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
struct module_format* modfmt;
|
struct module_format* modfmt;
|
||||||
struct pdb_module_info* pdb_module_info;
|
struct pdb_module_info* pdb_module_info;
|
||||||
|
SYMSRV_INDEX_INFOW info;
|
||||||
|
BOOL unmatched;
|
||||||
|
|
||||||
modfmt = HeapAlloc(GetProcessHeap(), 0,
|
if (path_find_symbol_file(pcs, msc_dbg->module, filename, TRUE, guid, timestamp, age, &info, &unmatched) &&
|
||||||
sizeof(struct module_format) + sizeof(struct pdb_module_info));
|
(modfmt = HeapAlloc(GetProcessHeap(), 0,
|
||||||
if (!modfmt) return FALSE;
|
sizeof(struct module_format) + sizeof(struct pdb_module_info))))
|
||||||
|
|
||||||
pdb_module_info = (void*)(modfmt + 1);
|
|
||||||
msc_dbg->module->format_info[DFI_PDB] = modfmt;
|
|
||||||
modfmt->module = msc_dbg->module;
|
|
||||||
modfmt->remove = pdb_module_remove;
|
|
||||||
modfmt->loc_compute = pdb_location_compute;
|
|
||||||
modfmt->u.pdb_info = pdb_module_info;
|
|
||||||
|
|
||||||
memset(cv_zmodules, 0, sizeof(cv_zmodules));
|
|
||||||
codeview_init_basic_types(msc_dbg->module);
|
|
||||||
ret = pdb_process_internal(pcs, msc_dbg, filename, guid, timestamp, age,
|
|
||||||
msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1);
|
|
||||||
codeview_clear_type_table();
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
struct pdb_module_info* pdb_info = msc_dbg->module->format_info[DFI_PDB]->u.pdb_info;
|
|
||||||
msc_dbg->module->module.SymType = SymPdb;
|
|
||||||
if (pdb_info->pdb_files[0].kind == PDB_JG)
|
|
||||||
msc_dbg->module->module.PdbSig = pdb_info->pdb_files[0].u.jg.timestamp;
|
|
||||||
else
|
|
||||||
msc_dbg->module->module.PdbSig70 = pdb_info->pdb_files[0].u.ds.guid;
|
|
||||||
msc_dbg->module->module.PdbAge = pdb_info->pdb_files[0].age;
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, filename, -1,
|
|
||||||
msc_dbg->module->module.LoadedPdbName,
|
|
||||||
ARRAY_SIZE(msc_dbg->module->module.LoadedPdbName));
|
|
||||||
/* FIXME: we could have a finer grain here */
|
|
||||||
msc_dbg->module->module.LineNumbers = TRUE;
|
|
||||||
msc_dbg->module->module.GlobalSymbols = TRUE;
|
|
||||||
msc_dbg->module->module.TypeInfo = TRUE;
|
|
||||||
msc_dbg->module->module.SourceIndexed = TRUE;
|
|
||||||
msc_dbg->module->module.Publics = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
pdb_module_info = (void*)(modfmt + 1);
|
||||||
|
msc_dbg->module->format_info[DFI_PDB] = modfmt;
|
||||||
|
modfmt->module = msc_dbg->module;
|
||||||
|
modfmt->remove = pdb_module_remove;
|
||||||
|
modfmt->loc_compute = pdb_location_compute;
|
||||||
|
modfmt->u.pdb_info = pdb_module_info;
|
||||||
|
|
||||||
|
memset(cv_zmodules, 0, sizeof(cv_zmodules));
|
||||||
|
codeview_init_basic_types(msc_dbg->module);
|
||||||
|
ret = pdb_process_internal(pcs, msc_dbg, info.pdbfile,
|
||||||
|
msc_dbg->module->format_info[DFI_PDB]->u.pdb_info, -1);
|
||||||
|
codeview_clear_type_table();
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
msc_dbg->module->module.SymType = SymPdb;
|
||||||
|
msc_dbg->module->module.PdbSig = info.sig;
|
||||||
|
msc_dbg->module->module.PdbAge = info.age;
|
||||||
|
msc_dbg->module->module.PdbSig70 = info.guid;
|
||||||
|
msc_dbg->module->module.PdbUnmatched = unmatched;
|
||||||
|
wcscpy(msc_dbg->module->module.LoadedPdbName, info.pdbfile);
|
||||||
|
|
||||||
|
/* FIXME: we could have a finer grain here */
|
||||||
|
msc_dbg->module->module.LineNumbers = TRUE;
|
||||||
|
msc_dbg->module->module.GlobalSymbols = TRUE;
|
||||||
|
msc_dbg->module->module.TypeInfo = TRUE;
|
||||||
|
msc_dbg->module->module.SourceIndexed = TRUE;
|
||||||
|
msc_dbg->module->module.Publics = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
msc_dbg->module->format_info[DFI_PDB] = NULL;
|
msc_dbg->module->format_info[DFI_PDB] = NULL;
|
||||||
HeapFree(GetProcessHeap(), 0, modfmt);
|
HeapFree(GetProcessHeap(), 0, modfmt);
|
||||||
}
|
}
|
||||||
return ret;
|
msc_dbg->module->module.SymType = SymNone;
|
||||||
|
if (guid)
|
||||||
|
msc_dbg->module->module.PdbSig70 = *guid;
|
||||||
|
else
|
||||||
|
memset(&msc_dbg->module->module.PdbSig70, 0, sizeof(GUID));
|
||||||
|
msc_dbg->module->module.PdbSig = timestamp;
|
||||||
|
msc_dbg->module->module.PdbAge = age;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================================================
|
/*========================================================================
|
||||||
|
@ -4262,8 +4255,8 @@ BOOL pdb_virtual_unwind(struct cpu_stack_walk *csw, DWORD_PTR ip,
|
||||||
#define CODEVIEW_NB11_SIG MAKESIG('N','B','1','1')
|
#define CODEVIEW_NB11_SIG MAKESIG('N','B','1','1')
|
||||||
#define CODEVIEW_RSDS_SIG MAKESIG('R','S','D','S')
|
#define CODEVIEW_RSDS_SIG MAKESIG('R','S','D','S')
|
||||||
|
|
||||||
static BOOL codeview_process_info(const struct process* pcs,
|
static BOOL codeview_process_info(const struct process *pcs,
|
||||||
const struct msc_debug_info* msc_dbg)
|
const struct msc_debug_info *msc_dbg)
|
||||||
{
|
{
|
||||||
const DWORD* signature = (const DWORD*)msc_dbg->root;
|
const DWORD* signature = (const DWORD*)msc_dbg->root;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
|
@ -455,7 +455,7 @@ BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path
|
||||||
|
|
||||||
struct module_find
|
struct module_find
|
||||||
{
|
{
|
||||||
BOOL is_pdb;
|
BOOL is_pdb;
|
||||||
/* pdb: guid PDB guid (if DS PDB file)
|
/* pdb: guid PDB guid (if DS PDB file)
|
||||||
* or dw1 PDB timestamp (if JG PDB file)
|
* or dw1 PDB timestamp (if JG PDB file)
|
||||||
* dw2 PDB age
|
* dw2 PDB age
|
||||||
|
@ -465,7 +465,8 @@ struct module_find
|
||||||
const GUID* guid;
|
const GUID* guid;
|
||||||
DWORD dw1;
|
DWORD dw1;
|
||||||
DWORD dw2;
|
DWORD dw2;
|
||||||
WCHAR filename[MAX_PATH];
|
SYMSRV_INDEX_INFOW *info;
|
||||||
|
WCHAR *buffer; /* MAX_PATH + 1 */
|
||||||
unsigned matched;
|
unsigned matched;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -483,48 +484,56 @@ static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
|
||||||
info.sizeofstruct = sizeof(info);
|
info.sizeofstruct = sizeof(info);
|
||||||
if (!SymSrvGetFileIndexInfoW(buffer, &info, 0))
|
if (!SymSrvGetFileIndexInfoW(buffer, &info, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
matched++;
|
||||||
if (!memcmp(&info.guid, mf->guid, sizeof(GUID))) matched++;
|
if (!memcmp(&info.guid, mf->guid, sizeof(GUID))) matched++;
|
||||||
if (info.timestamp == mf->dw1) matched++;
|
if (info.timestamp == mf->dw1) matched++;
|
||||||
if (info.age == mf->dw2) matched++;
|
if (info.age == mf->dw2) matched++;
|
||||||
|
|
||||||
if (matched > mf->matched)
|
if (matched > mf->matched)
|
||||||
{
|
{
|
||||||
lstrcpyW(mf->filename, buffer);
|
size_t len = min(wcslen(buffer), MAX_PATH);
|
||||||
|
memcpy(mf->buffer, buffer, len * sizeof(WCHAR));
|
||||||
|
mf->buffer[len] = L'\0';
|
||||||
mf->matched = matched;
|
mf->matched = matched;
|
||||||
|
mf->info->guid = info.guid;
|
||||||
|
mf->info->timestamp = info.timestamp;
|
||||||
|
mf->info->age = info.age;
|
||||||
}
|
}
|
||||||
/* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
|
/* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
|
||||||
* convention to stop/continue enumeration. sigh.
|
* convention to stop/continue enumeration. sigh.
|
||||||
*/
|
*/
|
||||||
return mf->matched == 3;
|
return mf->matched == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
|
BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
|
||||||
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
PCSTR full_path, BOOL is_pdb, const GUID* guid, DWORD dw1, DWORD dw2,
|
||||||
WCHAR *buffer, BOOL* is_unmatched)
|
SYMSRV_INDEX_INFOW *info, BOOL* is_unmatched)
|
||||||
{
|
{
|
||||||
struct module_find mf;
|
struct module_find mf;
|
||||||
WCHAR full_pathW[MAX_PATH];
|
WCHAR *ptr;
|
||||||
WCHAR* ptr;
|
|
||||||
const WCHAR* filename;
|
const WCHAR* filename;
|
||||||
WCHAR* searchPath = pcs->search_path;
|
WCHAR *searchPath = pcs->search_path;
|
||||||
|
WCHAR buffer[MAX_PATH];
|
||||||
|
|
||||||
TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08lx, dw2 = 0x%08lx, buffer = %p)\n",
|
TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08lx, dw2 = 0x%08lx)\n",
|
||||||
pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2, buffer);
|
pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2);
|
||||||
|
|
||||||
|
mf.info = info;
|
||||||
mf.guid = guid;
|
mf.guid = guid;
|
||||||
mf.dw1 = dw1;
|
mf.dw1 = dw1;
|
||||||
mf.dw2 = dw2;
|
mf.dw2 = dw2;
|
||||||
mf.matched = 0;
|
mf.matched = 0;
|
||||||
|
mf.buffer = is_pdb ? info->pdbfile : info->dbgfile;
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, full_path, -1, info->file, MAX_PATH);
|
||||||
filename = file_name(full_pathW);
|
filename = file_name(info->file);
|
||||||
mf.is_pdb = is_pdb;
|
mf.is_pdb = is_pdb;
|
||||||
*is_unmatched = FALSE;
|
*is_unmatched = FALSE;
|
||||||
|
|
||||||
/* first check full path to file */
|
/* first check full path to file */
|
||||||
if (module_find_cb(full_pathW, &mf))
|
if (is_pdb && module_find_cb(info->file, &mf))
|
||||||
{
|
{
|
||||||
lstrcpyW( buffer, full_pathW );
|
wcscpy( info->pdbfile, info->file );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,28 +557,29 @@ BOOL path_find_symbol_file(const struct process* pcs, const struct module* modul
|
||||||
|
|
||||||
while (searchPath)
|
while (searchPath)
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
ptr = wcschr(searchPath, ';');
|
ptr = wcschr(searchPath, ';');
|
||||||
if (ptr)
|
len = (ptr) ? ptr - searchPath : wcslen(searchPath);
|
||||||
|
|
||||||
|
if (len < ARRAY_SIZE(buffer))
|
||||||
{
|
{
|
||||||
memcpy(buffer, searchPath, (ptr - searchPath) * sizeof(WCHAR));
|
memcpy(buffer, searchPath, len * sizeof(WCHAR));
|
||||||
buffer[ptr - searchPath] = '\0';
|
buffer[len] = '\0';
|
||||||
searchPath = ptr + 1;
|
/* return first fully matched file */
|
||||||
|
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
ERR("Too long search element %ls\n", searchPath);
|
||||||
lstrcpyW(buffer, searchPath);
|
searchPath = ptr ? ptr + 1 : NULL;
|
||||||
searchPath = NULL;
|
|
||||||
}
|
|
||||||
/* return first fully matched file */
|
|
||||||
if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
|
|
||||||
}
|
}
|
||||||
/* if no fully matching file is found, return the best matching file if any */
|
/* if no fully matching file is found, return the best matching file if any */
|
||||||
if ((dbghelp_options & SYMOPT_LOAD_ANYTHING) && mf.matched)
|
if ((dbghelp_options & SYMOPT_LOAD_ANYTHING) && mf.matched)
|
||||||
{
|
{
|
||||||
lstrcpyW( buffer, mf.filename );
|
|
||||||
*is_unmatched = TRUE;
|
*is_unmatched = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
mf.buffer[0] = L'\0';
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -542,15 +542,15 @@ static BOOL pe_load_dwarf(struct module* module)
|
||||||
static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
|
static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
|
||||||
const char* dbg_name, DWORD timestamp)
|
const char* dbg_name, DWORD timestamp)
|
||||||
{
|
{
|
||||||
WCHAR tmp[MAX_PATH];
|
|
||||||
HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
|
HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0;
|
||||||
const BYTE* dbg_mapping = NULL;
|
const BYTE* dbg_mapping = NULL;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
SYMSRV_INDEX_INFOW info;
|
||||||
|
|
||||||
TRACE("Processing DBG file %s\n", debugstr_a(dbg_name));
|
TRACE("Processing DBG file %s\n", debugstr_a(dbg_name));
|
||||||
|
|
||||||
if (path_find_symbol_file(pcs, module, dbg_name, FALSE, NULL, timestamp, 0, tmp, &module->module.DbgUnmatched) &&
|
if (path_find_symbol_file(pcs, module, dbg_name, FALSE, NULL, timestamp, 0, &info, &module->module.DbgUnmatched) &&
|
||||||
(hFile = CreateFileW(tmp, GENERIC_READ, FILE_SHARE_READ, NULL,
|
(hFile = CreateFileW(info.dbgfile, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
|
||||||
((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
|
((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
|
||||||
((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
|
((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
|
||||||
|
@ -573,7 +573,7 @@ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
|
||||||
hdr->DebugDirectorySize / sizeof(*dbg));
|
hdr->DebugDirectorySize / sizeof(*dbg));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERR("Couldn't find .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_w(tmp));
|
ERR("Couldn't find .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_w(info.dbgfile));
|
||||||
|
|
||||||
if (dbg_mapping) UnmapViewOfFile(dbg_mapping);
|
if (dbg_mapping) UnmapViewOfFile(dbg_mapping);
|
||||||
if (hMap) CloseHandle(hMap);
|
if (hMap) CloseHandle(hMap);
|
||||||
|
|
|
@ -1574,10 +1574,8 @@ static void test_load_modules_path(void)
|
||||||
"Expected %ls as loaded image file, got '%ls' instead\n", L"bar.dll", im.LoadedImageName);
|
"Expected %ls as loaded image file, got '%ls' instead\n", L"bar.dll", im.LoadedImageName);
|
||||||
if (test->found_file == -1)
|
if (test->found_file == -1)
|
||||||
{
|
{
|
||||||
todo_wine
|
|
||||||
ok(im.SymType == SymNone, "Unexpected symtype %x\n", im.SymType);
|
ok(im.SymType == SymNone, "Unexpected symtype %x\n", im.SymType);
|
||||||
ok(!im.LoadedPdbName[0], "Expected empty loaded pdb file, got '%ls' instead\n", im.LoadedPdbName);
|
ok(!im.LoadedPdbName[0], "Expected empty loaded pdb file, got '%ls' instead\n", im.LoadedPdbName);
|
||||||
todo_wine
|
|
||||||
ok(im.PdbAge == 0x0030cafe, "Expected %x as pdb-age, got %lx instead\n", 0x0030cafe, im.PdbAge);
|
ok(im.PdbAge == 0x0030cafe, "Expected %x as pdb-age, got %lx instead\n", 0x0030cafe, im.PdbAge);
|
||||||
ok(!im.PdbUnmatched, "Expecting matched PDB\n");
|
ok(!im.PdbUnmatched, "Expecting matched PDB\n");
|
||||||
}
|
}
|
||||||
|
@ -1586,16 +1584,15 @@ static void test_load_modules_path(void)
|
||||||
todo_wine_if(i == 4 || i == 5 || i == 7 || i == 8 || i == 11)
|
todo_wine_if(i == 4 || i == 5 || i == 7 || i == 8 || i == 11)
|
||||||
ok(im.SymType == SymPdb, "Unexpected symtype %x\n", im.SymType);
|
ok(im.SymType == SymPdb, "Unexpected symtype %x\n", im.SymType);
|
||||||
make_path(filename, topdir, NULL, test_files[test->found_file].module_path);
|
make_path(filename, topdir, NULL, test_files[test->found_file].module_path);
|
||||||
todo_wine
|
todo_wine_if(i == 2 || i == 4 || i == 5 || i == 7 || i == 8 || i == 11 || i == 21)
|
||||||
ok(!wcscmp(im.LoadedPdbName, filename),
|
ok(!wcscmp(im.LoadedPdbName, filename),
|
||||||
"Expected %ls as loaded pdb file, got '%ls' instead\n", test_files[test->found_file].module_path, im.LoadedPdbName);
|
"Expected %ls as loaded pdb file, got '%ls' instead\n", test_files[test->found_file].module_path, im.LoadedPdbName);
|
||||||
todo_wine
|
todo_wine_if(i == 11 || i == 21)
|
||||||
ok(im.PdbAge == test_files[test->found_file].age_or_timestamp,
|
ok(im.PdbAge == test_files[test->found_file].age_or_timestamp,
|
||||||
"Expected %lx as pdb-age, got %lx instead\n", test_files[test->found_file].age_or_timestamp, im.PdbAge);
|
"Expected %lx as pdb-age, got %lx instead\n", test_files[test->found_file].age_or_timestamp, im.PdbAge);
|
||||||
todo_wine_if(i == 11)
|
todo_wine_if(i == 11)
|
||||||
ok(im.PdbUnmatched == !(test_files[test->found_file].age_or_timestamp == 0x0030cafe), "Expecting matched PDB\n");
|
ok(im.PdbUnmatched == !(test_files[test->found_file].age_or_timestamp == 0x0030cafe), "Expecting matched PDB\n");
|
||||||
}
|
}
|
||||||
todo_wine_if(i == 4 || i == 5 || i == 7 || i == 8 || i == 9 || i == 10 || i == 11 || i == 13 || i == 18 || i == 19)
|
|
||||||
ok(IsEqualGUID(&im.PdbSig70, &guid1), "Unexpected PDB GUID\n");
|
ok(IsEqualGUID(&im.PdbSig70, &guid1), "Unexpected PDB GUID\n");
|
||||||
ret = SymCleanup(dummy);
|
ret = SymCleanup(dummy);
|
||||||
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
||||||
|
@ -1811,7 +1808,7 @@ static void test_load_modules_details(void)
|
||||||
todo_wine_if(test->options & SYMOPT_DEFERRED_LOADS)
|
todo_wine_if(test->options & SYMOPT_DEFERRED_LOADS)
|
||||||
ok(!wcsicmp(im.LoadedImageName, (test->options & SYMOPT_DEFERRED_LOADS) ? L"" : loaded_img_name),
|
ok(!wcsicmp(im.LoadedImageName, (test->options & SYMOPT_DEFERRED_LOADS) ? L"" : loaded_img_name),
|
||||||
"Unexpected loaded image name '%ls' (%ls)\n", im.LoadedImageName, loaded_img_name);
|
"Unexpected loaded image name '%ls' (%ls)\n", im.LoadedImageName, loaded_img_name);
|
||||||
todo_wine_if(i == 3 || i == 4 || i == 6 || i == 8 || i == 12 || i == 14)
|
todo_wine_if(i == 3 || i == 4 || i == 6 || i == 8)
|
||||||
ok(im.SymType == test->sym_type, "Unexpected module type %u\n", im.SymType);
|
ok(im.SymType == test->sym_type, "Unexpected module type %u\n", im.SymType);
|
||||||
todo_wine_if(i == 8 || i == 10)
|
todo_wine_if(i == 8 || i == 10)
|
||||||
ok(!im.TypeInfo, "No type info present\n");
|
ok(!im.TypeInfo, "No type info present\n");
|
||||||
|
@ -1839,10 +1836,8 @@ static void test_load_modules_details(void)
|
||||||
ok(val < ARRAY_SIZE(test_files), "Incorrect index\n");
|
ok(val < ARRAY_SIZE(test_files), "Incorrect index\n");
|
||||||
ok(!im.PdbUnmatched, "Unexpected value\n");
|
ok(!im.PdbUnmatched, "Unexpected value\n");
|
||||||
ok(!im.DbgUnmatched, "Unexpected value\n");
|
ok(!im.DbgUnmatched, "Unexpected value\n");
|
||||||
todo_wine
|
|
||||||
ok(IsEqualGUID(&im.PdbSig70, test_files[val].guid), "Unexpected value %s %s\n",
|
ok(IsEqualGUID(&im.PdbSig70, test_files[val].guid), "Unexpected value %s %s\n",
|
||||||
wine_dbgstr_guid(&im.PdbSig70), wine_dbgstr_guid(test_files[val].guid));
|
wine_dbgstr_guid(&im.PdbSig70), wine_dbgstr_guid(test_files[val].guid));
|
||||||
todo_wine
|
|
||||||
ok(im.PdbAge == test_files[val].age_or_timestamp + 1, "Unexpected value\n");
|
ok(im.PdbAge == test_files[val].age_or_timestamp + 1, "Unexpected value\n");
|
||||||
}
|
}
|
||||||
else if (has_mismatch(test->mismatch_in, 'D', &val))
|
else if (has_mismatch(test->mismatch_in, 'D', &val))
|
||||||
|
@ -1874,6 +1869,7 @@ static void test_load_modules_details(void)
|
||||||
SymFromNameW(dummy, L"foo", sym);
|
SymFromNameW(dummy, L"foo", sym);
|
||||||
}
|
}
|
||||||
ret = SymAddSymbol(dummy, base, "winetest_symbol_virtual", base + 4242, 13, 0);
|
ret = SymAddSymbol(dummy, base, "winetest_symbol_virtual", base + 4242, 13, 0);
|
||||||
|
todo_wine_if(i >= 12 && i <= 15) { /* temp */
|
||||||
ok(ret, "Failed to add symbol\n");
|
ok(ret, "Failed to add symbol\n");
|
||||||
memset(sym, 0, sizeof(*sym));
|
memset(sym, 0, sizeof(*sym));
|
||||||
sym->SizeOfStruct = sizeof(*sym);
|
sym->SizeOfStruct = sizeof(*sym);
|
||||||
|
@ -1888,7 +1884,7 @@ static void test_load_modules_details(void)
|
||||||
ret = SymFromNameW(dummy, sym_name, (void*)sym);
|
ret = SymFromNameW(dummy, sym_name, (void*)sym);
|
||||||
ok(ret, "Couldn't find symbol %ls\n", sym_name);
|
ok(ret, "Couldn't find symbol %ls\n", sym_name);
|
||||||
}
|
}
|
||||||
|
} /* temp */
|
||||||
ret = SymCleanup(dummy);
|
ret = SymCleanup(dummy);
|
||||||
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
ok(ret, "SymCleanup failed: %lu\n", GetLastError());
|
||||||
for (ptr = test->test_files; *ptr; ptr++)
|
for (ptr = test->test_files; *ptr; ptr++)
|
||||||
|
|
Loading…
Add table
Reference in a new issue