Andreas Maier : dbghelp: SymFromAddr: Handle 2 or more symbols at the same address correct.

Alexandre Julliard julliard at winehq.org
Mon Nov 26 16:20:10 CST 2018


Module: wine
Branch: master
Commit: d614ac46718311f49541b32ac726c17a06077ae1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d614ac46718311f49541b32ac726c17a06077ae1

Author: Andreas Maier <staubim at quantentunnel.de>
Date:   Sun Nov 25 10:15:50 2018 +0100

dbghelp: SymFromAddr: Handle 2 or more symbols at the same address correct.

Signed-off-by: Andreas Maier <staubim at quantentunnel.de>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/symbol.c | 54 +++++++++++++++++++++++++++++++++------------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 05aea05..c9585c5 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -850,6 +850,33 @@ static void symt_get_length(struct module* module, const struct symt* symt, ULON
     *size = 0x1000; /* arbitrary value */
 }
 
+/* neede by symt_find_nearest */
+int symt_get_best_at(struct module* module, int idx_sorttab)
+{
+    ULONG64 ref_addr;
+    int idx_sorttab_orig = idx_sorttab;
+    if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
+    {
+        symt_get_address(&module->addr_sorttab[idx_sorttab]->symt, &ref_addr);
+        while (idx_sorttab > 0 &&
+               module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
+               !cmp_sorttab_addr(module, idx_sorttab - 1, ref_addr))
+            idx_sorttab--;
+        if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
+        {
+            idx_sorttab = idx_sorttab_orig;
+            while (idx_sorttab < module->num_sorttab - 1 &&
+                   module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol &&
+                   !cmp_sorttab_addr(module, idx_sorttab + 1, ref_addr))
+                idx_sorttab++;
+        }
+        /* if no better symbol fond restore original */
+        if (module->addr_sorttab[idx_sorttab]->symt.tag == SymTagPublicSymbol)
+            idx_sorttab = idx_sorttab_orig;
+    }
+    return idx_sorttab;
+}
+
 /* assume addr is in module */
 struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
 {
@@ -868,7 +895,12 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
     high = module->num_sorttab;
 
     symt_get_address(&module->addr_sorttab[0]->symt, &ref_addr);
-    if (addr < ref_addr) return NULL;
+    if (addr <= ref_addr)
+    {
+        low = symt_get_best_at(module, 0);
+        return module->addr_sorttab[low];
+    }
+
     if (high)
     {
         symt_get_address(&module->addr_sorttab[high - 1]->symt, &ref_addr);
@@ -891,23 +923,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD_PTR addr)
     /* If found symbol is a public symbol, check if there are any other entries that
      * might also have the same address, but would get better information
      */
-    if (module->addr_sorttab[low]->symt.tag == SymTagPublicSymbol)
-    {
-        symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr);
-        if (low > 0 &&
-            module->addr_sorttab[low - 1]->symt.tag != SymTagPublicSymbol &&
-            !cmp_sorttab_addr(module, low - 1, ref_addr))
-            low--;
-        else if (low < module->num_sorttab - 1 &&
-                 module->addr_sorttab[low + 1]->symt.tag != SymTagPublicSymbol &&
-                 !cmp_sorttab_addr(module, low + 1, ref_addr))
-            low++;
-    }
-    /* finally check that we fit into the found symbol */
-    symt_get_address(&module->addr_sorttab[low]->symt, &ref_addr);
-    if (addr < ref_addr) return NULL;
-    symt_get_length(module, &module->addr_sorttab[low]->symt, &ref_size);
-    if (addr >= ref_addr + ref_size) return NULL;
+    low = symt_get_best_at(module, low);
 
     return module->addr_sorttab[low];
 }
@@ -1236,7 +1252,7 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address,
 
     symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol);
     if (Displacement)
-        *Displacement = Address - Symbol->Address;
+        *Displacement = (Address >= Symbol->Address) ? (Address - Symbol->Address) : (DWORD64)-1;
     return TRUE;
 }
 




More information about the wine-cvs mailing list