dbghelp: Now moving the ELF loading code to Unicode.
This commit is contained in:
parent
c1269392e0
commit
3565d93ebe
|
@ -432,6 +432,9 @@ extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* add
|
|||
/* module.c */
|
||||
extern const WCHAR S_ElfW[];
|
||||
extern const WCHAR S_WineLoaderW[];
|
||||
extern const WCHAR S_WinePThreadW[];
|
||||
extern const WCHAR S_WineKThreadW[];
|
||||
extern const WCHAR S_SlashW[];
|
||||
|
||||
extern struct module*
|
||||
module_find_by_addr(const struct process* pcs, unsigned long addr,
|
||||
|
|
|
@ -95,7 +95,7 @@ struct elf_info
|
|||
unsigned flags; /* IN one (or several) of the ELF_INFO constants */
|
||||
unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
|
||||
struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
|
||||
const char* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
|
||||
const WCHAR* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
|
||||
};
|
||||
|
||||
/* structure holding information while handling an ELF image
|
||||
|
@ -1154,16 +1154,18 @@ BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
|
|||
* read or parsed)
|
||||
* 1 on success
|
||||
*/
|
||||
static BOOL elf_load_file(struct process* pcs, const char* filename,
|
||||
static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
|
||||
unsigned long load_offset, struct elf_info* elf_info)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
struct elf_file_map fmap;
|
||||
int i;
|
||||
char tmp[MAX_PATH];
|
||||
|
||||
TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
|
||||
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
|
||||
|
||||
if (!elf_map_file(filename, &fmap)) goto leave;
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, tmp, sizeof(tmp), NULL, NULL);
|
||||
if (!elf_map_file(tmp, &fmap)) goto leave;
|
||||
|
||||
/* Next, we need to find a few of the internal ELF headers within
|
||||
* this thing. We need the main executable header, and the section
|
||||
|
@ -1171,11 +1173,11 @@ static BOOL elf_load_file(struct process* pcs, const char* filename,
|
|||
*/
|
||||
if (!fmap.elf_start && !load_offset)
|
||||
ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
|
||||
filename);
|
||||
debugstr_w(filename));
|
||||
if (fmap.elf_start && load_offset)
|
||||
{
|
||||
WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
|
||||
"Assuming load address is corrupt\n", filename, load_offset);
|
||||
"Assuming load address is corrupt\n", debugstr_w(filename), load_offset);
|
||||
load_offset = 0;
|
||||
}
|
||||
|
||||
|
@ -1212,12 +1214,10 @@ static BOOL elf_load_file(struct process* pcs, const char* filename,
|
|||
|
||||
if (elf_info->flags & ELF_INFO_MODULE)
|
||||
{
|
||||
WCHAR wfilename[MAX_PATH];
|
||||
struct elf_module_info *elf_module_info =
|
||||
HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
|
||||
if (!elf_module_info) goto leave;
|
||||
MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, wfilename, sizeof(wfilename) / sizeof(WCHAR));
|
||||
elf_info->module = module_new(pcs, wfilename, DMT_ELF, FALSE,
|
||||
elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE,
|
||||
(load_offset) ? load_offset : fmap.elf_start,
|
||||
fmap.elf_size, 0, calc_crc32(&fmap));
|
||||
if (!elf_info->module)
|
||||
|
@ -1241,8 +1241,14 @@ static BOOL elf_load_file(struct process* pcs, const char* filename,
|
|||
|
||||
if (elf_info->flags & ELF_INFO_NAME)
|
||||
{
|
||||
elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
|
||||
strlen(filename) + 1), filename);
|
||||
WCHAR* ptr;
|
||||
ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
|
||||
if (ptr)
|
||||
{
|
||||
strcpyW(ptr, filename);
|
||||
elf_info->module_name = ptr;
|
||||
}
|
||||
else ret = FALSE;
|
||||
}
|
||||
leave:
|
||||
elf_unmap_file(&fmap);
|
||||
|
@ -1255,34 +1261,39 @@ leave:
|
|||
* tries to load an ELF file from a set of paths (separated by ':')
|
||||
*/
|
||||
static BOOL elf_load_file_from_path(HANDLE hProcess,
|
||||
const char* filename,
|
||||
const WCHAR* filename,
|
||||
unsigned long load_offset,
|
||||
const char* path,
|
||||
struct elf_info* elf_info)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
char *s, *t, *fn;
|
||||
char* paths = NULL;
|
||||
WCHAR *s, *t, *fn;
|
||||
WCHAR* pathW = NULL;
|
||||
unsigned len;
|
||||
|
||||
if (!path) return FALSE;
|
||||
|
||||
paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
|
||||
for (s = paths; s && *s; s = (t) ? (t+1) : NULL)
|
||||
len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
|
||||
pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||
if (!pathW) return FALSE;
|
||||
MultiByteToWideChar(CP_UNIXCP, 0, path, -1, pathW, len);
|
||||
|
||||
for (s = pathW; s && *s; s = (t) ? (t+1) : NULL)
|
||||
{
|
||||
t = strchr(s, ':');
|
||||
t = strchrW(s, ':');
|
||||
if (t) *t = '\0';
|
||||
fn = HeapAlloc(GetProcessHeap(), 0, strlen(filename) + 1 + strlen(s) + 1);
|
||||
fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1 + lstrlenW(s) + 1) * sizeof(WCHAR));
|
||||
if (!fn) break;
|
||||
strcpy(fn, s);
|
||||
strcat(fn, "/");
|
||||
strcat(fn, filename);
|
||||
strcpyW(fn, s);
|
||||
strcatW(fn, S_SlashW);
|
||||
strcatW(fn, filename);
|
||||
ret = elf_load_file(hProcess, fn, load_offset, elf_info);
|
||||
HeapFree(GetProcessHeap(), 0, fn);
|
||||
if (ret) break;
|
||||
s = (t) ? (t+1) : NULL;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, paths);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pathW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1292,7 +1303,7 @@ static BOOL elf_load_file_from_path(HANDLE hProcess,
|
|||
* Tries to load an ELF file from the dll path
|
||||
*/
|
||||
static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
|
||||
const char* filename,
|
||||
const WCHAR* filename,
|
||||
unsigned long load_offset,
|
||||
struct elf_info* elf_info)
|
||||
{
|
||||
|
@ -1302,11 +1313,18 @@ static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
|
|||
|
||||
while (!ret && (path = wine_dll_enum_load_path( index++ )))
|
||||
{
|
||||
char *name = HeapAlloc( GetProcessHeap(), 0, strlen(path) + strlen(filename) + 2 );
|
||||
WCHAR *name;
|
||||
unsigned len;
|
||||
|
||||
len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
|
||||
|
||||
name = HeapAlloc( GetProcessHeap(), 0,
|
||||
(len + lstrlenW(filename) + 2) * sizeof(WCHAR) );
|
||||
|
||||
if (!name) break;
|
||||
strcpy( name, path );
|
||||
strcat( name, "/" );
|
||||
strcat( name, filename );
|
||||
MultiByteToWideChar(CP_UNIXCP, 0, path, -1, name, len);
|
||||
strcatW( name, S_SlashW );
|
||||
strcatW( name, filename );
|
||||
ret = elf_load_file(hProcess, name, load_offset, elf_info);
|
||||
HeapFree( GetProcessHeap(), 0, name );
|
||||
}
|
||||
|
@ -1318,27 +1336,28 @@ static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
|
|||
*
|
||||
* lookup a file in standard ELF locations, and if found, load it
|
||||
*/
|
||||
static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
|
||||
unsigned long load_offset,
|
||||
static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
|
||||
unsigned long load_offset,
|
||||
struct elf_info* elf_info)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
struct module* module;
|
||||
static WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
|
||||
|
||||
if (filename == NULL || *filename == '\0') return FALSE;
|
||||
if ((module = module_find_by_nameA(pcs, filename, DMT_ELF)))
|
||||
if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
|
||||
{
|
||||
elf_info->module = module;
|
||||
module->elf_info->elf_mark = 1;
|
||||
return module->module.SymType;
|
||||
}
|
||||
|
||||
if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
|
||||
if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */
|
||||
ret = elf_load_file(pcs, filename, load_offset, elf_info);
|
||||
/* if relative pathname, try some absolute base dirs */
|
||||
if (!ret && !strchr(filename, '/'))
|
||||
if (!ret && !strchrW(filename, '/'))
|
||||
{
|
||||
ret = elf_load_file_from_path(pcs, filename, load_offset,
|
||||
ret = elf_load_file_from_path(pcs, filename, load_offset,
|
||||
getenv("PATH"), elf_info) ||
|
||||
elf_load_file_from_path(pcs, filename, load_offset,
|
||||
getenv("LD_LIBRARY_PATH"), elf_info);
|
||||
|
@ -1354,7 +1373,7 @@ static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
|
|||
* Enumerate ELF modules from a running process
|
||||
*/
|
||||
static BOOL elf_enum_modules_internal(const struct process* pcs,
|
||||
const char* main_name,
|
||||
const WCHAR* main_name,
|
||||
elf_enum_modules_cb cb, void* user)
|
||||
{
|
||||
struct r_debug dbg_hdr;
|
||||
|
@ -1380,11 +1399,11 @@ static BOOL elf_enum_modules_internal(const struct process* pcs,
|
|||
|
||||
if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
|
||||
lm.l_name != NULL &&
|
||||
ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
|
||||
ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
|
||||
{
|
||||
bufstr[sizeof(bufstr) - 1] = '\0';
|
||||
if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
|
||||
MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR));
|
||||
if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name);
|
||||
if (!cb(bufstrW, (unsigned long)lm.l_addr, user)) break;
|
||||
}
|
||||
}
|
||||
|
@ -1400,10 +1419,8 @@ struct elf_sync
|
|||
static BOOL elf_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user)
|
||||
{
|
||||
struct elf_sync* es = user;
|
||||
char tmp[MAX_PATH];
|
||||
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, name, -1, tmp, sizeof(tmp), 0, 0);
|
||||
elf_search_and_load_file(es->pcs, tmp, addr, &es->elf_info);
|
||||
elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1465,11 +1482,15 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
|
|||
* or wine-kthread is not 100% safe
|
||||
*/
|
||||
if ((ptr = getenv("WINELOADER")))
|
||||
ret = elf_search_and_load_file(pcs, ptr, 0, elf_info);
|
||||
else
|
||||
{
|
||||
ret = elf_search_and_load_file(pcs, "wine-kthread", 0, elf_info) ||
|
||||
elf_search_and_load_file(pcs, "wine-pthread", 0, elf_info);
|
||||
WCHAR tmp[MAX_PATH];
|
||||
MultiByteToWideChar(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp) / sizeof(WCHAR));
|
||||
ret = elf_search_and_load_file(pcs, tmp, 0, elf_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = elf_search_and_load_file(pcs, S_WineKThreadW, 0, elf_info) ||
|
||||
elf_search_and_load_file(pcs, S_WinePThreadW, 0, elf_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1517,7 +1538,7 @@ struct elf_load
|
|||
{
|
||||
struct process* pcs;
|
||||
struct elf_info elf_info;
|
||||
char name[MAX_PATH];
|
||||
const WCHAR* name;
|
||||
BOOL ret;
|
||||
};
|
||||
|
||||
|
@ -1527,20 +1548,17 @@ struct elf_load
|
|||
* Callback for elf_load_module, used to walk the list of loaded
|
||||
* modules.
|
||||
*/
|
||||
static BOOL elf_load_cb(const WCHAR* nameW, unsigned long addr, void* user)
|
||||
static BOOL elf_load_cb(const WCHAR* name, unsigned long addr, void* user)
|
||||
{
|
||||
struct elf_load* el = user;
|
||||
const char* p;
|
||||
char name[MAX_PATH];
|
||||
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, nameW, -1, name, sizeof(name), 0, 0);
|
||||
const WCHAR* p;
|
||||
|
||||
/* memcmp is needed for matches when bufstr contains also version information
|
||||
* el->name: libc.so, name: libc.so.6.0
|
||||
*/
|
||||
p = strrchr(name, '/');
|
||||
p = strrchrW(name, '/');
|
||||
if (!p++) p = name;
|
||||
if (!memcmp(p, el->name, strlen(el->name)))
|
||||
if (!memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
|
||||
{
|
||||
el->ret = elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
|
||||
return FALSE;
|
||||
|
@ -1566,15 +1584,12 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned
|
|||
|
||||
if (pcs->dbg_hdr_addr) /* we're debugging a life target */
|
||||
{
|
||||
const WCHAR* ptr;
|
||||
|
||||
el.pcs = pcs;
|
||||
/* do only the lookup from the filename, not the path (as we lookup module
|
||||
* name in the process' loaded module list)
|
||||
*/
|
||||
ptr = strrchrW(name, '/');
|
||||
if (!ptr++) ptr = name;
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, ptr, -1, el.name, sizeof(el.name), NULL, NULL);
|
||||
el.name = strrchrW(name, '/');
|
||||
if (!el.name++) el.name = name;
|
||||
el.ret = FALSE;
|
||||
|
||||
if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
|
||||
|
@ -1582,7 +1597,7 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned
|
|||
}
|
||||
else if (addr)
|
||||
{
|
||||
WideCharToMultiByte(CP_UNIXCP, 0, name, -1, el.name, sizeof(el.name), NULL, NULL);
|
||||
el.name = name;
|
||||
el.ret = elf_search_and_load_file(pcs, el.name, addr, &el.elf_info);
|
||||
}
|
||||
if (!el.ret) return NULL;
|
||||
|
|
|
@ -37,8 +37,9 @@ const WCHAR S_ElfW[] = {'<','e','l','f','>','\0'};
|
|||
const WCHAR S_WineLoaderW[] = {'<','w','i','n','e','-','l','o','a','d','e','r','>','\0'};
|
||||
static const WCHAR S_DotSoW[] = {'.','s','o','\0'};
|
||||
static const WCHAR S_DotPdbW[] = {'.','p','d','b','\0'};
|
||||
static const WCHAR S_WinePThreadW[] = {'w','i','n','e','-','p','t','h','r','e','a','d','\0'};
|
||||
static const WCHAR S_WineKThreadW[] = {'w','i','n','e','-','k','t','h','r','e','a','d','\0'};
|
||||
const WCHAR S_WinePThreadW[] = {'w','i','n','e','-','p','t','h','r','e','a','d','\0'};
|
||||
const WCHAR S_WineKThreadW[] = {'w','i','n','e','-','k','t','h','r','e','a','d','\0'};
|
||||
const WCHAR S_SlashW[] = {'/','\0'};
|
||||
|
||||
static const WCHAR S_AcmW[] = {'.','a','c','m','\0'};
|
||||
static const WCHAR S_DllW[] = {'.','d','l','l','\0'};
|
||||
|
|
Loading…
Reference in New Issue