mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 04:49:47 +00:00
dbghelp: Support loading modules from Wine's multi-arch build tree.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
31e76b5333
commit
1ed24f7ec6
|
@ -332,6 +332,16 @@ const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct cpu* process_get_cpu(const struct process* pcs)
|
||||||
|
{
|
||||||
|
const struct module* m = pcs->lmodules;
|
||||||
|
|
||||||
|
/* main module is the last one in list */
|
||||||
|
if (!m) return dbghelp_current_cpu;
|
||||||
|
while (m->next) m = m->next;
|
||||||
|
return m->cpu;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* check_live_target
|
* check_live_target
|
||||||
*
|
*
|
||||||
|
|
|
@ -696,6 +696,7 @@ extern void* fetch_buffer(struct process* pcs, unsigned size) DECLSPEC_HI
|
||||||
extern const char* wine_dbgstr_addr(const ADDRESS64* addr) DECLSPEC_HIDDEN;
|
extern const char* wine_dbgstr_addr(const ADDRESS64* addr) DECLSPEC_HIDDEN;
|
||||||
extern struct cpu* cpu_find(DWORD) DECLSPEC_HIDDEN;
|
extern struct cpu* cpu_find(DWORD) DECLSPEC_HIDDEN;
|
||||||
extern const WCHAR *process_getenv(const struct process *process, const WCHAR *name) DECLSPEC_HIDDEN;
|
extern const WCHAR *process_getenv(const struct process *process, const WCHAR *name) DECLSPEC_HIDDEN;
|
||||||
|
extern const struct cpu* process_get_cpu(const struct process* pcs) DECLSPEC_HIDDEN;
|
||||||
extern DWORD calc_crc32(HANDLE handle) DECLSPEC_HIDDEN;
|
extern DWORD calc_crc32(HANDLE handle) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* elf_module.c */
|
/* elf_module.c */
|
||||||
|
|
|
@ -31,22 +31,19 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
||||||
|
|
||||||
#ifdef __i386__
|
static const struct machine_dir
|
||||||
static const WCHAR pe_dir[] = L"\\i386-windows";
|
{
|
||||||
static const WCHAR so_dir[] = L"\\i386-unix";
|
DWORD machine;
|
||||||
#elif defined __x86_64__
|
const WCHAR *pe_dir;
|
||||||
static const WCHAR pe_dir[] = L"\\x86_64-windows";
|
const WCHAR *so_dir;
|
||||||
static const WCHAR so_dir[] = L"\\x86_64-unix";
|
}
|
||||||
#elif defined __arm__
|
all_machine_dir[] =
|
||||||
static const WCHAR pe_dir[] = L"\\arm-windows";
|
{
|
||||||
static const WCHAR so_dir[] = L"\\arm-unix";
|
{IMAGE_FILE_MACHINE_I386, L"\\i386-windows\\", L"\\i386-unix\\"},
|
||||||
#elif defined __aarch64__
|
{IMAGE_FILE_MACHINE_AMD64, L"\\x86_64-windows\\", L"\\x86_64-unix\\"},
|
||||||
static const WCHAR pe_dir[] = L"\\aarch64-windows";
|
{IMAGE_FILE_MACHINE_ARMNT, L"\\arm-windows\\", L"\\arm-unix\\"},
|
||||||
static const WCHAR so_dir[] = L"\\aarch64-unix";
|
{IMAGE_FILE_MACHINE_ARM64, L"\\aarch64-windows\\", L"\\aarch64-unix\\"},
|
||||||
#else
|
};
|
||||||
static const WCHAR pe_dir[] = L"";
|
|
||||||
static const WCHAR so_dir[] = L"";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline BOOL is_sepA(char ch) {return ch == '/' || ch == '\\';}
|
static inline BOOL is_sepA(char ch) {return ch == '/' || ch == '\\';}
|
||||||
static inline BOOL is_sep(WCHAR ch) {return ch == '/' || ch == '\\';}
|
static inline BOOL is_sep(WCHAR ch) {return ch == '/' || ch == '\\';}
|
||||||
|
@ -705,6 +702,14 @@ WCHAR *get_dos_file_name(const WCHAR *filename)
|
||||||
return dos_path;
|
return dos_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const WCHAR* get_machine_dir(const struct machine_dir *machine_dir, const WCHAR *name)
|
||||||
|
{
|
||||||
|
WCHAR *ptr;
|
||||||
|
if ((ptr = wcsrchr(name, L'.')) && !lstrcmpW(ptr, L".so"))
|
||||||
|
return machine_dir->so_dir;
|
||||||
|
return machine_dir->pe_dir;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL try_match_file(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param)
|
static BOOL try_match_file(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param)
|
||||||
{
|
{
|
||||||
HANDLE file = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE file = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
@ -721,18 +726,27 @@ BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*ma
|
||||||
{
|
{
|
||||||
const WCHAR *env;
|
const WCHAR *env;
|
||||||
WCHAR *p, *end;
|
WCHAR *p, *end;
|
||||||
size_t len, i;
|
size_t len, i, machine_dir_len;
|
||||||
WCHAR *buf;
|
WCHAR *buf;
|
||||||
|
const struct cpu* cpu;
|
||||||
|
const struct machine_dir* machine_dir;
|
||||||
|
|
||||||
name = file_name(name);
|
name = file_name(name);
|
||||||
|
|
||||||
|
cpu = process_get_cpu(process);
|
||||||
|
for (machine_dir = all_machine_dir; machine_dir < all_machine_dir + ARRAY_SIZE(all_machine_dir); machine_dir++)
|
||||||
|
if (machine_dir->machine == cpu->machine) break;
|
||||||
|
if (machine_dir >= all_machine_dir + ARRAY_SIZE(all_machine_dir)) return FALSE;
|
||||||
|
machine_dir_len = max(wcslen(machine_dir->pe_dir), wcslen(machine_dir->so_dir));
|
||||||
|
|
||||||
if ((env = process_getenv(process, L"WINEBUILDDIR")))
|
if ((env = process_getenv(process, L"WINEBUILDDIR")))
|
||||||
{
|
{
|
||||||
const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
|
const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
|
||||||
const WCHAR programsW[] = { '\\','p','r','o','g','r','a','m','s','\\' };
|
const WCHAR programsW[] = { '\\','p','r','o','g','r','a','m','s','\\' };
|
||||||
|
|
||||||
len = lstrlenW(env);
|
len = lstrlenW(env);
|
||||||
if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * sizeof(WCHAR)))) return FALSE;
|
if (!(buf = heap_alloc((len + ARRAY_SIZE(programsW) + machine_dir_len +
|
||||||
|
2 * lstrlenW(name) + 1) * sizeof(WCHAR)))) return FALSE;
|
||||||
wcscpy(buf, env);
|
wcscpy(buf, env);
|
||||||
end = buf + len;
|
end = buf + len;
|
||||||
|
|
||||||
|
@ -741,6 +755,11 @@ BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*ma
|
||||||
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".so")) *p = 0;
|
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".so")) *p = 0;
|
||||||
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".dll")) *p = 0;
|
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".dll")) *p = 0;
|
||||||
p = end + lstrlenW(end);
|
p = end + lstrlenW(end);
|
||||||
|
/* try multi-arch first */
|
||||||
|
wcscpy(p, get_machine_dir(machine_dir, name));
|
||||||
|
wcscpy(p + wcslen(p), name);
|
||||||
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
|
/* then old mono-arch */
|
||||||
*p++ = '\\';
|
*p++ = '\\';
|
||||||
lstrcpyW(p, name);
|
lstrcpyW(p, name);
|
||||||
if (try_match_file(buf, match, param)) goto found;
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
|
@ -751,6 +770,11 @@ BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*ma
|
||||||
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".so")) *p = 0;
|
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".so")) *p = 0;
|
||||||
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".exe")) *p = 0;
|
if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, L".exe")) *p = 0;
|
||||||
p = end + lstrlenW(end);
|
p = end + lstrlenW(end);
|
||||||
|
/* try multi-arch first */
|
||||||
|
wcscpy(p, get_machine_dir(machine_dir, name));
|
||||||
|
wcscpy(p + wcslen(p), name);
|
||||||
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
|
/* then old mono-arch */
|
||||||
*p++ = '\\';
|
*p++ = '\\';
|
||||||
lstrcpyW(p, name);
|
lstrcpyW(p, name);
|
||||||
if (try_match_file(buf, match, param)) goto found;
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
|
@ -763,12 +787,9 @@ BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*ma
|
||||||
WCHAR env_name[64];
|
WCHAR env_name[64];
|
||||||
swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i);
|
swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i);
|
||||||
if (!(env = process_getenv(process, env_name))) return FALSE;
|
if (!(env = process_getenv(process, env_name))) return FALSE;
|
||||||
len = wcslen(env) + wcslen(pe_dir) + wcslen(name) + 2;
|
len = wcslen(env) + machine_dir_len + wcslen(name) + 1;
|
||||||
if (!(buf = heap_alloc(len * sizeof(WCHAR)))) return FALSE;
|
if (!(buf = heap_alloc(len * sizeof(WCHAR)))) return FALSE;
|
||||||
if ((p = wcsrchr(name, '.')) && !lstrcmpW(p, L".so"))
|
swprintf(buf, len, L"%s%s%s", env, get_machine_dir(machine_dir, name), name);
|
||||||
swprintf(buf, len, L"%s%s\\%s", env, so_dir, name);
|
|
||||||
else
|
|
||||||
swprintf(buf, len, L"%s%s\\%s", env, pe_dir, name);
|
|
||||||
if (try_match_file(buf, match, param)) goto found;
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
swprintf(buf, len, L"%s\\%s", env, name);
|
swprintf(buf, len, L"%s\\%s", env, name);
|
||||||
if (try_match_file(buf, match, param)) goto found;
|
if (try_match_file(buf, match, param)) goto found;
|
||||||
|
|
Loading…
Reference in a new issue