dbghelp: Create the notion of image (PE, ELF modules) to uniformize some handlings.
This commit is contained in:
parent
fb169502a5
commit
cbff4f063f
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +343,7 @@ 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,
|
||||
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:
|
||||
|
@ -830,7 +842,7 @@ static BOOL elf_debuglink_parse(struct elf_file_map* fmap, const struct module*
|
|||
* 1 on success
|
||||
*/
|
||||
static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||
struct elf_file_map* fmap,
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
@ -1035,7 +1047,7 @@ 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;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -60,26 +60,36 @@
|
|||
#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 image_file_map
|
||||
{
|
||||
enum module_type modtype;
|
||||
union
|
||||
{
|
||||
struct elf_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) */
|
||||
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;
|
||||
|
@ -92,28 +102,68 @@ struct pe_file_map
|
|||
const char* mapped;
|
||||
}* sect;
|
||||
const char* strtable;
|
||||
} pe;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct elf_section_map
|
||||
struct image_section_map
|
||||
{
|
||||
struct elf_file_map* fmap;
|
||||
struct image_file_map* fmap;
|
||||
long sidx;
|
||||
};
|
||||
|
||||
struct pe_section_map
|
||||
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)
|
||||
{
|
||||
struct pe_file_map* fmap;
|
||||
long sidx;
|
||||
};
|
||||
switch (fmap->modtype)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
static inline const char* image_map_section(struct image_section_map* ism)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 void image_unmap_section(struct image_section_map* ism)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
fmap->sect[ism->sidx].mapped = RtlImageRvaToVa(nth, mapping,
|
||||
fmap->sect[ism->sidx].shdr.VirtualAddress,
|
||||
NULL);
|
||||
return psm->fmap->sect[psm->sidx].mapped;
|
||||
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", §_stabs) && pe_find_section(fmap, ".stabstr", §_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(§_stabs);
|
||||
stabstr = pe_map_section(§_stabstr);
|
||||
stab = image_map_section(§_stabs);
|
||||
stabstr = image_map_section(§_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(§_stabs),
|
||||
stabstr, pe_get_map_size(§_stabstr),
|
||||
module->module.BaseOfImage - fmap->u.pe.ntheader.OptionalHeader.ImageBase,
|
||||
stab, image_get_map_size(§_stabs),
|
||||
stabstr, image_get_map_size(§_stabstr),
|
||||
NULL, NULL);
|
||||
}
|
||||
pe_unmap_section(§_stabs);
|
||||
pe_unmap_section(§_stabstr);
|
||||
image_unmap_section(§_stabs);
|
||||
image_unmap_section(§_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", §_debuginfo))
|
||||
|
@ -433,28 +436,28 @@ static BOOL pe_load_dwarf(const struct process* pcs, struct module* module,
|
|||
pe_find_section(fmap, ".debug_line", §_debugline);
|
||||
pe_find_section(fmap, ".debug_loc", §_debugloc);
|
||||
|
||||
dw2_debuginfo = (const BYTE*)pe_map_section(§_debuginfo);
|
||||
dw2_debugabbrev = (const BYTE*)pe_map_section(§_debugabbrev);
|
||||
dw2_debugstr = (const BYTE*)pe_map_section(§_debugstr);
|
||||
dw2_debugline = (const BYTE*)pe_map_section(§_debugline);
|
||||
dw2_debugloc = (const BYTE*)pe_map_section(§_debugloc);
|
||||
dw2_debuginfo = (const BYTE*)image_map_section(§_debuginfo);
|
||||
dw2_debugabbrev = (const BYTE*)image_map_section(§_debugabbrev);
|
||||
dw2_debugstr = (const BYTE*)image_map_section(§_debugstr);
|
||||
dw2_debugline = (const BYTE*)image_map_section(§_debugline);
|
||||
dw2_debugloc = (const BYTE*)image_map_section(§_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(§_debuginfo),
|
||||
dw2_debugabbrev, pe_get_map_size(§_debugabbrev),
|
||||
dw2_debugstr, pe_get_map_size(§_debugstr),
|
||||
dw2_debugline, pe_get_map_size(§_debugline),
|
||||
dw2_debugloc, pe_get_map_size(§_debugloc));
|
||||
dw2_debuginfo, image_get_map_size(§_debuginfo),
|
||||
dw2_debugabbrev, image_get_map_size(§_debugabbrev),
|
||||
dw2_debugstr, image_get_map_size(§_debugstr),
|
||||
dw2_debugline, image_get_map_size(§_debugline),
|
||||
dw2_debugloc, image_get_map_size(§_debugloc));
|
||||
}
|
||||
pe_unmap_section(§_debuginfo);
|
||||
pe_unmap_section(§_debugabbrev);
|
||||
pe_unmap_section(§_debugstr);
|
||||
pe_unmap_section(§_debugline);
|
||||
pe_unmap_section(§_debugloc);
|
||||
image_unmap_section(§_debuginfo);
|
||||
image_unmap_section(§_debugabbrev);
|
||||
image_unmap_section(§_debugstr);
|
||||
image_unmap_section(§_debugline);
|
||||
image_unmap_section(§_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;
|
||||
|
||||
|
@ -673,7 +676,7 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
|
|||
{
|
||||
BOOL ret = FALSE;
|
||||
HANDLE hFile;
|
||||
struct pe_file_map fmap;
|
||||
struct image_file_map fmap;
|
||||
|
||||
hFile = CreateFileW(module->module.LoadedImageName, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
@ -697,7 +700,7 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
|
|||
{
|
||||
struct module* module = NULL;
|
||||
BOOL opened = FALSE;
|
||||
struct pe_file_map fmap;
|
||||
struct image_file_map fmap;
|
||||
WCHAR loaded_name[MAX_PATH];
|
||||
|
||||
loaded_name[0] = '\0';
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue