dbghelp: Create the notion of image (PE, ELF modules) to uniformize some handlings.

This commit is contained in:
Eric Pouech 2010-03-18 21:31:03 +01:00 committed by Alexandre Julliard
parent fb169502a5
commit cbff4f063f
4 changed files with 382 additions and 298 deletions

View File

@ -474,8 +474,8 @@ typedef BOOL (*enum_modules_cb)(const WCHAR*, unsigned long addr, void* user);
/* elf_module.c */
extern BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb, void*);
extern BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base, DWORD* size, DWORD* checksum);
struct elf_file_map;
extern BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap);
struct image_file_map;
extern BOOL elf_load_debug_info(struct module* module, struct image_file_map* fmap);
extern struct module*
elf_load_module(struct process* pcs, const WCHAR* name, unsigned long);
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs);

View File

@ -90,7 +90,7 @@ struct elf_module_info
unsigned long elf_addr;
unsigned short elf_mark : 1,
elf_loader : 1;
struct elf_file_map file_map;
struct image_file_map file_map;
};
/******************************************************************
@ -98,23 +98,26 @@ struct elf_module_info
*
* Maps a single section into memory from an ELF file
*/
const char* elf_map_section(struct elf_section_map* esm)
const char* elf_map_section(struct image_section_map* ism)
{
struct elf_file_map* fmap = &ism->fmap->u.elf;
unsigned pgsz = getpagesize();
unsigned ofst, size;
if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum ||
esm->fmap->sect[esm->sidx].shdr.sh_type == SHT_NOBITS)
assert(ism->fmap->modtype == DMT_ELF);
if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum ||
fmap->sect[ism->sidx].shdr.sh_type == SHT_NOBITS)
return IMAGE_NO_MAP;
/* align required information on page size (we assume pagesize is a power of 2) */
ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
esm->fmap->sect[esm->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
esm->fmap->fd, ofst);
if (esm->fmap->sect[esm->sidx].mapped == IMAGE_NO_MAP) return IMAGE_NO_MAP;
return esm->fmap->sect[esm->sidx].mapped + (esm->fmap->sect[esm->sidx].shdr.sh_offset & (pgsz - 1));
ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
size = ((fmap->sect[ism->sidx].shdr.sh_offset +
fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
fmap->sect[ism->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
fmap->fd, ofst);
if (fmap->sect[ism->sidx].mapped == IMAGE_NO_MAP) return IMAGE_NO_MAP;
return fmap->sect[ism->sidx].mapped + (fmap->sect[ism->sidx].shdr.sh_offset & (pgsz - 1));
}
/******************************************************************
@ -123,32 +126,34 @@ const char* elf_map_section(struct elf_section_map* esm)
* Finds a section by name (and type) into memory from an ELF file
* or its alternate if any
*/
BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
unsigned sht, struct elf_section_map* esm)
BOOL elf_find_section(struct image_file_map* _fmap, const char* name,
unsigned sht, struct image_section_map* ism)
{
struct elf_file_map* fmap;
unsigned i;
while (fmap)
while (_fmap)
{
fmap = &_fmap->u.elf;
if (fmap->shstrtab == IMAGE_NO_MAP)
{
struct elf_section_map hdr_esm = {fmap, fmap->elfhdr.e_shstrndx};
if ((fmap->shstrtab = elf_map_section(&hdr_esm)) == IMAGE_NO_MAP) break;
struct image_section_map hdr_ism = {_fmap, fmap->elfhdr.e_shstrndx};
if ((fmap->shstrtab = elf_map_section(&hdr_ism)) == IMAGE_NO_MAP) break;
}
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
{
if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
(sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
{
esm->fmap = fmap;
esm->sidx = i;
ism->fmap = _fmap;
ism->sidx = i;
return TRUE;
}
}
fmap = fmap->alternate;
_fmap = fmap->alternate;
}
esm->fmap = NULL;
esm->sidx = -1;
ism->fmap = NULL;
ism->sidx = -1;
return FALSE;
}
@ -157,33 +162,35 @@ BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
*
* Unmaps a single section from memory
*/
void elf_unmap_section(struct elf_section_map* esm)
void elf_unmap_section(struct image_section_map* ism)
{
if (esm->sidx >= 0 && esm->sidx < esm->fmap->elfhdr.e_shnum && esm->fmap->sect[esm->sidx].mapped != IMAGE_NO_MAP)
struct elf_file_map* fmap = &ism->fmap->u.elf;
if (ism->sidx >= 0 && ism->sidx < fmap->elfhdr.e_shnum && fmap->sect[ism->sidx].mapped != IMAGE_NO_MAP)
{
unsigned pgsz = getpagesize();
unsigned ofst, size;
ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
if (munmap((char*)esm->fmap->sect[esm->sidx].mapped, size) < 0)
ofst = fmap->sect[ism->sidx].shdr.sh_offset & ~(pgsz - 1);
size = ((fmap->sect[ism->sidx].shdr.sh_offset +
fmap->sect[ism->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
if (munmap((char*)fmap->sect[ism->sidx].mapped, size) < 0)
WARN("Couldn't unmap the section\n");
esm->fmap->sect[esm->sidx].mapped = IMAGE_NO_MAP;
fmap->sect[ism->sidx].mapped = IMAGE_NO_MAP;
}
}
static void elf_end_find(struct elf_file_map* fmap)
static void elf_end_find(struct image_file_map* fmap)
{
struct elf_section_map esm;
struct image_section_map ism;
while (fmap)
{
esm.fmap = fmap;
esm.sidx = fmap->elfhdr.e_shstrndx;
elf_unmap_section(&esm);
fmap->shstrtab = IMAGE_NO_MAP;
fmap = fmap->alternate;
ism.fmap = fmap;
ism.sidx = fmap->u.elf.elfhdr.e_shstrndx;
elf_unmap_section(&ism);
fmap->u.elf.shstrtab = IMAGE_NO_MAP;
fmap = fmap->u.elf.alternate;
}
}
@ -192,18 +199,18 @@ static void elf_end_find(struct elf_file_map* fmap)
*
* Get the size of an ELF section
*/
unsigned elf_get_map_size(const struct elf_section_map* esm)
unsigned elf_get_map_size(const struct image_section_map* ism)
{
if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum)
if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.elf.elfhdr.e_shnum)
return 0;
return esm->fmap->sect[esm->sidx].shdr.sh_size;
return ism->fmap->u.elf.sect[ism->sidx].shdr.sh_size;
}
static inline void elf_reset_file_map(struct elf_file_map* fmap)
static inline void elf_reset_file_map(struct image_file_map* fmap)
{
fmap->fd = -1;
fmap->shstrtab = IMAGE_NO_MAP;
fmap->alternate = NULL;
fmap->u.elf.fd = -1;
fmap->u.elf.shstrtab = IMAGE_NO_MAP;
fmap->u.elf.alternate = NULL;
}
/******************************************************************
@ -211,7 +218,7 @@ static inline void elf_reset_file_map(struct elf_file_map* fmap)
*
* Maps an ELF file into memory (and checks it's a real ELF file)
*/
static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
static BOOL elf_map_file(const WCHAR* filenameW, struct image_file_map* fmap)
{
static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
struct stat statbuf;
@ -228,52 +235,53 @@ static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
elf_reset_file_map(fmap);
fmap->modtype = DMT_ELF;
/* check that the file exists, and that the module hasn't been loaded yet */
if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;
/* Now open the file, so that we can mmap() it. */
if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done;
if ((fmap->u.elf.fd = open(filename, O_RDONLY)) == -1) goto done;
if (read(fmap->fd, &fmap->elfhdr, sizeof(fmap->elfhdr)) != sizeof(fmap->elfhdr))
if (read(fmap->u.elf.fd, &fmap->u.elf.elfhdr, sizeof(fmap->u.elf.elfhdr)) != sizeof(fmap->u.elf.elfhdr))
goto done;
/* and check for an ELF header */
if (memcmp(fmap->elfhdr.e_ident,
if (memcmp(fmap->u.elf.elfhdr.e_ident,
elf_signature, sizeof(elf_signature))) goto done;
/* and check 32 vs 64 size according to current machine */
#ifdef _WIN64
if (fmap->elfhdr.e_ident[EI_CLASS] != ELFCLASS64) goto done;
if (fmap->u.elf.elfhdr.e_ident[EI_CLASS] != ELFCLASS64) goto done;
#else
if (fmap->elfhdr.e_ident[EI_CLASS] != ELFCLASS32) goto done;
if (fmap->u.elf.elfhdr.e_ident[EI_CLASS] != ELFCLASS32) goto done;
#endif
fmap->sect = HeapAlloc(GetProcessHeap(), 0,
fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
if (!fmap->sect) goto done;
fmap->u.elf.sect = HeapAlloc(GetProcessHeap(), 0,
fmap->u.elf.elfhdr.e_shnum * sizeof(fmap->u.elf.sect[0]));
if (!fmap->u.elf.sect) goto done;
lseek(fmap->fd, fmap->elfhdr.e_shoff, SEEK_SET);
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
lseek(fmap->u.elf.fd, fmap->u.elf.elfhdr.e_shoff, SEEK_SET);
for (i = 0; i < fmap->u.elf.elfhdr.e_shnum; i++)
{
read(fmap->fd, &fmap->sect[i].shdr, sizeof(fmap->sect[i].shdr));
fmap->sect[i].mapped = IMAGE_NO_MAP;
read(fmap->u.elf.fd, &fmap->u.elf.sect[i].shdr, sizeof(fmap->u.elf.sect[i].shdr));
fmap->u.elf.sect[i].mapped = IMAGE_NO_MAP;
}
/* grab size of module once loaded in memory */
lseek(fmap->fd, fmap->elfhdr.e_phoff, SEEK_SET);
fmap->elf_size = 0;
fmap->elf_start = ~0L;
for (i = 0; i < fmap->elfhdr.e_phnum; i++)
lseek(fmap->u.elf.fd, fmap->u.elf.elfhdr.e_phoff, SEEK_SET);
fmap->u.elf.elf_size = 0;
fmap->u.elf.elf_start = ~0L;
for (i = 0; i < fmap->u.elf.elfhdr.e_phnum; i++)
{
if (read(fmap->fd, &phdr, sizeof(phdr)) == sizeof(phdr) &&
if (read(fmap->u.elf.fd, &phdr, sizeof(phdr)) == sizeof(phdr) &&
phdr.p_type == PT_LOAD)
{
tmp = (phdr.p_vaddr + phdr.p_memsz + page_mask) & ~page_mask;
if (fmap->elf_size < tmp) fmap->elf_size = tmp;
if (phdr.p_vaddr < fmap->elf_start) fmap->elf_start = phdr.p_vaddr;
if (fmap->u.elf.elf_size < tmp) fmap->u.elf.elf_size = tmp;
if (phdr.p_vaddr < fmap->u.elf.elf_start) fmap->u.elf.elf_start = phdr.p_vaddr;
}
}
/* if non relocatable ELF, then remove fixed address from computation
* otherwise, all addresses are zero based and start has no effect
*/
fmap->elf_size -= fmap->elf_start;
fmap->u.elf.elf_size -= fmap->u.elf.elf_start;
ret = TRUE;
done:
HeapFree(GetProcessHeap(), 0, filename);
@ -285,22 +293,22 @@ done:
*
* Unmaps an ELF file from memory (previously mapped with elf_map_file)
*/
static void elf_unmap_file(struct elf_file_map* fmap)
static void elf_unmap_file(struct image_file_map* fmap)
{
while (fmap)
{
if (fmap->fd != -1)
if (fmap->u.elf.fd != -1)
{
struct elf_section_map esm;
esm.fmap = fmap;
for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
struct image_section_map ism;
ism.fmap = fmap;
for (ism.sidx = 0; ism.sidx < fmap->u.elf.elfhdr.e_shnum; ism.sidx++)
{
elf_unmap_section(&esm);
elf_unmap_section(&ism);
}
HeapFree(GetProcessHeap(), 0, fmap->sect);
close(fmap->fd);
HeapFree(GetProcessHeap(), 0, fmap->u.elf.sect);
close(fmap->u.elf.fd);
}
fmap = fmap->alternate;
fmap = fmap->u.elf.alternate;
}
}
@ -334,8 +342,8 @@ int elf_is_in_thunk_area(unsigned long addr,
*
* creating an internal hash table to ease use ELF symtab information lookup
*/
static void elf_hash_symtab(struct module* module, struct pool* pool,
struct hash_table* ht_symtab, struct elf_file_map* fmap,
static void elf_hash_symtab(struct module* module, struct pool* pool,
struct hash_table* ht_symtab, struct image_file_map* fmap,
struct elf_thunk_area* thunks)
{
int i, j, nsym;
@ -345,16 +353,20 @@ static void elf_hash_symtab(struct module* module, struct pool* pool,
const char* ptr;
const Elf_Sym* symp;
struct symtab_elt* ste;
struct elf_section_map esm, esm_str;
struct image_section_map ism, ism_str;
if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &esm) &&
!elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &esm)) return;
if ((symp = (const Elf_Sym*)elf_map_section(&esm)) == IMAGE_NO_MAP) return;
esm_str.fmap = esm.fmap;
esm_str.sidx = fmap->sect[esm.sidx].shdr.sh_link;
if ((strp = elf_map_section(&esm_str)) == IMAGE_NO_MAP) return;
if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &ism) &&
!elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &ism)) return;
if ((symp = (const Elf_Sym*)image_map_section(&ism)) == IMAGE_NO_MAP) return;
ism_str.fmap = ism.fmap;
ism_str.sidx = fmap->u.elf.sect[ism.sidx].shdr.sh_link;
if ((strp = image_map_section(&ism_str)) == IMAGE_NO_MAP)
{
image_unmap_section(&ism);
return;
}
nsym = elf_get_map_size(&esm) / sizeof(*symp);
nsym = image_get_map_size(&ism) / sizeof(*symp);
for (j = 0; thunks[j].symname; j++)
thunks[j].rva_start = thunks[j].rva_end = 0;
@ -706,14 +718,14 @@ static int elf_new_public_symbols(struct module* module, const struct hash_table
return TRUE;
}
static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, DWORD crc)
static BOOL elf_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD crc)
{
BOOL ret;
if (!elf_map_file(file, fmap)) return FALSE;
if (!(ret = crc == calc_crc32(fmap->fd)))
if (!(ret = crc == calc_crc32(fmap->u.elf.fd)))
{
WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
debugstr_w(file), calc_crc32(fmap->fd), crc);
debugstr_w(file), calc_crc32(fmap->u.elf.fd), crc);
elf_unmap_file(fmap);
}
return ret;
@ -738,7 +750,7 @@ static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, D
* is the global debug file directory, and execdir has been turned
* into a relative path)." (from GDB manual)
*/
static BOOL elf_locate_debug_link(struct elf_file_map* fmap, const char* filename,
static BOOL elf_locate_debug_link(struct image_file_map* fmap, const char* filename,
const WCHAR* loaded_file, DWORD crc)
{
static const WCHAR globalDebugDirW[] = {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/'};
@ -747,7 +759,7 @@ static BOOL elf_locate_debug_link(struct elf_file_map* fmap, const char* filenam
size_t filename_len;
WCHAR* p = NULL;
WCHAR* slash;
struct elf_file_map* fmap_link = NULL;
struct image_file_map* fmap_link = NULL;
fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
if (!fmap_link) return FALSE;
@ -790,7 +802,7 @@ static BOOL elf_locate_debug_link(struct elf_file_map* fmap, const char* filenam
found:
TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
HeapFree(GetProcessHeap(), 0, p);
fmap->alternate = fmap_link;
fmap->u.elf.alternate = fmap_link;
return TRUE;
}
@ -800,7 +812,7 @@ found:
* Parses a .gnu_debuglink section and loads the debug info from
* the external file specified there.
*/
static BOOL elf_debuglink_parse(struct elf_file_map* fmap, const struct module* module,
static BOOL elf_debuglink_parse(struct image_file_map* fmap, const struct module* module,
const BYTE* debuglink)
{
/* The content of a debug link section is:
@ -829,8 +841,8 @@ static BOOL elf_debuglink_parse(struct elf_file_map* fmap, const struct module*
* read or parsed)
* 1 on success
*/
static BOOL elf_load_debug_info_from_map(struct module* module,
struct elf_file_map* fmap,
static BOOL elf_load_debug_info_from_map(struct module* module,
struct image_file_map* fmap,
struct pool* pool,
struct hash_table* ht_symtab)
{
@ -853,16 +865,16 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
{
struct elf_section_map stab_sect, stabstr_sect;
struct elf_section_map debuglink_sect;
struct elf_section_map debug_sect;
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))
{
const BYTE* dbg_link;
dbg_link = (const BYTE*)elf_map_section(&debuglink_sect);
dbg_link = (const BYTE*)image_map_section(&debuglink_sect);
if (dbg_link != IMAGE_NO_MAP)
{
lret = elf_debuglink_parse(fmap, module, dbg_link);
@ -871,7 +883,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
debugstr_w(module->module.ModuleName));
ret = ret || lret;
}
elf_unmap_section(&debuglink_sect);
image_unmap_section(&debuglink_sect);
}
if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
@ -879,14 +891,14 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
const char* stab;
const char* stabstr;
stab = elf_map_section(&stab_sect);
stabstr = elf_map_section(&stabstr_sect);
stab = image_map_section(&stab_sect);
stabstr = image_map_section(&stabstr_sect);
if (stab != IMAGE_NO_MAP && stabstr != IMAGE_NO_MAP)
{
/* OK, now just parse all of the stabs. */
lret = stabs_parse(module, module->elf_info->elf_addr,
stab, elf_get_map_size(&stab_sect),
stabstr, elf_get_map_size(&stabstr_sect),
stab, image_get_map_size(&stab_sect),
stabstr, image_get_map_size(&stabstr_sect),
NULL, NULL);
if (lret)
/* and fill in the missing information for stabs */
@ -896,12 +908,12 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
ret = ret || lret;
}
else lret = FALSE;
elf_unmap_section(&stab_sect);
elf_unmap_section(&stabstr_sect);
image_unmap_section(&stab_sect);
image_unmap_section(&stabstr_sect);
}
if (elf_find_section(fmap, ".debug_info", SHT_NULL, &debug_sect))
{
struct elf_section_map debug_str_sect, debug_abbrev_sect, debug_line_sect, debug_loclist_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;
@ -914,7 +926,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
* adjust symbol base addresses accordingly
*/
unsigned long load_offset = module->elf_info->elf_addr +
fmap->elf_start - debug_sect.fmap->elf_start;
fmap->u.elf.elf_start - debug_sect.fmap->u.elf.elf_start;
TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->module.ModuleName));
@ -923,30 +935,30 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
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*)elf_map_section(&debug_sect);
dw2_debug_abbrev = (const BYTE*)elf_map_section(&debug_abbrev_sect);
dw2_debug_str = (const BYTE*)elf_map_section(&debug_str_sect);
dw2_debug_line = (const BYTE*)elf_map_section(&debug_line_sect);
dw2_debug_loclist = (const BYTE*)elf_map_section(&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, elf_get_map_size(&debug_sect),
dw2_debug_abbrev, elf_get_map_size(&debug_abbrev_sect),
dw2_debug_str, elf_get_map_size(&debug_str_sect),
dw2_debug_line, elf_get_map_size(&debug_line_sect),
dw2_debug_loclist, elf_get_map_size(&debug_loclist_sect));
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;
}
elf_unmap_section(&debug_sect);
elf_unmap_section(&debug_abbrev_sect);
elf_unmap_section(&debug_str_sect);
elf_unmap_section(&debug_line_sect);
elf_unmap_section(&debug_loclist_sect);
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);
}
}
if (strstrW(module->module.ModuleName, S_ElfW) ||
@ -967,12 +979,12 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
*
* Loads ELF debugging information from the module image file.
*/
BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
BOOL elf_load_debug_info(struct module* module, struct image_file_map* fmap)
{
BOOL ret = TRUE;
struct pool pool;
struct hash_table ht_symtab;
struct elf_file_map my_fmap;
BOOL ret = TRUE;
struct pool pool;
struct hash_table ht_symtab;
struct image_file_map my_fmap;
if (module->type != DMT_ELF || !module->elf_info)
{
@ -1010,12 +1022,12 @@ BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
DWORD* size, DWORD* checksum)
{
struct elf_file_map fmap;
struct image_file_map fmap;
if (!elf_map_file(name, &fmap)) return FALSE;
if (base) *base = fmap.elf_start;
*size = fmap.elf_size;
*checksum = calc_crc32(fmap.fd);
if (base) *base = fmap.u.elf.elf_start;
*size = fmap.u.elf.elf_size;
*checksum = calc_crc32(fmap.u.elf.fd);
elf_unmap_file(&fmap);
return TRUE;
}
@ -1034,8 +1046,8 @@ BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
unsigned long load_offset, struct elf_info* elf_info)
{
BOOL ret = FALSE;
struct elf_file_map fmap;
BOOL ret = FALSE;
struct image_file_map fmap;
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
@ -1045,10 +1057,10 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
* this thing. We need the main executable header, and the section
* table.
*/
if (!fmap.elf_start && !load_offset)
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.elf_start && load_offset)
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);
@ -1057,12 +1069,12 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
{
struct elf_section_map esm;
struct image_section_map ism;
if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &ism))
{
Elf_Dyn dyn;
char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
char* ptr = (char*)fmap.u.elf.sect[ism.sidx].shdr.sh_addr;
unsigned long len;
do
@ -1088,8 +1100,8 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
if (!elf_module_info) goto leave;
elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE,
(load_offset) ? load_offset : fmap.elf_start,
fmap.elf_size, 0, calc_crc32(fmap.fd));
(load_offset) ? load_offset : fmap.u.elf.elf_start,
fmap.u.elf.elf_size, 0, calc_crc32(fmap.u.elf.fd));
elf_info->module->module_remove = elf_module_remove;
if (!elf_info->module)
{
@ -1477,6 +1489,25 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned
#else /* !__ELF__ */
BOOL elf_find_section(struct image_file_map* fmap, const char* name,
unsigned sht, struct image_section_map* ism)
{
return FALSE;
}
const char* elf_map_section(struct image_section_map* ism)
{
return NULL;
}
void elf_unmap_section(struct image_section_map* ism)
{}
unsigned elf_get_map_size(const struct image_section_map* ism)
{
return 0;
}
BOOL elf_synchronize_module_list(struct process* pcs)
{
return FALSE;
@ -1503,7 +1534,7 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned
return NULL;
}
BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap)
BOOL elf_load_debug_info(struct module* module, struct image_file_map* fmap)
{
return FALSE;
}

View File

@ -60,60 +60,110 @@
#define Elf_Dyn Elf32_Dyn
#define Elf_Sym Elf32_Sym
#endif
#else
#ifndef SHT_NULL
#define SHT_NULL 0
#endif
#endif
/* structure holding information while handling an ELF image
* allows one by one section mapping for memory savings
*/
struct elf_file_map
struct image_file_map
{
size_t elf_size;
size_t elf_start;
int fd;
const char* shstrtab;
struct elf_file_map* alternate; /* another ELF file (linked to this one) */
Elf_Ehdr elfhdr;
struct
enum module_type modtype;
union
{
Elf_Shdr shdr;
const char* mapped;
}* sect;
};
struct elf_file_map
{
size_t elf_size;
size_t elf_start;
int fd;
const char* shstrtab;
struct image_file_map* alternate; /* another ELF file (linked to this one) */
#ifdef __ELF__
Elf_Ehdr elfhdr;
struct
{
Elf_Shdr shdr;
const char* mapped;
}* sect;
#endif
} elf;
struct pe_file_map
{
HANDLE hMap;
IMAGE_NT_HEADERS ntheader;
unsigned full_count;
void* full_map;
struct
{
IMAGE_SECTION_HEADER shdr;
const char* mapped;
}* sect;
const char* strtable;
} pe;
} u;
};
struct pe_file_map
struct image_section_map
{
HANDLE hMap;
IMAGE_NT_HEADERS ntheader;
unsigned full_count;
void* full_map;
struct
struct image_file_map* fmap;
long sidx;
};
extern BOOL elf_find_section(struct image_file_map* fmap, const char* name,
unsigned sht, struct image_section_map* ism);
extern const char* elf_map_section(struct image_section_map* ism);
extern void elf_unmap_section(struct image_section_map* ism);
extern unsigned elf_get_map_size(const struct image_section_map* ism);
extern BOOL pe_find_section(struct image_file_map* fmap, const char* name,
struct image_section_map* ism);
extern const char* pe_map_section(struct image_section_map* psm);
extern void pe_unmap_section(struct image_section_map* psm);
extern unsigned pe_get_map_size(const struct image_section_map* psm);
static inline BOOL image_find_section(struct image_file_map* fmap, const char* name,
struct image_section_map* ism)
{
switch (fmap->modtype)
{
IMAGE_SECTION_HEADER shdr;
const char* mapped;
}* sect;
const char* strtable;
};
case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
case DMT_PE: return pe_find_section(fmap, name, ism);
default: assert(0); return FALSE;
}
}
struct elf_section_map
static inline const char* image_map_section(struct image_section_map* ism)
{
struct elf_file_map* fmap;
long sidx;
};
if (!ism->fmap) return NULL;
switch (ism->fmap->modtype)
{
case DMT_ELF: return elf_map_section(ism);
case DMT_PE: return pe_map_section(ism);
default: assert(0); return NULL;
}
}
struct pe_section_map
static inline void image_unmap_section(struct image_section_map* ism)
{
struct pe_file_map* fmap;
long sidx;
};
if (!ism->fmap) return;
switch (ism->fmap->modtype)
{
case DMT_ELF: elf_unmap_section(ism); break;
case DMT_PE: pe_unmap_section(ism); break;
default: assert(0); return;
}
}
extern BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
unsigned sht, struct elf_section_map* esm);
extern const char* elf_map_section(struct elf_section_map* esm);
extern void elf_unmap_section(struct elf_section_map* esm);
extern unsigned elf_get_map_size(const struct elf_section_map* esm);
extern BOOL pe_find_section(struct pe_file_map* fmap, const char* name,
struct pe_section_map* psm);
extern const char* pe_map_section(struct pe_section_map* psm);
extern void pe_unmap_section(struct pe_section_map* psm);
extern unsigned pe_get_map_size(const struct pe_section_map* psm);
static inline unsigned image_get_map_size(struct image_section_map* ism)
{
if (!ism->fmap) return 0;
switch (ism->fmap->modtype)
{
case DMT_ELF: return elf_get_map_size(ism);
case DMT_PE: return pe_get_map_size(ism);
default: assert(0); return 0;
}
}

View File

@ -36,27 +36,27 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
static void* pe_map_full(struct pe_file_map* fmap, IMAGE_NT_HEADERS** nth)
static void* pe_map_full(struct image_file_map* fmap, IMAGE_NT_HEADERS** nth)
{
if (!fmap->full_map)
if (!fmap->u.pe.full_map)
{
fmap->full_map = MapViewOfFile(fmap->hMap, FILE_MAP_READ, 0, 0, 0);
fmap->u.pe.full_map = MapViewOfFile(fmap->u.pe.hMap, FILE_MAP_READ, 0, 0, 0);
}
if (fmap->full_map)
if (fmap->u.pe.full_map)
{
if (nth) *nth = RtlImageNtHeader(fmap->full_map);
fmap->full_count++;
return fmap->full_map;
if (nth) *nth = RtlImageNtHeader(fmap->u.pe.full_map);
fmap->u.pe.full_count++;
return fmap->u.pe.full_map;
}
return IMAGE_NO_MAP;
}
static void pe_unmap_full(struct pe_file_map* fmap)
static void pe_unmap_full(struct image_file_map* fmap)
{
if (fmap->full_count && !--fmap->full_count)
if (fmap->u.pe.full_count && !--fmap->u.pe.full_count)
{
UnmapViewOfFile(fmap->full_map);
fmap->full_map = NULL;
UnmapViewOfFile(fmap->u.pe.full_map);
fmap->u.pe.full_map = NULL;
}
}
@ -65,24 +65,25 @@ static void pe_unmap_full(struct pe_file_map* fmap)
*
* Maps a single section into memory from an PE file
*/
const char* pe_map_section(struct pe_section_map* psm)
const char* pe_map_section(struct image_section_map* ism)
{
void* mapping;
struct pe_file_map* fmap = &ism->fmap->u.pe;
if (psm->sidx >= 0 && psm->sidx < psm->fmap->ntheader.FileHeader.NumberOfSections &&
psm->fmap->sect[psm->sidx].mapped == IMAGE_NO_MAP)
if (ism->sidx >= 0 && ism->sidx < fmap->ntheader.FileHeader.NumberOfSections &&
fmap->sect[ism->sidx].mapped == IMAGE_NO_MAP)
{
IMAGE_NT_HEADERS* nth;
/* FIXME: that's rather drastic, but that will do for now
* that's ok if the full file map exists, but we could be less agressive otherwise and
* only map the relevant section
*/
if ((mapping = pe_map_full(psm->fmap, &nth)))
if ((mapping = pe_map_full(ism->fmap, &nth)))
{
psm->fmap->sect[psm->sidx].mapped = RtlImageRvaToVa(nth, mapping,
psm->fmap->sect[psm->sidx].shdr.VirtualAddress,
NULL);
return psm->fmap->sect[psm->sidx].mapped;
fmap->sect[ism->sidx].mapped = RtlImageRvaToVa(nth, mapping,
fmap->sect[ism->sidx].shdr.VirtualAddress,
NULL);
return fmap->sect[ism->sidx].mapped;
}
}
return IMAGE_NO_MAP;
@ -94,19 +95,19 @@ const char* pe_map_section(struct pe_section_map* psm)
* Finds a section by name (and type) into memory from an PE file
* or its alternate if any
*/
BOOL pe_find_section(struct pe_file_map* fmap, const char* name,
struct pe_section_map* psm)
BOOL pe_find_section(struct image_file_map* fmap, const char* name,
struct image_section_map* ism)
{
const char* sectname;
unsigned i;
char tmp[IMAGE_SIZEOF_SHORT_NAME + 1];
for (i = 0; i < fmap->ntheader.FileHeader.NumberOfSections; i++)
for (i = 0; i < fmap->u.pe.ntheader.FileHeader.NumberOfSections; i++)
{
sectname = (const char*)fmap->sect[i].shdr.Name;
sectname = (const char*)fmap->u.pe.sect[i].shdr.Name;
/* long section names start with a '/' (at least on MinGW32) */
if (sectname[0] == '/' && fmap->strtable)
sectname = fmap->strtable + atoi(sectname + 1);
if (sectname[0] == '/' && fmap->u.pe.strtable)
sectname = fmap->u.pe.strtable + atoi(sectname + 1);
else
{
/* the section name may not be null terminated */
@ -115,13 +116,14 @@ BOOL pe_find_section(struct pe_file_map* fmap, const char* name,
}
if (!strcasecmp(sectname, name))
{
psm->fmap = fmap;
psm->sidx = i;
ism->fmap = fmap;
ism->sidx = i;
return TRUE;
}
}
psm->fmap = NULL;
psm->sidx = -1;
ism->fmap = NULL;
ism->sidx = -1;
return FALSE;
}
@ -130,13 +132,13 @@ BOOL pe_find_section(struct pe_file_map* fmap, const char* name,
*
* Unmaps a single section from memory
*/
void pe_unmap_section(struct pe_section_map* psm)
void pe_unmap_section(struct image_section_map* ism)
{
if (psm->sidx >= 0 && psm->sidx < psm->fmap->ntheader.FileHeader.NumberOfSections &&
psm->fmap->sect[psm->sidx].mapped != IMAGE_NO_MAP)
if (ism->sidx >= 0 && ism->sidx < ism->fmap->u.pe.ntheader.FileHeader.NumberOfSections &&
ism->fmap->u.pe.sect[ism->sidx].mapped != IMAGE_NO_MAP)
{
pe_unmap_full(psm->fmap);
psm->fmap->sect[psm->sidx].mapped = IMAGE_NO_MAP;
pe_unmap_full(ism->fmap);
ism->fmap->u.pe.sect[ism->sidx].mapped = IMAGE_NO_MAP;
}
}
@ -145,11 +147,11 @@ void pe_unmap_section(struct pe_section_map* psm)
*
* Get the size of an PE section
*/
unsigned pe_get_map_size(const struct pe_section_map* psm)
unsigned pe_get_map_size(const struct image_section_map* ism)
{
if (psm->sidx < 0 || psm->sidx >= psm->fmap->ntheader.FileHeader.NumberOfSections)
if (ism->sidx < 0 || ism->sidx >= ism->fmap->u.pe.ntheader.FileHeader.NumberOfSections)
return 0;
return psm->fmap->sect[psm->sidx].shdr.SizeOfRawData;
return ism->fmap->u.pe.sect[ism->sidx].shdr.SizeOfRawData;
}
/******************************************************************
@ -157,14 +159,15 @@ unsigned pe_get_map_size(const struct pe_section_map* psm)
*
* Maps an PE file into memory (and checks it's a real PE file)
*/
static BOOL pe_map_file(HANDLE file, struct pe_file_map* fmap, enum module_type mt)
static BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt)
{
void* mapping;
fmap->hMap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (fmap->hMap == 0) return FALSE;
fmap->full_count = 0;
fmap->full_map = NULL;
fmap->modtype = mt;
fmap->u.pe.hMap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (fmap->u.pe.hMap == 0) return FALSE;
fmap->u.pe.full_count = 0;
fmap->u.pe.full_map = NULL;
if (!(mapping = pe_map_full(fmap, NULL))) goto error;
switch (mt)
@ -176,16 +179,16 @@ static BOOL pe_map_file(HANDLE file, struct pe_file_map* fmap, enum module_type
unsigned i;
if (!(nthdr = RtlImageNtHeader(mapping))) goto error;
memcpy(&fmap->ntheader, nthdr, sizeof(fmap->ntheader));
memcpy(&fmap->u.pe.ntheader, nthdr, sizeof(fmap->u.pe.ntheader));
section = (IMAGE_SECTION_HEADER*)
((char*)&nthdr->OptionalHeader + nthdr->FileHeader.SizeOfOptionalHeader);
fmap->sect = HeapAlloc(GetProcessHeap(), 0,
nthdr->FileHeader.NumberOfSections * sizeof(fmap->sect[0]));
if (!fmap->sect) goto error;
fmap->u.pe.sect = HeapAlloc(GetProcessHeap(), 0,
nthdr->FileHeader.NumberOfSections * sizeof(fmap->u.pe.sect[0]));
if (!fmap->u.pe.sect) goto error;
for (i = 0; i < nthdr->FileHeader.NumberOfSections; i++)
{
memcpy(&fmap->sect[i].shdr, section + i, sizeof(IMAGE_SECTION_HEADER));
fmap->sect[i].mapped = IMAGE_NO_MAP;
memcpy(&fmap->u.pe.sect[i].shdr, section + i, sizeof(IMAGE_SECTION_HEADER));
fmap->u.pe.sect[i].mapped = IMAGE_NO_MAP;
}
if (nthdr->FileHeader.PointerToSymbolTable && nthdr->FileHeader.NumberOfSymbols)
{
@ -198,9 +201,9 @@ static BOOL pe_map_file(HANDLE file, struct pe_file_map* fmap, enum module_type
if ((dst = HeapAlloc(GetProcessHeap(), 0, sz)))
memcpy(dst, src, sz);
fmap->strtable = dst;
fmap->u.pe.strtable = dst;
}
else fmap->strtable = NULL;
else fmap->u.pe.strtable = NULL;
}
break;
default: assert(0); goto error;
@ -210,7 +213,7 @@ static BOOL pe_map_file(HANDLE file, struct pe_file_map* fmap, enum module_type
return TRUE;
error:
pe_unmap_full(fmap);
CloseHandle(fmap->hMap);
CloseHandle(fmap->u.pe.hMap);
return FALSE;
}
@ -219,20 +222,20 @@ error:
*
* Unmaps an PE file from memory (previously mapped with pe_map_file)
*/
static void pe_unmap_file(struct pe_file_map* fmap)
static void pe_unmap_file(struct image_file_map* fmap)
{
if (fmap->hMap != 0)
if (fmap->u.pe.hMap != 0)
{
struct pe_section_map psm;
psm.fmap = fmap;
for (psm.sidx = 0; psm.sidx < fmap->ntheader.FileHeader.NumberOfSections; psm.sidx++)
struct image_section_map ism;
ism.fmap = fmap;
for (ism.sidx = 0; ism.sidx < fmap->u.pe.ntheader.FileHeader.NumberOfSections; ism.sidx++)
{
pe_unmap_section(&psm);
pe_unmap_section(&ism);
}
while (fmap->full_count) pe_unmap_full(fmap);
HeapFree(GetProcessHeap(), 0, fmap->sect);
HeapFree(GetProcessHeap(), 0, (void*)fmap->strtable); /* FIXME ugly (see pe_map_file) */
CloseHandle(fmap->hMap);
while (fmap->u.pe.full_count) pe_unmap_full(fmap);
HeapFree(GetProcessHeap(), 0, fmap->u.pe.sect);
HeapFree(GetProcessHeap(), 0, (void*)fmap->u.pe.strtable); /* FIXME ugly (see pe_map_file) */
CloseHandle(fmap->u.pe.hMap);
}
}
@ -244,7 +247,7 @@ static void pe_unmap_file(struct pe_file_map* fmap)
* Mingw32 requires this for stabs debug information as address for global variables isn't filled in
* (this is similar to what is done in elf_module.c when using the .symtab ELF section)
*/
static BOOL pe_locate_with_coff_symbol_table(struct module* module, struct pe_file_map* fmap)
static BOOL pe_locate_with_coff_symbol_table(struct module* module, struct image_file_map* fmap)
{
const IMAGE_SYMBOL* isym;
int i, numsym, naux;
@ -255,23 +258,23 @@ static BOOL pe_locate_with_coff_symbol_table(struct module* module, struct pe_fi
struct symt_data* sym;
const char* mapping;
numsym = fmap->ntheader.FileHeader.NumberOfSymbols;
if (!fmap->ntheader.FileHeader.PointerToSymbolTable || !numsym)
numsym = fmap->u.pe.ntheader.FileHeader.NumberOfSymbols;
if (!fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable || !numsym)
return TRUE;
if (!(mapping = pe_map_full(fmap, NULL))) return FALSE;
isym = (const IMAGE_SYMBOL*)(mapping + fmap->ntheader.FileHeader.PointerToSymbolTable);
isym = (const IMAGE_SYMBOL*)(mapping + fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable);
for (i = 0; i < numsym; i+= naux, isym += naux)
{
if (isym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
isym->SectionNumber > 0 && isym->SectionNumber <= fmap->ntheader.FileHeader.NumberOfSections)
isym->SectionNumber > 0 && isym->SectionNumber <= fmap->u.pe.ntheader.FileHeader.NumberOfSections)
{
if (isym->N.Name.Short)
{
name = memcpy(tmp, isym->N.ShortName, 8);
tmp[8] = '\0';
}
else name = fmap->strtable + isym->N.Name.Long;
else name = fmap->u.pe.strtable + isym->N.Name.Long;
if (name[0] == '_') name++;
hash_table_iter_init(&module->ht_symbols, &hti, name);
while ((ptr = hash_table_iter_up(&hti)))
@ -284,10 +287,10 @@ static BOOL pe_locate_with_coff_symbol_table(struct module* module, struct pe_fi
TRACE("Changing absolute address for %d.%s: %lx -> %s\n",
isym->SectionNumber, name, sym->u.var.offset,
wine_dbgstr_longlong(module->module.BaseOfImage +
fmap->sect[isym->SectionNumber - 1].shdr.VirtualAddress +
fmap->u.pe.sect[isym->SectionNumber - 1].shdr.VirtualAddress +
isym->Value));
sym->u.var.offset = module->module.BaseOfImage +
fmap->sect[isym->SectionNumber - 1].shdr.VirtualAddress + isym->Value;
fmap->u.pe.sect[isym->SectionNumber - 1].shdr.VirtualAddress + isym->Value;
break;
}
}
@ -303,7 +306,7 @@ static BOOL pe_locate_with_coff_symbol_table(struct module* module, struct pe_fi
*
* Load public symbols out of the COFF symbol table (if any).
*/
static BOOL pe_load_coff_symbol_table(struct module* module, struct pe_file_map* fmap)
static BOOL pe_load_coff_symbol_table(struct module* module, struct image_file_map* fmap)
{
const IMAGE_SYMBOL* isym;
int i, numsym, naux;
@ -315,14 +318,14 @@ static BOOL pe_load_coff_symbol_table(struct module* module, struct pe_file_map*
const IMAGE_SECTION_HEADER* sect;
const char* mapping;
numsym = fmap->ntheader.FileHeader.NumberOfSymbols;
if (!fmap->ntheader.FileHeader.PointerToSymbolTable || !numsym)
numsym = fmap->u.pe.ntheader.FileHeader.NumberOfSymbols;
if (!fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable || !numsym)
return TRUE;
if (!(mapping = pe_map_full(fmap, NULL))) return FALSE;
isym = (const IMAGE_SYMBOL*)((char*)mapping + fmap->ntheader.FileHeader.PointerToSymbolTable);
isym = (const IMAGE_SYMBOL*)((char*)mapping + fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable);
/* FIXME: no way to get strtable size */
strtable = (const char*)&isym[numsym];
sect = IMAGE_FIRST_SECTION(&fmap->ntheader);
sect = IMAGE_FIRST_SECTION(&fmap->u.pe.ntheader);
for (i = 0; i < numsym; i+= naux, isym += naux)
{
@ -332,7 +335,7 @@ static BOOL pe_load_coff_symbol_table(struct module* module, struct pe_file_map*
compiland = NULL;
}
if (isym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
isym->SectionNumber > 0 && isym->SectionNumber <= fmap->ntheader.FileHeader.NumberOfSections)
isym->SectionNumber > 0 && isym->SectionNumber <= fmap->u.pe.ntheader.FileHeader.NumberOfSections)
{
if (isym->N.Name.Short)
{
@ -379,9 +382,9 @@ static inline DWORD pe_get_sect_size(IMAGE_SECTION_HEADER* sect)
* look for stabs information in PE header (it's how the mingw compiler provides
* its debugging information)
*/
static BOOL pe_load_stabs(const struct process* pcs, struct module* module, struct pe_file_map* fmap)
static BOOL pe_load_stabs(const struct process* pcs, struct module* module, struct image_file_map* fmap)
{
struct pe_section_map sect_stabs, sect_stabstr;
struct image_section_map sect_stabs, sect_stabstr;
BOOL ret = FALSE;
if (pe_find_section(fmap, ".stab", &sect_stabs) && pe_find_section(fmap, ".stabstr", &sect_stabstr))
@ -389,18 +392,18 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module, stru
const char* stab;
const char* stabstr;
stab = pe_map_section(&sect_stabs);
stabstr = pe_map_section(&sect_stabstr);
stab = image_map_section(&sect_stabs);
stabstr = image_map_section(&sect_stabstr);
if (stab != IMAGE_NO_MAP && stabstr != IMAGE_NO_MAP)
{
ret = stabs_parse(module,
module->module.BaseOfImage - fmap->ntheader.OptionalHeader.ImageBase,
stab, pe_get_map_size(&sect_stabs),
stabstr, pe_get_map_size(&sect_stabstr),
module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
stab, image_get_map_size(&sect_stabs),
stabstr, image_get_map_size(&sect_stabstr),
NULL, NULL);
}
pe_unmap_section(&sect_stabs);
pe_unmap_section(&sect_stabstr);
image_unmap_section(&sect_stabs);
image_unmap_section(&sect_stabstr);
if (ret) pe_locate_with_coff_symbol_table(module, fmap);
}
TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load");
@ -415,9 +418,9 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module, stru
* to provide its debugging information)
*/
static BOOL pe_load_dwarf(const struct process* pcs, struct module* module,
struct pe_file_map* fmap)
struct image_file_map* fmap)
{
struct pe_section_map sect_debuginfo, sect_debugstr, sect_debugabbrev, sect_debugline, sect_debugloc;
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))
@ -433,28 +436,28 @@ static BOOL pe_load_dwarf(const struct process* pcs, struct module* module,
pe_find_section(fmap, ".debug_line", &sect_debugline);
pe_find_section(fmap, ".debug_loc", &sect_debugloc);
dw2_debuginfo = (const BYTE*)pe_map_section(&sect_debuginfo);
dw2_debugabbrev = (const BYTE*)pe_map_section(&sect_debugabbrev);
dw2_debugstr = (const BYTE*)pe_map_section(&sect_debugstr);
dw2_debugline = (const BYTE*)pe_map_section(&sect_debugline);
dw2_debugloc = (const BYTE*)pe_map_section(&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->ntheader.OptionalHeader.ImageBase,
module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
NULL, /* FIXME: some thunks to deal with ? */
dw2_debuginfo, pe_get_map_size(&sect_debuginfo),
dw2_debugabbrev, pe_get_map_size(&sect_debugabbrev),
dw2_debugstr, pe_get_map_size(&sect_debugstr),
dw2_debugline, pe_get_map_size(&sect_debugline),
dw2_debugloc, pe_get_map_size(&sect_debugloc));
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));
}
pe_unmap_section(&sect_debuginfo);
pe_unmap_section(&sect_debugabbrev);
pe_unmap_section(&sect_debugstr);
pe_unmap_section(&sect_debugline);
pe_unmap_section(&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);
}
TRACE("%s the DWARF debug info\n", ret ? "successfully loaded" : "failed to load");
@ -513,7 +516,7 @@ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
*
* Process MSC debug information in PE file.
*/
static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* module, struct pe_file_map* fmap)
static BOOL pe_load_msc_debug_info(const struct process* pcs, struct module* module, struct image_file_map* fmap)
{
BOOL ret = FALSE;
const IMAGE_DATA_DIRECTORY* dir;
@ -563,7 +566,7 @@ done:
/***********************************************************************
* pe_load_export_debug_info
*/
static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* module, struct pe_file_map* fmap)
static BOOL pe_load_export_debug_info(const struct process* pcs, struct module* module, struct image_file_map* fmap)
{
unsigned int i;
const IMAGE_EXPORT_DIRECTORY* exports;
@ -647,7 +650,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs, struct module*
*
*/
BOOL pe_load_debug_info_internal(const struct process* pcs, struct module* module,
struct pe_file_map* fmap)
struct image_file_map* fmap)
{
BOOL ret = FALSE;
@ -671,9 +674,9 @@ BOOL pe_load_debug_info_internal(const struct process* pcs, struct module* modul
BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
{
BOOL ret = FALSE;
HANDLE hFile;
struct pe_file_map fmap;
BOOL ret = FALSE;
HANDLE hFile;
struct image_file_map fmap;
hFile = CreateFileW(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@ -695,10 +698,10 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
HANDLE hFile, DWORD base, DWORD size)
{
struct module* module = NULL;
BOOL opened = FALSE;
struct pe_file_map fmap;
WCHAR loaded_name[MAX_PATH];
struct module* module = NULL;
BOOL opened = FALSE;
struct image_file_map fmap;
WCHAR loaded_name[MAX_PATH];
loaded_name[0] = '\0';
if (!hFile)
@ -715,12 +718,12 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
if (pe_map_file(hFile, &fmap, DMT_PE))
{
if (!base) base = fmap.ntheader.OptionalHeader.ImageBase;
if (!size) size = fmap.ntheader.OptionalHeader.SizeOfImage;
if (!base) base = fmap.u.pe.ntheader.OptionalHeader.ImageBase;
if (!size) size = fmap.u.pe.ntheader.OptionalHeader.SizeOfImage;
module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size,
fmap.ntheader.FileHeader.TimeDateStamp,
fmap.ntheader.OptionalHeader.CheckSum);
fmap.u.pe.ntheader.FileHeader.TimeDateStamp,
fmap.u.pe.ntheader.OptionalHeader.CheckSum);
if (module)
{
if (dbghelp_options & SYMOPT_DEFERRED_LOADS)