libwine: Added a wine_call_on_stack function.
This commit is contained in:
parent
f6d871eecf
commit
c9f0bea910
|
@ -66,6 +66,7 @@ extern void wine_init( int argc, char *argv[], char *error, int error_size );
|
||||||
/* portability */
|
/* portability */
|
||||||
|
|
||||||
extern void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack );
|
extern void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack );
|
||||||
|
extern int wine_call_on_stack( int (*func)(void *), void *arg, void *stack );
|
||||||
extern void wine_set_pe_load_area( void *base, size_t size );
|
extern void wine_set_pe_load_area( void *base, size_t size );
|
||||||
extern void wine_free_pe_load_area(void);
|
extern void wine_free_pe_load_area(void);
|
||||||
|
|
||||||
|
|
|
@ -116,5 +116,69 @@ __ASM_GLOBAL_FUNC( wine_switch_to_stack,
|
||||||
"callq *%rax\n\t" /* call func */
|
"callq *%rax\n\t" /* call func */
|
||||||
"int $3")
|
"int $3")
|
||||||
#else
|
#else
|
||||||
|
void DECLSPEC_NORETURN wine_switch_to_stack( void (*func)(void *), void *arg, void *stack )
|
||||||
|
{
|
||||||
|
wine_call_on_stack( (int (*)(void *))func, arg, stack );
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* wine_call_on_stack
|
||||||
|
*
|
||||||
|
* Switch to the specified stack to call the function and return.
|
||||||
|
*/
|
||||||
|
int wine_call_on_stack( int (*func)(void *), void *arg, void *stack );
|
||||||
|
#if defined(__i386__) && defined(__GNUC__)
|
||||||
|
__ASM_GLOBAL_FUNC( wine_call_on_stack,
|
||||||
|
"pushl %ebp\n\t"
|
||||||
|
"pushl %esi\n\t"
|
||||||
|
"movl 12(%esp),%ecx\n\t" /* func */
|
||||||
|
"movl 16(%esp),%edx\n\t" /* arg */
|
||||||
|
"movl 20(%esp),%esi\n\t" /* stack */
|
||||||
|
"andl $~15,%esi\n\t"
|
||||||
|
"subl $12,%esi\n\t"
|
||||||
|
"xchgl %esi,%esp\n\t"
|
||||||
|
"pushl %edx\n\t"
|
||||||
|
"xorl %ebp,%ebp\n\t"
|
||||||
|
"call *%ecx\n\t"
|
||||||
|
"movl %esi,%esp\n\t"
|
||||||
|
"popl %esi\n\t"
|
||||||
|
"popl %ebp\n\t"
|
||||||
|
"ret" )
|
||||||
|
#elif defined(__i386__) && defined(_MSC_VER)
|
||||||
|
__declspec(naked) int wine_call_on_stack( int (*func)(void *), void *arg, void *stack )
|
||||||
|
{
|
||||||
|
__asm push ebp;
|
||||||
|
__asm push esi;
|
||||||
|
__asm mov ecx, 12[esp];
|
||||||
|
__asm mov edx, 16[esp];
|
||||||
|
__asm mov esi, 20[esp];
|
||||||
|
__asm xchg esp, esi;
|
||||||
|
__asm push edx;
|
||||||
|
__asm xor ebp, ebp;
|
||||||
|
__asm call [ecx];
|
||||||
|
__asm mov esp, esi;
|
||||||
|
__asm pop esi;
|
||||||
|
__asm pop ebp
|
||||||
|
__asm ret;
|
||||||
|
}
|
||||||
|
#elif defined(__x86_64__) && defined(__GNUC__)
|
||||||
|
__ASM_GLOBAL_FUNC( wine_call_on_stack,
|
||||||
|
"pushq %rbp\n\t"
|
||||||
|
"pushq %rbx\n\t"
|
||||||
|
"movq %rsp,%rbx\n\t"
|
||||||
|
"movq %rdi,%rax\n\t" /* func */
|
||||||
|
"movq %rsi,%rdi\n\t" /* arg */
|
||||||
|
"andq $~15,%rdx\n\t" /* stack */
|
||||||
|
"movq %rdx,%rsp\n\t"
|
||||||
|
"xorq %rbp,%rbp\n\t"
|
||||||
|
"callq *%rax\n\t" /* call func */
|
||||||
|
"movq %rbx,%rsp\n\t"
|
||||||
|
"popq %rbx\n\t"
|
||||||
|
"popq %rbp\n\t"
|
||||||
|
"ret")
|
||||||
|
#else
|
||||||
#error You must implement wine_switch_to_stack for your platform
|
#error You must implement wine_switch_to_stack for your platform
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -50,6 +50,7 @@ EXPORTS
|
||||||
vsnprintfW
|
vsnprintfW
|
||||||
vsprintfW
|
vsprintfW
|
||||||
wine_anon_mmap
|
wine_anon_mmap
|
||||||
|
wine_call_on_stack
|
||||||
wine_casemap_lower
|
wine_casemap_lower
|
||||||
wine_casemap_upper
|
wine_casemap_upper
|
||||||
wine_compare_string
|
wine_compare_string
|
||||||
|
@ -65,7 +66,7 @@ EXPORTS
|
||||||
wine_dbgstr_an
|
wine_dbgstr_an
|
||||||
wine_dbgstr_wn
|
wine_dbgstr_wn
|
||||||
wine_dlclose
|
wine_dlclose
|
||||||
wine_dll_enum_load_path;
|
wine_dll_enum_load_path
|
||||||
wine_dll_get_owner
|
wine_dll_get_owner
|
||||||
wine_dll_load
|
wine_dll_load
|
||||||
wine_dll_load_main_exe
|
wine_dll_load_main_exe
|
||||||
|
|
|
@ -50,6 +50,7 @@ WINE_1.0
|
||||||
vsnprintfW;
|
vsnprintfW;
|
||||||
vsprintfW;
|
vsprintfW;
|
||||||
wine_anon_mmap;
|
wine_anon_mmap;
|
||||||
|
wine_call_on_stack;
|
||||||
wine_casemap_lower;
|
wine_casemap_lower;
|
||||||
wine_casemap_upper;
|
wine_casemap_upper;
|
||||||
wine_compare_string;
|
wine_compare_string;
|
||||||
|
|
Loading…
Reference in New Issue