dbghelp: Rewrote the ELF section mapper for better data encapsulation.
This commit is contained in:
parent
0ee7264c37
commit
62b57f9e21
|
@ -114,6 +114,13 @@ struct elf_file_map
|
||||||
int fd;
|
int fd;
|
||||||
unsigned with_crc;
|
unsigned with_crc;
|
||||||
unsigned long crc;
|
unsigned long crc;
|
||||||
|
const char* shstrtab;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct elf_section_map
|
||||||
|
{
|
||||||
|
struct elf_file_map* fmap;
|
||||||
|
unsigned sidx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct symtab_elt
|
struct symtab_elt
|
||||||
|
@ -137,21 +144,52 @@ struct elf_thunk_area
|
||||||
*
|
*
|
||||||
* Maps a single section into memory from an ELF file
|
* Maps a single section into memory from an ELF file
|
||||||
*/
|
*/
|
||||||
static const char* elf_map_section(struct elf_file_map* fmap, int sidx)
|
static const char* elf_map_section(struct elf_section_map* esm)
|
||||||
{
|
{
|
||||||
unsigned pgsz = getpagesize();
|
unsigned pgsz = getpagesize();
|
||||||
unsigned ofst, size;
|
unsigned ofst, size;
|
||||||
|
|
||||||
if (sidx < 0 || sidx >= fmap->elfhdr.e_shnum ||
|
if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum ||
|
||||||
fmap->sect[sidx].shdr.sh_type == SHT_NOBITS)
|
esm->fmap->sect[esm->sidx].shdr.sh_type == SHT_NOBITS)
|
||||||
return ELF_NO_MAP;
|
return ELF_NO_MAP;
|
||||||
|
|
||||||
/* align required information on page size (we assume pagesize is a power of 2) */
|
/* align required information on page size (we assume pagesize is a power of 2) */
|
||||||
ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
|
ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
|
||||||
size = ((fmap->sect[sidx].shdr.sh_offset +
|
size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
|
||||||
fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
|
esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
|
||||||
fmap->sect[sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fmap->fd, ofst);
|
esm->fmap->sect[esm->sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE,
|
||||||
if (fmap->sect[sidx].mapped == ELF_NO_MAP) return ELF_NO_MAP;
|
esm->fmap->fd, ofst);
|
||||||
return fmap->sect[sidx].mapped + (fmap->sect[sidx].shdr.sh_offset & (pgsz - 1));
|
if (esm->fmap->sect[esm->sidx].mapped == ELF_NO_MAP) return ELF_NO_MAP;
|
||||||
|
return esm->fmap->sect[esm->sidx].mapped + (esm->fmap->sect[esm->sidx].shdr.sh_offset & (pgsz - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* elf_find_section
|
||||||
|
*
|
||||||
|
* Finds a section by name (and type) into memory from an ELF file
|
||||||
|
*/
|
||||||
|
static BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
|
||||||
|
unsigned sht, struct elf_section_map* esm)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (fmap->shstrtab == ELF_NO_MAP)
|
||||||
|
{
|
||||||
|
struct elf_section_map hdr_esm = {fmap, fmap->elfhdr.e_shstrndx};
|
||||||
|
fmap->shstrtab = elf_map_section(&hdr_esm);
|
||||||
|
if (fmap->shstrtab == ELF_NO_MAP) return FALSE;
|
||||||
|
}
|
||||||
|
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
|
||||||
|
(sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
|
||||||
|
{
|
||||||
|
esm->fmap = fmap;
|
||||||
|
esm->sidx = i;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -159,32 +197,41 @@ static const char* elf_map_section(struct elf_file_map* fmap, int sidx)
|
||||||
*
|
*
|
||||||
* Unmaps a single section from memory
|
* Unmaps a single section from memory
|
||||||
*/
|
*/
|
||||||
static void elf_unmap_section(struct elf_file_map* fmap, int sidx)
|
static void elf_unmap_section(struct elf_section_map* esm)
|
||||||
{
|
{
|
||||||
if (sidx >= 0 && sidx < fmap->elfhdr.e_shnum && fmap->sect[sidx].mapped != ELF_NO_MAP)
|
if (esm->sidx >= 0 && esm->sidx < esm->fmap->elfhdr.e_shnum && esm->fmap->sect[esm->sidx].mapped != ELF_NO_MAP)
|
||||||
{
|
{
|
||||||
unsigned pgsz = getpagesize();
|
unsigned pgsz = getpagesize();
|
||||||
unsigned ofst, size;
|
unsigned ofst, size;
|
||||||
|
|
||||||
ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
|
ofst = esm->fmap->sect[esm->sidx].shdr.sh_offset & ~(pgsz - 1);
|
||||||
size = ((fmap->sect[sidx].shdr.sh_offset +
|
size = ((esm->fmap->sect[esm->sidx].shdr.sh_offset +
|
||||||
fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
|
esm->fmap->sect[esm->sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
|
||||||
if (munmap((char*)fmap->sect[sidx].mapped, size) < 0)
|
if (munmap((char*)esm->fmap->sect[esm->sidx].mapped, size) < 0)
|
||||||
WARN("Couldn't unmap the section\n");
|
WARN("Couldn't unmap the section\n");
|
||||||
fmap->sect[sidx].mapped = ELF_NO_MAP;
|
esm->fmap->sect[esm->sidx].mapped = ELF_NO_MAP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void elf_end_find(struct elf_file_map* fmap)
|
||||||
|
{
|
||||||
|
struct elf_section_map esm;
|
||||||
|
|
||||||
|
esm.fmap = fmap; esm.sidx = fmap->elfhdr.e_shstrndx;
|
||||||
|
elf_unmap_section(&esm);
|
||||||
|
fmap->shstrtab = ELF_NO_MAP;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* elf_get_map_size
|
* elf_get_map_size
|
||||||
*
|
*
|
||||||
* Get the size of an ELF section
|
* Get the size of an ELF section
|
||||||
*/
|
*/
|
||||||
static inline unsigned elf_get_map_size(struct elf_file_map* fmap, int sidx)
|
static inline unsigned elf_get_map_size(struct elf_section_map* esm)
|
||||||
{
|
{
|
||||||
if (sidx < 0 || sidx >= fmap->elfhdr.e_shnum)
|
if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum)
|
||||||
return 0;
|
return 0;
|
||||||
return fmap->sect[sidx].shdr.sh_size;
|
return esm->fmap->sect[esm->sidx].shdr.sh_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
|
@ -209,6 +256,7 @@ static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
|
||||||
|
|
||||||
fmap->fd = -1;
|
fmap->fd = -1;
|
||||||
fmap->with_crc = 0;
|
fmap->with_crc = 0;
|
||||||
|
fmap->shstrtab = ELF_NO_MAP;
|
||||||
|
|
||||||
/* check that the file exists, and that the module hasn't been loaded yet */
|
/* 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;
|
if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done;
|
||||||
|
@ -266,10 +314,11 @@ static void elf_unmap_file(struct elf_file_map* fmap)
|
||||||
{
|
{
|
||||||
if (fmap->fd != -1)
|
if (fmap->fd != -1)
|
||||||
{
|
{
|
||||||
int i;
|
struct elf_section_map esm;
|
||||||
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
|
esm.fmap = fmap;
|
||||||
|
for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
|
||||||
{
|
{
|
||||||
elf_unmap_section(fmap, i);
|
elf_unmap_section(&esm);
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, fmap->sect);
|
HeapFree(GetProcessHeap(), 0, fmap->sect);
|
||||||
close(fmap->fd);
|
close(fmap->fd);
|
||||||
|
@ -302,7 +351,7 @@ int elf_is_in_thunk_area(unsigned long addr,
|
||||||
*/
|
*/
|
||||||
static void elf_hash_symtab(struct module* module, struct pool* pool,
|
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 elf_file_map* fmap,
|
||||||
int symtab_idx, struct elf_thunk_area* thunks)
|
struct elf_thunk_area* thunks)
|
||||||
{
|
{
|
||||||
int i, j, nsym;
|
int i, j, nsym;
|
||||||
const char* strp;
|
const char* strp;
|
||||||
|
@ -311,12 +360,16 @@ static void elf_hash_symtab(struct module* module, struct pool* pool,
|
||||||
const char* ptr;
|
const char* ptr;
|
||||||
const Elf32_Sym* symp;
|
const Elf32_Sym* symp;
|
||||||
struct symtab_elt* ste;
|
struct symtab_elt* ste;
|
||||||
|
struct elf_section_map esm, esm_str;
|
||||||
|
|
||||||
symp = (const Elf32_Sym*)elf_map_section(fmap, symtab_idx);
|
if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &esm) &&
|
||||||
strp = elf_map_section(fmap, fmap->sect[symtab_idx].shdr.sh_link);
|
!elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &esm)) return;
|
||||||
if (symp == ELF_NO_MAP || strp == ELF_NO_MAP) return;
|
if ((symp = (const Elf32_Sym*)elf_map_section(&esm)) == ELF_NO_MAP) return;
|
||||||
|
esm_str.fmap = fmap;
|
||||||
|
esm_str.sidx = fmap->sect[esm.sidx].shdr.sh_link;
|
||||||
|
if ((strp = elf_map_section(&esm_str)) == ELF_NO_MAP) return;
|
||||||
|
|
||||||
nsym = elf_get_map_size(fmap, symtab_idx) / sizeof(*symp);
|
nsym = elf_get_map_size(&esm) / sizeof(*symp);
|
||||||
|
|
||||||
for (j = 0; thunks[j].symname; j++)
|
for (j = 0; thunks[j].symname; j++)
|
||||||
thunks[j].rva_start = thunks[j].rva_end = 0;
|
thunks[j].rva_start = thunks[j].rva_end = 0;
|
||||||
|
@ -922,12 +975,6 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||||
struct hash_table* ht_symtab)
|
struct hash_table* ht_symtab)
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE, lret;
|
BOOL ret = FALSE, lret;
|
||||||
const char* shstrtab;
|
|
||||||
int i;
|
|
||||||
int symtab_sect, dynsym_sect, stab_sect, stabstr_sect;
|
|
||||||
int debug_sect, debug_str_sect, debug_abbrev_sect;
|
|
||||||
int debug_line_sect, debug_loclist_sect;
|
|
||||||
int debuglink_sect;
|
|
||||||
struct elf_thunk_area thunks[] =
|
struct elf_thunk_area thunks[] =
|
||||||
{
|
{
|
||||||
{"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
|
{"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
|
||||||
|
@ -947,77 +994,32 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Next, we need to find a few of the internal ELF headers within
|
|
||||||
* this thing. We need the main executable header, and the section
|
|
||||||
* table.
|
|
||||||
*/
|
|
||||||
shstrtab = elf_map_section(fmap, fmap->elfhdr.e_shstrndx);
|
|
||||||
if (shstrtab == ELF_NO_MAP) return FALSE;
|
|
||||||
|
|
||||||
symtab_sect = dynsym_sect = stab_sect = stabstr_sect = -1;
|
|
||||||
debug_sect = debug_str_sect = debug_abbrev_sect = -1;
|
|
||||||
debug_line_sect = debug_loclist_sect = -1;
|
|
||||||
debuglink_sect = -1;
|
|
||||||
|
|
||||||
for (i = 0; i < fmap->elfhdr.e_shnum; i++)
|
|
||||||
{
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stab") == 0)
|
|
||||||
stab_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".stabstr") == 0)
|
|
||||||
stabstr_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_info") == 0)
|
|
||||||
debug_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_str") == 0)
|
|
||||||
debug_str_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_abbrev") == 0)
|
|
||||||
debug_abbrev_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_line") == 0)
|
|
||||||
debug_line_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".debug_loc") == 0)
|
|
||||||
debug_loclist_sect = i;
|
|
||||||
if (strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".gnu_debuglink") == 0)
|
|
||||||
debuglink_sect = i;
|
|
||||||
if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".symtab") == 0) &&
|
|
||||||
(fmap->sect[i].shdr.sh_type == SHT_SYMTAB))
|
|
||||||
symtab_sect = i;
|
|
||||||
if ((strcmp(shstrtab + fmap->sect[i].shdr.sh_name, ".dynsym") == 0) &&
|
|
||||||
(fmap->sect[i].shdr.sh_type == SHT_DYNSYM))
|
|
||||||
dynsym_sect = i;
|
|
||||||
}
|
|
||||||
elf_unmap_section(fmap, fmap->elfhdr.e_shstrndx);
|
|
||||||
shstrtab = NULL;
|
|
||||||
|
|
||||||
if (symtab_sect == -1)
|
|
||||||
{
|
|
||||||
/* if we don't have a symtab but a dynsym, process the dynsym
|
|
||||||
* section instead. It'll contain less (relevant) information,
|
|
||||||
* but it'll be better than nothing
|
|
||||||
*/
|
|
||||||
if (dynsym_sect == -1) return FALSE;
|
|
||||||
symtab_sect = dynsym_sect;
|
|
||||||
}
|
|
||||||
|
|
||||||
module->module.SymType = SymExport;
|
module->module.SymType = SymExport;
|
||||||
|
|
||||||
/* create a hash table for the symtab */
|
/* create a hash table for the symtab */
|
||||||
elf_hash_symtab(module, pool, ht_symtab, fmap, symtab_sect, thunks);
|
elf_hash_symtab(module, pool, ht_symtab, fmap, thunks);
|
||||||
|
|
||||||
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
||||||
{
|
{
|
||||||
if (stab_sect != -1 && stabstr_sect != -1)
|
struct elf_section_map stab_sect, stabstr_sect;
|
||||||
|
struct elf_section_map debug_sect, debug_str_sect, debug_abbrev_sect,
|
||||||
|
debug_line_sect, debug_loclist_sect;
|
||||||
|
struct elf_section_map debuglink_sect;
|
||||||
|
|
||||||
|
if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
|
||||||
|
elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
|
||||||
{
|
{
|
||||||
const char* stab;
|
const char* stab;
|
||||||
const char* stabstr;
|
const char* stabstr;
|
||||||
|
|
||||||
stab = elf_map_section(fmap, stab_sect);
|
stab = elf_map_section(&stab_sect);
|
||||||
stabstr = elf_map_section(fmap, stabstr_sect);
|
stabstr = elf_map_section(&stabstr_sect);
|
||||||
if (stab != ELF_NO_MAP && stabstr != ELF_NO_MAP)
|
if (stab != ELF_NO_MAP && stabstr != ELF_NO_MAP)
|
||||||
{
|
{
|
||||||
/* OK, now just parse all of the stabs. */
|
/* OK, now just parse all of the stabs. */
|
||||||
lret = stabs_parse(module, module->elf_info->elf_addr,
|
lret = stabs_parse(module, module->elf_info->elf_addr,
|
||||||
stab, elf_get_map_size(fmap, stab_sect),
|
stab, elf_get_map_size(&stab_sect),
|
||||||
stabstr, elf_get_map_size(fmap, stabstr_sect));
|
stabstr, elf_get_map_size(&stabstr_sect));
|
||||||
if (lret)
|
if (lret)
|
||||||
/* and fill in the missing information for stabs */
|
/* and fill in the missing information for stabs */
|
||||||
elf_finish_stabs_info(module, ht_symtab);
|
elf_finish_stabs_info(module, ht_symtab);
|
||||||
|
@ -1026,11 +1028,10 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||||
ret = ret || lret;
|
ret = ret || lret;
|
||||||
}
|
}
|
||||||
else lret = FALSE;
|
else lret = FALSE;
|
||||||
elf_unmap_section(fmap, stab_sect);
|
elf_unmap_section(&stab_sect);
|
||||||
elf_unmap_section(fmap, stabstr_sect);
|
elf_unmap_section(&stabstr_sect);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (debug_sect != -1)
|
if (elf_find_section(fmap, ".debug_info", SHT_NULL, &debug_sect))
|
||||||
{
|
{
|
||||||
/* Dwarf 2 debug information */
|
/* Dwarf 2 debug information */
|
||||||
const BYTE* dw2_debug;
|
const BYTE* dw2_debug;
|
||||||
|
@ -1041,36 +1042,41 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||||
|
|
||||||
TRACE("Loading Dwarf2 information for %s\n", module->module_name);
|
TRACE("Loading Dwarf2 information for %s\n", module->module_name);
|
||||||
|
|
||||||
dw2_debug = (const BYTE*) elf_map_section(fmap, debug_sect);
|
elf_find_section(fmap, ".debug_str", SHT_NULL, &debug_str_sect);
|
||||||
dw2_debug_abbrev = (const BYTE*) elf_map_section(fmap, debug_abbrev_sect);
|
elf_find_section(fmap, ".debug_abbrev", SHT_NULL, &debug_abbrev_sect);
|
||||||
dw2_debug_str = (const BYTE*) elf_map_section(fmap, debug_str_sect);
|
elf_find_section(fmap, ".debug_line", SHT_NULL, &debug_line_sect);
|
||||||
dw2_debug_line = (const BYTE*) elf_map_section(fmap, debug_line_sect);
|
elf_find_section(fmap, ".debug_loc", SHT_NULL, &debug_loclist_sect);
|
||||||
dw2_debug_loclist = (const BYTE*) elf_map_section(fmap, 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);
|
||||||
if (dw2_debug != ELF_NO_MAP && dw2_debug_abbrev != ELF_NO_MAP && dw2_debug_str != ELF_NO_MAP)
|
if (dw2_debug != ELF_NO_MAP && dw2_debug_abbrev != ELF_NO_MAP && dw2_debug_str != ELF_NO_MAP)
|
||||||
{
|
{
|
||||||
/* OK, now just parse dwarf2 debug infos. */
|
/* OK, now just parse dwarf2 debug infos. */
|
||||||
lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks,
|
lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks,
|
||||||
dw2_debug, elf_get_map_size(fmap, debug_sect),
|
dw2_debug, elf_get_map_size(&debug_sect),
|
||||||
dw2_debug_abbrev, elf_get_map_size(fmap, debug_abbrev_sect),
|
dw2_debug_abbrev, elf_get_map_size(&debug_abbrev_sect),
|
||||||
dw2_debug_str, elf_get_map_size(fmap, debug_str_sect),
|
dw2_debug_str, elf_get_map_size(&debug_str_sect),
|
||||||
dw2_debug_line, elf_get_map_size(fmap, debug_line_sect),
|
dw2_debug_line, elf_get_map_size(&debug_line_sect),
|
||||||
dw2_debug_loclist, elf_get_map_size(fmap, debug_loclist_sect));
|
dw2_debug_loclist, elf_get_map_size(&debug_loclist_sect));
|
||||||
|
|
||||||
if (!lret)
|
if (!lret)
|
||||||
WARN("Couldn't correctly read stabs\n");
|
WARN("Couldn't correctly read stabs\n");
|
||||||
ret = ret || lret;
|
ret = ret || lret;
|
||||||
}
|
}
|
||||||
elf_unmap_section(fmap, debug_sect);
|
elf_unmap_section(&debug_sect);
|
||||||
elf_unmap_section(fmap, debug_abbrev_sect);
|
elf_unmap_section(&debug_abbrev_sect);
|
||||||
elf_unmap_section(fmap, debug_str_sect);
|
elf_unmap_section(&debug_str_sect);
|
||||||
elf_unmap_section(fmap, debug_line_sect);
|
elf_unmap_section(&debug_line_sect);
|
||||||
elf_unmap_section(fmap, debug_loclist_sect);
|
elf_unmap_section(&debug_loclist_sect);
|
||||||
}
|
}
|
||||||
if (debuglink_sect != -1)
|
if (elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
|
||||||
{
|
{
|
||||||
const BYTE* dbg_link;
|
const BYTE* dbg_link;
|
||||||
|
|
||||||
dbg_link = (const BYTE*) elf_map_section(fmap, debuglink_sect);
|
dbg_link = (const BYTE*)elf_map_section(&debuglink_sect);
|
||||||
if (dbg_link != ELF_NO_MAP)
|
if (dbg_link != ELF_NO_MAP)
|
||||||
{
|
{
|
||||||
lret = elf_debuglink_parse(module, pool, ht_symtab, dbg_link);
|
lret = elf_debuglink_parse(module, pool, ht_symtab, dbg_link);
|
||||||
|
@ -1079,7 +1085,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
|
||||||
debugstr_w(module->module.ModuleName));
|
debugstr_w(module->module.ModuleName));
|
||||||
ret = ret || lret;
|
ret = ret || lret;
|
||||||
}
|
}
|
||||||
elf_unmap_section(fmap, debuglink_sect);
|
elf_unmap_section(&debuglink_sect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strstrW(module->module.ModuleName, S_ElfW) ||
|
if (strstrW(module->module.ModuleName, S_ElfW) ||
|
||||||
|
@ -1163,7 +1169,6 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
struct elf_file_map fmap;
|
struct elf_file_map fmap;
|
||||||
int i;
|
|
||||||
|
|
||||||
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
|
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
|
||||||
|
|
||||||
|
@ -1185,33 +1190,29 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
|
||||||
|
|
||||||
if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
|
if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
|
||||||
{
|
{
|
||||||
const char* shstrtab = elf_map_section(&fmap, fmap.elfhdr.e_shstrndx);
|
struct elf_section_map esm;
|
||||||
if (shstrtab == ELF_NO_MAP) goto leave;
|
|
||||||
for (i = 0; i < fmap.elfhdr.e_shnum; i++)
|
|
||||||
{
|
|
||||||
if (strcmp(shstrtab + fmap.sect[i].shdr.sh_name, ".dynamic") == 0 &&
|
|
||||||
fmap.sect[i].shdr.sh_type == SHT_DYNAMIC)
|
|
||||||
{
|
|
||||||
Elf32_Dyn dyn;
|
|
||||||
char* ptr = (char*)fmap.sect[i].shdr.sh_addr;
|
|
||||||
unsigned long len;
|
|
||||||
|
|
||||||
do
|
if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
|
||||||
|
{
|
||||||
|
Elf32_Dyn dyn;
|
||||||
|
char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
|
||||||
|
unsigned long len;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
|
||||||
|
len != sizeof(dyn))
|
||||||
|
goto leave;
|
||||||
|
if (dyn.d_tag == DT_DEBUG)
|
||||||
{
|
{
|
||||||
if (!ReadProcessMemory(pcs->handle, ptr, &dyn, sizeof(dyn), &len) ||
|
elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
|
||||||
len != sizeof(dyn))
|
break;
|
||||||
goto leave;
|
}
|
||||||
if (dyn.d_tag == DT_DEBUG)
|
ptr += sizeof(dyn);
|
||||||
{
|
} while (dyn.d_tag != DT_NULL);
|
||||||
elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
|
if (dyn.d_tag == DT_NULL) goto leave;
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr += sizeof(dyn);
|
|
||||||
} while (dyn.d_tag != DT_NULL);
|
|
||||||
if (dyn.d_tag == DT_NULL) goto leave;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elf_unmap_section(&fmap, fmap.elfhdr.e_shstrndx);
|
elf_end_find(&fmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf_info->flags & ELF_INFO_MODULE)
|
if (elf_info->flags & ELF_INFO_MODULE)
|
||||||
|
|
Loading…
Reference in New Issue