Eric Pouech : winedump: Add support for S_DEFRANGE* family of CodeView records.

Alexandre Julliard julliard at winehq.org
Tue Aug 24 15:56:11 CDT 2021


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

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Tue Aug 24 11:11:37 2021 +0200

winedump: Add support for S_DEFRANGE* family of CodeView records.

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/wine/mscvpdb.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/winedump/msc.c   | 52 +++++++++++++++++++++++++++++++
 2 files changed, 135 insertions(+)

diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index 4d4b8166473..ca3f120a5d6 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -1245,6 +1245,19 @@ union codeview_fieldtype
  *            Symbol information
  * ======================================== */
 
+struct cv_addr_range
+{
+    unsigned int                offStart;
+    unsigned short              isectStart;
+    unsigned short              cbRange;
+};
+
+struct cv_addr_gap
+{
+    unsigned short              gapStartOffset;
+    unsigned short              cbRange;
+};
+
 union codeview_symbol
 {
     struct
@@ -1736,6 +1749,76 @@ union codeview_symbol
         unsigned short          varflags;
         char                    name[1];
     } local_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned int            program;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned int            program;
+        unsigned int            offParent;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_subfield_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned short          reg;
+        unsigned short          attr;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_register_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned int            offFramePointer;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_frameptrrel_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned int            offFramePointer;
+    } defrange_frameptr_relfullscope_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned short          reg;
+        unsigned short          attr;
+        unsigned int            offParent : 12;
+        unsigned int            padding   : 20;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_subfield_register_v3;
+
+    struct
+    {
+        unsigned short int      len;
+        unsigned short int      id;
+        unsigned short          baseReg;
+        unsigned short          spilledUdtMember : 1;
+        unsigned short          padding          : 3;
+        unsigned short          offsetParent     : 12;
+        unsigned int            offBasePointer;
+        struct cv_addr_range    range;
+        struct cv_addr_gap      gaps[0];
+    } defrange_registerrel_v3;
 };
 
 #define S_COMPILE       0x0001
diff --git a/tools/winedump/msc.c b/tools/winedump/msc.c
index 6d463c0ee1b..20471bd23bc 100644
--- a/tools/winedump/msc.c
+++ b/tools/winedump/msc.c
@@ -1136,6 +1136,21 @@ BOOL codeview_dump_types_from_block(const void* table, unsigned long len)
     return TRUE;
 }
 
+static void dump_defrange(const struct cv_addr_range* range, const void* last, const char* pfx)
+{
+    const struct cv_addr_gap* gap;
+
+    printf("%s%04x:%08x range:#%x\n", pfx, range->isectStart, range->offStart, range->cbRange);
+    for (gap = (const struct cv_addr_gap*)(range + 1); (const void*)(gap + 1) <= last; ++gap)
+        printf("%s\toffset:%x range:#%x\n", pfx, gap->gapStartOffset, gap->cbRange);
+}
+
+/* return adress of first byte after the symbol */
+static inline const char* get_last(const union codeview_symbol* sym)
+{
+    return (const char*)sym + sym->generic.len + 2;
+}
+
 BOOL codeview_dump_symbols(const void* root, unsigned long size)
 {
     unsigned int i;
@@ -1598,6 +1613,43 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
 
             break;
 
+        case S_DEFRANGE:
+            printf("\tS-DefRange dia:%x\n", sym->defrange_v3.program);
+            dump_defrange(&sym->defrange_v3.range, get_last(sym), "\t\t");
+            break;
+        case S_DEFRANGE_SUBFIELD:
+            printf("\tS-DefRange-subfield V3 dia:%x off-parent:%x\n",
+                   sym->defrange_subfield_v3.program, sym->defrange_subfield_v3.offParent);
+            dump_defrange(&sym->defrange_subfield_v3.range, get_last(sym), "\t\t");
+            break;
+        case S_DEFRANGE_REGISTER:
+            printf("\tS-DefRange-register V3 reg:%x attr-unk:%x\n",
+                   sym->defrange_register_v3.reg, sym->defrange_register_v3.attr);
+            dump_defrange(&sym->defrange_register_v3.range, get_last(sym), "\t\t");
+            break;
+        case S_DEFRANGE_FRAMEPOINTER_REL:
+            printf("\tS-DefRange-framepointer-rel V3 offFP:%x\n",
+                   sym->defrange_frameptrrel_v3.offFramePointer);
+            dump_defrange(&sym->defrange_frameptrrel_v3.range, get_last(sym), "\t\t");
+            break;
+        case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
+            printf("\tS-DefRange-framepointer-rel-fullscope V3 offFP:%x\n",
+                   sym->defrange_frameptr_relfullscope_v3.offFramePointer);
+            break;
+        case S_DEFRANGE_SUBFIELD_REGISTER:
+            printf("\tS-DefRange-subfield-register V3 reg:%d attr-unk:%x off-parent:%x\n",
+                   sym->defrange_subfield_register_v3.reg,
+                   sym->defrange_subfield_register_v3.attr,
+                   sym->defrange_subfield_register_v3.offParent);
+            dump_defrange(&sym->defrange_subfield_register_v3.range, get_last(sym), "\t\t");
+            break;
+        case S_DEFRANGE_REGISTER_REL:
+            printf("\tS-DefRange-register-rel V3 reg:%x off-parent:%x off-BP:%x\n",
+                   sym->defrange_registerrel_v3.baseReg, sym->defrange_registerrel_v3.offsetParent,
+                   sym->defrange_registerrel_v3.offBasePointer);
+            dump_defrange(&sym->defrange_registerrel_v3.range, get_last(sym), "\t\t");
+            break;
+
         default:
             printf(">>> Unsupported symbol-id %x sz=%d\n", sym->generic.id, sym->generic.len + 2);
             dump_data((const void*)sym, sym->generic.len + 2, "  ");




More information about the wine-cvs mailing list