dbghelp: Move alternate file map pointer to generic image_file_map.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Jacek Caban 2020-03-16 16:05:23 +01:00 committed by Alexandre Julliard
parent a3e1c7fa02
commit 02dfd959ca
4 changed files with 63 additions and 27 deletions

View File

@ -176,14 +176,36 @@ const char* elf_map_section(struct image_section_map* ism)
* Finds a section by name (and type) into memory from an ELF file * Finds a section by name (and type) into memory from an ELF file
* or its alternate if any * or its alternate if any
*/ */
BOOL elf_find_section(struct image_file_map* _fmap, const char* name, BOOL elf_find_section(struct image_file_map* _fmap, const char* name, struct image_section_map* ism)
unsigned sht, struct image_section_map* ism) {
struct elf_file_map* fmap = &_fmap->u.elf;
unsigned i;
if (fmap->shstrtab == IMAGE_NO_MAP)
{
struct image_section_map hdr_ism = {_fmap, fmap->elfhdr.e_shstrndx};
if ((fmap->shstrtab = elf_map_section(&hdr_ism)) == IMAGE_NO_MAP) return FALSE;
}
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
{
if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0)
{
ism->fmap = _fmap;
ism->sidx = i;
return TRUE;
}
}
return FALSE;
}
static BOOL elf_find_section_type(struct image_file_map* _fmap, const char* name, unsigned sht, struct image_section_map* ism)
{ {
struct elf_file_map* fmap; struct elf_file_map* fmap;
unsigned i; unsigned i;
while (_fmap) while (_fmap)
{ {
if (_fmap->modtype != DMT_ELF) break;
fmap = &_fmap->u.elf; fmap = &_fmap->u.elf;
if (fmap->shstrtab == IMAGE_NO_MAP) if (fmap->shstrtab == IMAGE_NO_MAP)
{ {
@ -192,15 +214,14 @@ BOOL elf_find_section(struct image_file_map* _fmap, const char* name,
} }
for (i = 0; i < fmap->elfhdr.e_shnum; i++) for (i = 0; i < fmap->elfhdr.e_shnum; i++)
{ {
if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 && if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 && sht == fmap->sect[i].shdr.sh_type)
(sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
{ {
ism->fmap = _fmap; ism->fmap = _fmap;
ism->sidx = i; ism->sidx = i;
return TRUE; return TRUE;
} }
} }
_fmap = fmap->alternate; _fmap = _fmap->alternate;
} }
ism->fmap = NULL; ism->fmap = NULL;
ism->sidx = -1; ism->sidx = -1;
@ -229,13 +250,13 @@ static void elf_end_find(struct image_file_map* fmap)
{ {
struct image_section_map ism; struct image_section_map ism;
while (fmap) while (fmap && fmap->modtype == DMT_ELF)
{ {
ism.fmap = fmap; ism.fmap = fmap;
ism.sidx = fmap->u.elf.elfhdr.e_shstrndx; ism.sidx = fmap->u.elf.elfhdr.e_shstrndx;
elf_unmap_section(&ism); elf_unmap_section(&ism);
fmap->u.elf.shstrtab = IMAGE_NO_MAP; fmap->u.elf.shstrtab = IMAGE_NO_MAP;
fmap = fmap->u.elf.alternate; fmap = fmap->alternate;
} }
} }
@ -265,9 +286,9 @@ unsigned elf_get_map_size(const struct image_section_map* ism)
static inline void elf_reset_file_map(struct image_file_map* fmap) static inline void elf_reset_file_map(struct image_file_map* fmap)
{ {
fmap->alternate = NULL;
fmap->u.elf.handle = INVALID_HANDLE_VALUE; fmap->u.elf.handle = INVALID_HANDLE_VALUE;
fmap->u.elf.shstrtab = IMAGE_NO_MAP; fmap->u.elf.shstrtab = IMAGE_NO_MAP;
fmap->u.elf.alternate = NULL;
fmap->u.elf.target_copy = NULL; fmap->u.elf.target_copy = NULL;
} }
@ -512,7 +533,7 @@ static BOOL elf_map_file(struct elf_map_file_data* emfd, struct image_file_map*
*/ */
static void elf_unmap_file(struct image_file_map* fmap) static void elf_unmap_file(struct image_file_map* fmap)
{ {
while (fmap) while (fmap && fmap->modtype == DMT_ELF)
{ {
if (fmap->u.elf.handle != INVALID_HANDLE_VALUE) if (fmap->u.elf.handle != INVALID_HANDLE_VALUE)
{ {
@ -526,7 +547,7 @@ static void elf_unmap_file(struct image_file_map* fmap)
CloseHandle(fmap->u.elf.handle); CloseHandle(fmap->u.elf.handle);
} }
HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy); HeapFree(GetProcessHeap(), 0, fmap->u.elf.target_copy);
fmap = fmap->u.elf.alternate; fmap = fmap->alternate;
} }
} }
@ -573,8 +594,8 @@ static void elf_hash_symtab(struct module* module, struct pool* pool,
struct image_section_map ism, ism_str; struct image_section_map ism, ism_str;
const char *symtab; const char *symtab;
if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &ism) && if (!elf_find_section_type(fmap, ".symtab", SHT_SYMTAB, &ism) &&
!elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &ism)) return; !elf_find_section_type(fmap, ".dynsym", SHT_DYNSYM, &ism)) return;
if ((symtab = image_map_section(&ism)) == IMAGE_NO_MAP) return; if ((symtab = image_map_section(&ism)) == IMAGE_NO_MAP) return;
ism_str.fmap = ism.fmap; ism_str.fmap = ism.fmap;
ism_str.sidx = fmap->u.elf.sect[ism.sidx].shdr.sh_link; ism_str.sidx = fmap->u.elf.sect[ism.sidx].shdr.sh_link;
@ -1040,7 +1061,7 @@ static BOOL elf_locate_debug_link(struct image_file_map* fmap, const char* filen
found: found:
TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p)); TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
HeapFree(GetProcessHeap(), 0, p); HeapFree(GetProcessHeap(), 0, p);
fmap->u.elf.alternate = fmap_link; fmap->alternate = fmap_link;
return TRUE; return TRUE;
} }
@ -1094,7 +1115,7 @@ static BOOL elf_locate_build_id_target(struct image_file_map* fmap, const BYTE*
if (elf_map_file(&emfd, fmap_link)) if (elf_map_file(&emfd, fmap_link))
{ {
struct image_section_map buildid_sect; struct image_section_map buildid_sect;
if (elf_find_section(fmap_link, ".note.gnu.build-id", SHT_NULL, &buildid_sect)) if (image_find_section(fmap_link, ".note.gnu.build-id", &buildid_sect))
{ {
const uint32_t* note; const uint32_t* note;
@ -1109,7 +1130,7 @@ static BOOL elf_locate_build_id_target(struct image_file_map* fmap, const BYTE*
{ {
TRACE("Located debug information file at %s\n", debugstr_w(p)); TRACE("Located debug information file at %s\n", debugstr_w(p));
HeapFree(GetProcessHeap(), 0, p); HeapFree(GetProcessHeap(), 0, p);
fmap->u.elf.alternate = fmap_link; fmap->alternate = fmap_link;
return TRUE; return TRUE;
} }
WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p)); WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p));
@ -1223,8 +1244,8 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
/* check if we need an alternate file (from debuglink or build-id) */ /* check if we need an alternate file (from debuglink or build-id) */
ret = elf_check_alternate(fmap, module); ret = elf_check_alternate(fmap, module);
if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) && if (image_find_section(fmap, ".stab", &stab_sect) &&
elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect)) image_find_section(fmap, ".stabstr", &stabstr_sect))
{ {
const char* stab; const char* stab;
const char* stabstr; const char* stabstr;
@ -1323,7 +1344,7 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename,
{ {
struct image_section_map ism; struct image_section_map ism;
if (elf_find_section(fmap, ".dynamic", SHT_DYNAMIC, &ism)) if (elf_find_section_type(fmap, ".dynamic", SHT_DYNAMIC, &ism))
{ {
char* ptr = (char*)(ULONG_PTR)fmap->u.elf.sect[ism.sidx].shdr.sh_addr; char* ptr = (char*)(ULONG_PTR)fmap->u.elf.sect[ism.sidx].shdr.sh_addr;
unsigned long len; unsigned long len;
@ -1385,7 +1406,7 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename,
struct image_section_map ism; struct image_section_map ism;
unsigned long modbase = load_offset; unsigned long modbase = load_offset;
if (elf_find_section(fmap, ".dynamic", SHT_DYNAMIC, &ism)) if (elf_find_section_type(fmap, ".dynamic", SHT_DYNAMIC, &ism))
{ {
unsigned long rva_dyn = elf_get_map_rva(&ism); unsigned long rva_dyn = elf_get_map_rva(&ism);
@ -2016,7 +2037,7 @@ BOOL elf_synchronize_module_list(struct process* pcs)
#else /* !__ELF__ */ #else /* !__ELF__ */
BOOL elf_find_section(struct image_file_map* fmap, const char* name, BOOL elf_find_section(struct image_file_map* fmap, const char* name,
unsigned sht, struct image_section_map* ism) struct image_section_map* ism)
{ {
return FALSE; return FALSE;
} }

View File

@ -61,6 +61,7 @@ struct image_file_map
{ {
enum module_type modtype; enum module_type modtype;
unsigned addr_size; /* either 16 (not used), 32 or 64 */ unsigned addr_size; /* either 16 (not used), 32 or 64 */
struct image_file_map* alternate; /* another file linked to this one */
union union
{ {
struct elf_file_map struct elf_file_map
@ -69,7 +70,6 @@ struct image_file_map
size_t elf_start; size_t elf_start;
HANDLE handle; HANDLE handle;
const char* shstrtab; const char* shstrtab;
struct image_file_map* alternate; /* another ELF file (linked to this one) */
char* target_copy; char* target_copy;
#ifdef __ELF__ #ifdef __ELF__
Elf64_Ehdr elfhdr; Elf64_Ehdr elfhdr;
@ -130,7 +130,7 @@ struct image_section_map
}; };
extern BOOL elf_find_section(struct image_file_map* fmap, const char* name, extern BOOL elf_find_section(struct image_file_map* fmap, const char* name,
unsigned sht, struct image_section_map* ism) DECLSPEC_HIDDEN; struct image_section_map* ism) DECLSPEC_HIDDEN;
extern const char* elf_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN; extern const char* elf_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
extern void elf_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN; extern void elf_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
extern DWORD_PTR elf_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN; extern DWORD_PTR elf_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN;
@ -153,13 +153,26 @@ extern unsigned pe_get_map_size(const struct image_section_map* psm) DECLSPE
static inline BOOL image_find_section(struct image_file_map* fmap, const char* name, static inline BOOL image_find_section(struct image_file_map* fmap, const char* name,
struct image_section_map* ism) struct image_section_map* ism)
{ {
switch (fmap->modtype) while (fmap)
{ {
case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism); switch (fmap->modtype)
case DMT_MACHO: return macho_find_section(fmap, NULL, name, ism); {
case DMT_PE: return pe_find_section(fmap, name, ism); case DMT_ELF:
default: assert(0); return FALSE; if (elf_find_section(fmap, name, ism)) return TRUE;
break;
case DMT_MACHO:
if (macho_find_section(fmap, NULL, name, ism)) return TRUE;
break;
case DMT_PE:
if (pe_find_section(fmap, name, ism)) return TRUE;
break;
default: assert(0); return FALSE;
}
fmap = fmap->alternate;
} }
ism->fmap = NULL;
ism->sidx = -1;
return FALSE;
} }
static inline const char* image_map_section(struct image_section_map* ism) static inline const char* image_map_section(struct image_section_map* ism)

View File

@ -680,6 +680,7 @@ static BOOL macho_map_file(struct process *pcs, const WCHAR *filenameW,
reset_file_map(ifm); reset_file_map(ifm);
ifm->modtype = DMT_MACHO; ifm->modtype = DMT_MACHO;
ifm->alternate = NULL;
ifm->addr_size = (pcs->is_64bit) ? 64 : 32; ifm->addr_size = (pcs->is_64bit) ? 64 : 32;
fmap->header_size = (pcs->is_64bit) ? sizeof(struct mach_header_64) : sizeof(struct mach_header); fmap->header_size = (pcs->is_64bit) ? sizeof(struct mach_header_64) : sizeof(struct mach_header);

View File

@ -211,6 +211,7 @@ static BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_ty
void* mapping; void* mapping;
fmap->modtype = mt; fmap->modtype = mt;
fmap->alternate = NULL;
fmap->u.pe.hMap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL); fmap->u.pe.hMap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (fmap->u.pe.hMap == 0) return FALSE; if (fmap->u.pe.hMap == 0) return FALSE;
fmap->u.pe.full_count = 0; fmap->u.pe.full_count = 0;