From: Victor Chiletto v@hnn.net.br
More specifically: a mod for Fallout: New Vegas relies on rewind not modifying the first argument passed to it [1].
[1]: https://github.com/jazzisparis/UIO-User-Interface-Organizer/blob/426d96391f9... --- dlls/ucrtbase/tests/misc.c | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 069de0787b7..1371bc79b32 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -38,6 +38,10 @@ #include <winbase.h> #include "wine/test.h"
+#if defined(__i386__) && defined(__GNUC__) +#include "wine/asm.h" +#endif + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -1591,6 +1595,41 @@ static void test_fopen_exclusive( void ) unlink(path); }
+#if defined(__i386__) +#if defined(__GNUC__) +extern CDECL FILE *test_rewind_wrapper(FILE *fp); +__ASM_GLOBAL_FUNC(test_rewind_wrapper, + "pushl 4(%esp)\n\t" + "call " __ASM_NAME("rewind") "\n\t" + "popl %eax\n\t" + "ret") +#else +FILE* CDECL test_rewind_wrapper(FILE* fp); +__declspec(naked) FILE* test_rewind_wrapper(FILE *fp) +{ + __asm + { + push [esp + 4]; + call rewind; + pop eax; + ret; + } +} +#endif + +static void test_rewind_i386_abi(void) +{ + FILE *fp_in, *fp_out; + + fp_in = fopen("rewind_abi.tst", "wb"); + fp_out = test_rewind_wrapper(fp_in); + todo_wine ok(fp_in == fp_out, "rewind modified the first argument in the stack\n"); + + fclose(fp_in); + unlink("rewind_abi.tst"); +} +#endif + START_TEST(misc) { int arg_c; @@ -1633,4 +1672,7 @@ START_TEST(misc) test_thread_storage(); test_fenv(); test_fopen_exclusive(); +#if defined(__i386__) + test_rewind_i386_abi(); +#endif }