/****************************************************************** * pe_load_dbg_file * * loads a .dbg file */ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module, const char* dbg_name, DWORD timestamp) { char tmp[MAX_PATH]; HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0; const BYTE* dbg_mapping = NULL; const IMAGE_SEPARATE_DEBUG_HEADER* hdr; const IMAGE_DEBUG_DIRECTORY* dbg; BOOL ret = FALSE; WINE_TRACE("Processing DBG file %s\n", debugstr_a(dbg_name)); if (SymFindFileInPath(pcs->handle, NULL, dbg_name, NULL, 0, 0, 0, tmp, dbg_match, NULL) && (hFile = CreateFileA(tmp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE && ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) && ((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)) { hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)dbg_mapping; if (hdr->TimeDateStamp != timestamp) { WINE_ERR("Warning - %s has incorrect internal timestamp\n", debugstr_a(dbg_name)); /* * Well, sometimes this happens to DBG files which ARE REALLY the * right .DBG files but nonetheless this check fails. Anyway, * WINDBG (debugger for Windows by Microsoft) loads debug symbols * which have incorrect timestamps. */ } if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE) { /* section headers come immediately after debug header */ const IMAGE_SECTION_HEADER *sectp = (const IMAGE_SECTION_HEADER*)(hdr + 1); /* and after that and the exported names comes the debug directory */ dbg = (const IMAGE_DEBUG_DIRECTORY*) (dbg_mapping + sizeof(*hdr) + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + hdr->ExportedNamesSize); ret = pe_load_debug_directory(pcs, module, dbg_mapping, sectp, hdr->NumberOfSections, dbg, hdr->DebugDirectorySize / sizeof(*dbg)); } else ERR("Wrong signature in .DBG file %s\n", debugstr_a(tmp)); } else WINE_ERR("-Unable to peruse .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_a(tmp)); if (dbg_mapping) UnmapViewOfFile(dbg_mapping); if (hMap) CloseHandle(hMap); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return ret; }
/****************************************************************** * pe_load_msc_debug_info * * Process MSC debug information in PE file. */ static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* module) { struct image_file_map* fmap = &module->format_info[DFI_PE]->u.pe_info->fmap; BOOL ret = FALSE; const IMAGE_DATA_DIRECTORY* dir; const IMAGE_DEBUG_DIRECTORY*dbg = NULL; int nDbg; void* mapping; IMAGE_NT_HEADERS* nth; if (!(mapping = pe_map_full(fmap, &nth))) return FALSE; /* Read in debug directory */ dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG; nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY); if (!nDbg) goto done; dbg = RtlImageRvaToVa(nth, mapping, dir->VirtualAddress, NULL); /* Parse debug directory */ if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) { /* Debug info is stripped to .DBG file */ const IMAGE_DEBUG_MISC* misc = (const IMAGE_DEBUG_MISC*) ((const char*)mapping + dbg->PointerToRawData); if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC || misc->DataType != IMAGE_DEBUG_MISC_EXENAME) { ERR("-Debug info stripped, but no .DBG file in module %s\n", debugstr_w(module->module.ModuleName)); } else { ret = pe_load_dbg_file(pcs, module, (const char*)misc->Data, nth->FileHeader.TimeDateStamp); } } else { const IMAGE_SECTION_HEADER *sectp = (const IMAGE_SECTION_HEADER*)((const char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader); /* Debug info is embedded into PE module */ ret = pe_load_debug_directory(pcs, module, mapping, sectp, nth->FileHeader.NumberOfSections, dbg, nDbg); } done: pe_unmap_full(fmap); return ret; }
/****************************************************************** * pe_load_dbg_file * * loads a .dbg file */ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module, const char* dbg_name, DWORD timestamp) { WCHAR tmp[MAX_PATH]; HANDLE hFile = INVALID_HANDLE_VALUE, hMap = 0; const BYTE* dbg_mapping = NULL; BOOL ret = FALSE; TRACE("Processing DBG file %s\n", debugstr_a(dbg_name)); if (path_find_symbol_file(pcs, module, dbg_name, NULL, timestamp, 0, tmp, &module->module.DbgUnmatched) && (hFile = CreateFileW(tmp, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE && ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) && ((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)) { const IMAGE_SEPARATE_DEBUG_HEADER* hdr; const IMAGE_SECTION_HEADER* sectp; const IMAGE_DEBUG_DIRECTORY* dbg; hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)dbg_mapping; /* section headers come immediately after debug header */ sectp = (const IMAGE_SECTION_HEADER*)(hdr + 1); /* and after that and the exported names comes the debug directory */ dbg = (const IMAGE_DEBUG_DIRECTORY*) (dbg_mapping + sizeof(*hdr) + hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + hdr->ExportedNamesSize); ret = pe_load_debug_directory(pcs, module, dbg_mapping, sectp, hdr->NumberOfSections, dbg, hdr->DebugDirectorySize / sizeof(*dbg)); } else ERR("Couldn't find .DBG file %s (%s)\n", debugstr_a(dbg_name), debugstr_w(tmp)); if (dbg_mapping) UnmapViewOfFile(dbg_mapping); if (hMap) CloseHandle(hMap); if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return ret; }