You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by ji...@apache.org on 2020/12/26 20:56:29 UTC
[openoffice] branch AOO419 updated: Updates to macOS UNO
implementation pulled from AOO42X but w/o unsupported functionality.
This is an automated email from the ASF dual-hosted git repository.
jim pushed a commit to branch AOO419
in repository https://gitbox.apache.org/repos/asf/openoffice.git
The following commit(s) were added to refs/heads/AOO419 by this push:
new 67a794b Updates to macOS UNO implementation pulled from AOO42X but w/o unsupported functionality.
new b36e2b2 Merge branch 'AOO419' of https://gitbox.apache.org/repos/asf/openoffice into AOO419
67a794b is described below
commit 67a794bc92a1e8ffd80bf2fdc9bf74ed09144659
Author: Jim Jagielski <ji...@gmail.com>
AuthorDate: Sat Dec 26 15:54:46 2020 -0500
Updates to macOS UNO implementation pulled from AOO42X
but w/o unsupported functionality.
---
.../source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx | 137 ++++++++++-----------
.../source/cpp_uno/s5abi_macosx_x86-64/except.cxx | 36 ++++--
.../source/cpp_uno/s5abi_macosx_x86-64/makefile.mk | 1 -
.../source/cpp_uno/s5abi_macosx_x86-64/share.hxx | 21 ++--
.../source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx | 4 +-
5 files changed, 103 insertions(+), 96 deletions(-)
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx
index f65ecea..d7fd5b2 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/cpp2uno.cxx
@@ -102,12 +102,12 @@ static typelib_TypeClass cpp2uno_call(
// stack space
// parameters
- void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pUnoArgs = reinterpret_cast<void **>(alloca( 4 * sizeof(void *) * nParams ));
void ** pCppArgs = pUnoArgs + nParams;
// indizes of values this have to be converted (interface conversion cpp<=>uno)
- sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ sal_Int32 * pTempIndizes = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams));
// type descriptions for reconversions
- typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+ typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
sal_Int32 nTempIndizes = 0;
@@ -117,10 +117,7 @@ static typelib_TypeClass cpp2uno_call(
int nUsedGPR = 0;
int nUsedSSE = 0;
-#if OSL_DEBUG_LEVEL > 0
- bool bFitsRegisters =
-#endif
- x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
+ bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
{
// Simple types must fit exactly one register on x86_64
@@ -194,7 +191,7 @@ static typelib_TypeClass cpp2uno_call(
// invoke uno dispatch call
(*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
- // in case an exception occured...
+ // in case an exception occurred...
if ( pUnoExc )
{
// destruct temporary in/inout params
@@ -213,7 +210,7 @@ static typelib_TypeClass cpp2uno_call(
// is here for dummy
return typelib_TypeClass_VOID;
}
- else // else no exception occured...
+ else // else no exception occurred...
{
// temporary params
for ( ; nTempIndizes--; )
@@ -244,7 +241,7 @@ static typelib_TypeClass cpp2uno_call(
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
}
// complex return ptr is set to return reg
- *(void **)pRegisterReturn = pCppReturn;
+ *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn;
}
if ( pReturnTypeDescr )
{
@@ -349,7 +346,7 @@ extern "C" typelib_TypeClass cpp_vtable_call(
XInterface * pInterface = 0;
(*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
( pCppI->getBridge()->getCppEnv(),
- (void **)&pInterface,
+ reinterpret_cast<void **>(&pInterface),
pCppI->getOid().pData,
reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
@@ -395,70 +392,62 @@ extern "C" typelib_TypeClass cpp_vtable_call(
}
//==================================================================================================
-
-// privateSnippetExecutor() is only called by the trampolines created by codeSnippet()
-//
-// it saves all the registers used for parameter passing in the x86_64 ABI.
-// Then it uses them to provide the parameters to its cpp_vtable_call() and
-// to handle the return value.
-//
-// This method makes assumptions about the stack layout of the stack frame above!
-
extern "C" void privateSnippetExecutor( void )
{
- asm volatile (
- "subq $160, %%rsp\n\t"
- "movq %%r10, -152(%%rbp)\n\t" // Save (nVtableOffset << 32) + nFunctionIndex
-
- "movq %%rdi, -112(%%rbp)\n\t" // Save GP registers
- "movq %%rsi, -104(%%rbp)\n\t"
- "movq %%rdx, -96(%%rbp)\n\t"
- "movq %%rcx, -88(%%rbp)\n\t"
- "movq %%r8 , -80(%%rbp)\n\t"
- "movq %%r9 , -72(%%rbp)\n\t"
-
- "movsd %%xmm0, -64(%%rbp)\n\t" // Save FP registers
- "movsd %%xmm1, -56(%%rbp)\n\t"
- "movsd %%xmm2, -48(%%rbp)\n\t"
- "movsd %%xmm3, -40(%%rbp)\n\t"
- "movsd %%xmm4, -32(%%rbp)\n\t"
- "movsd %%xmm5, -24(%%rbp)\n\t"
- "movsd %%xmm6, -16(%%rbp)\n\t"
- "movsd %%xmm7, -8(%%rbp)\n\t"
-
- "leaq -144(%%rbp), %%r9\n\t" // 6th param: sal_uInt64* pRegisterReturn
- "leaq 16(%%rbp), %%r8\n\t" // 5rd param: void** ovrflw
- "leaq -64(%%rbp), %%rcx\n\t" // 4th param: void** fpreg
- "leaq -112(%%rbp), %%rdx\n\t" // 3rd param: void** gpreg
- "movl -148(%%rbp), %%esi\n\t" // 2nd param: sal_int32 nVtableOffset
- "movl -152(%%rbp), %%edi\n\t" // 1st param: sal_int32 nFunctionIndex
-
- "call _cpp_vtable_call\n\t"
-
- "cmp $10, %%rax\n\t" // typelib_TypeClass_FLOAT
- "je .Lfloat\n\t"
- "cmp $11, %%rax\n\t" // typelib_TypeClass_DOUBLE
- "je .Lfloat\n\t"
-
- "movq -144(%%rbp), %%rax\n\t" // Return value (int case)
- "movq -136(%%rbp), %%rdx\n\t" // Return value (int case)
- "movq -144(%%rbp), %%xmm0\n\t" // Return value (int case)
- "movq -136(%%rbp), %%xmm1\n\t" // Return value (int case)
- "jmp .Lfinish\n"
-".Lfloat:\n\t"
- "movlpd -144(%%rbp), %%xmm0\n" // Return value (float/double case)
-".Lfinish:\n\t"
- "addq $160, %%rsp\n"
- :
- :
- : "rax", "r10", "xmm0" );
+ asm volatile (
+ " subq $160, %rsp\n"
+ " movq %r10, -152(%rbp)\n" // Save (nVtableOffset << 32) + nFunctionIndex
+
+ " movq %rdi, -112(%rbp)\n" // Save GP registers
+ " movq %rsi, -104(%rbp)\n"
+ " movq %rdx, -96(%rbp)\n"
+ " movq %rcx, -88(%rbp)\n"
+ " movq %r8 , -80(%rbp)\n"
+ " movq %r9 , -72(%rbp)\n"
+
+ " movsd %xmm0, -64(%rbp)\n" // Save FP registers
+ " movsd %xmm1, -56(%rbp)\n"
+ " movsd %xmm2, -48(%rbp)\n"
+ " movsd %xmm3, -40(%rbp)\n"
+ " movsd %xmm4, -32(%rbp)\n"
+ " movsd %xmm5, -24(%rbp)\n"
+ " movsd %xmm6, -16(%rbp)\n"
+ " movsd %xmm7, -8(%rbp)\n"
+
+ " leaq -144(%rbp), %r9\n" // 6th param: sal_uInt64* pRegisterReturn
+ " leaq 16(%rbp), %r8\n" // 5rd param: void** ovrflw
+ " leaq -64(%rbp), %rcx\n" // 4th param: void** fpreg
+ " leaq -112(%rbp), %rdx\n" // 3rd param: void** gpreg
+ " movl -148(%rbp), %esi\n" // 2nd param: sal_int32 nVtableOffset
+ " movl -152(%rbp), %edi\n" // 1st param: sal_int32 nFunctionIndex
+
+ " call _cpp_vtable_call\n"
+
+ " cmp $10, %rax\n" // typelib_TypeClass_FLOAT
+ " je .Lfloat\n"
+ " cmp $11, %rax\n" // typelib_TypeClass_DOUBLE
+ " je .Lfloat\n"
+
+ " movq -144(%rbp), %rax\n" // Return value (int case)
+ " movq -136(%rbp), %rdx\n" // Return value (int case)
+ " movq -144(%rbp), %xmm0\n" // Return value (int case)
+ " movq -136(%rbp), %xmm1\n" // Return value (int case)
+ " jmp .Lfinish\n"
+ ".Lfloat:\n"
+ " movlpd -144(%rbp), %xmm0\n" // Return value (float/double case)
+ ".Lfinish:\n"
+ " addq $160, %rsp\n"
+ );
}
-
-static const int codeSnippetSize = 24;
+const int codeSnippetSize = 24;
// Generate a trampoline that redirects method calls to
// privateSnippetExecutor().
//
+// privateSnippetExecutor() saves all the registers that are used for
+// parameter passing on x86_64, and calls the cpp_vtable_call().
+// When it returns, privateSnippetExecutor() sets the return value.
+//
// Note: The code snippet we build here must not create a stack frame,
// otherwise the UNO exceptions stop working thanks to non-existing
// unwinding info.
@@ -466,18 +455,18 @@ unsigned char * codeSnippet( unsigned char * code,
sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
bool bHasHiddenParam ) SAL_THROW( () )
{
- sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+ sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>( nVtableOffset ) << 32 ) | static_cast<sal_uInt64>( nFunctionIndex );
if ( bHasHiddenParam )
nOffsetAndIndex |= 0x80000000;
// movq $<nOffsetAndIndex>, %r10
- *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
- *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
+ *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
+ *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
// movq $<address of the privateSnippetExecutor>, %r11
- *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
- *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
+ *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
+ *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
// jmpq *%r11
*reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
@@ -519,7 +508,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
sal_Int32 functionCount, sal_Int32 nVtableOffset )
{
- static const sal_PtrDiff writetoexecdiff = 0;
+ const sal_PtrDiff writetoexecdiff = 0;
(*slots) -= functionCount;
Slot * s = *slots;
for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx
index f82ef9f..9e89ee0 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/except.cxx
@@ -141,7 +141,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
if (iFind == m_rttis.end())
{
- // build the mangled name for unoName's RTTI typeinfo symbol
+ // RTTI symbol
OStringBuffer buf( 64 );
buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
sal_Int32 index = 0;
@@ -156,7 +156,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
buf.append( 'E' );
OString symName( buf.makeStringAndClear() );
- rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+ rtti = static_cast<std::type_info *>(dlsym( m_hApp, symName.getStr() ));
if (rtti)
{
@@ -174,15 +174,12 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
// symbol and rtti-name is nearly identical,
// the symbol is prefixed with _ZTI
char const * rttiName = symName.getStr() +4;
-#if OSL_DEBUG_LEVEL >= 1
+#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
-#if 0 // TODO: enable it again when the generated class_type_infos always work.
- // Forcing the toolchain to create authentic typeinfos is much better though
- // than the sick concept of reverse-engineering the platform's toolchain
- // and generating the missing type_infos.
+#if 0
if (pTypeDescr->pBaseTypeDescription)
{
// ensure availability of base
@@ -197,9 +194,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
rtti = new __class_type_info( strdup( rttiName ) );
}
#else
- rtti = NULL;
+ rtti = NULL;
#endif
-
bool bOK = m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti )).second;
OSL_ENSURE( bOK, "### inserting new generated rtti failed?!" );
}
@@ -220,7 +216,7 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
//--------------------------------------------------------------------------------------------------
static void deleteException( void * pExc )
{
- __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ __cxa_exception const * header = static_cast<__cxa_exception const *>(pExc) - 1;
if( !header->exceptionType) // TODO: remove this when getRTTI() always returns non-NULL
return; // NOTE: leak for now
typelib_TypeDescription * pTD = 0;
@@ -242,7 +238,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
OUStringToOString(
*reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
RTL_TEXTENCODING_ASCII_US ) );
- fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+ fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
#endif
void * pCppExc;
type_info * rtti;
@@ -312,11 +308,27 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping
return;
}
+ /*
+ * 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
+ */
+ {
+ // Does this look like the newer struct __cxa_exception?
+ // That is, is the 1st element NULL (*reserved)?
+ if (*reinterpret_cast<void **>(header) == NULL) {
+ // Yes. So we move up a slot to offset
+ header = reinterpret_cast<__cxa_exception *>(reinterpret_cast<void **>(header) + 1);
+ }
+ }
+
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 occured: %s\n", cstr_unoName.getStr() );
+ fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() );
#endif
typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
if (0 == pExcTypeDescr)
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk
index 7f92ad1..f6fcc98 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/makefile.mk
@@ -69,4 +69,3 @@ SHL1STDLIBS= \
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
-
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx
index b64609d..82bdd29 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/share.hxx
@@ -32,19 +32,28 @@ 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
{
- unsigned long exception_class;
+ uint64_t exception_class;
void * exception_cleanup;
uintptr_t private_1;
uintptr_t private_2;
};
struct __cxa_exception
-{
-#if __LP64__ // ----- from libcxxabi/src/cxa_exception.hpp
+{
+#if __LP64__
+ // From LLVM 10 - Added reserved member at top of struct. Who the hell does that?
+ // https://reviews.llvm.org/rG674ec1eb16678b8addc02a4b0534ab383d22fa77
+ // Sure would be nice to be able to test for CCNUMVER >= 1000000000
+ // and COM == CLANG here.
+ // void *reserved;
+ // ----- from libcxxabi/src/cxa_exception.hpp
// This is a new field to support C++ 0x exception_ptr.
// For binary compatibility it is at the start of this
// struct which is prepended to the object thrown in
@@ -85,12 +94,12 @@ extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
// -----
-#if 0 // #i124421# disabled because its use in except.cxx is disabled
-
+#if 0
// 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:
@@ -107,9 +116,7 @@ public:
: __class_type_info( pRttiName), mpBaseType( pBaseType)
{}
};
-
#endif
-
//==================================================================================================
void raiseException(
uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx
index ca38fb3..c9f5e5d 100644
--- a/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx
+++ b/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx
@@ -149,7 +149,7 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
:
: "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
"m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 ),
- "m" (pCallStack) // dummy input to prevent the compiler from optimizing it out
+ "m" (pCallStack) // dummy input to prevent the compiler from optimizing the alloca out
: "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "r8", "r9",
"r10", "r11", "r10", "r12", "r13", "r14", "r15", "rbx",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
@@ -409,7 +409,7 @@ static void cpp_call(
Reference< XInterface >());
}
- // NO exception occured...
+ // NO exception occurred...
*ppUnoExc = 0;
// reconvert temporary params