Commit dc43edff authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- fixed loading stabs from PE modules compiled with MingW

- enhance some loading logic between ELF/PE DLL pairs - removed unused indirect memory access function - get rid of some GCC generated symbols
parent 99e07b5b
...@@ -296,16 +296,6 @@ extern struct module* ...@@ -296,16 +296,6 @@ extern struct module*
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs); extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs);
extern BOOL elf_synchronize_module_list(struct process* pcs); extern BOOL elf_synchronize_module_list(struct process* pcs);
/* memory.c */
struct memory_access
{
BOOL (*read_mem)(HANDLE hProcess, DWORD addr, void* buf, DWORD len);
BOOL (*write_mem)(HANDLE hProcess, DWORD addr, void* buf, DWORD len);
};
extern struct memory_access mem_access;
#define read_mem(p,a,b,l) (mem_access.read_mem)((p),(a),(b),(l))
#define write_mem(p,a,b,l) (mem_access.write_mem)((p),(a),(b),(l))
extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr); extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr);
/* module.c */ /* module.c */
...@@ -351,10 +341,9 @@ extern unsigned source_new(struct module* module, const char* source); ...@@ -351,10 +341,9 @@ extern unsigned source_new(struct module* module, const char* source);
extern const char* source_get(const struct module* module, unsigned idx); extern const char* source_get(const struct module* module, unsigned idx);
/* stabs.c */ /* stabs.c */
extern BOOL stabs_parse(struct module* module, const char* addr, extern BOOL stabs_parse(struct module* module, unsigned long load_offset,
unsigned long load_offset, const void* stabs, int stablen,
unsigned int staboff, int stablen, const char* strs, int strtablen);
unsigned int strtaboff, int strtablen);
/* symbol.c */ /* symbol.c */
extern const char* symt_get_name(const struct symt* sym); extern const char* symt_get_name(const struct symt* sym);
......
...@@ -158,6 +158,12 @@ static void elf_hash_symtab(const struct module* module, struct pool* pool, ...@@ -158,6 +158,12 @@ static void elf_hash_symtab(const struct module* module, struct pool* pool,
} }
if (j < num_areas) continue; if (j < num_areas) continue;
/* FIXME: we don't need to handle them (GCC internals)
* Moreover, they screw up our symbol lookup :-/
*/
if (symname[0] == '.' && symname[1] == 'L' && isdigit(symname[2]))
continue;
ste = pool_alloc(pool, sizeof(*ste)); ste = pool_alloc(pool, sizeof(*ste));
/* GCC seems to emit, in some cases, a .<digit>+ suffix. /* GCC seems to emit, in some cases, a .<digit>+ suffix.
* This is used for static variable inside functions, so * This is used for static variable inside functions, so
...@@ -286,7 +292,7 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt ...@@ -286,7 +292,7 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt
((struct symt_function*)sym)->address = module->elf_info->elf_addr + ((struct symt_function*)sym)->address = module->elf_info->elf_addr +
symp->st_value; symp->st_value;
((struct symt_function*)sym)->size = symp->st_size; ((struct symt_function*)sym)->size = symp->st_size;
} } else FIXME("Couldn't find %s\n", sym->hash_elt.name);
break; break;
case SymTagData: case SymTagData:
switch (((struct symt_data*)sym)->kind) switch (((struct symt_data*)sym)->kind)
...@@ -694,9 +700,10 @@ static BOOL elf_load_debug_info_from_file( ...@@ -694,9 +700,10 @@ static BOOL elf_load_debug_info_from_file(
if (stab_sect != -1 && stabstr_sect != -1) if (stab_sect != -1 && stabstr_sect != -1)
{ {
/* OK, now just parse all of the stabs. */ /* OK, now just parse all of the stabs. */
ret = stabs_parse(module, addr, module->elf_info->elf_addr, ret = stabs_parse(module, module->elf_info->elf_addr,
spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size, addr + spnt[stab_sect].sh_offset,
spnt[stabstr_sect].sh_offset, spnt[stab_sect].sh_size,
addr + spnt[stabstr_sect].sh_offset,
spnt[stabstr_sect].sh_size); spnt[stabstr_sect].sh_size);
if (!ret) if (!ret)
{ {
...@@ -1010,8 +1017,9 @@ BOOL elf_synchronize_module_list(struct process* pcs) ...@@ -1010,8 +1017,9 @@ BOOL elf_synchronize_module_list(struct process* pcs)
struct elf_info elf_info; struct elf_info elf_info;
struct module* module; struct module* module;
if (!pcs->dbg_hdr_addr) return FALSE; if (!pcs->dbg_hdr_addr ||
if (!read_mem(pcs->handle, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr))) !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr,
&dbg_hdr, sizeof(dbg_hdr), NULL))
return FALSE; return FALSE;
for (module = pcs->lmodules; module; module = module->next) for (module = pcs->lmodules; module; module = module->next)
...@@ -1027,12 +1035,12 @@ BOOL elf_synchronize_module_list(struct process* pcs) ...@@ -1027,12 +1035,12 @@ BOOL elf_synchronize_module_list(struct process* pcs)
*/ */
for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
{ {
if (!read_mem(pcs->handle, (ULONG)lm_addr, &lm, sizeof(lm))) if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
return FALSE; return FALSE;
if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
lm.l_name != NULL && lm.l_name != NULL &&
read_mem(pcs->handle, (ULONG)lm.l_name, bufstr, sizeof(bufstr))) ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
{ {
bufstr[sizeof(bufstr) - 1] = '\0'; bufstr[sizeof(bufstr) - 1] = '\0';
elf_search_and_load_file(pcs, bufstr, (unsigned long)lm.l_addr, elf_search_and_load_file(pcs, bufstr, (unsigned long)lm.l_addr,
...@@ -1087,7 +1095,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs) ...@@ -1087,7 +1095,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
* elf_load_module * elf_load_module
* *
* loads an ELF module and stores it in process' module list * loads an ELF module and stores it in process' module list
* if 'sync' is TRUE, let's find module real name and load address from * Also, find module real name and load address from
* the real loaded modules list in pcs address space * the real loaded modules list in pcs address space
*/ */
struct module* elf_load_module(struct process* pcs, const char* name) struct module* elf_load_module(struct process* pcs, const char* name)
...@@ -1111,17 +1119,17 @@ struct module* elf_load_module(struct process* pcs, const char* name) ...@@ -1111,17 +1119,17 @@ struct module* elf_load_module(struct process* pcs, const char* name)
xname = strrchr(name, '/'); xname = strrchr(name, '/');
if (!xname++) xname = name; if (!xname++) xname = name;
if (!read_mem(pcs->handle, pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr))) if (!ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, &dbg_hdr, sizeof(dbg_hdr), NULL))
return NULL; return NULL;
for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next)
{ {
if (!read_mem(pcs->handle, (ULONG)lm_addr, &lm, sizeof(lm))) if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL))
return NULL; return NULL;
if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */
lm.l_name != NULL && lm.l_name != NULL &&
read_mem(pcs->handle, (ULONG)lm.l_name, bufstr, sizeof(bufstr))) ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL))
{ {
bufstr[sizeof(bufstr) - 1] = '\0'; bufstr[sizeof(bufstr) - 1] = '\0';
/* memcmp is needed for matches when bufstr contains also version information /* memcmp is needed for matches when bufstr contains also version information
......
...@@ -26,21 +26,6 @@ ...@@ -26,21 +26,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
BOOL win32_read_mem(HANDLE hProcess, DWORD addr, void* buf, DWORD len)
{
return ReadProcessMemory(hProcess, (void*)addr, buf, len, NULL);
}
BOOL win32_write_mem(HANDLE hProcess, DWORD addr, void* buf, DWORD len)
{
return WriteProcessMemory(hProcess, (void*)addr, buf, len, NULL);
}
/* standard routines for reading / writing memory. Can be overriden for some
* minidump usage
*/
struct memory_access mem_access = {win32_read_mem, win32_write_mem};
/****************************************************************** /******************************************************************
* addr_to_linear * addr_to_linear
* *
......
...@@ -201,16 +201,17 @@ struct module* module_get_containee(const struct process* pcs, ...@@ -201,16 +201,17 @@ struct module* module_get_containee(const struct process* pcs,
*/ */
struct module* module_get_debug(const struct process* pcs, struct module* module) struct module* module_get_debug(const struct process* pcs, struct module* module)
{ {
BOOL ret; struct module* parent;
if (!module) return NULL; if (!module) return NULL;
switch (module->module.SymType) /* for a PE builtin, always get info from parent */
if ((parent = module_get_container(pcs, module)))
module = parent;
/* if deferred, force loading */
if (module->module.SymType == SymDeferred)
{ {
case SymNone: BOOL ret;
module = module_get_container(pcs, module);
if (!module || module->module.SymType != SymDeferred) break;
/* fall through */
case SymDeferred:
switch (module->type) switch (module->type)
{ {
case DMT_ELF: ret = elf_load_debug_info(module); break; case DMT_ELF: ret = elf_load_debug_info(module); break;
...@@ -218,8 +219,7 @@ struct module* module_get_debug(const struct process* pcs, struct module* module ...@@ -218,8 +219,7 @@ struct module* module_get_debug(const struct process* pcs, struct module* module
default: ret = FALSE; break; default: ret = FALSE; break;
} }
if (!ret) module->module.SymType = SymNone; if (!ret) module->module.SymType = SymNone;
break; assert(module->module.SymType != SymDeferred);
default: break;
} }
return (module && module->module.SymType != SymNone) ? module : NULL; return (module && module->module.SymType != SymNone) ? module : NULL;
} }
......
...@@ -66,8 +66,12 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module, ...@@ -66,8 +66,12 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module,
if (stabstrsize && stabsize) if (stabstrsize && stabsize)
{ {
ret = stabs_parse(module, mapping, module->module.BaseOfImage, ret = stabs_parse(module,
stabs, stabsize, stabstr, stabstrsize); module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
RtlImageRvaToVa(nth, (void*)mapping, stabs, NULL),
stabsize,
RtlImageRvaToVa(nth, (void*)mapping, stabstr, NULL),
stabstrsize);
} }
return ret; return ret;
} }
...@@ -269,7 +273,8 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, ...@@ -269,7 +273,8 @@ static BOOL pe_load_export_debug_info(const struct process* pcs,
} }
} }
/* no real debug info, only entry points */ /* no real debug info, only entry points */
module->module.SymType = SymExport; if (module->module.SymType == SymDeferred)
module->module.SymType = SymExport;
return TRUE; return TRUE;
} }
...@@ -303,6 +308,7 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module) ...@@ -303,6 +308,7 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
* in which case we'll rely on the export's on the ELF side * in which case we'll rely on the export's on the ELF side
*/ */
} }
// FIXME shouldn't we check that? if (!module_get_debug(pcs, module))l
if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret) if (pe_load_export_debug_info(pcs, module, mapping, nth) && !ret)
ret = TRUE; ret = TRUE;
UnmapViewOfFile(mapping); UnmapViewOfFile(mapping);
...@@ -403,9 +409,10 @@ struct module* pe_load_module_from_pcs(struct process* pcs, const char* name, ...@@ -403,9 +409,10 @@ struct module* pe_load_module_from_pcs(struct process* pcs, const char* name,
IMAGE_DOS_HEADER dos; IMAGE_DOS_HEADER dos;
IMAGE_NT_HEADERS nth; IMAGE_NT_HEADERS nth;
if (read_mem(pcs->handle, base, &dos, sizeof(dos)) && if (ReadProcessMemory(pcs->handle, (char*)base, &dos, sizeof(dos), NULL) &&
dos.e_magic == IMAGE_DOS_SIGNATURE && dos.e_magic == IMAGE_DOS_SIGNATURE &&
read_mem(pcs->handle, base + dos.e_lfanew, &nth, sizeof(nth)) && ReadProcessMemory(pcs->handle, (char*)(base + dos.e_lfanew),
&nth, sizeof(nth), NULL) &&
nth.Signature == IMAGE_NT_SIGNATURE) nth.Signature == IMAGE_NT_SIGNATURE)
{ {
if (!size) size = nth.OptionalHeader.SizeOfImage; if (!size) size = nth.OptionalHeader.SizeOfImage;
......
...@@ -1060,8 +1060,11 @@ struct pending_loc_var ...@@ -1060,8 +1060,11 @@ struct pending_loc_var
* Ends function creation: mainly: * Ends function creation: mainly:
* - cleans up line number information * - cleans up line number information
* - tries to set up a debug-start tag (FIXME: heuristic to be enhanced) * - tries to set up a debug-start tag (FIXME: heuristic to be enhanced)
* - for stabs which have abolute address in them, initializes the size of the
* function (assuming that current function ends where next function starts)
*/ */
static void stabs_finalize_function(struct module* module, struct symt_function* func) static void stabs_finalize_function(struct module* module, struct symt_function* func,
unsigned long end)
{ {
IMAGEHLP_LINE il; IMAGEHLP_LINE il;
...@@ -1076,11 +1079,12 @@ static void stabs_finalize_function(struct module* module, struct symt_function* ...@@ -1076,11 +1079,12 @@ static void stabs_finalize_function(struct module* module, struct symt_function*
symt_add_function_point(module, func, SymTagFuncDebugStart, symt_add_function_point(module, func, SymTagFuncDebugStart,
il.Address - func->address, NULL); il.Address - func->address, NULL);
} }
if (end) func->size = end - func->address;
} }
BOOL stabs_parse(struct module* module, const char* addr, BOOL stabs_parse(struct module* module, unsigned long load_offset,
unsigned long load_offset, unsigned int staboff, int stablen, const void* pv_stab_ptr, int stablen,
unsigned int strtaboff, int strtablen) const char* strs, int strtablen)
{ {
struct symt_function* curr_func = NULL; struct symt_function* curr_func = NULL;
struct symt_block* block = NULL; struct symt_block* block = NULL;
...@@ -1092,8 +1096,7 @@ BOOL stabs_parse(struct module* module, const char* addr, ...@@ -1092,8 +1096,7 @@ BOOL stabs_parse(struct module* module, const char* addr,
const char* ptr; const char* ptr;
char* stabbuff; char* stabbuff;
unsigned int stabbufflen; unsigned int stabbufflen;
const struct stab_nlist* stab_ptr; const struct stab_nlist* stab_ptr = pv_stab_ptr;
const char* strs;
const char* strs_end; const char* strs_end;
int strtabinc; int strtabinc;
char symname[4096]; char symname[4096];
...@@ -1106,8 +1109,6 @@ BOOL stabs_parse(struct module* module, const char* addr, ...@@ -1106,8 +1109,6 @@ BOOL stabs_parse(struct module* module, const char* addr,
BOOL ret = TRUE; BOOL ret = TRUE;
nstab = stablen / sizeof(struct stab_nlist); nstab = stablen / sizeof(struct stab_nlist);
stab_ptr = (const struct stab_nlist*)(addr + staboff);
strs = (const char*)(addr + strtaboff);
strs_end = strs + strtablen; strs_end = strs + strtablen;
memset(srcpath, 0, sizeof(srcpath)); memset(srcpath, 0, sizeof(srcpath));
...@@ -1355,7 +1356,8 @@ BOOL stabs_parse(struct module* module, const char* addr, ...@@ -1355,7 +1356,8 @@ BOOL stabs_parse(struct module* module, const char* addr,
break; break;
case N_FUN: case N_FUN:
/* First, clean up the previous function we were working on. */ /* First, clean up the previous function we were working on. */
stabs_finalize_function(module, curr_func); stabs_finalize_function(module, curr_func,
stab_ptr->n_value ? load_offset + stab_ptr->n_value : 0);
/* /*
* For now, just declare the various functions. Later * For now, just declare the various functions. Later
...@@ -1394,7 +1396,8 @@ BOOL stabs_parse(struct module* module, const char* addr, ...@@ -1394,7 +1396,8 @@ BOOL stabs_parse(struct module* module, const char* addr,
{ {
/* Nuke old path. */ /* Nuke old path. */
srcpath[0] = '\0'; srcpath[0] = '\0';
stabs_finalize_function(module, curr_func); stabs_finalize_function(module, curr_func,
stab_ptr->n_value ? load_offset + stab_ptr->n_value : 0);
curr_func = NULL; curr_func = NULL;
source_idx = -1; source_idx = -1;
incl_stk = -1; incl_stk = -1;
...@@ -1429,7 +1432,9 @@ BOOL stabs_parse(struct module* module, const char* addr, ...@@ -1429,7 +1432,9 @@ BOOL stabs_parse(struct module* module, const char* addr,
case N_UNDF: case N_UNDF:
strs += strtabinc; strs += strtabinc;
strtabinc = stab_ptr->n_value; strtabinc = stab_ptr->n_value;
stabs_finalize_function(module, curr_func); /* I'm not sure this is needed, so trace it before we obsolete it */
if (curr_func) FIXME("UNDF: curr_func %s\n", curr_func->hash_elt.name);
stabs_finalize_function(module, curr_func, 0); /* FIXME */
curr_func = NULL; curr_func = NULL;
break; break;
case N_OPT: case N_OPT:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment