This is an automated email from the ASF dual-hosted git repository.
leginee pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/trunk by this push:
new 079530e0cc Win64 bridge backport (#492)
079530e0cc is described below
commit 079530e0cc63d88d2438d6ca375766814976df0e
Author: Peter <[email protected]>
AuthorDate: Sat Aug 1 10:24:35 2026 +0000
Win64 bridge backport (#492)
* bridges/msvc_win64: pass simple argument values, not the temp's address
uno2cpp.cxx converts each simple by-value argument into an 8-byte alloca
temp and stores the pointer in pCppArgs[nPos]:
uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), ... );
Copying the value into the outgoing slot therefore has to dereference that
pointer. The marshalling switch used &pCppArgs[nPos] instead, which reads
the pCppArgs array slot itself, i.e. the temp's address -- so every HYPER,
LONG, ENUM, SHORT, CHAR, BOOLEAN, BYTE, FLOAT and DOUBLE parameter reached
the callee as a stack address (or its low 16/32 bits) rather than a value.
The same expression is correct in the complex/ref branch, where the pointer
IS the argument; written there as (sal_uInt64)pCppArgs[nPos] to make the
difference between the two branches obvious.
This only affects calls that cross between the uno and cpp environments, so
a pure-C++ session never trips it; it surfaces via pyuno and the invocation
adapters.
Co-Authored-By: Claude Opus 5 <[email protected]>
* bridges/msvc_win64: return queryInterface's Any in the hidden return
buffer
The Win64 call stack is "ret addr, this, [ret *], params", so a method with
a hidden return pointer finds it at pCallStack[2] -- cpp2uno_call() reads
pCppReturn from [2], and the queryInterface shortcut in cpp_mediate() reads
its Type argument from [3] accordingly.
That shortcut nevertheless built the returned Any at pCallStack[1] and
returned [1] in the register slot. [1] is `this`, so it constructed a
24-byte Any over the proxy object and never wrote the caller's own return
buffer. The caller then read and destructed an uninitialised Any, faulting
in uno_any_destruct() on a stale stack value used as a
typelib_TypeDescription*.
The x86 bridge has always used pCallStack[2] here; the Win64 port carried
over the x86 index, where the layout puts the hidden pointer before `this`.
Reproducer: any queryInterface on a raw uno_Interface proxy -- e.g. pyuno's
Adapter::getOutIndexes() inspecting an InvocationAdapterFactory adapter,
which crashed on every use of the Python macro organiser.
Co-Authored-By: Claude Opus 5 <[email protected]>
* pre-commit: fix whitespace in the msvc_win64 bridge sources
The x64 bridge backport in ebdb555ed2 brought these files over from
origin/windows-amd64, a branch predating the tree-wide whitespace
cleanups in #383 and #462, so it silently reintroduced trailing
whitespace in the license headers of call.asm, cpp2uno.cxx and
except.cxx plus a stray blank line at the end of except.cxx.
Since the pre-commit workflow runs with --all-files, this fails the
check on every pull request against trunk, not just ones touching
these files.
Co-Authored-By: Claude Opus 5 <[email protected]>
---------
Co-authored-by: Claude Opus 5 <[email protected]>
---
.../bridges/source/cpp_uno/msvc_win64_x86-64/call.asm | 10 +++++-----
.../source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx | 19 ++++++++++++-------
.../source/cpp_uno/msvc_win64_x86-64/except.cxx | 19 +++++++++----------
.../source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx | 18 ++++++++++++------
4 files changed, 38 insertions(+), 28 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 402d7e2319..ebee156e3a 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
@@ -6,16 +6,16 @@
; to you under the Apache License, Version 2.0 (the
; "License"); you may not use this file except in compliance
; with the License. You may obtain a copy of the License at
-;
+;
; http://www.apache.org/licenses/LICENSE-2.0
-;
+;
; Unless required by applicable law or agreed to in writing,
; software distributed under the License is distributed on an
; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
; KIND, either express or implied. See the License for the
; specific language governing permissions and limitations
; under the License.
-;
+;
typelib_TypeClass_VOID equ 0
@@ -79,7 +79,7 @@ privateSnippetExecutor PROC FRAME
sub rsp, 48
.ENDPROLOG
- ; 4th param: sal_uInt64 *pRegisterReturn
+ ; 4th param: sal_uInt64 *pRegisterReturn
lea r9, -8[rbp]
; 3rd param: sal_Int32 nVtableOffset
@@ -183,7 +183,7 @@ populateArgumentRegisters:
.ENDPROLOG
-
+
callMethod:
; Find the method pointer
mov rax, 16[rbp]
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
index 59f250784c..aa3c1a7086 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/cpp2uno.cxx
@@ -1,5 +1,5 @@
/**************************************************************
- *
+ *
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,16 +7,16 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
+ *
*************************************************************/
@@ -301,13 +301,18 @@ extern "C" typelib_TypeClass cpp_vtable_call(
if ( pInterface )
{
- ::uno_any_construct(
reinterpret_cast<uno_Any *>( pCallStack[1] ),
+ // pCallStack is "ret addr, this, [ret *],
params", so the
+ // hidden return buffer is [2]; [1] is
`this`. Writing the
+ // Any to [1] overwrote the proxy object
and left the
+ // caller's return buffer untouched, so the
caller then
+ // destructed an uninitialised Any.
+ ::uno_any_construct(
reinterpret_cast<uno_Any *>( pCallStack[2] ),
&pInterface, pTD, cpp_acquire );
pInterface->release();
TYPELIB_DANGER_RELEASE( pTD );
- reinterpret_cast<void **>( pRegisterReturn
)[0] = pCallStack[1];
+ reinterpret_cast<void **>( pRegisterReturn
)[0] = pCallStack[2];
eRet = typelib_TypeClass_ANY;
break;
}
@@ -366,7 +371,7 @@ unsigned char * codeSnippet(
// rsp+08 +----------------------------+ -------
// | return address |
// rsp--> +----------------------------+
- //
+ //
//
// When it doubt about correctness,
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
index 98218480ab..d689dccd6e 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/except.cxx
@@ -1,5 +1,5 @@
/**************************************************************
- *
+ *
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,16 +7,16 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
+ *
*************************************************************/
@@ -486,7 +486,7 @@ ExceptionInfos::~ExceptionInfos() throw ()
#if OSL_DEBUG_LEVEL > 1
OSL_TRACE( "> freeing exception infos... <\n" );
#endif
-
+
MutexGuard aGuard( _aMutex );
for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
iPos != _allRaiseInfos.end(); ++iPos )
@@ -608,7 +608,7 @@ int mscx_filterCppException(
// handle only C++ exceptions:
if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
return EXCEPTION_CONTINUE_SEARCH;
-
+
#if _MSC_VER < 1300 // MSVC -6
bool rethrow = (pRecord->NumberParameters < 4 ||
pRecord->ExceptionInformation[ 2 ] == 0);
@@ -633,7 +633,7 @@ int mscx_filterCppException(
// rethrow: handle only C++ exceptions:
if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
return EXCEPTION_CONTINUE_SEARCH;
-
+
if (pRecord->NumberParameters == 4 &&
// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
pRecord->ExceptionInformation[ 1 ] != 0 &&
@@ -655,7 +655,7 @@ int mscx_filterCppException(
baseAddress + pType->_pTypeInfo )->_m_d_name,
RTL_TEXTENCODING_ASCII_US ) );
OUString aUNOname( toUNOname( aRTTIname ) );
-
+
typelib_TypeDescription * pExcTypeDescr = 0;
typelib_typedescription_getByName(
&pExcTypeDescr, aUNOname.pData );
@@ -699,7 +699,7 @@ int mscx_filterCppException(
#endif
typelib_typedescription_release(
pExcTypeDescr );
}
-
+
return EXCEPTION_EXECUTE_HANDLER;
}
}
@@ -719,4 +719,3 @@ int mscx_filterCppException(
}
#pragma pack(pop)
-
diff --git a/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
b/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
index 2f8e80ca4d..b9e43adb45 100644
--- a/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
+++ b/main/bridges/source/cpp_uno/msvc_win64_x86-64/uno2cpp.cxx
@@ -105,29 +105,34 @@ static void cpp_call(
uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ),
pUnoArgs[nPos], pParamTypeDescr,
pThis->getBridge()->getUno2Cpp() );
+ // pCppArgs[nPos] is the alloca(8) temp above, i.e. a
POINTER to the
+ // converted value -- the value is *pCppArgs[nPos].
Using
+ // &pCppArgs[nPos] would read the array slot instead,
passing the
+ // temp's address as the argument. (That form is
correct only in the
+ // complex/ref branch below, where the pointer IS the
argument.)
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
- *pStack++ = *(sal_uInt64*)&pCppArgs[nPos];
+ *pStack++ = *(sal_uInt64*)pCppArgs[nPos];
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
- *pStack++ = *(sal_uInt32*)&pCppArgs[nPos];
+ *pStack++ = *(sal_uInt32*)pCppArgs[nPos];
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
case typelib_TypeClass_CHAR:
- *pStack++ = *(sal_uInt16*)&pCppArgs[nPos];
+ *pStack++ = *(sal_uInt16*)pCppArgs[nPos];
break;
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
- *pStack++ = *(sal_uInt8*)&pCppArgs[nPos];
+ *pStack++ = *(sal_uInt8*)pCppArgs[nPos];
break;
case typelib_TypeClass_FLOAT:
case typelib_TypeClass_DOUBLE:
- *pStack++ = *(sal_uInt64*)&pCppArgs[nPos]; //
verbatim!
+ *pStack++ = *(sal_uInt64*)pCppArgs[nPos]; //
verbatim!
break;
default:
break;
@@ -164,7 +169,8 @@ static void cpp_call(
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
- *pStack++ = *(sal_uInt64*)&pCppArgs[nPos];
+ // here the POINTER is the argument (complex value
passed by ref)
+ *pStack++ = (sal_uInt64)pCppArgs[nPos];
}
}