/*********************************************************************** * SymGetModuleBase (DBGHELP.@) */ DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr) { DWORD64 ret; ret = SymGetModuleBase64(hProcess, dwAddr); return validate_addr64(ret) ? ret : 0; }
/*********************************************************************** * SymLoadModuleEx (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize, PMODLOAD_DATA Data, DWORD Flags) { TRACE("(%p %p %s %s %s %08lx %p %08lx)\n", hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName), wine_dbgstr_longlong(BaseOfDll), DllSize, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, ImageName); if (!validate_addr64(BaseOfDll)) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs) return FALSE; module = module_new(pcs, ImageName, module_get_type_by_name(ImageName), TRUE, (DWORD)BaseOfDll, DllSize, 0, 0); if (!module) return FALSE; if (ModuleName) lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName)); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08lx for %s\n", Flags, ImageName); return SymLoadModule(hProcess, hFile, (char*)ImageName, (char*)ModuleName, (DWORD)BaseOfDll, DllSize); }
/****************************************************************** * SymUnloadModule64 (DBGHELP.@) * */ BOOL WINAPI SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll) { struct process* pcs; struct module* module; pcs = process_find_by_handle(hProcess); if (!pcs) return FALSE; if (!validate_addr64(BaseOfDll)) return FALSE; module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); if (!module) return FALSE; return module_remove(pcs, module); }
/****************************************************************** * fetch_pe_module_info_cb * * Callback for accumulating in dump_context a PE modules set */ static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size, PVOID user) { struct dump_context* dc = user; IMAGE_NT_HEADERS nth; if (!validate_addr64(base)) return FALSE; if (pe_load_nt_header(dc->hProcess, base, &nth)) add_module(user, name, base, size, nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum, FALSE); return TRUE; }
/*********************************************************************** * SymLoadModuleExW (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageName, PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll, PMODLOAD_DATA Data, DWORD Flags) { struct process* pcs; struct module* module = NULL; TRACE("(%p %p %s %s %s %08x %p %08x)\n", hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName), wine_dbgstr_longlong(BaseOfDll), SizeOfDll, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, debugstr_w(wImageName)); if (!validate_addr64(BaseOfDll)) return FALSE; if (!(pcs = process_find_by_handle(hProcess))) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { if (!wImageName) return FALSE; module = module_new(pcs, wImageName, module_get_type_by_name(wImageName), TRUE, BaseOfDll, SizeOfDll, 0, 0); if (!module) return FALSE; if (wModuleName) module_set_module(module, wModuleName); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); refresh_module_list(pcs); /* this is a Wine extension to the API just to redo the synchronisation */ if (!wImageName && !hFile) return 0; /* check if the module is already loaded, or if it's a builtin PE module with * an containing ELF module */ if (wImageName) { module = module_is_already_loaded(pcs, wImageName); if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll)) { /* force the loading of DLL as builtin */ module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll); } } if (!module) { /* otherwise, try a regular PE module */ if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) && wImageName) { /* and finally an ELF or Mach-O module */ switch (module_get_type_by_name(wImageName)) { case DMT_ELF: module = elf_load_module(pcs, wImageName, BaseOfDll); break; case DMT_MACHO: module = macho_load_module(pcs, wImageName, BaseOfDll); break; default: /* Ignored */ break; } } } if (!module) { WARN("Couldn't locate %s\n", debugstr_w(wImageName)); return 0; } module->module.NumSyms = module->ht_symbols.num_elts; /* by default module_new fills module.ModuleName from a derivation * of LoadedImageName. Overwrite it, if we have better information */ if (wModuleName) module_set_module(module, wModuleName); if (wImageName) lstrcpynW(module->module.ImageName, wImageName, sizeof(module->module.ImageName) / sizeof(WCHAR)); return module->module.BaseOfImage; }
/* machLoadModule(): attempts to find and load the debug information for the module <imageName>. The filename in <imageName> is assumed to be a windows DLL name (and optional path). The <moduleBase> and <moduleSize> parameters are stored in the module information that is returned. On success, a module object is created, added to the module list in the process desription <pcs>, and is returned. Failing to load the debug information from a module is not considered failure, and the module object will still be returned. Returns NULL if the module does not represent a dylib, the file could not be opened or read, or the memory could not be allocated. */ struct module *machLoadModule(struct process *pcs, const WCHAR *imageName, DWORD64 moduleBase, ULONG moduleSize){ struct module * module; WCHAR * actualName; MachMap map; TRACE("adding mach-o module {pcs = %p, imageName = %s, moduleBase = 0x%08llx, moduleSize = %d bytes}\n", pcs, debugstr_w(imageName), moduleBase, moduleSize); /* make sure it's not a 64-bit address */ if (!validate_addr64(moduleBase)){ FIXME("module base is actually 64-bit!\n"); return NULL; } moduleBase = normalize_addr64(moduleBase); /* verify that this image represents a dylib file */ if (!machIsMachFile(imageName, &actualName, NULL) || actualName == NULL){ TRACE("the module %s was not loaded from a dylib file\n", debugstr_w(imageName)); SAFEFREEBUF(actualName); return NULL; } /* need to load the module file to get the header information */ if (machMapFile(actualName, &map, FALSE)){ /* correct the module base and size if they were passed in as 0 */ if (moduleBase == 0){ if (map.modStart == 0) FIXME("no module base specified and couldn't guess at it\n"); moduleBase = map.modStart; } if (moduleSize == 0) moduleSize = map.modSize; } else{ ERR("could not open the dylib %s to gather module header information\n", debugstr_w(actualName)); SAFEFREEBUF(actualName); return NULL; } /* create a container for the module information */ module = module_new(pcs, imageName, DMT_DYLIB, FALSE, /* <-- not a virtual module */ moduleBase, moduleSize, map.timestamp, map.checksum); if (module == NULL){ ERR("could not create a new module container\n"); SAFEFREEBUF(actualName); machUnmapFile(&map); return NULL; } /* deferred module debug loads is set in the options => mark it and allow the module to be loaded when first needed */ if (dbghelp_options & SYMOPT_DEFERRED_LOADS) module->module.SymType = SymDeferred; /* attempt to load the module's debug information */ else{ BOOL ret; TRACE("loading the debug information for module %p\n", module); ret = machLoadDebugInfo(pcs, module, &map); TRACE("loading debug information %s\n", ret ? "SUCCEEDED" : "FAILED"); } machUnmapFile(&map); SAFEFREEBUF(actualName); return module; }
/*********************************************************************** * SymGetModuleBase64 (DBGHELP.@) */ DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) { if (!validate_addr64(dwAddr)) return 0; return SymGetModuleBase(hProcess, (DWORD)dwAddr); }
/*********************************************************************** * SymLoadModule64 (DBGHELP.@) */ DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) { if (!validate_addr64(BaseOfDll)) return FALSE; return SymLoadModule(hProcess, hFile, ImageName, ModuleName, (DWORD)BaseOfDll, SizeOfDll); }