[RFC] msvcp120: Change exported vbtable sizes.

Bernhard Übelacker bernhardu at vr-web.de
Mon Jan 4 05:08:26 CST 2016


https://bugs.winehq.org/show_bug.cgi?id=39034

It looks like the descructor for the virtual base class is looked up
at the wrong offset.

This probably also would appear in msvcp110 as there the exported sizes
do also not match.

The test contains 2 tests:
 - Simply check the exports of the vbtable sizes for their values.
 - Call constructor and destructor like it is done in Supertux.

I tried to add these 8 bytes as an unknown field to basic_istream_*
and basic_ostream_* structs. But then I cannot find a way to get the
sizes for basic_iostream_* right.

Additional Questions:
 - Should I start by sending just the vbtable size test as todo_wine for
   the different msvcp versions?
 - Does someone know where this 8 byte shift comes from?
---
 dlls/msvcp120/tests/msvcp120.c | 334 +++++++++++++++++++++++++++++++++++++++++
 dlls/msvcp90/ios.c             |  20 ++-
 2 files changed, 347 insertions(+), 7 deletions(-)

diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 6ea024a..854d74f 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -24,6 +24,13 @@
 #include "wine/test.h"
 #include "winbase.h"
 
+#undef __thiscall
+#ifdef __i386__
+#define __thiscall __stdcall
+#else
+#define __thiscall __cdecl
+#endif
+
 static inline float __port_infinity(void)
 {
     static const unsigned __inf_bytes = 0x7f800000;
@@ -40,6 +47,22 @@ static inline float __port_nan(void)
 
 typedef int MSVCRT_long;
 typedef unsigned char MSVCP_bool;
+typedef SIZE_T MSVCP_size_t;
+typedef SSIZE_T streamoff;
+typedef SSIZE_T streamsize;
+
+typedef void (*vtable_ptr)(void);
+
+/* class mutex */
+typedef struct {
+        void *mutex;
+} mutex;
+
+/* class locale */
+typedef struct
+{
+    struct _locale__Locimp *ptr;
+} locale;
 
 /* xtime */
 typedef struct {
@@ -66,6 +89,132 @@ enum file_type {
     type_unknown
 };
 
+typedef enum {
+    FMTFLAG_skipws      = 0x0001,
+    FMTFLAG_unitbuf     = 0x0002,
+    FMTFLAG_uppercase   = 0x0004,
+    FMTFLAG_showbase    = 0x0008,
+    FMTFLAG_showpoint   = 0x0010,
+    FMTFLAG_showpos     = 0x0020,
+    FMTFLAG_left        = 0x0040,
+    FMTFLAG_right       = 0x0080,
+    FMTFLAG_internal    = 0x0100,
+    FMTFLAG_dec         = 0x0200,
+    FMTFLAG_oct         = 0x0400,
+    FMTFLAG_hex         = 0x0800,
+    FMTFLAG_scientific  = 0x1000,
+    FMTFLAG_fixed       = 0x2000,
+    FMTFLAG_hexfloat    = 0x3000,
+    FMTFLAG_boolalpha   = 0x4000,
+    FMTFLAG_stdio       = 0x8000,
+    FMTFLAG_adjustfield = FMTFLAG_left|FMTFLAG_right|FMTFLAG_internal,
+    FMTFLAG_basefield   = FMTFLAG_dec|FMTFLAG_oct|FMTFLAG_hex,
+    FMTFLAG_floatfield  = FMTFLAG_scientific|FMTFLAG_fixed,
+    FMTFLAG_mask        = 0xffff
+} IOSB_fmtflags;
+
+typedef enum {
+    IOSTATE_goodbit   = 0x00,
+    IOSTATE_eofbit    = 0x01,
+    IOSTATE_failbit   = 0x02,
+    IOSTATE_badbit    = 0x04,
+    IOSTATE__Hardfail = 0x10,
+    IOSTATE_mask      = 0x17
+} IOSB_iostate;
+
+/* class basic_streambuf<char> */
+typedef struct {
+    const vtable_ptr *vtable;
+    mutex lock;
+    char *rbuf;
+    char *wbuf;
+    char **prbuf;
+    char **pwbuf;
+    char *rpos;
+    char *wpos;
+    char **prpos;
+    char **pwpos;
+    int rsize;
+    int wsize;
+    int *prsize;
+    int *pwsize;
+    locale *loc;
+} basic_streambuf_char;
+
+typedef struct _iosarray {
+    struct _iosarray *next;
+    int index;
+    int long_val;
+    void *ptr_val;
+} IOS_BASE_iosarray;
+
+typedef enum {
+    EVENT_erase_event,
+    EVENT_imbue_event,
+    EVENT_copyfmt_event
+} IOS_BASE_event;
+
+struct _ios_base;
+typedef void (CDECL *IOS_BASE_event_callback)(IOS_BASE_event, struct _ios_base*, int);
+typedef struct _fnarray {
+    struct _fnarray *next;
+    int index;
+    IOS_BASE_event_callback event_handler;
+} IOS_BASE_fnarray;
+
+/* class ios_base */
+typedef struct _ios_base {
+    const vtable_ptr *vtable;
+    MSVCP_size_t stdstr;
+    IOSB_iostate state;
+    IOSB_iostate except;
+    IOSB_fmtflags fmtfl;
+    streamsize prec;
+    streamsize wide;
+    IOS_BASE_iosarray *arr;
+    IOS_BASE_fnarray *calls;
+    locale *loc;
+} ios_base;
+
+typedef struct {
+    ios_base base;
+    basic_streambuf_char *strbuf;
+    struct _basic_ostream_char *stream;
+    char fillch;
+} basic_ios_char;
+
+typedef struct _basic_ostream_char {
+    const int *vbtable;
+    /* virtual inheritance
+     * basic_ios_char basic_ios;
+     */
+} basic_ostream_char;
+
+typedef struct {
+    const int *vbtable;
+    streamsize count;
+#if _MSVCP_VER == 120
+    char unknown[8];
+#endif
+    /* virtual inheritance
+     * basic_ios_char basic_ios;
+     */
+} basic_istream_char;
+
+typedef struct {
+    basic_istream_char base1;
+    basic_ostream_char base2;
+    /* virtual inheritance
+     * basic_ios_char basic_ios;
+     */
+} basic_iostream_char;
+
+typedef struct {
+    streamoff off;
+    __int64 DECLSPEC_ALIGN(8) pos;
+    int state;
+} fpos_int;
+
 static BOOL compare_float(float f, float g, unsigned int ulps)
 {
     int x = *(int *)&f;
@@ -181,6 +330,98 @@ static int (__cdecl *p__Cnd_timedwait)(_Cnd_t*, _Mtx_t*, const xtime*);
 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t*);
 static int (__cdecl *p__Cnd_signal)(_Cnd_t*);
 
+/* supertux */
+static basic_streambuf_char* (*__thiscall p_basic_streambuf_char_ctor)(basic_streambuf_char*);
+static basic_istream_char* (*__thiscall p_basic_istream_char_ctor)(basic_istream_char*, basic_streambuf_char*, MSVCP_bool, MSVCP_bool);
+static void (*__thiscall p_basic_istream_char_dtor)(basic_ios_char*);
+static void (*__thiscall p_basic_ios_char_dtor)(basic_ios_char*);
+
+static const int *p_basic_iostream_char_vbtable1;
+static const int *p_basic_iostream_char_vbtable2;
+static const int *p_basic_iostream_wchar_vbtable1_1;
+static const int *p_basic_iostream_wchar_vbtable2_1;
+static const int *p_basic_iostream_wchar_vbtable1_2;
+static const int *p_basic_iostream_wchar_vbtable2_2;
+static const int *p_basic_istream_char_vbtable;
+static const int *p_basic_istream_short_vbtable;
+static const int *p_basic_istream_wchar_vbtable;
+static const int *p_basic_ostream_char_vbtable;
+static const int *p_basic_ostream_short_vbtable;
+static const int *p_basic_ostream_wchar_vbtable;
+
+/* Emulate a __thiscall */
+#ifdef __i386__
+
+#include "pshpack1.h"
+struct thiscall_thunk
+{
+    BYTE pop_eax;    /* popl  %eax (ret addr) */
+    BYTE pop_edx;    /* popl  %edx (func) */
+    BYTE pop_ecx;    /* popl  %ecx (this) */
+    BYTE push_eax;   /* pushl %eax */
+    WORD jmp_edx;    /* jmp  *%edx */
+};
+#include "poppack.h"
+
+static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
+static void * (WINAPI *call_thiscall_func2)( void *func, void *this, const void *a );
+static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void *a, const void *b );
+static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a, const void *b,
+        const void *c );
+static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a, const void *b,
+        const void *c, const void *d );
+
+/* to silence compiler errors */
+static void * (WINAPI *call_thiscall_func2_ptr_dbl)( void *func, void *this, double a );
+static void * (WINAPI *call_thiscall_func2_ptr_flt)( void *func, void *this, float a );
+static void * (WINAPI *call_thiscall_func2_ptr_fpos)( void *func, void *this, fpos_int a );
+
+static void init_thiscall_thunk(void)
+{
+    struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
+                                                 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+    thunk->pop_eax  = 0x58;   /* popl  %eax */
+    thunk->pop_edx  = 0x5a;   /* popl  %edx */
+    thunk->pop_ecx  = 0x59;   /* popl  %ecx */
+    thunk->push_eax = 0x50;   /* pushl %eax */
+    thunk->jmp_edx  = 0xe2ff; /* jmp  *%edx */
+    call_thiscall_func1 = (void *)thunk;
+    call_thiscall_func2 = (void *)thunk;
+    call_thiscall_func3 = (void *)thunk;
+    call_thiscall_func4 = (void *)thunk;
+    call_thiscall_func5 = (void *)thunk;
+
+    call_thiscall_func2_ptr_dbl  = (void *)thunk;
+    call_thiscall_func2_ptr_flt  = (void *)thunk;
+    call_thiscall_func2_ptr_fpos = (void *)thunk;
+}
+
+#define call_func1(func,_this) call_thiscall_func1(func,_this)
+#define call_func2(func,_this,a) call_thiscall_func2(func,_this,(const void*)(a))
+#define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(const void*)(a),(const void*)(b))
+#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),(const void*)(b), \
+        (const void*)(c))
+#define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),(const void*)(b), \
+        (const void*)(c), (const void *)(d))
+
+#define call_func2_ptr_dbl(func,_this,a)  call_thiscall_func2_ptr_dbl(func,_this,a)
+#define call_func2_ptr_flt(func,_this,a)  call_thiscall_func2_ptr_flt(func,_this,a)
+#define call_func2_ptr_fpos(func,_this,a) call_thiscall_func2_ptr_fpos(func,_this,a)
+
+#else
+
+#define init_thiscall_thunk()
+#define call_func1(func,_this) func(_this)
+#define call_func2(func,_this,a) func(_this,a)
+#define call_func3(func,_this,a,b) func(_this,a,b)
+#define call_func4(func,_this,a,b,c) func(_this,a,b,c)
+#define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
+
+#define call_func2_ptr_dbl   call_func2
+#define call_func2_ptr_flt   call_func2
+#define call_func2_ptr_fpos  call_func2
+
+#endif /* __i386__ */
 
 static HMODULE msvcp;
 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -360,10 +601,68 @@ static BOOL init(void)
     SET(p__Cnd_signal,
             "_Cnd_signal");
 
+    if(sizeof(void*) == 8) { /* 64-bit initialization */
+        SET(p_basic_streambuf_char_ctor,
+            "??0?$basic_streambuf at DU?$char_traits at D@std@@@std@@IEAA at XZ");
+        SET(p_basic_istream_char_ctor,
+            "??0?$basic_istream at DU?$char_traits at D@std@@@std@@QEAA at PEAV?$basic_streambuf at DU?$char_traits at D@std@@@1 at _N@Z");
+        SET(p_basic_istream_char_dtor,
+            "??1?$basic_istream at DU?$char_traits at D@std@@@std@@UEAA at XZ");
+        SET(p_basic_ios_char_dtor,
+            "??1?$basic_ios at DU?$char_traits at D@std@@@std@@UEAA at XZ");
+    } else {
+#ifdef __arm__
+        SET(p_basic_streambuf_char_ctor,
+            "??0?$basic_streambuf at DU?$char_traits at D@std@@@std@@IAA at XZ");
+        SET(p_basic_istream_char_ctor,
+            "??0?$basic_istream at DU?$char_traits at D@std@@@std@@QAA at PAV?$basic_streambuf at DU?$char_traits at D@std@@@1 at _N@Z");
+        SET(p_basic_istream_char_dtor,
+            "??1?$basic_istream at DU?$char_traits at D@std@@@std@@UAA at XZ");
+        SET(p_basic_ios_char_dtor,
+            "??1?$basic_ios at DU?$char_traits at D@std@@@std@@UAA at XZ");
+#else
+        SET(p_basic_streambuf_char_ctor,
+            "??0?$basic_streambuf at DU?$char_traits at D@std@@@std@@IAE at XZ");
+        SET(p_basic_istream_char_ctor,
+            "??0?$basic_istream at DU?$char_traits at D@std@@@std@@QAE at PAV?$basic_streambuf at DU?$char_traits at D@std@@@1 at _N@Z");
+        SET(p_basic_istream_char_dtor,
+            "??1?$basic_istream at DU?$char_traits at D@std@@@std@@UAE at XZ");
+        SET(p_basic_ios_char_dtor,
+            "??1?$basic_ios at DU?$char_traits at D@std@@@std@@UAE at XZ");
+#endif
+    }
+
+    SET(p_basic_iostream_char_vbtable1,
+            "??_8?$basic_iostream at DU?$char_traits at D@std@@@std@@7B?$basic_istream at DU?$char_traits at D@std@@@1@@");
+    SET(p_basic_iostream_char_vbtable2,
+            "??_8?$basic_iostream at DU?$char_traits at D@std@@@std@@7B?$basic_ostream at DU?$char_traits at D@std@@@1@@");
+    SET(p_basic_iostream_wchar_vbtable1_1,
+            "??_8?$basic_iostream at GU?$char_traits at G@std@@@std@@7B?$basic_istream at GU?$char_traits at G@std@@@1@@");
+    SET(p_basic_iostream_wchar_vbtable2_1,
+            "??_8?$basic_iostream at GU?$char_traits at G@std@@@std@@7B?$basic_ostream at GU?$char_traits at G@std@@@1@@");
+    SET(p_basic_iostream_wchar_vbtable1_2,
+            "??_8?$basic_iostream at _WU?$char_traits at _W@std@@@std@@7B?$basic_istream at _WU?$char_traits at _W@std@@@1@@");
+    SET(p_basic_iostream_wchar_vbtable2_2,
+            "??_8?$basic_iostream at _WU?$char_traits at _W@std@@@std@@7B?$basic_ostream at _WU?$char_traits at _W@std@@@1@@");
+    SET(p_basic_istream_char_vbtable,
+            "??_8?$basic_istream at DU?$char_traits at D@std@@@std@@7B@");
+    SET(p_basic_istream_short_vbtable,
+            "??_8?$basic_istream at GU?$char_traits at G@std@@@std@@7B@");
+    SET(p_basic_istream_wchar_vbtable,
+            "??_8?$basic_istream at _WU?$char_traits at _W@std@@@std@@7B@");
+    SET(p_basic_ostream_char_vbtable,
+            "??_8?$basic_ostream at DU?$char_traits at D@std@@@std@@7B@");
+    SET(p_basic_ostream_short_vbtable,
+            "??_8?$basic_ostream at GU?$char_traits at G@std@@@std@@7B@");
+    SET(p_basic_ostream_wchar_vbtable,
+            "??_8?$basic_ostream at _WU?$char_traits at _W@std@@@std@@7B@");
+
     msvcr = GetModuleHandleA("msvcr120.dll");
     p_setlocale = (void*)GetProcAddress(msvcr, "setlocale");
     p__setmbcp = (void*)GetProcAddress(msvcr, "_setmbcp");
     p_isleadbyte = (void*)GetProcAddress(msvcr, "isleadbyte");
+
+    init_thiscall_thunk();
     return TRUE;
 }
 
@@ -1549,6 +1848,38 @@ static void test_cnd(void)
     CloseHandle(cm.initialized);
 }
 
+static void test_vbtable(void)
+{
+    ok(p_basic_iostream_char_vbtable1[1] == 0x20, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_char_vbtable1[1]);
+    ok(p_basic_iostream_char_vbtable2[1] == 0x10, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_char_vbtable2[1]);
+    ok(p_basic_iostream_wchar_vbtable1_1[1] == 0x20, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_wchar_vbtable1_1[1]);
+    ok(p_basic_iostream_wchar_vbtable2_1[1] == 0x10, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_wchar_vbtable2_1[1]);
+    ok(p_basic_iostream_wchar_vbtable1_2[1] == 0x20, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_wchar_vbtable1_2[1]);
+    ok(p_basic_iostream_wchar_vbtable2_2[1] == 0x10, "vbtable[1] wrong, got 0x%x\n", p_basic_iostream_wchar_vbtable2_2[1]);
+    ok(p_basic_istream_char_vbtable[1] == 0x18, "vbtable[1] wrong, got 0x%x\n", p_basic_istream_char_vbtable[1]);
+    ok(p_basic_istream_short_vbtable[1] == 0x18, "vbtable[1] wrong, got 0x%x\n", p_basic_istream_short_vbtable[1]);
+    ok(p_basic_istream_wchar_vbtable[1] == 0x18, "vbtable[1] wrong, got 0x%x\n", p_basic_istream_wchar_vbtable[1]);
+    ok(p_basic_ostream_char_vbtable[1] == 0x8, "vbtable[1] wrong, got 0x%x\n", p_basic_ostream_char_vbtable[1]);
+    ok(p_basic_ostream_short_vbtable[1] == 0x8, "vbtable[1] wrong, got 0x%x\n", p_basic_ostream_short_vbtable[1]);
+    ok(p_basic_ostream_wchar_vbtable[1] == 0x8, "vbtable[1] wrong, got 0x%x\n", p_basic_ostream_wchar_vbtable[1]);
+}
+
+static void test_supertux(void)
+{
+    basic_streambuf_char sb[2];
+    basic_istream_char is[2];
+    basic_ios_char* i;
+
+    call_func1(p_basic_streambuf_char_ctor, sb);
+    call_func4(p_basic_istream_char_ctor, is, sb, 0, 1);
+
+    i = (void*)(((int)is) + 0x10 + 0x8); /* calculated from WINEDEBUG=+msvcp log of supertux2.exe */
+
+    call_func1(p_basic_istream_char_dtor, i);
+    call_func1(p_basic_ios_char_dtor, i);
+    ok(1, "%d\n", __LINE__);
+}
+
 START_TEST(msvcp120)
 {
     if(!init()) return;
@@ -1577,5 +1908,8 @@ START_TEST(msvcp120)
     test_thrd();
     test_cnd();
 
+    test_vbtable();
+    test_supertux();
+
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 6a75476..04286ec 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -398,34 +398,40 @@ const int basic_ostream_short_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_ostream_
 /* ??_7?$basic_ostream at GU?$char_traits at G@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_ostream_short_vtable;
 
+#if _MSVCP_VER >= 100
+#define ADD_UNKNOWN 8
+#else
+#define ADD_UNKNOWN 0
+#endif
+
 /* ??_8?$basic_istream at DU?$char_traits at D@std@@@std@@7B@ */
-const int basic_istream_char_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_char), VBTABLE_ALIGN)};
+const int basic_istream_char_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_char), VBTABLE_ALIGN) + ADD_UNKNOWN};
 /* ??_7?$basic_istream at DU?$char_traits at D@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_istream_char_vtable;
 
 /* ??_8?$basic_istream at _WU?$char_traits at _W@std@@@std@@7B@ */
-const int basic_istream_wchar_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN)};
+const int basic_istream_wchar_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN) + ADD_UNKNOWN};
 /* ??_7?$basic_istream at _WU?$char_traits at _W@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_istream_wchar_vtable;
 
 /* ??_8?$basic_istream at GU?$char_traits at G@std@@@std@@7B@ */
-const int basic_istream_short_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN)};
+const int basic_istream_short_vbtable[] = {0, ALIGNED_SIZE(sizeof(basic_istream_wchar), VBTABLE_ALIGN) + ADD_UNKNOWN};
 /* ??_7?$basic_istream at GU?$char_traits at G@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_istream_short_vtable;
 
 /* ??_8?$basic_iostream at DU?$char_traits at D@std@@@std@@7B?$basic_istream at DU?$char_traits at D@std@@@1@@ */
-const int basic_iostream_char_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN)};
+const int basic_iostream_char_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN) + ADD_UNKNOWN};
 /* ??_8?$basic_iostream at DU?$char_traits at D@std@@@std@@7B?$basic_ostream at DU?$char_traits at D@std@@@1@@ */
-const int basic_iostream_char_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_char, base2)};
+const int basic_iostream_char_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_char), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_char, base2) + ADD_UNKNOWN};
 /* ??_7?$basic_iostream at DU?$char_traits at D@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_iostream_char_vtable;
 
 /* ??_8?$basic_iostream at _WU?$char_traits at _W@std@@@std@@7B?$basic_istream at _WU?$char_traits at _W@std@@@1@@ */
 /* ??_8?$basic_iostream at GU?$char_traits at G@std@@@std@@7B?$basic_istream at GU?$char_traits at G@std@@@1@@ */
-const int basic_iostream_wchar_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN)};
+const int basic_iostream_wchar_vbtable1[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN) + ADD_UNKNOWN};
 /* ??_8?$basic_iostream at _WU?$char_traits at _W@std@@@std@@7B?$basic_ostream at _WU?$char_traits at _W@std@@@1@@ */
 /* ??_8?$basic_iostream at GU?$char_traits at G@std@@@std@@7B?$basic_ostream at GU?$char_traits at G@std@@@1@@ */
-const int basic_iostream_wchar_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_wchar, base2)};
+const int basic_iostream_wchar_vbtable2[] = {0, ALIGNED_SIZE(sizeof(basic_iostream_wchar), VBTABLE_ALIGN)-FIELD_OFFSET(basic_iostream_wchar, base2) + ADD_UNKNOWN};
 /* ??_7?$basic_iostream at _WU?$char_traits at _W@std@@@std@@6B@ */
 extern const vtable_ptr MSVCP_basic_iostream_wchar_vtable;
 /* ??_7?$basic_iostream at GU?$char_traits at G@std@@@std@@6B@ */
-- 
2.1.4




More information about the wine-patches mailing list