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