Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
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,
/* Emulate a __thiscall */
#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
;
__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
)
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
init_thiscall_thunk
(
void
)
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg1
push
arg2
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
return
(
void
*
)
retval
;
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
;
}
#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_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_func1(func,_this)
call_this
call_func1(func,_this)
#define call_func2(func,_this,a)
call_this
call_func2(func,_this,(const void*)a)
#define call_func3(func,_this,a,b)
call_this
call_func3(func,_this,(const void*)a,(const void*)b)
#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)
...
...
@@ -217,6 +163,7 @@ static BOOL init(void)
SET
(
p_char_max_size
,
"?max_size@?$allocator@D@std@@QBEIXZ"
);
}
init_thiscall_thunk
();
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,
/* Emulate a __thiscall */
#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
,
const
void
*
arg1
,
const
void
*
arg2
,
const
void
*
arg3
,
const
void
*
arg4
,
const
void
*
arg5
)
#include "pshpack1.h"
struct
thiscall_thunk
{
volatile
void
*
retval
=
0
;
__asm
{
push
ecx
push
arg1
push
arg2
push
arg3
push
arg4
push
arg5
mov
ecx
,
_this
call
func
mov
retval
,
eax
pop
ecx
}
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
)
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
);
static
void
*
(
WINAPI
*
call_thiscall_func6
)(
void
*
func
,
void
*
this
,
const
void
*
a
,
const
void
*
b
,
const
void
*
c
,
const
void
*
d
,
const
void
*
e
);
static
void
init_thiscall_thunk
(
void
)
{
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
;
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_func6
=
(
void
*
)
thunk
;
}
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
;
}
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,\
#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)
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)
#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)
#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)
...
...
@@ -472,6 +329,7 @@ static BOOL init(void)
"?swap@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEXAAV12@@Z"
);
}
init_thiscall_thunk
();
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