Module: wine Branch: master Commit: 39a347945da91ec16848c31aaf4276f06e763c17 URL: http://source.winehq.org/git/wine.git/?a=commit;h=39a347945da91ec16848c31aaf...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Mar 16 18:35:17 2014 +0400
winedump: Output parameters and default values type for methods.
---
tools/winedump/tlb.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 184 insertions(+), 6 deletions(-)
diff --git a/tools/winedump/tlb.c b/tools/winedump/tlb.c index bcaa859..26da2a4 100644 --- a/tools/winedump/tlb.c +++ b/tools/winedump/tlb.c @@ -44,6 +44,61 @@ enum TYPEKIND { TKIND_MAX };
+enum VARENUM { + VT_EMPTY = 0, + VT_NULL = 1, + VT_I2 = 2, + VT_I4 = 3, + VT_R4 = 4, + VT_R8 = 5, + VT_CY = 6, + VT_DATE = 7, + VT_BSTR = 8, + VT_DISPATCH = 9, + VT_ERROR = 10, + VT_BOOL = 11, + VT_VARIANT = 12, + VT_UNKNOWN = 13, + VT_DECIMAL = 14, + VT_I1 = 16, + VT_UI1 = 17, + VT_UI2 = 18, + VT_UI4 = 19, + VT_I8 = 20, + VT_UI8 = 21, + VT_INT = 22, + VT_UINT = 23, + VT_VOID = 24, + VT_HRESULT = 25, + VT_PTR = 26, + VT_SAFEARRAY = 27, + VT_CARRAY = 28, + VT_USERDEFINED = 29, + VT_LPSTR = 30, + VT_LPWSTR = 31, + VT_RECORD = 36, + VT_INT_PTR = 37, + VT_UINT_PTR = 38, + VT_FILETIME = 64, + VT_BLOB = 65, + VT_STREAM = 66, + VT_STORAGE = 67, + VT_STREAMED_OBJECT = 68, + VT_STORED_OBJECT = 69, + VT_BLOB_OBJECT = 70, + VT_CF = 71, + VT_CLSID = 72, + VT_VERSIONED_STREAM = 73, + VT_BSTR_BLOB = 0xfff, + VT_VECTOR = 0x1000, + VT_ARRAY = 0x2000, + VT_BYREF = 0x4000, + VT_RESERVED = 0x8000, + VT_ILLEGAL = 0xffff, + VT_ILLEGALMASKED = 0xfff, + VT_TYPEMASK = 0xfff +}; + struct seg_t;
typedef BOOL (*dump_seg_t)(struct seg_t*); @@ -54,6 +109,25 @@ typedef struct seg_t { int offset; int length; } seg_t; +static seg_t segdir[]; + +enum SEGDIRTYPE { + SEGDIR_TYPEINFO, + SEGDIR_IMPINFO, + SEGDIR_IMPFILES, + SEGDIR_REF, + SEGDIR_GUIDHASH, + SEGDIR_GUID, + SEGDIR_NAMEHASH, + SEGDIR_NAME, + SEGDIR_STRING, + SEGDIR_TYPEDESC, + SEGDIR_ARRAYDESC, + SEGDIR_CUSTDATA, + SEGDIR_CDGUID, + SEGDIR_res0e, + SEGDIR_res0f +};
static int offset=0; static int indent; @@ -172,6 +246,25 @@ static void print_guid(const char *name) guid.Data4[5], guid.Data4[6], guid.Data4[7]); }
+static void print_vartype(int vartype) +{ + static const char *vartypes[VT_LPWSTR+1] = { + "VT_EMPTY", "VT_NULL", "VT_I2", "VT_I4", "VT_R4", + "VT_R8", "VT_CY", "VT_DATE", "VT_BSTR", "VT_DISPATCH", + "VT_ERROR", "VT_BOOL", "VT_VARIANT", "VT_UNKNOWN","VT_DECIMAL", + "unk 15", "VT_I1", "VT_UI1", "VT_UI2", "VT_UI4", + "VT_I8", "VT_UI8", "VT_INT", "VT_UINT", "VT_VOID", + "VT_HRESULT", "VT_PTR", "VT_SAFEARRAY","VT_CARRAY", "VT_USERDEFINED", + "VT_LPSTR", "VT_LPWSTR" + }; + + vartype &= VT_TYPEMASK; + if (vartype >= VT_EMPTY && vartype <= VT_LPWSTR) + printf("%s\n", vartypes[vartype]); + else + printf("unk %d\n", vartype); +} + static void print_ctl2(const char *name) { int len; @@ -266,11 +359,27 @@ static void dump_msft_header(void) print_end_block(); }
+static int dump_msft_typekind(void) +{ + static const char *tkind[TKIND_MAX] = { + "TKIND_ENUM", "TKIND_RECORD", "TKIND_MODULE", + "TKIND_INTERFACE", "TKIND_DISPATCH", "TKIND_COCLASS", + "TKIND_ALIAS", "TKIND_UNION" + }; + int ret, typekind; + + print_offset(); + ret = tlb_read_int(); + typekind = ret & 0xf; + printf("typekind = %s, align = %d\n", typekind < TKIND_MAX ? tkind[typekind] : "unknown", (ret >> 11) & 0x1f); + return ret; +} + static void dump_msft_typeinfobase(void) { print_begin_block_id("TypeInfoBase", msft_typeinfo_cnt);
- msft_typeinfo_kind[msft_typeinfo_cnt] = print_hex("typekind"); + msft_typeinfo_kind[msft_typeinfo_cnt] = dump_msft_typekind(); msft_typeinfo_offs[msft_typeinfo_cnt] = print_hex("memoffset"); print_hex("res2"); print_hex("res3"); @@ -531,7 +640,7 @@ static BOOL dump_msft_custdata(seg_t *seg) n = tlb_read_int();
switch(vt) { - case 8 /* VT_BSTR */: + case VT_BSTR: printf(" len %d: ", n); dump_string(n, 2); printf("\n"); @@ -586,6 +695,75 @@ static BOOL dump_msft_res0f(seg_t *seg) return TRUE; }
+/* Used for function return value and arguments type */ +static void dump_msft_datatype(const char *name) +{ + int datatype; + + print_offset(); + datatype = tlb_read_int(); + printf("%s = %08x", name, datatype); + if (datatype < 0) { + printf(", "); + print_vartype(datatype); + } + else { + const short *vt; + + if (datatype > segdir[SEGDIR_TYPEDESC].length) { + printf(", invalid offset\n"); + return; + } + + /* FIXME: in case of VT_USERDEFINED use hreftype */ + vt = PRD(segdir[SEGDIR_TYPEDESC].offset + datatype, 4*sizeof(short)); + datatype = vt[0] & VT_TYPEMASK; + if (datatype == VT_PTR) { + printf(", VT_PTR -> "); + if (vt[3] < 0) + datatype = vt[2]; + else { + vt = PRD(segdir[SEGDIR_TYPEDESC].offset + vt[2], 4*sizeof(short)); + datatype = *vt; + } + } + else { + printf(", "); + datatype = *vt; + } + + print_vartype(datatype); + } +} + +static void dump_defaultvalue(int id) +{ + int offset; + + print_offset(); + offset = tlb_read_int(); + + printf("default value[%d] = %08x", id, offset); + if (offset == -1) + printf("\n"); + else if (offset < 0) { + printf(", "); + print_vartype((offset & 0x7c000000) >> 26); + } + else { + const unsigned short *vt; + + if (offset > segdir[SEGDIR_CUSTDATA].length) { + printf(", invalid offset\n"); + return; + } + + vt = PRD(segdir[SEGDIR_CUSTDATA].offset + offset, sizeof(*vt)); + printf(", "); + print_vartype(*vt); + } +} + static void dump_msft_func(int n) { int size, args_cnt, i, extra_attr, fkccic; @@ -594,7 +772,7 @@ static void dump_msft_func(int n)
size = print_short_hex("size"); print_short_hex("index"); - print_hex("DataType"); + dump_msft_datatype("retval type"); print_hex("flags"); print_short_hex("VtableOffset"); print_short_hex("funcdescsize"); @@ -623,16 +801,16 @@ static void dump_msft_func(int n)
if(fkccic & 0x1000) { for(i=0; i < args_cnt; i++) - print_hex_id("default value[%d]", i); + dump_defaultvalue(i); }
for(i=0; i < args_cnt; i++) { print_begin_block_id("param", i);
/* FIXME: Handle default values */ - print_hex("data[0]"); + dump_msft_datatype("datatype"); + print_hex("name"); print_hex("paramflags"); - print_hex("data[2]");
print_end_block(); }