dbghelp: Dwarf & thunks.

- added the elf_is_in_thunk_area() function to locate an address
  within the known thunk area of Wine's builtin modules
- now passing this thunk information to the dwarf parser so that it
  can drop functions from the thunk areas (as dwarf symbols), so that
  those functions can be later on marked as thunks in dbghelp
  internals
This commit is contained in:
Eric Pouech 2006-06-24 09:50:10 +02:00 committed by Alexandre Julliard
parent f939b0853d
commit e9910fee66
3 changed files with 43 additions and 16 deletions

View file

@ -375,7 +375,8 @@ extern struct module*
elf_load_module(struct process* pcs, const char* name, unsigned long);
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs);
extern BOOL elf_synchronize_module_list(struct process* pcs);
struct elf_thunk_area;
extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks);
extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr);
/* module.c */
@ -432,6 +433,7 @@ extern BOOL stabs_parse(struct module* module, unsigned long load_offset
/* dwarf.c */
extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
const struct elf_thunk_area* thunks,
const unsigned char* debug, unsigned int debug_size,
const unsigned char* abbrev, unsigned int abbrev_size,
const unsigned char* str, unsigned int str_size,

View file

@ -170,6 +170,7 @@ typedef struct dwarf2_parse_context_s
{
struct pool pool;
struct module* module;
const struct elf_thunk_area*thunks;
struct sparse_array abbrev_table;
struct sparse_array debug_info_table;
unsigned char word_size;
@ -1255,6 +1256,13 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
if (!dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) high_pc.uvalue = 0;
/* As functions (defined as inline assembly) get debug info with dwarf
* (not the case for stabs), we just drop Wine's thunks here...
* Actual thunks will be created in elf_module from the symbol table
*/
if (elf_is_in_thunk_area(ctx->module->module.BaseOfImage + low_pc.uvalue,
ctx->thunks) >= 0)
return NULL;
if (!dwarf2_find_attribute(di, DW_AT_declaration, &is_decl)) is_decl.uvalue = 0;
if (!dwarf2_find_attribute(di, DW_AT_inline, &inline_flags)) inline_flags.uvalue = 0;
dwarf2_find_name(ctx, di, &name, "subprogram");
@ -1558,6 +1566,7 @@ static void dwarf2_parse_line_numbers(const dwarf2_section_t* sections,
static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
const dwarf2_comp_unit_t* comp_unit,
struct module* module,
const struct elf_thunk_area* thunks,
const unsigned char* comp_unit_cursor)
{
dwarf2_parse_context_t ctx;
@ -1583,6 +1592,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
pool_init(&ctx.pool, 65536);
ctx.module = module;
ctx.word_size = comp_unit->word_size;
ctx.thunks = thunks;
traverse.sections = sections;
traverse.section = section_debug;
@ -1634,6 +1644,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
}
BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
const struct elf_thunk_area* thunks,
const unsigned char* debug, unsigned int debug_size,
const unsigned char* abbrev, unsigned int abbrev_size,
const unsigned char* str, unsigned int str_size,
@ -1663,7 +1674,8 @@ BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
dwarf2_parse_compilation_unit(section, &comp_unit, module, comp_unit_cursor);
dwarf2_parse_compilation_unit(section, &comp_unit, module,
thunks, comp_unit_cursor);
comp_unit_cursor += comp_unit.length + sizeof(unsigned);
}
module->module.SymType = SymDia;

View file

@ -125,7 +125,7 @@ struct symtab_elt
unsigned used;
};
struct thunk_area
struct elf_thunk_area
{
const char* symname;
THUNK_ORDINAL ordinal;
@ -249,6 +249,25 @@ static void elf_unmap_file(struct elf_file_map* fmap)
}
}
/******************************************************************
* elf_is_in_thunk_area
*
* Check whether an address lies within one of the thunk area we
* know of.
*/
int elf_is_in_thunk_area(unsigned long addr,
const struct elf_thunk_area* thunks)
{
unsigned i;
for (i = 0; thunks[i].symname; i++)
{
if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
return i;
}
return -1;
}
/******************************************************************
* elf_hash_symtab
*
@ -256,7 +275,7 @@ static void elf_unmap_file(struct elf_file_map* fmap)
*/
static void elf_hash_symtab(struct module* module, struct pool* pool,
struct hash_table* ht_symtab, struct elf_file_map* fmap,
int symtab_idx, struct thunk_area* thunks)
int symtab_idx, struct elf_thunk_area* thunks)
{
int i, j, nsym;
const char* strp;
@ -503,7 +522,7 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt
* creating the thunk objects for a wine native DLL
*/
static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
unsigned num_areas, struct thunk_area* thunks)
const struct elf_thunk_area* thunks)
{
int j;
struct hash_table_iter hti;
@ -518,13 +537,8 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt
addr = module->elf_info->elf_addr + ste->symp->st_value;
for (j = 0; j < num_areas; j++)
{
if (ste->symp->st_value >= thunks[j].rva_start &&
ste->symp->st_value < thunks[j].rva_end)
break;
}
if (j < num_areas) /* thunk found */
j = elf_is_in_thunk_area(ste->symp->st_value, thunks);
if (j >= 0) /* thunk found */
{
symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
addr, ste->symp->st_size);
@ -767,7 +781,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
int symtab_sect, dynsym_sect, stab_sect, stabstr_sect;
int debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect;
int debuglink_sect;
struct thunk_area thunks[] =
struct elf_thunk_area thunks[] =
{
{"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
{"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
@ -883,7 +897,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP)
{
/* OK, now just parse dwarf2 debug infos. */
lret = dwarf2_parse(module, module->elf_info->elf_addr,
lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks,
dw2_debug, fmap->sect[debug_sect].shdr.sh_size,
dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size,
dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size,
@ -930,8 +944,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
{
/* add the thunks for native libraries */
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
elf_new_wine_thunks(module, ht_symtab,
sizeof(thunks) / sizeof(thunks[0]), thunks);
elf_new_wine_thunks(module, ht_symtab, thunks);
}
/* add all the public symbols from symtab */
if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;