Module: wine Branch: master Commit: 922caac23bcce7d9264ee38c43f9ce271960aad4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=922caac23bcce7d9264ee38c43...
Author: Eric Pouech eric.pouech@orange.fr Date: Sat Oct 9 08:51:27 2010 +0200
dbghelp: Compute ELF load address using the link_map ld's address (and get correct relocation computation).
---
dlls/dbghelp/elf_module.c | 29 +++++++++++++++++++++-------- 1 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 41c046d..8b03eaa 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -1017,12 +1017,6 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename, if (!fmap.u.elf.elf_start && !load_offset) ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n", debugstr_w(filename)); - if (fmap.u.elf.elf_start && load_offset) - { - WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. " - "Assuming load address is corrupt\n", debugstr_w(filename), load_offset); - load_offset = 0; - }
if (elf_info->flags & ELF_INFO_DEBUG_HEADER) { @@ -1042,6 +1036,9 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename, if (dyn.d_tag == DT_DEBUG) { elf_info->dbg_hdr_addr = dyn.d_un.d_ptr; + if (load_offset == 0 && dyn_addr == 0) /* likely the case */ + /* Assume this module (the Wine loader) has been loaded at its preferred address */ + dyn_addr = ism.fmap->u.elf.sect[ism.sidx].shdr.sh_addr; break; } ptr += sizeof(dyn); @@ -1055,12 +1052,28 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename, { struct elf_module_info *elf_module_info; struct module_format* modfmt; + struct image_section_map ism; + unsigned long modbase = load_offset; + + if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &ism)) + { + unsigned long rva_dyn = elf_get_map_rva(&ism); + + TRACE("For module %s, got ELF (start=%lx dyn=%lx), link_map (start=%lx dyn=%lx)\n", + debugstr_w(filename), (unsigned long)fmap.u.elf.elf_start, rva_dyn, + load_offset, dyn_addr); + if (dyn_addr && load_offset + rva_dyn != dyn_addr) + { + WARN("\thave to relocate: %lx\n", dyn_addr - rva_dyn); + modbase = dyn_addr - rva_dyn; + } + } else WARN("For module %s, no .dynamic section\n", debugstr_w(filename)); + elf_end_find(&fmap);
modfmt = HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct elf_module_info)); if (!modfmt) goto leave; - elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, - (load_offset) ? load_offset : fmap.u.elf.elf_start, + elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE, modbase, fmap.u.elf.elf_size, 0, calc_crc32(fmap.u.elf.fd)); if (!elf_info->module) {