diff options
Diffstat (limited to 'src/libw32dll/wine/wrapper.S')
| -rw-r--r-- | src/libw32dll/wine/wrapper.S | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/libw32dll/wine/wrapper.S b/src/libw32dll/wine/wrapper.S index fe2d85619..72b4dfe8f 100644 --- a/src/libw32dll/wine/wrapper.S +++ b/src/libw32dll/wine/wrapper.S @@ -1,17 +1,19 @@ .section .data -.globl caller_return caller_return: .long 0 -.globl report_entry -report_entry: - .long null_call -.globl report_ret -report_ret: - .long null_call .global wrapper_target wrapper_target: .long null_call +#undef __i686 /* gcc define gets in our way */ + .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits +.globl __i686.get_pc_thunk.bx + .hidden __i686.get_pc_thunk.bx + .type __i686.get_pc_thunk.bx,@function +__i686.get_pc_thunk.bx: + movl (%esp), %ebx + ret + .section .text .globl null_call .type null_call, @function @@ -22,46 +24,61 @@ null_call: .type wrapper, @function .balign 16,0x90 wrapper: + pushl $0 pusha # store registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) pushf # store flags push %ebp # set up a stack frame movl %esp, %ebp + call __i686.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr push %eax - leal 40(%ebp), %edx + leal 44(%ebp), %edx movl (%ebp), %eax subl %edx, %eax push %eax push %edx - call *report_entry # report entry + call report_func@PLT # report entry test %eax, %eax jnz .Ldone + movl 44(%ebp), %eax # switch return addresses + movl %eax, caller_return@GOTOFF(%ebx) + leal .Lwrapper_return@GOTOFF(%ebx), %eax + movl %eax, 40(%ebp) + + movl wrapper_target@GOT(%ebx), %eax + movl (%eax), %eax + mov %eax, 40(%ebp) # wrapper_target should return at .Lwrapper_return + leave # restore %esp, %ebp popf # restore flags popa # restore registers - - popl caller_return # switch return addresses - pushl $.Lwrapper_return - - jmp *wrapper_target # wrapper_target should return at .Lwrapper_return + + ret # fake 'return' to wrapper_target actually .balign 16, 0x90 .Lwrapper_return: - pushl caller_return # restore the original return address + pushl $0 pusha # more for reference sake here pushf push %ebp # set up a stack frame movl %esp, %ebp + call __i686.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl caller_return@GOTOFF(%ebx), %eax + movl %eax, 40(%ebp) # restore the original return address + leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr @@ -73,11 +90,13 @@ wrapper: push %eax push %edx - call *report_ret # report the return information (same args) + call report_func_ret@PLT# report the return information (same args) .Ldone: leave popf popa ret - + +.section .note.GNU-stack,"",@progbits + |
