Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
99cdacb9
Commit
99cdacb9
authored
Jul 05, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcp90/tests: Dynamically generate a thunk to call thiscall functions.
It's not possible to do this correctly with inline assembly.
parent
718c6149
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
267 deletions
+72
-267
misc.c
dlls/msvcp90/tests/misc.c
+30
-83
string.c
dlls/msvcp90/tests/string.c
+42
-184
No files found.
dlls/msvcp90/tests/misc.c
View file @
99cdacb9
...
@@ -65,97 +65,43 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
...
@@ -65,97 +65,43 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
/* Emulate a __thiscall */
/* Emulate a __thiscall */
#ifdef __i386__
#ifdef __i386__
#ifdef _MSC_VER
static
inline
void
*
do_call_func1
(
void
*
func
,
void
*
_this
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func2
(
void
*
func
,
void
*
_this
,
const
void
*
arg
)
#include "pshpack1.h"
struct
thiscall_thunk
{
{
volatile
void
*
retval
=
0
;
BYTE
pop_eax
;
/* popl %eax (ret addr) */
__asm
BYTE
pop_edx
;
/* popl %edx (func) */
{
BYTE
pop_ecx
;
/* popl %ecx (this) */
push
ecx
BYTE
push_eax
;
/* pushl %eax */
push
arg
WORD
jmp_edx
;
/* jmp *%edx */
mov
ecx
,
_this
};
call
func
#include "poppack.h"
mov
retval
,
eax
pop
ecx
static
void
*
(
WINAPI
*
call_thiscall_func1
)(
void
*
func
,
void
*
this
);
}
static
void
*
(
WINAPI
*
call_thiscall_func2
)(
void
*
func
,
void
*
this
,
const
void
*
a
);
return
(
void
*
)
retval
;
static
void
*
(
WINAPI
*
call_thiscall_func3
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
);
}
static
void
init_thiscall_thunk
(
void
)
static
inline
void
*
do_call_func3
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
)
{
{
volatile
void
*
retval
=
0
;
struct
thiscall_thunk
*
thunk
=
VirtualAlloc
(
NULL
,
sizeof
(
*
thunk
),
__asm
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
{
thunk
->
pop_eax
=
0x58
;
/* popl %eax */
push
ecx
thunk
->
pop_edx
=
0x5a
;
/* popl %edx */
push
arg1
thunk
->
pop_ecx
=
0x59
;
/* popl %ecx */
push
arg2
thunk
->
push_eax
=
0x50
;
/* pushl %eax */
mov
ecx
,
_this
thunk
->
jmp_edx
=
0xe2ff
;
/* jmp *%edx */
call
func
call_thiscall_func1
=
(
void
*
)
thunk
;
mov
retval
,
eax
call_thiscall_func2
=
(
void
*
)
thunk
;
pop
ecx
call_thiscall_func3
=
(
void
*
)
thunk
;
}
return
(
void
*
)
retval
;
}
}
#else
static
void
*
do_call_func1
(
void
*
func
,
void
*
_this
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"g"
(
func
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func2
(
void
*
func
,
void
*
_this
,
const
void
*
arg
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func3
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"pushl %4
\n\t
pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg1
),
"r"
(
arg2
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
#endif
#define call_func1(func,_this)
do_
call_func1(func,_this)
#define call_func1(func,_this)
call_this
call_func1(func,_this)
#define call_func2(func,_this,a)
do_
call_func2(func,_this,(const void*)a)
#define call_func2(func,_this,a)
call_this
call_func2(func,_this,(const void*)a)
#define call_func3(func,_this,a,b)
do_
call_func3(func,_this,(const void*)a,(const void*)b)
#define call_func3(func,_this,a,b)
call_this
call_func3(func,_this,(const void*)a,(const void*)b)
#else
#else
#define init_thiscall_thunk()
#define call_func1(func,_this) func(_this)
#define call_func1(func,_this) func(_this)
#define call_func2(func,_this,a) func(_this,a)
#define call_func2(func,_this,a) func(_this,a)
#define call_func3(func,_this,a,b) func(_this,a,b)
#define call_func3(func,_this,a,b) func(_this,a,b)
...
@@ -217,6 +163,7 @@ static BOOL init(void)
...
@@ -217,6 +163,7 @@ static BOOL init(void)
SET
(
p_char_max_size
,
"?max_size@?$allocator@D@std@@QBEIXZ"
);
SET
(
p_char_max_size
,
"?max_size@?$allocator@D@std@@QBEIXZ"
);
}
}
init_thiscall_thunk
();
return
TRUE
;
return
TRUE
;
}
}
...
...
dlls/msvcp90/tests/string.c
View file @
99cdacb9
...
@@ -127,201 +127,58 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
...
@@ -127,201 +127,58 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
/* Emulate a __thiscall */
/* Emulate a __thiscall */
#ifdef __i386__
#ifdef __i386__
#ifdef _MSC_VER
static
inline
void
*
do_call_func1
(
void
*
func
,
void
*
_this
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func2
(
void
*
func
,
void
*
_this
,
const
void
*
arg
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func3
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg1
push
arg2
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func4
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg1
push
arg2
push
arg3
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func5
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
,
const
void
*
arg4
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg1
push
arg2
push
arg3
push
arg4
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
}
static
inline
void
*
do_call_func6
(
void
*
func
,
void
*
_this
,
#include "pshpack1.h"
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
,
struct
thiscall_thunk
const
void
*
arg4
,
const
void
*
arg5
)
{
{
volatile
void
*
retval
=
0
;
BYTE
pop_eax
;
/* popl %eax (ret addr) */
__asm
BYTE
pop_edx
;
/* popl %edx (func) */
{
BYTE
pop_ecx
;
/* popl %ecx (this) */
push
ecx
BYTE
push_eax
;
/* pushl %eax */
push
arg1
WORD
jmp_edx
;
/* jmp *%edx */
push
arg2
};
push
arg3
#include "poppack.h"
push
arg4
push
arg5
static
void
*
(
WINAPI
*
call_thiscall_func1
)(
void
*
func
,
void
*
this
);
mov
ecx
,
_this
static
void
*
(
WINAPI
*
call_thiscall_func2
)(
void
*
func
,
void
*
this
,
const
void
*
a
);
call
func
static
void
*
(
WINAPI
*
call_thiscall_func3
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
);
mov
retval
,
eax
static
void
*
(
WINAPI
*
call_thiscall_func4
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
,
pop
ecx
const
void
*
c
);
}
static
void
*
(
WINAPI
*
call_thiscall_func5
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
,
return
(
void
*
)
retval
;
const
void
*
c
,
const
void
*
d
);
}
static
void
*
(
WINAPI
*
call_thiscall_func6
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
,
#else
const
void
*
c
,
const
void
*
d
,
const
void
*
e
);
static
void
*
do_call_func1
(
void
*
func
,
void
*
_this
)
{
static
void
init_thiscall_thunk
(
void
)
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"g"
(
func
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func2
(
void
*
func
,
void
*
_this
,
const
void
*
arg
)
{
{
void
*
ret
,
*
dummy
;
struct
thiscall_thunk
*
thunk
=
VirtualAlloc
(
NULL
,
sizeof
(
*
thunk
),
__asm__
__volatile__
(
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
"pushl %3
\n\t
call *%2"
thunk
->
pop_eax
=
0x58
;
/* popl %eax */
:
"=a"
(
ret
),
"=c"
(
dummy
)
thunk
->
pop_edx
=
0x5a
;
/* popl %edx */
:
"r"
(
func
),
"r"
(
arg
),
"1"
(
_this
)
thunk
->
pop_ecx
=
0x59
;
/* popl %ecx */
:
"edx"
,
"memory"
thunk
->
push_eax
=
0x50
;
/* pushl %eax */
);
thunk
->
jmp_edx
=
0xe2ff
;
/* jmp *%edx */
return
ret
;
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_func6
=
(
void
*
)
thunk
;
}
}
static
void
*
do_call_func3
(
void
*
func
,
void
*
_this
,
#define call_func1(func,_this) call_thiscall_func1(func,_this)
const
void
*
arg1
,
const
void
*
arg2
)
#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)
void
*
ret
,
*
dummy
;
#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)a,\
__asm__
__volatile__
(
"pushl %4
\n\t
pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg1
),
"r"
(
arg2
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func4
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"pushl %5
\n\t
pushl %4
\n\t
pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg1
),
"r"
(
arg2
),
"m"
(
arg3
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func5
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
,
const
void
*
arg4
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"pushl %6
\n\t
pushl %5
\n\t
pushl %4
\n\t
pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg1
),
"r"
(
arg2
),
"m"
(
arg3
),
"m"
(
arg4
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
static
void
*
do_call_func6
(
void
*
func
,
void
*
_this
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
,
const
void
*
arg4
,
const
void
*
arg5
)
{
void
*
ret
,
*
dummy
;
__asm__
__volatile__
(
"pushl %7
\n\t
pushl %6
\n\t
pushl %5
\n\t
pushl %4
\n\t
pushl %3
\n\t
call *%2"
:
"=a"
(
ret
),
"=c"
(
dummy
)
:
"r"
(
func
),
"r"
(
arg1
),
"r"
(
arg2
),
"m"
(
arg3
),
"m"
(
arg4
),
"m"
(
arg5
),
"1"
(
_this
)
:
"edx"
,
"memory"
);
return
ret
;
}
#endif
#define call_func1(func,_this) do_call_func1(func,_this)
#define call_func2(func,_this,a) do_call_func2(func,_this,(const void*)a)
#define call_func3(func,_this,a,b) do_call_func3(func,_this,(const void*)a,(const void*)b)
#define call_func4(func,_this,a,b,c) do_call_func4(func,_this,(const void*)a,\
(const void*)b,(const void*)c)
(const void*)b,(const void*)c)
#define call_func5(func,_this,a,b,c,d)
do_
call_func5(func,_this,(const void*)a,\
#define call_func5(func,_this,a,b,c,d)
call_this
call_func5(func,_this,(const void*)a,\
(const void*)b,(const void*)c,(const void*)d)
(const void*)b,(const void*)c,(const void*)d)
#define call_func6(func,_this,a,b,c,d,e)
do_
call_func6(func,_this,(const void*)a,\
#define call_func6(func,_this,a,b,c,d,e)
call_this
call_func6(func,_this,(const void*)a,\
(const void*)b,(const void*)c,(const void*)d,(const void*)e)
(const void*)b,(const void*)c,(const void*)d,(const void*)e)
#else
#else
#define init_thiscall_thunk()
#define call_func1(func,_this) func(_this)
#define call_func1(func,_this) func(_this)
#define call_func2(func,_this,a) func(_this,a)
#define call_func2(func,_this,a) func(_this,a)
#define call_func3(func,_this,a,b) func(_this,a,b)
#define call_func3(func,_this,a,b) func(_this,a,b)
...
@@ -472,6 +329,7 @@ static BOOL init(void)
...
@@ -472,6 +329,7 @@ static BOOL init(void)
"?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXAAV12@@Z"
);
"?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXAAV12@@Z"
);
}
}
init_thiscall_thunk
();
return
TRUE
;
return
TRUE
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment