This is an automated email from the ASF dual-hosted git repository. damjan pushed a commit to branch windows-amd64 in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 607903dd38f9217a1b2aa61f7ce75d257336de99 Author: Damjan Jovanovic <[email protected]> AuthorDate: Fri Feb 20 04:18:44 2026 +0200 Many fixes to the privateSnippetExecutor and callVirtualMethod assembly language functions on Windows/AMD64: - Write return values <= 8 bytes in size to *pRegisterReturn, instead of overwriting pRegisterReturn with it. - Return values > 8 bytes in size have already been written into *pRegisterReturn by the called function, so don't do anything else. Previously we were writing pRegisterReturn into *pRegisterReturn, corrupting it... - Keep the stack aligned to a 16 byte boundary after the prolog. - Generate .pdata and .xdata sections in the PE32+ binary to allow proper exception unwinding, which is necessary to allow both C++ and SEH exceptions to pass through functions. (On Win64, the only functions that are allowed to lack this static data describing how to unwind them, are leaf functions that don't touch the RBP register.) - Improve documentation in the comments. Patch by: me --- .../source/cpp_uno/msvc_win64_x86-64/call.asm | 48 ++++++++++++++-------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm b/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm index 0b190228d8..402d7e2319 100644 --- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm +++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/call.asm @@ -51,8 +51,8 @@ EXTERN cpp_vtable_call: PROC ; rbp+16 rsp+08 +----------------------------+ ------- ; | return address | ; rbp+08 rsp--> +----------------------------+ -; | old rbp | -; rbp---------> +----------------------------+ +; | caller's rbp | +; rbp---------> +----------------------------+ <------ 16 byte boundary ; | pRegisterReturn memory | ; rbp-08 -----> +----------------------------+ ; | | @@ -72,11 +72,11 @@ EXTERN cpp_vtable_call: PROC ; privateSnippetExecutor PROC FRAME - push rbp + .PUSHREG rbp mov rbp, rsp + .SETFRAME rbp, 0 sub rsp, 48 - .ALLOCSTACK(48) .ENDPROLOG ; 4th param: sal_uInt64 *pRegisterReturn @@ -122,7 +122,7 @@ privateSnippetExecutor ENDP ; rbp+16 -----> +---------------------------------------------+ ------- ; | return address | ; rbp+08 -----> +---------------------------------------------+ -; | old rbp | +; | caller's rbp | ; rbp --------> +---------------------------------------------+ <---- 16 byte boundary ; | (possible 16 byte alignment placeholder) | ; rbp-08 -----> +---------------------------------------------+ @@ -134,8 +134,9 @@ privateSnippetExecutor ENDP callVirtualMethod PROC FRAME push rbp + .PUSHREG rbp mov rbp, rsp - .ENDPROLOG + .SETFRAME rbp, 0 ; Save our register arguments to the shadow space: mov 16[rbp], rcx @@ -143,22 +144,28 @@ callVirtualMethod PROC FRAME mov 32[rbp], r8 mov 40[rbp], r9 - ; We must maintain the stack aligned to a 16 byte boundary: + ; nStack rounded to multiple of 2, so the stack is aligned to a 16 byte boundary: mov eax, 56[rbp] - test eax, eax - jz populateArgumentRegisters inc eax shr eax, 1 shl eax, 1 + ; if nStack < 4, add (4 - nStack) empty slots to the stack: + mov r10d, 4 + sub r10d, eax + js copyStack + shl r10, 3 + sub rsp, r10 + +copyStack: mov r10, rax shl rax, 3 add rax, 48[rbp] -copyStack: +copyStackLoop: sub rax, 8 push [rax] dec r10 - jne copyStack + jne copyStackLoop populateArgumentRegisters: ; First 4 args are passed in registers. Floating point args needs to be @@ -173,6 +180,9 @@ populateArgumentRegisters: movsd xmm2, qword ptr 16[rsp] mov r9, 24[rsp] movsd xmm3, qword ptr 24[rsp] + + .ENDPROLOG + callMethod: ; Find the method pointer @@ -184,6 +194,7 @@ callMethod: call qword ptr [r10] mov r10d, 40[rbp] + mov r11, 32[rbp] cmp r10, typelib_TypeClass_VOID je cleanup cmp r10, typelib_TypeClass_LONG @@ -213,30 +224,31 @@ callMethod: ; https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2017 ; "The same pointer must be returned by the callee in RAX." - jmp Lint64 + jmp cleanup Lint64: - mov 32[rbp], rax + mov qword ptr [r11], rax jmp cleanup Lint32: - mov 32[rbp], eax + mov dword ptr [r11], eax jmp cleanup Lint16: - mov 32[rbp], ax + mov word ptr [r11], ax jmp cleanup Lint8: - mov 32[rbp], al + mov byte ptr [r11], al jmp cleanup Lfloat: - movsd qword ptr 32[rbp], xmm0 + movsd qword ptr [r11], xmm0 jmp cleanup cleanup: - leave + lea rsp, 0[rbp] + pop rbp ret callVirtualMethod ENDP
