Commit 2d8c7883 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Let dwarf_parse decide on which sections it needs to map.

parent c9bac2ef
......@@ -566,11 +566,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,
const unsigned char* line, unsigned int line_size,
const unsigned char* loclist, unsigned int loclist_size);
struct image_file_map* fmap);
/* stack.c */
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz);
......
......@@ -159,6 +159,7 @@ typedef struct dwarf2_section_s
{
const unsigned char* address;
unsigned size;
DWORD_PTR rva;
} dwarf2_section_t;
enum dwarf2_sections {section_debug, section_string, section_abbrev, section_line, section_max};
......@@ -2350,44 +2351,84 @@ static void dwarf2_location_compute(struct process* pcs,
}
}
static inline BOOL dwarf2_init_section(dwarf2_section_t* section, struct image_file_map* fmap,
const char* sectname, struct image_section_map* ism)
{
struct image_section_map local_ism;
if (!ism) ism = &local_ism;
if (!image_find_section(fmap, sectname, ism))
{
section->address = NULL;
section->size = 0;
section->rva = 0;
return FALSE;
}
section->address = (const BYTE*)image_map_section(ism);
section->size = image_get_map_size(ism);
section->rva = image_get_map_rva(ism);
return TRUE;
}
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,
const unsigned char* line, unsigned int line_size,
const unsigned char* loclist, unsigned int loclist_size)
struct image_file_map* fmap)
{
dwarf2_section_t section[section_max];
unsigned char* ptr;
dwarf2_traverse_context_t mod_ctx;
struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
debug_line_sect, debug_loclist_sect;
BOOL ret = TRUE;
if (!dwarf2_init_section(&section[section_debug], fmap, ".debug_info", &debug_sect))
{
/* no Dwarf debug info here, so there's no error */
return TRUE;
}
dwarf2_init_section(&section[section_abbrev], fmap, ".debug_abbrev", &debug_abbrev_sect);
dwarf2_init_section(&section[section_string], fmap, ".debug_str", &debug_str_sect);
dwarf2_init_section(&section[section_line], fmap, ".debug_line", &debug_line_sect);
image_find_section(fmap, ".debug_loc", &debug_loclist_sect);
if (section[section_debug].address == IMAGE_NO_MAP ||
section[section_abbrev].address == IMAGE_NO_MAP ||
section[section_string].address == IMAGE_NO_MAP)
{
ret = FALSE;
goto leave;
}
if (fmap->modtype == DMT_ELF)
{
/* debug info might have a different base address than .so file
* when elf file is prelinked after splitting off debug info
* adjust symbol base addresses accordingly
*/
load_offset += fmap->u.elf.elf_start - debug_sect.fmap->u.elf.elf_start;
}
mod_ctx.start_data = mod_ctx.data = debug;
mod_ctx.end_data = debug + debug_size;
TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
module->loc_compute = dwarf2_location_compute;
mod_ctx.start_data = mod_ctx.data = section[section_debug].address;
mod_ctx.end_data = mod_ctx.data + section[section_debug].size;
section[section_debug].address = debug;
section[section_debug].size = debug_size;
section[section_abbrev].address = abbrev;
section[section_abbrev].size = abbrev_size;
section[section_string].address = str;
section[section_string].size = str_size;
section[section_line].address = line;
section[section_line].size = line_size;
module->loc_compute = dwarf2_location_compute;
if (loclist_size)
if (image_get_map_size(&debug_loclist_sect))
{
/* initialize the dwarf2 specific info block for this module.
* As we'll need later on the .debug_loc section content, we copy it in
* the module structure for later reuse
*/
module->dwarf2_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*module->dwarf2_info) + loclist_size);
module->dwarf2_info = HeapAlloc(GetProcessHeap(), 0, sizeof(*module->dwarf2_info) +
image_get_map_size(&debug_loclist_sect));
if (!module->dwarf2_info) return FALSE;
ptr = (unsigned char*)(module->dwarf2_info + 1);
memcpy(ptr, loclist, loclist_size);
memcpy(ptr, image_map_section(&debug_loclist_sect), image_get_map_size(&debug_loclist_sect));
module->dwarf2_info->debug_loc.address = ptr;
module->dwarf2_info->debug_loc.size = loclist_size;
module->dwarf2_info->debug_loc.size = image_get_map_size(&debug_loclist_sect);
}
while (mod_ctx.data < mod_ctx.end_data)
......@@ -2401,5 +2442,12 @@ BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
module->module.TypeInfo = TRUE;
module->module.SourceIndexed = TRUE;
module->module.Publics = TRUE;
return TRUE;
leave:
image_unmap_section(&debug_sect);
image_unmap_section(&debug_abbrev_sect);
image_unmap_section(&debug_str_sect);
image_unmap_section(&debug_line_sect);
image_unmap_section(&debug_loclist_sect);
return ret;
}
......@@ -879,7 +879,6 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
{
struct image_section_map stab_sect, stabstr_sect;
struct image_section_map debuglink_sect;
struct image_section_map debug_sect;
/* if present, add the .gnu_debuglink file as an alternate to current one */
if (elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
......@@ -923,55 +922,8 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
image_unmap_section(&stab_sect);
image_unmap_section(&stabstr_sect);
}
if (elf_find_section(fmap, ".debug_info", SHT_NULL, &debug_sect))
{
struct image_section_map debug_str_sect, debug_abbrev_sect, debug_line_sect, debug_loclist_sect;
/* Dwarf 2 debug information */
const BYTE* dw2_debug;
const BYTE* dw2_debug_abbrev;
const BYTE* dw2_debug_str;
const BYTE* dw2_debug_line;
const BYTE* dw2_debug_loclist;
/* debug info might have a different base address than .so file
* when elf file is prelinked after splitting off debug info
* adjust symbol base addresses accordingly
*/
unsigned long load_offset = module->elf_info->elf_addr +
fmap->u.elf.elf_start - debug_sect.fmap->u.elf.elf_start;
TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
elf_find_section(fmap, ".debug_str", SHT_NULL, &debug_str_sect);
elf_find_section(fmap, ".debug_abbrev", SHT_NULL, &debug_abbrev_sect);
elf_find_section(fmap, ".debug_line", SHT_NULL, &debug_line_sect);
elf_find_section(fmap, ".debug_loc", SHT_NULL, &debug_loclist_sect);
dw2_debug = (const BYTE*)image_map_section(&debug_sect);
dw2_debug_abbrev = (const BYTE*)image_map_section(&debug_abbrev_sect);
dw2_debug_str = (const BYTE*)image_map_section(&debug_str_sect);
dw2_debug_line = (const BYTE*)image_map_section(&debug_line_sect);
dw2_debug_loclist = (const BYTE*)image_map_section(&debug_loclist_sect);
if (dw2_debug != IMAGE_NO_MAP && dw2_debug_abbrev != IMAGE_NO_MAP && dw2_debug_str != IMAGE_NO_MAP)
{
/* OK, now just parse dwarf2 debug infos. */
lret = dwarf2_parse(module, load_offset, thunks,
dw2_debug, image_get_map_size(&debug_sect),
dw2_debug_abbrev, image_get_map_size(&debug_abbrev_sect),
dw2_debug_str, image_get_map_size(&debug_str_sect),
dw2_debug_line, image_get_map_size(&debug_line_sect),
dw2_debug_loclist, image_get_map_size(&debug_loclist_sect));
if (!lret)
WARN("Couldn't correctly read dwarf2\n");
ret = ret || lret;
}
image_unmap_section(&debug_sect);
image_unmap_section(&debug_abbrev_sect);
image_unmap_section(&debug_str_sect);
image_unmap_section(&debug_line_sect);
image_unmap_section(&debug_loclist_sect);
}
lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks, fmap);
ret = ret || lret;
}
if (strstrW(module->module.ModuleName, S_ElfW) ||
!strcmpW(module->module.ModuleName, S_WineLoaderW))
......@@ -1520,6 +1472,11 @@ unsigned elf_get_map_size(const struct image_section_map* ism)
return 0;
}
DWORD_PTR elf_get_map_rva(const struct image_section_map* ism)
{
return 0;
}
BOOL elf_synchronize_module_list(struct process* pcs)
{
return FALSE;
......
......@@ -374,9 +374,12 @@ static BOOL pe_load_coff_symbol_table(struct module* module)
if (!compiland && lastfilename)
compiland = symt_new_compiland(module, 0,
source_new(module, NULL, lastfilename));
symt_new_public(module, compiland, name,
module->module.BaseOfImage + sect[isym->SectionNumber - 1].VirtualAddress + isym->Value,
1);
if (!(dbghelp_options & SYMOPT_NO_PUBLICS))
symt_new_public(module, compiland, name,
module->module.BaseOfImage + sect[isym->SectionNumber - 1].VirtualAddress +
isym->Value,
1);
}
naux = isym->NumberOfAuxSymbols + 1;
}
......@@ -444,48 +447,15 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module)
* look for dwarf information in PE header (it's also a way for the mingw compiler
* to provide its debugging information)
*/
static BOOL pe_load_dwarf(const struct process* pcs, struct module* module)
static BOOL pe_load_dwarf(struct module* module)
{
struct image_file_map* fmap = &module->pe_info->fmap;
struct image_section_map sect_debuginfo, sect_debugstr, sect_debugabbrev, sect_debugline, sect_debugloc;
BOOL ret = FALSE;
if (pe_find_section(fmap, ".debug_info", &sect_debuginfo))
{
const BYTE* dw2_debuginfo;
const BYTE* dw2_debugabbrev;
const BYTE* dw2_debugstr;
const BYTE* dw2_debugline;
const BYTE* dw2_debugloc;
pe_find_section(fmap, ".debug_str", &sect_debugstr);
pe_find_section(fmap, ".debug_abbrev", &sect_debugabbrev);
pe_find_section(fmap, ".debug_line", &sect_debugline);
pe_find_section(fmap, ".debug_loc", &sect_debugloc);
dw2_debuginfo = (const BYTE*)image_map_section(&sect_debuginfo);
dw2_debugabbrev = (const BYTE*)image_map_section(&sect_debugabbrev);
dw2_debugstr = (const BYTE*)image_map_section(&sect_debugstr);
dw2_debugline = (const BYTE*)image_map_section(&sect_debugline);
dw2_debugloc = (const BYTE*)image_map_section(&sect_debugloc);
if (dw2_debuginfo != IMAGE_NO_MAP && dw2_debugabbrev != IMAGE_NO_MAP && dw2_debugstr != IMAGE_NO_MAP)
{
ret = dwarf2_parse(module,
module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
NULL, /* FIXME: some thunks to deal with ? */
dw2_debuginfo, image_get_map_size(&sect_debuginfo),
dw2_debugabbrev, image_get_map_size(&sect_debugabbrev),
dw2_debugstr, image_get_map_size(&sect_debugstr),
dw2_debugline, image_get_map_size(&sect_debugline),
dw2_debugloc, image_get_map_size(&sect_debugloc));
}
image_unmap_section(&sect_debuginfo);
image_unmap_section(&sect_debugabbrev);
image_unmap_section(&sect_debugstr);
image_unmap_section(&sect_debugline);
image_unmap_section(&sect_debugloc);
}
ret = dwarf2_parse(module,
module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
NULL, /* FIXME: some thunks to deal with ? */
fmap);
TRACE("%s the DWARF debug info\n", ret ? "successfully loaded" : "failed to load");
return ret;
......@@ -684,10 +654,10 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
{
ret = pe_load_stabs(pcs, module) ||
pe_load_dwarf(pcs, module) ||
pe_load_msc_debug_info(pcs, module) ||
pe_load_coff_symbol_table(module);
ret = pe_load_stabs(pcs, module);
ret = pe_load_dwarf(module) || ret;
ret = pe_load_msc_debug_info(pcs, module) || ret;
ret = ret || pe_load_coff_symbol_table(module); /* FIXME */
/* if we still have no debug info (we could only get SymExport at this
* point), then do the SymExport except if we have an ELF container,
* in which case we'll rely on the export's on the ELF side
......
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