dbghelp: Match the crc for debug link files in
elf_locate_debug_link
so that we get the correct debug file before trying to parse it.
Eric Pouech
eric.pouech at wanadoo.fr
Sat Feb 24 02:41:10 CST 2007
Eric Pouech a écrit :
> Robert Shearman a écrit :
>> Eric Pouech wrote:
>>> Robert Shearman a écrit :
>>>>
>>>> Keep the debuglink elf_file_map mapped until after
>>>> elf_new_public_symbols is called, otherwise we could use unmapped
>>>> memory.
>>>
>>> this is still not the full valid solution... what should be done is:
>>> when we search for a given section, we should look first in the
>>> original .so, then, if not found, in the .gnu_debuglink one...
>>> your patch only covers the case where all relevant information is to
>>> be found in the .gnu_debuglink file, which is not guaranteed
>>
>> And that should be easier for an interested person to do after this
>> patch is applied, right? I was just interested in getting rid of
>> bogus crc errors when using winedbg.
>>
> first, it's not exactly what your patch is entirely about... your
> patch ensures that the newly .gnu_debuglink mapped file is present for
> symbols resolution... and the bogus CRC errors come from the fact that
> we have an ERR for that, were it should be a WARN... a user could have
> different versions of the debug info files
> secondly, the correct fix will require a rewrite of the mapping
> algorithm itself, which is rather orthogonal to what you did
> my reco would simply to downgrade the ERR to a WARN if you don't want
> to go into the full fix
> A+
>
Rob, Peter
as you both were looking for solution to public symbols hashing in
.gnu_link files, the attached patches should fix it
could you test them to ensure that they really fix it ?
(order to apply patches: 1/ dbghelp-elf-map, 2/ dbghelp-elf-alternate,
3/ dbghelp-elf-link-alternate)
A+
-------------- next part --------------
[DbgHelp]: allowed to add an alternate file_map for an ELF file (where to
From: Eric Pouech <eric.pouech at wanadoo.fr>
look for its debug information)
---
dlls/dbghelp/elf_module.c | 37 ++++++++++++++++++++++++-------------
1 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index b0cc90c..41a37f9 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -115,6 +115,7 @@ struct elf_file_map
unsigned with_crc;
unsigned long crc;
const char* shstrtab;
+ struct elf_file_map* alternate; /* another ELF file (linked to this one) */
};
struct elf_section_map
@@ -167,6 +168,7 @@ static const char* elf_map_section(struc
* elf_find_section
*
* Finds a section by name (and type) into memory from an ELF file
+ * or its alternate if any
*/
static BOOL elf_find_section(struct elf_file_map* fmap, const char* name,
unsigned sht, struct elf_section_map* esm)
@@ -179,15 +181,19 @@ static BOOL elf_find_section(struct elf_
fmap->shstrtab = elf_map_section(&hdr_esm);
if (fmap->shstrtab == ELF_NO_MAP) return FALSE;
}
- for (i = 0; i < fmap->elfhdr.e_shnum; i++)
+ while (fmap)
{
- if (strcmp(fmap->shstrtab + fmap->sect[i].shdr.sh_name, name) == 0 &&
- (sht == SHT_NULL || sht == fmap->sect[i].shdr.sh_type))
+ for (i = 0; i < fmap->elfhdr.e_shnum; i++)
{
- esm->fmap = fmap;
- esm->sidx = i;
- return TRUE;
+ 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;
+ }
}
+ fmap = fmap->alternate;
}
return FALSE;
}
@@ -257,6 +263,7 @@ static BOOL elf_map_file(const WCHAR* fi
fmap->fd = -1;
fmap->with_crc = 0;
fmap->shstrtab = ELF_NO_MAP;
+ fmap->alternate = NULL;
/* 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;
@@ -312,16 +319,20 @@ done:
*/
static void elf_unmap_file(struct elf_file_map* fmap)
{
- if (fmap->fd != -1)
+ while (fmap)
{
- struct elf_section_map esm;
- esm.fmap = fmap;
- for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
+ if (fmap->fd != -1)
{
- elf_unmap_section(&esm);
+ struct elf_section_map esm;
+ esm.fmap = fmap;
+ for (esm.sidx = 0; esm.sidx < fmap->elfhdr.e_shnum; esm.sidx++)
+ {
+ elf_unmap_section(&esm);
+ }
+ HeapFree(GetProcessHeap(), 0, fmap->sect);
+ close(fmap->fd);
}
- HeapFree(GetProcessHeap(), 0, fmap->sect);
- close(fmap->fd);
+ fmap = fmap->alternate;
}
}
-------------- next part --------------
[DbgHelp]: now handling the .gnu_debuglink files with the newly added
From: Eric Pouech <eric.pouech at wanadoo.fr>
alternate mechanism
---
dlls/dbghelp/elf_module.c | 118 +++++++++++++++++++--------------------------
1 files changed, 51 insertions(+), 67 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 41a37f9..4c5e53a 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -112,8 +112,6 @@ struct elf_file_map
const char* mapped;
}* sect;
int fd;
- unsigned with_crc;
- unsigned long crc;
const char* shstrtab;
struct elf_file_map* alternate; /* another ELF file (linked to this one) */
};
@@ -261,7 +259,6 @@ static BOOL elf_map_file(const WCHAR* fi
WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, filename, len, NULL, NULL);
fmap->fd = -1;
- fmap->with_crc = 0;
fmap->shstrtab = ELF_NO_MAP;
fmap->alternate = NULL;
@@ -851,10 +848,18 @@ #define UPDC32(octet,crc) (crc_32_tab[((
#undef UPDC32
}
-static BOOL elf_load_debug_info_from_map(struct module* module,
- struct elf_file_map* fmap,
- struct pool* pool,
- struct hash_table* ht_symtab);
+static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, DWORD crc)
+{
+ BOOL ret;
+ if (!elf_map_file(file, fmap)) return FALSE;
+ if (!(ret = crc == calc_crc32(fmap)))
+ {
+ WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
+ debugstr_w(file), calc_crc32(fmap), crc);
+ elf_unmap_file(fmap);
+ }
+ return ret;
+}
/******************************************************************
* elf_locate_debug_link
@@ -875,20 +880,24 @@ static BOOL elf_load_debug_info_from_map
* is the global debug file directory, and execdir has been turned
* into a relative path)." (from GDB manual)
*/
-static WCHAR* elf_locate_debug_link(const char* filename, const WCHAR* loaded_file,
- struct elf_file_map* fmap_link)
+static BOOL elf_locate_debug_link(struct elf_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','/'};
static const WCHAR dotDebugW[] = {'.','d','e','b','u','g','/'};
const size_t globalDebugDirLen = sizeof(globalDebugDirW) / sizeof(WCHAR);
size_t filename_len;
- WCHAR* p;
+ WCHAR* p = NULL;
WCHAR* slash;
+ struct elf_file_map* fmap_link = NULL;
+
+ fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
+ if (!fmap_link) return FALSE;
filename_len = MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, NULL, 0);
p = HeapAlloc(GetProcessHeap(), 0,
(globalDebugDirLen + strlenW(loaded_file) + 6 + 1 + filename_len + 1) * sizeof(WCHAR));
- if (!p) return FALSE;
+ if (!p) goto found;
/* we prebuild the string with "execdir" */
strcpyW(p, loaded_file);
@@ -897,33 +906,34 @@ static WCHAR* elf_locate_debug_link(cons
/* testing execdir/filename */
MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
- if (elf_map_file(p, fmap_link)) goto found;
-
- HeapValidate(GetProcessHeap(), 0, 0);
+ if (elf_check_debug_link(p, fmap_link, crc)) goto found;
/* testing execdir/.debug/filename */
memcpy(slash, dotDebugW, sizeof(dotDebugW));
MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + sizeof(dotDebugW) / sizeof(WCHAR), filename_len);
- if (elf_map_file(p, fmap_link)) goto found;
+ if (elf_check_debug_link(p, fmap_link, crc)) goto found;
/* testing globaldebugdir/execdir/filename */
memmove(p + globalDebugDirLen, p, (slash - p) * sizeof(WCHAR));
memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR));
slash += globalDebugDirLen;
MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len);
- if (elf_map_file(p, fmap_link)) goto found;
+ if (elf_check_debug_link(p, fmap_link, crc)) goto found;
/* finally testing filename */
- if (elf_map_file(slash, fmap_link)) goto found;
+ if (elf_check_debug_link(slash, fmap_link, crc)) goto found;
- HeapFree(GetProcessHeap(), 0, p);
WARN("Couldn't locate or map %s\n", filename);
- return NULL;
+ HeapFree(GetProcessHeap(), 0, p);
+ HeapFree(GetProcessHeap(), 0, fmap_link);
+ return FALSE;
found:
TRACE("Located debug information file %s at %s\n", filename, debugstr_w(p));
- return p;
+ HeapFree(GetProcessHeap(), 0, p);
+ fmap->alternate = fmap_link;
+ return TRUE;
}
/******************************************************************
@@ -932,10 +942,8 @@ found:
* Parses a .gnu_debuglink section and loads the debug info from
* the external file specified there.
*/
-static BOOL elf_debuglink_parse (struct module* module,
- struct pool* pool,
- struct hash_table* ht_symtab,
- const BYTE* debuglink)
+static BOOL elf_debuglink_parse(struct elf_file_map* fmap, struct module* module,
+ const BYTE* debuglink)
{
/* The content of a debug link section is:
* 1/ a NULL terminated string, containing the file name for the
@@ -943,28 +951,11 @@ static BOOL elf_debuglink_parse (struct
* 2/ padding on 4 byte boundary
* 3/ CRC of the linked ELF file
*/
- BOOL ret = FALSE;
const char* dbg_link = (char*)debuglink;
- struct elf_file_map fmap_link;
- WCHAR* link_file;
+ DWORD crc;
- link_file = elf_locate_debug_link(dbg_link, module->module.LoadedImageName, &fmap_link);
-
- if (link_file)
- {
- fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
- fmap_link.with_crc = 1;
- ret = elf_load_debug_info_from_map(module, &fmap_link, pool,
- ht_symtab);
- if (ret)
- strcpyW(module->module.LoadedPdbName,link_file);
- else
- WARN("Couldn't load debug information from %s\n", debugstr_w(link_file));
- elf_unmap_file(&fmap_link);
- HeapFree(GetProcessHeap(), 0, link_file);
- }
-
- return ret;
+ crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
+ return elf_locate_debug_link(fmap, dbg_link, module->module.LoadedImageName, crc);
}
/******************************************************************
@@ -997,14 +988,6 @@ static BOOL elf_load_debug_info_from_map
{NULL, 0, 0, 0}
};
- if (fmap->with_crc && (fmap->crc != calc_crc32(fmap)))
- {
- ERR("Bad CRC for module %s (got %08x while expecting %08lx)\n",
- debugstr_w(module->module.LoadedImageName), calc_crc32(fmap), fmap->crc);
- /* we don't tolerate mis-matched files */
- return FALSE;
- }
-
module->module.SymType = SymExport;
/* create a hash table for the symtab */
@@ -1017,6 +1000,22 @@ static BOOL elf_load_debug_info_from_map
debug_line_sect, debug_loclist_sect;
struct elf_section_map debuglink_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);
+ if (dbg_link != ELF_NO_MAP)
+ {
+ lret = elf_debuglink_parse(fmap, module, dbg_link);
+ if (!lret)
+ WARN("Couldn't load linked debug file for %s\n",
+ debugstr_w(module->module.ModuleName));
+ ret = ret || lret;
+ }
+ elf_unmap_section(&debuglink_sect);
+ }
if (elf_find_section(fmap, ".stab", SHT_NULL, &stab_sect) &&
elf_find_section(fmap, ".stabstr", SHT_NULL, &stabstr_sect))
{
@@ -1083,21 +1082,6 @@ static BOOL elf_load_debug_info_from_map
elf_unmap_section(&debug_line_sect);
elf_unmap_section(&debug_loclist_sect);
}
- if (elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
- {
- const BYTE* dbg_link;
-
- dbg_link = (const BYTE*)elf_map_section(&debuglink_sect);
- if (dbg_link != ELF_NO_MAP)
- {
- lret = elf_debuglink_parse(module, pool, ht_symtab, dbg_link);
- if (!lret)
- WARN("Couldn't load linked debug file for %s\n",
- debugstr_w(module->module.ModuleName));
- ret = ret || lret;
- }
- elf_unmap_section(&debuglink_sect);
- }
}
if (strstrW(module->module.ModuleName, S_ElfW) ||
!strcmpW(module->module.ModuleName, S_WineLoaderW))
-------------- next part --------------
[DbgHelp]: rewrote the ELF section mapper for better data encapsulation
From: Eric Pouech <eric.pouech at wanadoo.fr>
---
dlls/dbghelp/elf_module.c | 273 +++++++++++++++++++++++----------------------
1 files changed, 137 insertions(+), 136 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 7758199..b0cc90c 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -114,6 +114,13 @@ struct elf_file_map
int fd;
unsigned with_crc;
unsigned long crc;
+ const char* shstrtab;
+};
+
+struct elf_section_map
+{
+ struct elf_file_map* fmap;
+ unsigned sidx;
};
struct symtab_elt
@@ -137,21 +144,52 @@ struct elf_thunk_area
*
* 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 ofst, size;
- if (sidx < 0 || sidx >= fmap->elfhdr.e_shnum ||
- fmap->sect[sidx].shdr.sh_type == SHT_NOBITS)
+ if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum ||
+ esm->fmap->sect[esm->sidx].shdr.sh_type == SHT_NOBITS)
return ELF_NO_MAP;
+
/* align required information on page size (we assume pagesize is a power of 2) */
- ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
- size = ((fmap->sect[sidx].shdr.sh_offset +
- fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
- fmap->sect[sidx].mapped = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fmap->fd, ofst);
- if (fmap->sect[sidx].mapped == ELF_NO_MAP) return ELF_NO_MAP;
- return fmap->sect[sidx].mapped + (fmap->sect[sidx].shdr.sh_offset & (pgsz - 1));
+ 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 == 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(struc
*
* 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 ofst, size;
- ofst = fmap->sect[sidx].shdr.sh_offset & ~(pgsz - 1);
- size = ((fmap->sect[sidx].shdr.sh_offset +
- fmap->sect[sidx].shdr.sh_size + pgsz - 1) & ~(pgsz - 1)) - ofst;
- if (munmap((char*)fmap->sect[sidx].mapped, size) < 0)
+ 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)
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
*
* 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 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* fi
fmap->fd = -1;
fmap->with_crc = 0;
+ fmap->shstrtab = ELF_NO_MAP;
/* 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;
@@ -266,10 +314,11 @@ static void elf_unmap_file(struct elf_fi
{
if (fmap->fd != -1)
{
- int i;
- for (i = 0; i < fmap->elfhdr.e_shnum; i++)
+ struct elf_section_map esm;
+ 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);
close(fmap->fd);
@@ -302,7 +351,7 @@ int elf_is_in_thunk_area(unsigned long a
*/
static void elf_hash_symtab(struct module* module, struct pool* pool,
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;
const char* strp;
@@ -311,12 +360,16 @@ static void elf_hash_symtab(struct modul
const char* ptr;
const Elf32_Sym* symp;
struct symtab_elt* ste;
+ struct elf_section_map esm, esm_str;
- symp = (const Elf32_Sym*)elf_map_section(fmap, symtab_idx);
- strp = elf_map_section(fmap, fmap->sect[symtab_idx].shdr.sh_link);
- if (symp == ELF_NO_MAP || strp == ELF_NO_MAP) return;
+ if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &esm) &&
+ !elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &esm)) 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++)
thunks[j].rva_start = thunks[j].rva_end = 0;
@@ -922,12 +975,6 @@ static BOOL elf_load_debug_info_from_map
struct hash_table* ht_symtab)
{
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[] =
{
{"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
@@ -947,77 +994,32 @@ static BOOL elf_load_debug_info_from_map
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;
/* 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 (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* stabstr;
- stab = elf_map_section(fmap, stab_sect);
- stabstr = elf_map_section(fmap, stabstr_sect);
+ stab = elf_map_section(&stab_sect);
+ stabstr = elf_map_section(&stabstr_sect);
if (stab != ELF_NO_MAP && stabstr != ELF_NO_MAP)
{
/* OK, now just parse all of the stabs. */
lret = stabs_parse(module, module->elf_info->elf_addr,
- stab, elf_get_map_size(fmap, stab_sect),
- stabstr, elf_get_map_size(fmap, stabstr_sect));
+ stab, elf_get_map_size(&stab_sect),
+ stabstr, elf_get_map_size(&stabstr_sect));
if (lret)
/* and fill in the missing information for stabs */
elf_finish_stabs_info(module, ht_symtab);
@@ -1026,11 +1028,10 @@ static BOOL elf_load_debug_info_from_map
ret = ret || lret;
}
else lret = FALSE;
- elf_unmap_section(fmap, stab_sect);
- elf_unmap_section(fmap, stabstr_sect);
-
+ elf_unmap_section(&stab_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 */
const BYTE* dw2_debug;
@@ -1041,36 +1042,41 @@ static BOOL elf_load_debug_info_from_map
TRACE("Loading Dwarf2 information for %s\n", module->module_name);
- dw2_debug = (const BYTE*) elf_map_section(fmap, debug_sect);
- dw2_debug_abbrev = (const BYTE*) elf_map_section(fmap, debug_abbrev_sect);
- dw2_debug_str = (const BYTE*) elf_map_section(fmap, debug_str_sect);
- dw2_debug_line = (const BYTE*) elf_map_section(fmap, debug_line_sect);
- dw2_debug_loclist = (const BYTE*) elf_map_section(fmap, debug_loclist_sect);
+ elf_find_section(fmap, ".debug_str", SHT_NULL, &debug_str_sect);
+ elf_find_section(fmap, ".debug_abbrev", SHT_NULL, &debug_abbrev_sect);
+ 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);
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. */
lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks,
- dw2_debug, elf_get_map_size(fmap, debug_sect),
- dw2_debug_abbrev, elf_get_map_size(fmap, debug_abbrev_sect),
- dw2_debug_str, elf_get_map_size(fmap, debug_str_sect),
- dw2_debug_line, elf_get_map_size(fmap, debug_line_sect),
- dw2_debug_loclist, elf_get_map_size(fmap, debug_loclist_sect));
+ 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));
if (!lret)
WARN("Couldn't correctly read stabs\n");
ret = ret || lret;
}
- elf_unmap_section(fmap, debug_sect);
- elf_unmap_section(fmap, debug_abbrev_sect);
- elf_unmap_section(fmap, debug_str_sect);
- elf_unmap_section(fmap, debug_line_sect);
- elf_unmap_section(fmap, debug_loclist_sect);
+ 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);
}
- if (debuglink_sect != -1)
+ if (elf_find_section(fmap, ".gnu_debuglink", SHT_NULL, &debuglink_sect))
{
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)
{
lret = elf_debuglink_parse(module, pool, ht_symtab, dbg_link);
@@ -1079,7 +1085,7 @@ static BOOL elf_load_debug_info_from_map
debugstr_w(module->module.ModuleName));
ret = ret || lret;
}
- elf_unmap_section(fmap, debuglink_sect);
+ elf_unmap_section(&debuglink_sect);
}
}
if (strstrW(module->module.ModuleName, S_ElfW) ||
@@ -1163,7 +1169,6 @@ static BOOL elf_load_file(struct process
{
BOOL ret = FALSE;
struct elf_file_map fmap;
- int i;
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
@@ -1185,33 +1190,29 @@ static BOOL elf_load_file(struct process
if (elf_info->flags & ELF_INFO_DEBUG_HEADER)
{
- const char* shstrtab = elf_map_section(&fmap, fmap.elfhdr.e_shstrndx);
- if (shstrtab == ELF_NO_MAP) goto leave;
- for (i = 0; i < fmap.elfhdr.e_shnum; i++)
+ struct elf_section_map esm;
+
+ if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
{
- 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;
+ Elf32_Dyn dyn;
+ char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
+ unsigned long len;
- do
+ 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) ||
- len != sizeof(dyn))
- goto leave;
- if (dyn.d_tag == DT_DEBUG)
- {
- elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
- break;
- }
- ptr += sizeof(dyn);
- } while (dyn.d_tag != DT_NULL);
- if (dyn.d_tag == DT_NULL) goto leave;
- }
+ elf_info->dbg_hdr_addr = dyn.d_un.d_ptr;
+ 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)
-------------- next part --------------
# This series applies on GIT commit a52c2c0dfe3deaa872fe10c751447844e73dcdef
dbghelp-elf-map
dbghelp-elf-alternate
dbghelp-elf-link-alternate
More information about the wine-devel
mailing list