Signed-off-by: Paul Gofman pgofman@codeweavers.com --- Halo Infinite needs this export with Wine 7.0-rc. The export was also absent in the previous Wine versions so the absence of it is not a regression of course and I don't know what exactly change made it start depending on it. But since the adding of the data export is trivial I guess that maybe doing it is ok during the code freeze.
dlls/concrt140/concrt140.spec | 2 +- dlls/concrt140/details.c | 21 +++++++++++++++++++++ dlls/concrt140/tests/concrt140.c | 24 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/dlls/concrt140/concrt140.spec b/dlls/concrt140/concrt140.spec index 364a1ad8d84..50db9348327 100644 --- a/dlls/concrt140/concrt140.spec +++ b/dlls/concrt140/concrt140.spec @@ -433,7 +433,7 @@ @ stub -arch=arm ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IAAXABV123@@Z @ stub -arch=i386 ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IAEXABV123@@Z @ stub -arch=win64 ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAAXAEBV123@@Z -# extern ?_Byte_reverse_table@details@Concurrency@@3QBEB +@ extern ?_Byte_reverse_table@details@Concurrency@@3QBEB byte_reverse_table @ stub -arch=arm ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAAXXZ @ stub -arch=i386 ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QAEXXZ @ stub -arch=win64 ?_Cancel@_StructuredTaskCollection@details@Concurrency@@QEAAXXZ diff --git a/dlls/concrt140/details.c b/dlls/concrt140/details.c index 27cdd911ad2..3f5d2008358 100644 --- a/dlls/concrt140/details.c +++ b/dlls/concrt140/details.c @@ -1103,6 +1103,27 @@ __ASM_BLOCK_BEGIN(concurrency_details_vtables) VTABLE_ADD_FUNC(_Runtime_object__GetId)); __ASM_BLOCK_END
+/* ?_Byte_reverse_table@details@Concurrency@@3QBEB */ +const BYTE byte_reverse_table[256] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; + void init_concurrency_details(void *base) { #ifdef __x86_64__ diff --git a/dlls/concrt140/tests/concrt140.c b/dlls/concrt140/tests/concrt140.c index 55b200c6c78..7b3300a3d59 100644 --- a/dlls/concrt140/tests/concrt140.c +++ b/dlls/concrt140/tests/concrt140.c @@ -90,6 +90,8 @@ static void (__thiscall *p__Timer_dtor)(_Timer*); static void (__thiscall *p__Timer__Start)(_Timer*); static void (__thiscall *p__Timer__Stop)(_Timer*);
+static const BYTE *p_byte_reverse_table; + #define SETNOFAIL(x,y) x = (void*)GetProcAddress(module,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
@@ -142,6 +144,7 @@ static BOOL init(void) }
init_thiscall_thunk(); + SET(p_byte_reverse_table, "?_Byte_reverse_table@details@Concurrency@@3QBEB"); return TRUE; }
@@ -217,9 +220,30 @@ static void test_Timer(void) CloseHandle(callback_called); }
+static BYTE byte_reverse(BYTE b) +{ + b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4); + b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2); + b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1); + return b; +} + +static void test_data_exports(void) +{ + unsigned int i; + + ok(IsBadWritePtr((BYTE *)p_byte_reverse_table, 256), "byte_reverse_table is writeable.\n"); + for (i = 0; i < 256; ++i) + { + ok(p_byte_reverse_table[i] == byte_reverse(i), "Got unexpected byte %#x, expected %#x.\n", + p_byte_reverse_table[i], byte_reverse(i)); + } +} + START_TEST(concrt140) { if (!init()) return; test_CurrentContext(); test_Timer(); + test_data_exports(); }
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/msvcp110/msvcp110.spec | 2 +- dlls/msvcp110/tests/msvcp110.c | 24 ++++++++++++++++++++++++ dlls/msvcp90/details.c | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index b67bc0bb0ad..514bc90b5e7 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -1149,7 +1149,7 @@ @ stub -arch=win64 ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAAXAEBV123@@Z @ stub ?_Atexit@@YAXP6AXXZ@Z @ extern ?_BADOFF@std@@3_JB std_BADOFF -# extern ?_Byte_reverse_table@details@Concurrency@@3QBEB +@ extern ?_Byte_reverse_table@details@Concurrency@@3QBEB byte_reverse_table @ cdecl -arch=arm ?_C_str@?$_Yarn@D@std@@QBAPBDXZ(ptr) _Yarn_char_c_str @ thiscall -arch=i386 ?_C_str@?$_Yarn@D@std@@QBEPBDXZ(ptr) _Yarn_char_c_str @ cdecl -arch=win64 ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ(ptr) _Yarn_char_c_str diff --git a/dlls/msvcp110/tests/msvcp110.c b/dlls/msvcp110/tests/msvcp110.c index 8491e292d58..75f445e4644 100644 --- a/dlls/msvcp110/tests/msvcp110.c +++ b/dlls/msvcp110/tests/msvcp110.c @@ -37,6 +37,8 @@ static __int64 (__cdecl *p_tr2_sys__Last_write_time_wchar)(WCHAR const*); static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64); static void (__cdecl *p_tr2_sys__Last_write_time_set_wchar)(WCHAR const*, __int64);
+static const BYTE *p_byte_reverse_table; + static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) @@ -76,6 +78,7 @@ static BOOL init(void) SET(p_tr2_sys__Last_write_time_set_wchar, "?_Last_write_time@sys@tr2@std@@YAXPB_W_J@Z"); } + SET(p_byte_reverse_table, "?_Byte_reverse_table@details@Concurrency@@3QBEB"); return TRUE; }
@@ -205,10 +208,31 @@ static void test_vbtable_size_exports(void) } }
+static BYTE byte_reverse(BYTE b) +{ + b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4); + b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2); + b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1); + return b; +} + +static void test_data_exports(void) +{ + unsigned int i; + + ok(IsBadWritePtr((BYTE *)p_byte_reverse_table, 256), "byte_reverse_table is writeable.\n"); + for (i = 0; i < 256; ++i) + { + ok(p_byte_reverse_table[i] == byte_reverse(i), "Got unexpected byte %#x, expected %#x.\n", + p_byte_reverse_table[i], byte_reverse(i)); + } +} + START_TEST(msvcp110) { if(!init()) return; test_tr2_sys__Last_write_time(); test_vbtable_size_exports(); + test_data_exports(); FreeLibrary(msvcp); } diff --git a/dlls/msvcp90/details.c b/dlls/msvcp90/details.c index e3c3148a133..d2969516af4 100644 --- a/dlls/msvcp90/details.c +++ b/dlls/msvcp90/details.c @@ -1129,3 +1129,26 @@ void init_concurrency_details(void *base) #endif } #endif + +#if _MSVCP_VER >= 110 +/* ?_Byte_reverse_table@details@Concurrency@@3QBEB */ +const BYTE byte_reverse_table[256] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; +#endif
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/msvcp120/msvcp120.spec | 2 +- dlls/msvcp120/tests/msvcp120.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index 269290bbf90..6f868e190a9 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -1114,7 +1114,7 @@ @ stub -arch=win64 ?_Assign@_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAAXAEBV123@@Z @ stub ?_Atexit@@YAXP6AXXZ@Z @ extern ?_BADOFF@std@@3_JB std_BADOFF -# extern ?_Byte_reverse_table@details@Concurrency@@3QBEB +@ extern ?_Byte_reverse_table@details@Concurrency@@3QBEB byte_reverse_table @ cdecl -arch=arm ?_C_str@?$_Yarn@D@std@@QBAPBDXZ(ptr) _Yarn_char_c_str @ thiscall -arch=i386 ?_C_str@?$_Yarn@D@std@@QBEPBDXZ(ptr) _Yarn_char_c_str @ cdecl -arch=win64 ?_C_str@?$_Yarn@D@std@@QEBAPEBDXZ(ptr) _Yarn_char_c_str diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index 6bc636c4b1f..9e36071d06a 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -417,6 +417,8 @@ static void (__thiscall *p_vector_base_v4__Internal_resize)( vector_base_v4*, size_t, size_t, size_t, void (__cdecl*)(void*, size_t), void (__cdecl *copy)(void*, const void*, size_t), const void*);
+static const BYTE *p_byte_reverse_table; + static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0) @@ -809,6 +811,8 @@ static BOOL init(void) SET(p__Cnd_do_broadcast_at_thread_exit, "_Cnd_do_broadcast_at_thread_exit");
+ SET(p_byte_reverse_table, "?_Byte_reverse_table@details@Concurrency@@3QBEB"); + hdll = GetModuleHandleA("msvcr120.dll"); p_setlocale = (void*)GetProcAddress(hdll, "setlocale"); p__setmbcp = (void*)GetProcAddress(hdll, "_setmbcp"); @@ -3305,6 +3309,26 @@ static void test_vector_base_v4(void) ok(!vector_alloc_count, "vector_alloc_count = %d, expected 0\n", vector_alloc_count); }
+static BYTE byte_reverse(BYTE b) +{ + b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4); + b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2); + b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1); + return b; +} + +static void test_data_exports(void) +{ + unsigned int i; + + ok(IsBadWritePtr((BYTE *)p_byte_reverse_table, 256), "byte_reverse_table is writeable.\n"); + for (i = 0; i < 256; ++i) + { + ok(p_byte_reverse_table[i] == byte_reverse(i), "Got unexpected byte %#x, expected %#x.\n", + p_byte_reverse_table[i], byte_reverse(i)); + } +} + START_TEST(msvcp120) { if(!init()) return; @@ -3350,6 +3374,8 @@ START_TEST(msvcp120)
test_vbtable_size_exports();
+ test_data_exports(); + free_expect_struct(); TlsFree(expect_idx); FreeLibrary(msvcp);
Hi Paul,
The patch looks good to me. I'm not sure if it's good for code freeze but it looks like a low risk change. I guess that Halo Infinite was never working in vanilla wine.
When introducing detals.c file copy in concrt140 the idea was to keep the files as similar as possible (currently there's only change in one include + _MSVCP_VER define is not present in concrt). Could you please add the table in the same place both in concrt140 and msvcp90?
Please also update msvcp120_app.spec file.
Thanks, Piotr
On 12/20/21 19:08, Piotr Caban wrote:
Hi Paul,
The patch looks good to me. I'm not sure if it's good for code freeze but it looks like a low risk change. I guess that Halo Infinite was never working in vanilla wine.
When introducing detals.c file copy in concrt140 the idea was to keep the files as similar as possible (currently there's only change in one include + _MSVCP_VER define is not present in concrt). Could you please add the table in the same place both in concrt140 and msvcp90?
Please also update msvcp120_app.spec file.
Thanks, Piotr
Thanks, I will update that. I just discovered however that the reason it worked before for me was only because the native library was used. With the builtin it needs more with the next being ??0_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAA@AEBV_Concurrent_queue_base_v4@12@@Z (probably other iterator details to follow at least).
So could you pleas advise what is the best for now, finish the data export once started or leave until the code freeze end?
On 12/20/21 17:10, Paul Gofman wrote:
Thanks, I will update that. I just discovered however that the reason it worked before for me was only because the native library was used. With the builtin it needs more with the next being ??0_Concurrent_queue_iterator_base_v4@details@Concurrency@@IEAA@AEBV_Concurrent_queue_base_v4@12@@Z (probably other iterator details to follow at least).
So could you pleas advise what is the best for now, finish the data export once started or leave until the code freeze end?
I guess it's better to resend the patches after code freeze.
Thanks, Piotr