This is an automated email from the ASF dual-hosted git repository.
jimjag 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 245a583a7b Substantially harden the macOS Silicon bridge
new 9aebfb1384 Merge branch 'trunk' of
https://github.com/apache/openoffice into trunk
245a583a7b is described below
commit 245a583a7b65e1047b3d72e26165ab349b0ae791
Author: Jim Jagielski <[email protected]>
AuthorDate: Mon Aug 3 07:56:36 2026 -0400
Substantially harden the macOS Silicon bridge
---
.../source/cpp_uno/s5abi_macosx_aarch64/abi.cxx | 40 ++++-
.../source/cpp_uno/s5abi_macosx_aarch64/abi.hxx | 5 +
.../source/cpp_uno/s5abi_macosx_aarch64/call.s | 56 +++++--
.../cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx | 27 ++-
.../source/cpp_uno/s5abi_macosx_aarch64/except.cxx | 184 +++++----------------
.../source/cpp_uno/s5abi_macosx_aarch64/share.hxx | 73 +-------
.../cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx | 138 ++++++++++------
.../source/cpp_uno/shared/vtablefactory.cxx | 6 +
main/solenv/bin/addsym-macosx.sh | 2 +-
main/solenv/src/component.map | 2 +
main/testtools/source/bridgetest/bridgetest.cxx | 54 ++++++
main/testtools/source/bridgetest/cppobj.cxx | 25 +++
.../testtools/source/bridgetest/idl/bridgetest.idl | 48 ++++++
13 files changed, 381 insertions(+), 279 deletions(-)
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
index 48d7ce36aa..d99ee651ee 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
@@ -49,6 +49,7 @@
#include "bridges/cpp_uno/shared/types.hxx"
#include <rtl/ustring.hxx>
+#include <string.h>
using namespace aarch64;
@@ -135,6 +136,14 @@ bool collectHfa( typelib_TypeDescriptionReference
*pTypeRef, HfaKind &rKind, int
for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
bOk = collectHfa( pComp->ppTypeRefs[i], rKind, rCount );
+ if ( bOk )
+ {
+ sal_Int32 elementSize = rKind == HFA_FLOAT ? 4 : 8;
+ bOk = pTypeDescr->nSize == rCount * elementSize;
+ for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
+ bOk = pComp->pMemberOffsets[i] % elementSize == 0;
+ }
+
TYPELIB_DANGER_RELEASE( pTypeDescr );
return bOk;
}
@@ -316,9 +325,32 @@ void aarch64::fill_struct(
typelib_TypeDescriptionReference *pTypeRef, const sal
}
else
{
- // Non-HFA aggregate <= 16 bytes: raw copy of the 1-2 GPRs.
- sal_uInt64 *pDest = reinterpret_cast<sal_uInt64 *>( pStruct );
- for ( int i = 0; i < nUsedGPR; ++i )
- pDest[i] = pGPR[i];
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+ // The registers contain up to 16 bytes, but the destination has the
+ // aggregate's exact size and need not be 64-bit aligned.
+ memcpy( pStruct, pGPR, pTypeDescr->nSize );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
}
}
+
+sal_uInt32 aarch64::align_stack_offset(
+ sal_uInt32 offset, typelib_TypeDescriptionReference *pTypeRef )
+{
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+ sal_uInt32 alignment = pTypeDescr->nAlignment;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ if ( alignment == 0 )
+ alignment = 1;
+ return (offset + alignment - 1) & ~(alignment - 1);
+}
+
+sal_uInt32 aarch64::stack_size( typelib_TypeDescriptionReference *pTypeRef )
+{
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+ sal_uInt32 size = pTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return size;
+}
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
index e6b210afdb..8bdd0d9a9d 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
@@ -90,6 +90,11 @@ sal_uInt32 get_return_kind( typelib_TypeDescriptionReference
*pTypeRef );
*/
void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const
sal_uInt64* pGPR, const double* pFPR, void *pStruct );
+sal_uInt32 align_stack_offset(
+ sal_uInt32 offset, typelib_TypeDescriptionReference *pTypeRef );
+
+sal_uInt32 stack_size( typelib_TypeDescriptionReference *pTypeRef );
+
} // namespace aarch64
#endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
index 25677b3294..90994778d1 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
@@ -32,8 +32,8 @@
// sal_uInt64 pIndirectRet, // x1: value for x8 (indirect result ptr), 0
if none
// sal_uInt64 *pGPR, // x2: 8 words -> x0..x7
// double *pFPR, // x3: 8 doubles -> d0..d7
-// sal_uInt64 *pStack, // x4: overflow-arg words
-// sal_uInt32 nStackWords, // x5: number of 8-byte overflow words
+// unsigned char *pStack, // x4: packed overflow-argument bytes
+// sal_uInt32 nStackBytes, // x5: byte count
// sal_uInt64 *pGPRReturn, // x6: [out] x0,x1
// double *pFPRReturn); // x7: [out] d0..d3 (HFA up to 4 elements)
@@ -51,6 +51,12 @@ _callVirtualFunction:
.cfi_def_cfa x29, 64
.cfi_offset x29, -16
.cfi_offset x30, -8
+ .cfi_offset x19, -32
+ .cfi_offset x20, -24
+ .cfi_offset x21, -48
+ .cfi_offset x22, -40
+ .cfi_offset x23, -64
+ .cfi_offset x24, -56
// stash inputs that must survive the call into callee-saved registers
mov x19, x0 // pFunction
@@ -61,17 +67,16 @@ _callVirtualFunction:
mov x24, x1 // x8 indirect-result value
// allocate and copy the outgoing overflow stack arguments.
- // bytes = ((nStackWords + 1) & ~1) * 8, to keep sp 16-byte aligned.
- add x9, x5, #1
- bic x9, x9, #1
- lsl x9, x9, #3
+ // Round the packed byte area up to preserve 16-byte SP alignment.
+ add x9, x5, #15
+ bic x9, x9, #15
sub sp, sp, x9
mov x10, #0
Lcvf_copy:
cmp x10, x5
b.ge Lcvf_copied
- ldr x11, [x4, x10, lsl #3]
- str x11, [sp, x10, lsl #3]
+ ldrb w11, [x4, x10]
+ strb w11, [sp, x10]
add x10, x10, #1
b Lcvf_copy
Lcvf_copied:
@@ -168,10 +173,24 @@ _privateSnippetExecutor:
b.eq Lpse_float
cmp w0, #11 // typelib_TypeClass_DOUBLE
b.eq Lpse_float
- // integer / pointer / <=16B aggregate: load both banks; caller reads the
- // ones that matter for its return type.
+ cmp w0, #3 // typelib_TypeClass_BYTE
+ b.eq Lpse_signed_byte
+ cmp w0, #4 // typelib_TypeClass_SHORT
+ b.eq Lpse_signed_short
+ cmp w0, #1 // typelib_TypeClass_CHAR
+ b.eq Lpse_unsigned_short
+ cmp w0, #5 // typelib_TypeClass_UNSIGNED_SHORT
+ b.eq Lpse_unsigned_short
+ cmp w0, #2 // typelib_TypeClass_BOOLEAN
+ b.eq Lpse_unsigned_byte
+ cmp w0, #6 // typelib_TypeClass_LONG
+ b.eq Lpse_word
+ cmp w0, #7 // typelib_TypeClass_UNSIGNED_LONG
+ b.eq Lpse_word
+ cmp w0, #15 // typelib_TypeClass_ENUM
+ b.eq Lpse_word
+ // Integer / pointer / <=16B aggregate.
ldp x0, x1, [sp, #144]
- ldp d0, d1, [sp, #144]
b Lpse_done
Lpse_float:
ldr d0, [sp, #144]
@@ -185,6 +204,21 @@ Lpse_hfa_float:
Lpse_hfa_double:
ldp d0, d1, [sp, #144]
ldp d2, d3, [sp, #160]
+ b Lpse_done
+Lpse_signed_byte:
+ ldrsb w0, [sp, #144]
+ b Lpse_done
+Lpse_unsigned_byte:
+ ldrb w0, [sp, #144]
+ b Lpse_done
+Lpse_signed_short:
+ ldrsh w0, [sp, #144]
+ b Lpse_done
+Lpse_unsigned_short:
+ ldrh w0, [sp, #144]
+ b Lpse_done
+Lpse_word:
+ ldr w0, [sp, #144]
Lpse_done:
mov sp, x29
ldp x29, x30, [sp], #176
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
index 5d8161498e..c6bb914985 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
@@ -69,12 +69,13 @@ static typelib_TypeClass cpp2uno_call(
const typelib_TypeDescription * pMemberTypeDescr,
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void
return
sal_Int32 nParams, typelib_MethodParameter * pParams,
- void ** gpreg, void ** fpreg, void ** ovrflw,
+ void ** gpreg, void ** fpreg, unsigned char * ovrflw,
void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if
none)
sal_uInt64 * pRegisterReturn /* space for register return */ )
{
unsigned int nr_gpr = 0; //number of gpr registers used
unsigned int nr_fpr = 0; //number of fpr registers used
+ sal_uInt32 stackOffset = 0;
// return
typelib_TypeDescription * pReturnTypeDescr = 0;
@@ -137,7 +138,12 @@ static typelib_TypeClass cpp2uno_call(
nr_fpr++;
}
else
- pCppArgs[nPos] = pUnoArgs[nPos] =
ovrflw++;
+ {
+ stackOffset =
aarch64::align_stack_offset(
+ stackOffset, rParam.pTypeRef );
+ pCppArgs[nPos] = pUnoArgs[nPos] =
ovrflw + stackOffset;
+ stackOffset += aarch64::stack_size(
rParam.pTypeRef );
+ }
}
else if ( nUsedGPR == 1 )
{
@@ -147,7 +153,12 @@ static typelib_TypeClass cpp2uno_call(
nr_gpr++;
}
else
- pCppArgs[nPos] = pUnoArgs[nPos] =
ovrflw++;
+ {
+ stackOffset =
aarch64::align_stack_offset(
+ stackOffset, rParam.pTypeRef );
+ pCppArgs[nPos] = pUnoArgs[nPos] =
ovrflw + stackOffset;
+ stackOffset += aarch64::stack_size(
rParam.pTypeRef );
+ }
}
}
else // struct <= 16 bytes || ptr to complex value || ref
@@ -162,7 +173,13 @@ static typelib_TypeClass cpp2uno_call(
nr_gpr++;
}
else
- pCppArgs[nPos] = pCppStack = *ovrflw++;
+ {
+ stackOffset = (stackOffset + sizeof(void *) -
1) &
+ ~(sizeof(void *) - 1);
+ pCppArgs[nPos] = pCppStack =
+ *reinterpret_cast<void **>( ovrflw +
stackOffset );
+ stackOffset += sizeof(void *);
+ }
if (! rParam.bIn) // is pure out
{
@@ -264,7 +281,7 @@ static typelib_TypeClass cpp2uno_call(
//==================================================================================================
extern "C" sal_uInt32 cpp_vtable_call(
sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
- void ** gpreg, void ** fpreg, void ** ovrflw,
+ void ** gpreg, void ** fpreg, unsigned char * ovrflw,
void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if
none)
sal_uInt64 * pRegisterReturn /* space for register return */ )
{
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
index 1e88673b81..7d920cf975 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
@@ -60,14 +60,27 @@ namespace CPPU_CURRENT_NAMESPACE
namespace {
+typedef hash_map< void *, typelib_TypeDescription * > ThrownTypes;
typedef hash_map< OUString, type_info *, OUStringHash > ObservedRttiMap;
+ThrownTypes & thrownTypes()
+{
+ static ThrownTypes types;
+ return types;
+}
+
ObservedRttiMap & observedRttis()
{
static ObservedRttiMap map;
return map;
}
+Mutex & observedRttisMutex()
+{
+ static Mutex mutex;
+ return mutex;
+}
+
}
void dummy_can_throw_anything( char const * )
@@ -119,9 +132,6 @@ class RTTI
Mutex m_mutex;
t_rtti_map m_rttis;
- t_rtti_map m_generatedRttis;
-
- void * m_hApp;
public:
RTTI() SAL_THROW( () );
@@ -132,14 +142,12 @@ public:
//__________________________________________________________________________________________________
RTTI::RTTI() SAL_THROW( () )
- : m_hApp( dlopen( 0, RTLD_LAZY ) )
{
}
//__________________________________________________________________________________________________
RTTI::~RTTI() SAL_THROW( () )
{
- dlclose( m_hApp );
}
//__________________________________________________________________________________________________
@@ -151,9 +159,12 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription
*pTypeDescr ) SAL_THR
MutexGuard guard( m_mutex );
- ObservedRttiMap::const_iterator observed( observedRttis().find( unoName )
);
- if ( observed != observedRttis().end() )
- return observed->second;
+ {
+ MutexGuard observedGuard( observedRttisMutex() );
+ ObservedRttiMap::const_iterator observed( observedRttis().find(
unoName ) );
+ if ( observed != observedRttis().end() )
+ return observed->second;
+ }
t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
if (iFind == m_rttis.end())
@@ -177,50 +188,10 @@ type_info * RTTI::getRTTI(
typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
if (rtti)
{
- pair< t_rtti_map::iterator, bool > insertion(
- m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
- OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) );
}
else
- {
- // try to lookup the symbol in the generated rtti map
- t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName
) );
- if (iFind2 == m_generatedRttis.end())
- {
- // we must generate it !
- // symbol and rtti-name is nearly identical,
- // the symbol is prefixed with _ZTI
- char const * rttiName = symName.getStr() +4;
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr,"generated rtti for %s\n", rttiName );
- const OString aCUnoName = OUStringToOString( unoName,
RTL_TEXTENCODING_UTF8);
- OSL_TRACE( "TypeInfo for \"%s\" not found and cannot be
generated.\n", aCUnoName.getStr());
-#endif
-#ifndef AOO_BYPASS_RTTI
- if (pTypeDescr->pBaseTypeDescription)
- {
- // ensure availability of base
- type_info * base_rtti = getRTTI(
- (typelib_CompoundTypeDescription
*)pTypeDescr->pBaseTypeDescription );
- rtti = new __si_class_type_info(
- strdup( rttiName ), (__class_type_info *)base_rtti );
- }
- else
- {
- // this class has no base class
- rtti = new __class_type_info( strdup( rttiName ) );
- }
-#else
- rtti = NULL;
-#endif
- bool bOK = m_generatedRttis.insert( t_rtti_map::value_type(
unoName, rtti )).second;
- OSL_ENSURE( bOK, "### inserting new generated rtti failed?!" );
- }
- else // taking already generated rtti
- {
- rtti = iFind2->second;
- }
- }
+ rtti = 0;
}
else
{
@@ -233,25 +204,21 @@ type_info * RTTI::getRTTI(
typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
//--------------------------------------------------------------------------------------------------
static void deleteException( void * pExc )
{
- __cxa_exception const * header = static_cast<__cxa_exception const
*>(pExc) - 1;
- /* More __cxa_exception mumbo-jumbo. See share.hxx and fillUnoException()
below */
- if (header->exceptionDestructor != &deleteException)
+ typelib_TypeDescription * pTD = 0;
{
- header = reinterpret_cast<__cxa_exception const
*>(reinterpret_cast<char const *>(header) - 8);
+ MutexGuard guard( observedRttisMutex() );
+ ThrownTypes::iterator i = thrownTypes().find( pExc );
+ if ( i != thrownTypes().end() )
+ {
+ pTD = i->second;
+ thrownTypes().erase( i );
+ }
}
- if( !header->exceptionType)
+ if ( pTD )
{
- return; // NOTE: leak for now
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
}
- typelib_TypeDescription * pTD = 0;
- OUString unoName( toUNOname( header->exceptionType->name() ) );
- ::typelib_typedescription_getByName( &pTD, unoName.pData );
- OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction =>
leaking!!!" );
- if (pTD)
- {
- ::uno_destructData( pExc, pTD, cpp_release );
- ::typelib_typedescription_release( pTD );
- }
}
//==================================================================================================
@@ -266,6 +233,8 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping *
pUno2Cpp )
#endif
void * pCppExc;
type_info * rtti;
+ OUString typeName(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ) );
{
// construct cpp exception object
@@ -283,93 +252,30 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping *
pUno2Cpp )
pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp
);
- // destruct uno exception
- ::uno_any_destruct( pUnoExc, 0 );
- // avoiding locked counts
- static RTTI * s_rtti = 0;
- if (! s_rtti)
- {
- MutexGuard guard( Mutex::getGlobalMutex() );
- if (! s_rtti)
- {
-#ifdef LEAK_STATIC_DATA
- s_rtti = new RTTI();
-#else
- static RTTI rtti_data;
- s_rtti = &rtti_data;
-#endif
- }
- }
- rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription
*) pTypeDescr );
- TYPELIB_DANGER_RELEASE( pTypeDescr );
+ static RTTI rtti_data;
+ rtti = rtti_data.getRTTI(
+ (typelib_CompoundTypeDescription *) pTypeDescr );
OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
if (! rtti)
{
throw RuntimeException(
OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
- *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName
),
+ typeName,
Reference< XInterface >() );
}
- }
-
- __cxa_throw( pCppExc, rtti, deleteException );
-}
-//==================================================================================================
-void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc,
uno_Mapping * pCpp2Uno )
-{
- if (! header)
{
- RuntimeException aRE(
- OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
- Reference< XInterface >() );
- Type const & rType = ::getCppuType( &aRE );
- uno_type_any_constructAndConvert( pUnoExc, &aRE,
rType.getTypeLibType(), pCpp2Uno );
-#if OSL_DEBUG_LEVEL > 0
- OString cstr( OUStringToOString( aRE.Message,
RTL_TEXTENCODING_ASCII_US ) );
- OSL_ENSURE( 0, cstr.getStr() );
-#endif
- return;
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ typelib_typedescription_acquire( pTypeDescr );
+ thrownTypes()[pCppExc] = pTypeDescr;
}
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
- /*
- * Handle the case where we are built on llvm 10 (or later) but are running
- * on an earlier version (eg, community builds). In this situation the
- * reserved ptr doesn't exist in the struct returned and so the offsets
- * that header uses are wrong. This assumes that reserved isn't used
- * and that referenceCount is always >0 in the cases we handle.
- * See share.hxx for the definition of __cxa_exception
- */
- if (*reinterpret_cast<void **>(header) == 0)
- {
- header = reinterpret_cast<__cxa_exception *>(reinterpret_cast<char
*>(header) + 8);
+ // The C++ payload and its retained type description now own the value.
+ ::uno_any_destruct( pUnoExc, 0 );
}
- typelib_TypeDescription * pExcTypeDescr = 0;
- OUString unoName( toUNOname( header->exceptionType->name() ) );
-#if OSL_DEBUG_LEVEL > 1
- OString cstr_unoName( OUStringToOString( unoName,
RTL_TEXTENCODING_ASCII_US ) );
- fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() );
-#endif
- typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
- if (0 == pExcTypeDescr)
- {
- RuntimeException aRE(
- OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found:
") ) + unoName,
- Reference< XInterface >() );
- Type const & rType = ::getCppuType( &aRE );
- uno_type_any_constructAndConvert( pUnoExc, &aRE,
rType.getTypeLibType(), pCpp2Uno );
-#if OSL_DEBUG_LEVEL > 0
- OString cstr( OUStringToOString( aRE.Message,
RTL_TEXTENCODING_ASCII_US ) );
- OSL_ENSURE( 0, cstr.getStr() );
-#endif
- }
- else
- {
- // construct uno exception any
- uno_any_constructAndConvert( pUnoExc, header->adjustedPtr,
pExcTypeDescr, pCpp2Uno );
- typelib_typedescription_release( pExcTypeDescr );
- }
+ __cxa_throw( pCppExc, rtti, deleteException );
}
void fillUnoException(
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
index 451f925b4a..aeac9e526f 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
@@ -32,88 +32,17 @@ namespace CPPU_CURRENT_NAMESPACE
void dummy_can_throw_anything( char const * );
-typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
-
-// ----- the following structure is compatible with the one declared in
libunwind's unwind.h
-// (use forced types)
-
-struct _Unwind_Exception
-{
- uint64_t exception_class;
- void * exception_cleanup;
- uintptr_t private_1;
- uintptr_t private_2;
-};
-
-struct __cxa_exception
-{
- /* From LLVM 10 a reserved member was added at the top of the struct on
- 64-bit targets. Who the hell does that?
- https://reviews.llvm.org/rG674ec1eb16678b8addc02a4b0534ab383d22fa77
- It is required on arm64 (Apple Silicon): the trailing _Unwind_Exception
- must be 16-byte aligned within the allocation, and only WITH this member
- does unwindHeader land at a 16-byte boundary (offset 96, vs a misaligned
- 88 without it). Verified empirically against this host's libc++abi.
- NOTE: Apple clang version != upstream LLVM version. */
- void *reserved;
- size_t referenceCount;
- ::std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
- ::std::unexpected_handler unexpectedHandler;
- ::std::terminate_handler terminateHandler;
- __cxa_exception *nextException;
- int handlerCount;
- int handlerSwitchValue;
- const unsigned char *actionRecord;
- const unsigned char *languageSpecificData;
- void *catchTemp;
- void *adjustedPtr;
- _Unwind_Exception unwindHeader;
-};
-
extern "C" void *__cxa_allocate_exception(
std::size_t thrown_size ) throw();
+extern "C" void __cxa_free_exception( void *thrown_exception ) throw();
extern "C" void __cxa_throw (
void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) )
__attribute__((noreturn));
-
-struct __cxa_eh_globals
-{
- __cxa_exception *caughtExceptions;
- unsigned int uncaughtExceptions;
-};
-extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
extern "C" std::type_info *__cxa_current_exception_type();
-// -----
-
-// on OSX 64bit the class_type_info classes are specified
-// in http://refspecs.linuxbase.org/cxxabi-1.86.html#rtti but
-// these details are not generally available in a public header
-// of most development environments. So we define them here.
-// NOTE:
https://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf
-class __class_type_info : public std::type_info
-{
-public:
- explicit __class_type_info( const char* pRttiName)
- : std::type_info( pRttiName)
- {}
-};
-
-class __si_class_type_info : public __class_type_info
-{
- const __class_type_info* mpBaseType;
-public:
- explicit __si_class_type_info( const char* pRttiName,
__class_type_info* pBaseType)
- : __class_type_info( pRttiName), mpBaseType( pBaseType)
- {}
-};
-
//==================================================================================================
void raiseException(
uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
//==================================================================================================
-void fillUnoException(
- __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
void fillUnoException(
std::type_info const & type, void * exception, uno_Any *,
uno_Mapping * pCpp2Uno );
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
index fdecf3c547..41c1bc3048 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
@@ -56,20 +56,20 @@ using namespace ::com::sun::star::uno;
extern "C" void callVirtualFunction(
sal_uInt64 pFunction, sal_uInt64 pIndirectRet,
sal_uInt64 *pGPR, double *pFPR,
- sal_uInt64 *pStack, sal_uInt32 nStackWords,
+ unsigned char *pStack, sal_uInt32 nStackBytes,
sal_uInt64 *pGPRReturn, double *pFPRReturn );
static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
void * pRegisterReturn,
typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
void * pIndirectReturn,
- sal_uInt64 *pStack, sal_uInt32 nStack,
+ unsigned char *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR)
__attribute__((noinline));
static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
void * pRegisterReturn,
typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
void * pIndirectReturn,
- sal_uInt64 *pStack, sal_uInt32 nStack,
+ unsigned char *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR)
{
@@ -136,27 +136,40 @@ static void callVirtualMethod(void * pThis, sal_uInt32
nVtableIndex,
*reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = gpReturn[0];
break;
case typelib_TypeClass_LONG:
+ *reinterpret_cast<sal_Int32 *>( pRegisterReturn ) =
+ *reinterpret_cast<sal_Int32 *>( &gpReturn[0] );
+ break;
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
- *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) =
*reinterpret_cast<sal_uInt32*>( &gpReturn[0] );
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) =
+ *reinterpret_cast<sal_uInt32 *>( &gpReturn[0] );
break;
case typelib_TypeClass_CHAR:
- case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
*reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) =
*reinterpret_cast<sal_uInt16*>( &gpReturn[0] );
break;
+ case typelib_TypeClass_SHORT:
+ *reinterpret_cast<sal_Int16 *>( pRegisterReturn ) =
+ *reinterpret_cast<sal_Int16 *>( &gpReturn[0] );
+ break;
case typelib_TypeClass_BOOLEAN:
- case typelib_TypeClass_BYTE:
*reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) =
*reinterpret_cast<sal_uInt8*>( &gpReturn[0] );
break;
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_Int8 *>( pRegisterReturn ) =
+ *reinterpret_cast<sal_Int8 *>( &gpReturn[0] );
+ break;
case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) =
+ *reinterpret_cast<float *>( &fpReturn[0] );
+ break;
case typelib_TypeClass_DOUBLE:
*reinterpret_cast<double *>( pRegisterReturn ) = fpReturn[0];
break;
default:
{
sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
- if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
+ if (bSimpleReturn && nRetSize > 0)
{
// Register-returned aggregate: an HFA arrives in d0..d3, a
// non-HFA <= 16 bytes in x0,x1. fill_struct picks the right
one.
@@ -169,52 +182,52 @@ static void callVirtualMethod(void * pThis, sal_uInt32
nVtableIndex,
//==================================================================================================
-// Macros for easier insertion of values to registers or stack
+// Macros for inserting values into registers. Stack arguments are handled
+// separately with a byte cursor because Apple packs them by size/alignment.
// pSV - pointer to the source
// nr - order of the value [will be increased if stored to register]
// pFPR, pGPR - pointer to the registers
-// pDS - pointer to the stack [will be increased if stored here]
// Each pFPR slot is the low 64 bits of a v register. A float occupies only
// the low 32 bits, while a double occupies all 64 bits.
-#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+#define INSERT_FLOAT( pSV, nr, pFPR ) \
if ( nr < aarch64::MAX_FPR_REGS ) \
{ \
pFPR[nr] = 0; \
*reinterpret_cast<float *>( pFPR + nr++ ) =
*reinterpret_cast<const float *>( pSV ); \
- } \
- else \
- *pDS++ = *reinterpret_cast<const sal_uInt32 *>( pSV );
+ }
-#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+#define INSERT_DOUBLE( pSV, nr, pFPR ) \
if ( nr < aarch64::MAX_FPR_REGS ) \
- pFPR[nr++] = *reinterpret_cast<const double *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<const sal_uInt64 *>( pSV ); //
verbatim!
+ pFPR[nr++] = *reinterpret_cast<const double *>( pSV );
+
+#define INSERT_INT64( pSV, nr, pGPR ) \
+ if ( nr < aarch64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<const sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR ) \
+ if ( nr < aarch64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<const sal_uInt32 *>( pSV );
-#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+#define INSERT_SIGNED_INT32( pSV, nr, pGPR ) \
if ( nr < aarch64::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<const sal_uInt64 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<const sal_uInt64 *>( pSV );
+ pGPR[nr++] = static_cast<sal_Int64>( *reinterpret_cast<const
sal_Int32 *>( pSV ) );
-#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+#define INSERT_INT16( pSV, nr, pGPR ) \
if ( nr < aarch64::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+ pGPR[nr++] = *reinterpret_cast<const sal_uInt16 *>( pSV );
-#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+#define INSERT_SIGNED_INT16( pSV, nr, pGPR ) \
if ( nr < aarch64::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+ pGPR[nr++] = static_cast<sal_Int64>( *reinterpret_cast<const
sal_Int16 *>( pSV ) );
-#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+#define INSERT_INT8( pSV, nr, pGPR ) \
if ( nr < aarch64::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+ pGPR[nr++] = *reinterpret_cast<const sal_uInt8 *>( pSV );
+
+#define INSERT_SIGNED_INT8( pSV, nr, pGPR ) \
+ if ( nr < aarch64::MAX_GPR_REGS ) \
+ pGPR[nr++] = static_cast<sal_Int64>( *reinterpret_cast<const
sal_Int8 *>( pSV ) );
//==================================================================================================
@@ -237,10 +250,9 @@ static void cpp_call(
sal_Int32 nParams, typelib_MethodParameter * pParams,
void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
{
- // Maxium space for [complex ret ptr], values | ptr ...
- // (but will be used less - some of the values will be in pGPR and pFPR)
- sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) *
sizeof(sal_uInt64) );
- sal_uInt64 *pStackStart = pStack;
+ unsigned char *pStackStart = static_cast<unsigned char *>(
+ __builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) ) );
+ sal_uInt32 nStack = 0;
sal_uInt64 pGPR[aarch64::MAX_GPR_REGS];
sal_uInt32 nGPR = 0;
@@ -280,7 +292,7 @@ static void cpp_call(
// Push "this" pointer
void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI()
) + aVtableSlot.offset;
- INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR );
// Args
void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
@@ -301,36 +313,59 @@ static void cpp_call(
{
uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ),
pUnoArgs[nPos], pParamTypeDescr,
pThis->getBridge()->getUno2Cpp() );
+ bool onStack = false;
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
- INSERT_INT64( pCppArgs[nPos], nGPR, pGPR,
pStack );
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR );
break;
case typelib_TypeClass_LONG:
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_SIGNED_INT32( pCppArgs[nPos], nGPR, pGPR
);
+ break;
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
- INSERT_INT32( pCppArgs[nPos], nGPR, pGPR,
pStack );
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR );
break;
case typelib_TypeClass_SHORT:
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_SIGNED_INT16( pCppArgs[nPos], nGPR, pGPR
);
+ break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
- INSERT_INT16( pCppArgs[nPos], nGPR, pGPR,
pStack );
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR );
break;
- case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
- INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack
);
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_SIGNED_INT8( pCppArgs[nPos], nGPR, pGPR
);
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ onStack = nGPR >= aarch64::MAX_GPR_REGS;
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR );
break;
case typelib_TypeClass_FLOAT:
- INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR,
pStack );
+ onStack = nFPR >= aarch64::MAX_FPR_REGS;
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR );
break;
case typelib_TypeClass_DOUBLE:
- INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR,
pStack );
+ onStack = nFPR >= aarch64::MAX_FPR_REGS;
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR );
break;
default:
break;
}
+ if ( onStack )
+ {
+ nStack = aarch64::align_stack_offset( nStack,
rParam.pTypeRef );
+ sal_uInt32 size = aarch64::stack_size(
rParam.pTypeRef );
+ memcpy( pStackStart + nStack, pCppArgs[nPos],
size );
+ nStack += size;
+ }
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
@@ -364,7 +399,16 @@ static void cpp_call(
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
- INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ if ( nGPR < aarch64::MAX_GPR_REGS )
+ {
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR );
+ }
+ else
+ {
+ nStack = (nStack + sizeof(void *) - 1) &
~(sizeof(void *) - 1);
+ memcpy( pStackStart + nStack, &pCppArgs[nPos],
sizeof(void *) );
+ nStack += sizeof(void *);
+ }
}
}
@@ -375,7 +419,7 @@ static void cpp_call(
pAdjustedThisPtr, aVtableSlot.index,
pCppReturn, pReturnTypeRef, bSimpleReturn,
pIndirectReturn,
- pStackStart, ( pStack - pStackStart ),
+ pStackStart, nStack,
pGPR, nGPR,
pFPR, nFPR );
} catch (Exception &) {
diff --git a/main/bridges/source/cpp_uno/shared/vtablefactory.cxx
b/main/bridges/source/cpp_uno/shared/vtablefactory.cxx
index 39cdee1cfb..fa7cd1bb4e 100644
--- a/main/bridges/source/cpp_uno/shared/vtablefactory.cxx
+++ b/main/bridges/source/cpp_uno/shared/vtablefactory.cxx
@@ -352,12 +352,18 @@ void VtableFactory::freeBlock(Block const & block) const {
#else
bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
{
+#if defined MACOSX && defined AARCH64
+ JitWriteGuard jitWriteGuard;
+#endif
block.size = getBlockSize(slotCount);
block.start = rtl_arena_alloc(m_arena, &block.size);
return block.start != 0;
}
void VtableFactory::freeBlock(Block const & block) const {
+#if defined MACOSX && defined AARCH64
+ JitWriteGuard jitWriteGuard;
+#endif
rtl_arena_free(m_arena, block.start, block.size);
}
#endif
diff --git a/main/solenv/bin/addsym-macosx.sh b/main/solenv/bin/addsym-macosx.sh
index a0b2ed6601..604440a5b5 100755
--- a/main/solenv/bin/addsym-macosx.sh
+++ b/main/solenv/bin/addsym-macosx.sh
@@ -45,4 +45,4 @@ s#$#$#' | tr '\n' '|' | sed "s#|\$##" >$2
# On Panther we have to filter out symbols with a value "1f" otherwise external
# symbols will erroneously be added to the generated export symbols list file.
awk -v SYMBOLSREGEXP="`cat $2`" '
-match ($6,SYMBOLSREGEXP) > 0 && $6 !~ /_GLOBAL_/ { if (($2 != 1) && ( $2 !=
"1f" ) ) print $6 }'
+match ($6,SYMBOLSREGEXP) > 0 && $6 !~ /_GLOBAL_/ { if (($2 != 1) && (($2 !=
"1f") || ($6 ~ /^__ZT[IS]/))) print $6 }'
diff --git a/main/solenv/src/component.map b/main/solenv/src/component.map
index ae0e47828f..aecd1e1ffe 100644
--- a/main/solenv/src/component.map
+++ b/main/solenv/src/component.map
@@ -22,6 +22,8 @@ UDK_3_0_0 {
global:
component_getImplementationEnvironment;
component_getFactory;
+ _ZTI*;
+ _ZTS*;
local:
*;
};
diff --git a/main/testtools/source/bridgetest/bridgetest.cxx
b/main/testtools/source/bridgetest/bridgetest.cxx
index 70197b1443..e0a5265433 100644
--- a/main/testtools/source/bridgetest/bridgetest.cxx
+++ b/main/testtools/source/bridgetest/bridgetest.cxx
@@ -518,10 +518,64 @@ static sal_Bool performTest(
memcmp(&aIn, &aOut, sizeof(AllFloats)) == 0,
"all floats struct test");
}
+ {
+ TwoFloats aIn(1.25f, -2.5f);
+ TwoFloats aOut(xLBT->echoTwoFloats(aIn));
+ bRet &= check(aOut.a == aIn.a && aOut.b == aIn.b,
+ "two-float HFA test");
+ }
+ {
+ ThreeDoubles aIn(1.25, -2.5, 9.75);
+ ThreeDoubles aOut(xLBT->echoThreeDoubles(aIn));
+ bRet &= check(
+ aOut.a == aIn.a && aOut.b == aIn.b && aOut.c == aIn.c,
+ "three-double HFA test");
+ }
+ {
+ MixedFloatLong aIn(1.25f, -123456);
+ MixedFloatLong aOut(xLBT->echoMixedFloatLong(aIn));
+ bRet &= check(aOut.a == aIn.a && aOut.b == aIn.b,
+ "mixed float-long struct test");
+ }
+ {
+ OneByte aIn(-7);
+ OneByte aOut(xLBT->echoOneByte(aIn));
+ bRet &= check(aOut.value == aIn.value, "one-byte struct test");
+ }
+ {
+ ThreeLongs aIn(0x11223344, -7, 0x55667788);
+ ThreeLongs aOut(xLBT->echoThreeLongs(aIn));
+ bRet &= check(
+ aOut.a == aIn.a && aOut.b == aIn.b && aOut.c == aIn.c,
+ "three-long struct test");
+ }
{
sal_Int32 i2 = xLBT->testPPCAlignment(0, 0, 0, 0, 0xBEAF);
bRet &= check(i2 == 0xBEAF, "ppc-style alignment test");
}
+ {
+ sal_Int8 b = -2;
+ sal_Int8 c = 0x35;
+ sal_Int16 s = -1234;
+ sal_Int32 l = 0x11223344;
+ sal_Int8 d = -7;
+ sal_Int64 h = SAL_CONST_INT64(0x0102030405060708);
+ sal_Int64 expected = ((static_cast<sal_Int64>(b) << 56) |
+ (static_cast<sal_uInt64>(static_cast<sal_uInt8>(c)) << 48)
|
+ (static_cast<sal_uInt64>(static_cast<sal_uInt16>(s)) <<
32) |
+ static_cast<sal_uInt32>(l)) ^
+ (static_cast<sal_Int64>(d) << 24) ^ h;
+ bRet &= check(
+ xLBT->testPackedStack(0, 1, 2, 3, 4, 5, 6, b, c, s, l, d,
h)
+ == expected,
+ "packed stack argument test");
+ }
+ {
+ double result = xLBT->testFpStack(
+ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
+ -3.25f, 9.5);
+ bRet &= check(result == 6.25, "fp stack argument test");
+ }
// Test extended attributes that raise exceptions:
try {
xLBT->getRaiseAttr1();
diff --git a/main/testtools/source/bridgetest/cppobj.cxx
b/main/testtools/source/bridgetest/cppobj.cxx
index b6dd183cd7..5d2cc941fd 100644
--- a/main/testtools/source/bridgetest/cppobj.cxx
+++ b/main/testtools/source/bridgetest/cppobj.cxx
@@ -217,8 +217,33 @@ public:
{ return rStruct; }
virtual AllFloats SAL_CALL echoAllFloats(const AllFloats& rStruct)
throw(com::sun::star::uno::RuntimeException)
{ return rStruct; }
+ virtual TwoFloats SAL_CALL echoTwoFloats(const TwoFloats& rStruct)
throw(com::sun::star::uno::RuntimeException)
+ { return rStruct; }
+ virtual ThreeDoubles SAL_CALL echoThreeDoubles(const ThreeDoubles&
rStruct) throw(com::sun::star::uno::RuntimeException)
+ { return rStruct; }
+ virtual MixedFloatLong SAL_CALL echoMixedFloatLong(const MixedFloatLong&
rStruct) throw(com::sun::star::uno::RuntimeException)
+ { return rStruct; }
+ virtual OneByte SAL_CALL echoOneByte(const OneByte& rStruct)
throw(com::sun::star::uno::RuntimeException)
+ { return rStruct; }
+ virtual ThreeLongs SAL_CALL echoThreeLongs(const ThreeLongs& rStruct)
throw(com::sun::star::uno::RuntimeException)
+ { return rStruct; }
virtual sal_Int32 SAL_CALL testPPCAlignment( sal_Int64, sal_Int64,
sal_Int32, sal_Int64, sal_Int32 i2 )
throw(com::sun::star::uno::RuntimeException)
{ return i2; }
+ virtual sal_Int64 SAL_CALL testPackedStack(
+ sal_Int64, sal_Int64, sal_Int64, sal_Int64, sal_Int64, sal_Int64,
+ sal_Int64, sal_Int8 b, sal_Int8 c, sal_Int16 s, sal_Int32 l,
+ sal_Int8 d, sal_Int64 h) throw(com::sun::star::uno::RuntimeException)
+ {
+ return ((static_cast<sal_Int64>(b) << 56) |
+ (static_cast<sal_uInt64>(static_cast<sal_uInt8>(c)) << 48) |
+ (static_cast<sal_uInt64>(static_cast<sal_uInt16>(s)) << 32) |
+ static_cast<sal_uInt32>(l)) ^
+ (static_cast<sal_Int64>(d) << 24) ^ h;
+ }
+ virtual double SAL_CALL testFpStack(
+ double, double, double, double, double, double, double, double,
+ float f8, double d9) throw(com::sun::star::uno::RuntimeException)
+ { return static_cast<double>(f8) + d9; }
virtual sal_Bool SAL_CALL getBool()
throw(com::sun::star::uno::RuntimeException)
{ return _aData.Bool; }
diff --git a/main/testtools/source/bridgetest/idl/bridgetest.idl
b/main/testtools/source/bridgetest/idl/bridgetest.idl
index e4638aef1f..103bd6f9a6 100644
--- a/main/testtools/source/bridgetest/idl/bridgetest.idl
+++ b/main/testtools/source/bridgetest/idl/bridgetest.idl
@@ -106,6 +106,37 @@ struct AllFloats
float c;
float d;
};
+
+struct TwoFloats
+{
+ float a;
+ float b;
+};
+
+struct ThreeDoubles
+{
+ double a;
+ double b;
+ double c;
+};
+
+struct MixedFloatLong
+{
+ float a;
+ long b;
+};
+
+struct OneByte
+{
+ byte value;
+};
+
+struct ThreeLongs
+{
+ long a;
+ long b;
+ long c;
+};
/**
* complex types adding string, inteface, any
*/
@@ -261,12 +292,29 @@ interface XBridgeTestBase :
com::sun::star::uno::XInterface
* register return test 4
*/
AllFloats echoAllFloats( [in] AllFloats aStruct );
+ TwoFloats echoTwoFloats( [in] TwoFloats aStruct );
+ ThreeDoubles echoThreeDoubles( [in] ThreeDoubles aStruct );
+ MixedFloatLong echoMixedFloatLong( [in] MixedFloatLong aStruct );
+
+ OneByte echoOneByte( [in] OneByte aStruct );
+ ThreeLongs echoThreeLongs( [in] ThreeLongs aStruct );
/**
* register return test 4 (i107182)
*/
long testPPCAlignment( [in] hyper l1, [in] hyper l2, [in] long i1, [in]
hyper l3, [in] long i2 );
+ hyper testPackedStack(
+ [in] hyper a0, [in] hyper a1, [in] hyper a2, [in] hyper a3,
+ [in] hyper a4, [in] hyper a5, [in] hyper a6,
+ [in] byte b, [in] byte c, [in] short s, [in] long l,
+ [in] byte d, [in] hyper h );
+
+ double testFpStack(
+ [in] double a0, [in] double a1, [in] double a2, [in] double a3,
+ [in] double a4, [in] double a5, [in] double a6, [in] double a7,
+ [in] float f8, [in] double d9 );
+
[attribute] boolean Bool;
[attribute] byte Byte;
[attribute] char Char;