so it seems that the C++ UNO bridges, when built with gcc 4.7, crash and burn in the bridges test in testtools.
fortunately Stephan has fixed this problem on master, at least as far as i can see, applying the attached patches in a x86_64 --enable-dbgutil build gives me a nicely working office that passes all subsequent tests. so, i guess it would make sense to put these into libreoffice-3-5.
>From b3b700fe40b8b485ca8a1dbb3b9e3799d173806d Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Thu, 29 Mar 2012 17:50:16 +0200 Subject: [PATCH 01/11] Make cpp_uno/gcc3_linux_x86-64 bridge work with GCC 4.7 See comment in callvirtualmethod.cxx for details. (cherry picked from commit 0fdbb5b0eabbaa571f3747fda12a56c938cba474) Conflicts: bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx Change-Id: I476df49ce61bc46b8fcdce337d67210d756cdfaf Signed-off-by: Michael Stahl <mst...@redhat.com> --- bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx | 13 +- bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx | 6 +- .../gcc3_linux_x86-64/callvirtualmethod.cxx | 170 ++++++++++++++++++++ .../gcc3_linux_x86-64/callvirtualmethod.hxx | 49 ++++++ .../source/cpp_uno/gcc3_linux_x86-64/except.cxx | 6 +- .../source/cpp_uno/gcc3_linux_x86-64/makefile.mk | 1 + bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx | 2 - .../source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx | 156 +----------------- 8 files changed, 234 insertions(+), 169 deletions(-) create mode 100644 bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx create mode 100644 bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx index 48b7d46..e548095 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx @@ -59,9 +59,9 @@ OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ -#include <abi.hxx> +#include "sal/config.h" -#include <rtl/ustring.hxx> +#include "abi.hxx" using namespace x86_64; @@ -98,6 +98,7 @@ enum x86_64_reg_class static enum x86_64_reg_class merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) + throw () { /* Rule #1: If both classes are equal, this is the resulting class. */ if (class1 == class2) @@ -140,7 +141,7 @@ merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) See the x86-64 PS ABI for details. */ static int -classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int byteOffset ) +classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int byteOffset ) throw () { switch ( pTypeRef->eTypeClass ) { @@ -262,7 +263,7 @@ classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_c /* Examine the argument and return set number of register required in each class. Return 0 iff parameter should be passed in memory. */ -bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE ) +bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE ) throw () { enum x86_64_reg_class classes[MAX_CLASSES]; int n; @@ -303,14 +304,14 @@ bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool return true; } -bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ) +bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ) throw () { int g, s; return examine_argument( pTypeRef, true, g, s ) == 0; } -void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64 *pGPR, const double *pSSE, void *pStruct ) +void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64 *pGPR, const double *pSSE, void *pStruct ) throw () { enum x86_64_reg_class classes[MAX_CLASSES]; int n; diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx index c9f71f1..ba3e8f2 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx @@ -51,7 +51,7 @@ const sal_uInt32 MAX_SSE_REGS = 8; Return false iff parameter should be passed in memory. */ -bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE ); +bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE ) throw (); /** Does function that returns this type use a hidden parameter, or registers? @@ -59,9 +59,9 @@ bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInRetur pointer to a structure allocated by the caller), or in registers (rax, rdx for the integers, xmm0, xmm1 for the floating point numbers). */ -bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ); +bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ) throw (); -void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct ); +void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct ) throw (); } // namespace x86_64 diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx new file mode 100644 index 0000000..c91d461 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "sal/config.h" + +#include <cstring> + +#include "sal/types.h" +#include "typelib/typeclass.h" +#include "typelib/typedescription.h" + +#include "abi.hxx" +#include "callvirtualmethod.hxx" + +// The call instruction within the asm block of callVirtualMethod may throw +// exceptions. At least GCC 4.7.0 with -O0 would create (unnecessary) +// .gcc_exception_table call-site table entries around all other calls in this +// function that can throw, leading to std::terminate if the asm call throws an +// exception and the unwinding C++ personality routine finds the unexpected hole +// in the .gcc_exception_table. Therefore, make sure this function explicitly +// only calls nothrow-functions (so GCC 4.7.0 with -O0 happens to not create a +// .gcc_exception_table section at all for this function). For some reason, +// this also needs to be in a source file of its own. +// +// Also, this file should be compiled with -fnon-call-exceptions, and ideally +// there would be a way to tell the compiler that the asm block contains calls +// to functions that can potentially throw; see the mail thread starting at +// <http://gcc.gnu.org/ml/gcc/2012-03/msg00454.html> "C++: Letting compiler know +// asm block can call function that can throw?" + +void CPPU_CURRENT_NAMESPACE::callVirtualMethod( + void * pThis, sal_uInt32 nVtableIndex, void * pRegisterReturn, + typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn, + sal_uInt64 *pStack, sal_uInt32 nStack, sal_uInt64 *pGPR, sal_uInt32 nGPR, + double * pFPR, sal_uInt32 nFPR) +{ + // Should not happen, but... + if ( nFPR > x86_64::MAX_SSE_REGS ) + nFPR = x86_64::MAX_SSE_REGS; + if ( nGPR > x86_64::MAX_GPR_REGS ) + nGPR = x86_64::MAX_GPR_REGS; + + // Get pointer to method + sal_uInt64 pMethod = *((sal_uInt64 *)pThis); + pMethod += 8 * nVtableIndex; + pMethod = *((sal_uInt64 *)pMethod); + + // Load parameters to stack, if necessary + if ( nStack ) + { + // 16-bytes aligned + sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16; + sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes ); + std::memcpy( pCallStack, pStack, nStackBytes ); + } + + // Return values + sal_uInt64 rax; + sal_uInt64 rdx; + double xmm0; + double xmm1; + + asm volatile ( + + // Fill the xmm registers + "movq %6, %%rax\n\t" + + "movsd (%%rax), %%xmm0\n\t" + "movsd 8(%%rax), %%xmm1\n\t" + "movsd 16(%%rax), %%xmm2\n\t" + "movsd 24(%%rax), %%xmm3\n\t" + "movsd 32(%%rax), %%xmm4\n\t" + "movsd 40(%%rax), %%xmm5\n\t" + "movsd 48(%%rax), %%xmm6\n\t" + "movsd 56(%%rax), %%xmm7\n\t" + + // Fill the general purpose registers + "movq %5, %%rax\n\t" + + "movq (%%rax), %%rdi\n\t" + "movq 8(%%rax), %%rsi\n\t" + "movq 16(%%rax), %%rdx\n\t" + "movq 24(%%rax), %%rcx\n\t" + "movq 32(%%rax), %%r8\n\t" + "movq 40(%%rax), %%r9\n\t" + + // Perform the call + "movq %4, %%r11\n\t" + "movq %7, %%rax\n\t" + "call *%%r11\n\t" + + // Fill the return values + "movq %%rax, %0\n\t" + "movq %%rdx, %1\n\t" + "movsd %%xmm0, %2\n\t" + "movsd %%xmm1, %3\n\t" + : "=m" ( rax ), "=m" ( rdx ), "=m" ( xmm0 ), "=m" ( xmm1 ) + : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ) + : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11" + ); + + switch (pReturnTypeRef->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax; + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_ENUM: + *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax ); + break; + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax ); + break; + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax ); + break; + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_DOUBLE: + *reinterpret_cast<double *>( pRegisterReturn ) = xmm0; + break; + default: + { + sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize; + if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0) + { + sal_uInt64 longs[2]; + longs[0] = rax; + longs[1] = rdx; + + double doubles[2]; + doubles[0] = xmm0; + doubles[1] = xmm1; + x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn); + } + break; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx new file mode 100644 index 0000000..adc05ed --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX +#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX + +#include "sal/config.h" + +#include "sal/types.h" +#include "typelib/typedescription.h" + +namespace CPPU_CURRENT_NAMESPACE { + +void callVirtualMethod( + void * pThis, sal_uInt32 nVtableIndex, void * pRegisterReturn, + typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn, + sal_uInt64 *pStack, sal_uInt32 nStack, sal_uInt64 *pGPR, sal_uInt32 nGPR, + double * pFPR, sal_uInt32 nFPR); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx index c39f6dd..29750c1 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx @@ -57,12 +57,8 @@ using namespace ::__cxxabiv1; namespace CPPU_CURRENT_NAMESPACE { -void dummy_can_throw_anything( char const * ) -{ -} - //================================================================================================== -static OUString toUNOname( char const * p ) SAL_THROW( () ) +static OUString toUNOname( char const * p ) SAL_THROW(()) { #if OSL_DEBUG_LEVEL > 1 char const * start = p; diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk index acc590b..b2095c2 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk @@ -57,6 +57,7 @@ CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing SLOFILES= \ $(SLO)$/abi.obj \ $(SLO)$/except.obj \ + $(SLO)$/callvirtualmethod.obj \ $(SLO)$/cpp2uno.obj \ $(SLO)$/uno2cpp.obj \ $(SLO)$/call.obj diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx index da2367a..b01ae9e 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx @@ -35,8 +35,6 @@ namespace CPPU_CURRENT_NAMESPACE { -void dummy_can_throw_anything( char const * ); - // ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h struct _Unwind_Exception diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx index 3b1aea1..4e74698 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx @@ -26,12 +26,9 @@ * ************************************************************************/ - +#include <alloca.h> #include <exception> #include <typeinfo> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include "rtl/alloc.h" #include "rtl/ustrbuf.hxx" @@ -46,159 +43,12 @@ #include "bridges/cpp_uno/shared/vtables.hxx" #include "abi.hxx" +#include "callvirtualmethod.hxx" #include "share.hxx" using namespace ::rtl; using namespace ::com::sun::star::uno; -//================================================================================================== -static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, - void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn, - sal_uInt64 *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, - sal_uInt64 *pStack, sal_uInt32 nStack, - sal_uInt64 *pGPR, sal_uInt32 nGPR, - double *pFPR, sal_uInt32 nFPR) -{ -#if OSL_DEBUG_LEVEL > 1 - // Let's figure out what is really going on here - { - fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR ); - for ( unsigned int i = 0; i < nGPR; ++i ) - fprintf( stderr, "0x%lx, ", pGPR[i] ); - fprintf( stderr, "\nFPR's (%d): ", nFPR ); - for ( unsigned int i = 0; i < nFPR; ++i ) - fprintf( stderr, "%f, ", pFPR[i] ); - fprintf( stderr, "\nStack (%d): ", nStack ); - for ( unsigned int i = 0; i < nStack; ++i ) - fprintf( stderr, "0x%lx, ", pStack[i] ); - fprintf( stderr, "\n" ); - } -#endif - - // The call instruction within the asm section of callVirtualMethod may throw - // exceptions. So that the compiler handles this correctly, it is important - // that (a) callVirtualMethod might call dummy_can_throw_anything (although this - // never happens at runtime), which in turn can throw exceptions, and (b) - // callVirtualMethod is not inlined at its call site (so that any exceptions are - // caught which are thrown from the instruction calling callVirtualMethod): - if ( !pThis ) - CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something - - // Should not happen, but... - if ( nFPR > x86_64::MAX_SSE_REGS ) - nFPR = x86_64::MAX_SSE_REGS; - if ( nGPR > x86_64::MAX_GPR_REGS ) - nGPR = x86_64::MAX_GPR_REGS; - - // Get pointer to method - sal_uInt64 pMethod = *((sal_uInt64 *)pThis); - pMethod += 8 * nVtableIndex; - pMethod = *((sal_uInt64 *)pMethod); - - // Load parameters to stack, if necessary - if ( nStack ) - { - // 16-bytes aligned - sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16; - sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes ); - memcpy( pCallStack, pStack, nStackBytes ); - } - - // Return values - sal_uInt64 rax; - sal_uInt64 rdx; - double xmm0; - double xmm1; - - asm volatile ( - - // Fill the xmm registers - "movq %6, %%rax\n\t" - - "movsd (%%rax), %%xmm0\n\t" - "movsd 8(%%rax), %%xmm1\n\t" - "movsd 16(%%rax), %%xmm2\n\t" - "movsd 24(%%rax), %%xmm3\n\t" - "movsd 32(%%rax), %%xmm4\n\t" - "movsd 40(%%rax), %%xmm5\n\t" - "movsd 48(%%rax), %%xmm6\n\t" - "movsd 56(%%rax), %%xmm7\n\t" - - // Fill the general purpose registers - "movq %5, %%rax\n\t" - - "movq (%%rax), %%rdi\n\t" - "movq 8(%%rax), %%rsi\n\t" - "movq 16(%%rax), %%rdx\n\t" - "movq 24(%%rax), %%rcx\n\t" - "movq 32(%%rax), %%r8\n\t" - "movq 40(%%rax), %%r9\n\t" - - // Perform the call - "movq %4, %%r11\n\t" - "movq %7, %%rax\n\t" - "call *%%r11\n\t" - - // Fill the return values - "movq %%rax, %0\n\t" - "movq %%rdx, %1\n\t" - "movsd %%xmm0, %2\n\t" - "movsd %%xmm1, %3\n\t" - : "=m" ( rax ), "=m" ( rdx ), "=m" ( xmm0 ), "=m" ( xmm1 ) - : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ) - : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11" - ); - - switch (pReturnTypeRef->eTypeClass) - { - case typelib_TypeClass_HYPER: - case typelib_TypeClass_UNSIGNED_HYPER: - *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax; - break; - case typelib_TypeClass_LONG: - case typelib_TypeClass_UNSIGNED_LONG: - case typelib_TypeClass_ENUM: - *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax ); - break; - case typelib_TypeClass_CHAR: - case typelib_TypeClass_SHORT: - case typelib_TypeClass_UNSIGNED_SHORT: - *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax ); - break; - case typelib_TypeClass_BOOLEAN: - case typelib_TypeClass_BYTE: - *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax ); - break; - case typelib_TypeClass_FLOAT: - case typelib_TypeClass_DOUBLE: - *reinterpret_cast<double *>( pRegisterReturn ) = xmm0; - break; - default: - { - sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize; - if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0) - { - sal_uInt64 longs[2]; - longs[0] = rax; - longs[1] = rdx; - - double doubles[2]; - doubles[0] = xmm0; - doubles[1] = xmm1; - x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn); - } - break; - } - } -} - -//================================================================================================== - // Macros for easier insertion of values to registers or stack // pSV - pointer to the source // nr - order of the value [will be increased if stored to register] @@ -384,7 +234,7 @@ static void cpp_call( try { try { - callVirtualMethod( + CPPU_CURRENT_NAMESPACE::callVirtualMethod( pAdjustedThisPtr, aVtableSlot.index, pCppReturn, pReturnTypeRef, bSimpleReturn, pStackStart, ( pStack - pStackStart ), -- 1.7.10.2
>From 4de189ca7037b34cab071eeae25a3b5ae4e915c5 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Thu, 29 Mar 2012 17:52:13 +0200 Subject: [PATCH 02/11] Mark all registered as clobbered that are not saved across call (cherry picked from commit 3db7c67ddda3f6f9f0e6aa70c83ea43db65b325a) Signed-off-by: Michael Stahl <mst...@redhat.com> --- bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx index c91d461..901265d 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx @@ -121,7 +121,9 @@ void CPPU_CURRENT_NAMESPACE::callVirtualMethod( "movsd %%xmm1, %3\n\t" : "=m" ( rax ), "=m" ( rdx ), "=m" ( xmm0 ), "=m" ( xmm1 ) : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ) - : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11" + : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r10", "r11", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" ); switch (pReturnTypeRef->eTypeClass) -- 1.7.10.2
>From 79750c70de7b565836e5dbea327c8900242e54c2 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Fri, 30 Mar 2012 13:58:34 +0200 Subject: [PATCH 03/11] Adapt cpp_uno/gcc3_linux_x86-64 to GCC 4.7 cxxabi.h ...the same way cpp_uno/mingw_intel was already adapted. (cherry picked from commit fa09866ccb5bc197ad3e1ec1a453d6fab20cd7df) Signed-off-by: Michael Stahl <mst...@redhat.com> --- .../source/cpp_uno/gcc3_linux_x86-64/except.cxx | 9 ++++++++- bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx | 21 ++++++++++++++------ .../source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx index 29750c1..6893a03 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx @@ -30,7 +30,12 @@ #include <stdio.h> #include <string.h> #include <dlfcn.h> + #include <cxxabi.h> +#ifndef _GLIBCXX_CDTOR_CALLABI // new in GCC 4.7 cxxabi.h +#define _GLIBCXX_CDTOR_CALLABI +#endif + #include <boost/unordered_map.hpp> #include <rtl/instance.hxx> @@ -213,7 +218,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR struct RTTISingleton: public rtl::Static< RTTI, RTTISingleton > {}; //-------------------------------------------------------------------------------------------------- -static void deleteException( void * pExc ) +extern "C" { +static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc ) { __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); typelib_TypeDescription * pTD = 0; @@ -226,6 +232,7 @@ static void deleteException( void * pExc ) ::typelib_typedescription_release( pTD ); } } +} //================================================================================================== void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx index b01ae9e..a02ccb2 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx @@ -66,17 +66,26 @@ struct __cxa_exception _Unwind_Exception unwindHeader; }; -extern "C" void *__cxa_allocate_exception( - std::size_t thrown_size ) 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" CPPU_CURRENT_NAMESPACE::__cxa_eh_globals *__cxa_get_globals () throw(); + +// The following are in cxxabi.h since GCC 4.7: +#if __GNUC__ == 4 && __GNUC_MINOR__ <= 6 +extern "C" void *__cxa_allocate_exception( + std::size_t thrown_size ) throw(); +extern "C" void __cxa_throw ( + void *thrown_exception, void *tinfo, void (*dest) (void *) ) __attribute__((noreturn)); +#endif + +namespace CPPU_CURRENT_NAMESPACE +{ // ----- diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx index 4e74698..aa9ff82 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx @@ -296,7 +296,7 @@ static void cpp_call( catch (...) { // fill uno exception - fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); + fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); // temporary params for ( ; nTempIndizes--; ) -- 1.7.10.2
>From d38c474422885b9ff45c15e116f874d562cb394d Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Fri, 30 Mar 2012 14:01:23 +0200 Subject: [PATCH 04/11] Missing includes (cherry picked from commit 166be18da0686f2c445f521e3f1a83db8a3c3360) Signed-off-by: Michael Stahl <mst...@redhat.com> --- bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx | 1 + bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx | 1 + 2 files changed, 2 insertions(+) diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx index 901265d..57d0395 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx @@ -30,6 +30,7 @@ #include <cstring> +#include "cppu/macros.hxx" #include "sal/types.h" #include "typelib/typeclass.h" #include "typelib/typedescription.h" diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx index adc05ed..2a776b9 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx @@ -31,6 +31,7 @@ #include "sal/config.h" +#include "cppu/macros.hxx" #include "sal/types.h" #include "typelib/typedescription.h" -- 1.7.10.2
>From 54ef93911c0b35bf0d191dbdb5f1f84802433ee8 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Fri, 30 Mar 2012 16:32:53 +0200 Subject: [PATCH 05/11] Hack around different __cxa_* declarations in different GCC versions (cherry picked from commit a8e489495af7b0e74c3aca256e673fa6a34b9244) Conflicts: bridges/source/cpp_uno/mingw_intel/share.hxx Change-Id: I4ff25f0e0829e46594d319adceb9b8790f717130 Signed-off-by: Michael Stahl <mst...@redhat.com> --- bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx index a02ccb2..f84958b 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx @@ -76,7 +76,14 @@ struct __cxa_eh_globals extern "C" CPPU_CURRENT_NAMESPACE::__cxa_eh_globals *__cxa_get_globals () throw(); -// The following are in cxxabi.h since GCC 4.7: +namespace CPPU_CURRENT_NAMESPACE +{ + +// The following are in cxxabi.h since GCC 4.7 (they are wrapped in +// CPPU_CURRENT_NAMESPACE here as different GCC versions have slightly different +// declarations for them, e.g., with or without throw() specification, so would +// complain about redeclarations of these somewhat implicitly declared +// functions): #if __GNUC__ == 4 && __GNUC_MINOR__ <= 6 extern "C" void *__cxa_allocate_exception( std::size_t thrown_size ) throw(); @@ -84,9 +91,6 @@ extern "C" void __cxa_throw ( void *thrown_exception, void *tinfo, void (*dest) (void *) ) __attribute__((noreturn)); #endif -namespace CPPU_CURRENT_NAMESPACE -{ - // ----- //================================================================================================== -- 1.7.10.2
>From 4dfd82bd9fc02702f1674c4d4752587c59c03b39 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Wed, 4 Apr 2012 13:02:44 +0200 Subject: [PATCH 06/11] Adapt cpp_uno/gcc3_linux_intel to GCC 4.7 ...the same way cpp_uno/gcc3_linux_x86-64 was already adapted. (cherry picked from commit b0515ea5fa6c29faebed616ae3e0213c72d24904) Signed-off-by: Michael Stahl <mst...@redhat.com> --- .../cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx | 154 ++++++++++++++++++++ .../cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx | 49 +++++++ bridges/source/cpp_uno/gcc3_linux_intel/except.cxx | 11 +- .../source/cpp_uno/gcc3_linux_intel/makefile.mk | 1 + bridges/source/cpp_uno/gcc3_linux_intel/share.hxx | 27 +++- .../source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx | 126 +--------------- 6 files changed, 233 insertions(+), 135 deletions(-) create mode 100644 bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx create mode 100644 bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx new file mode 100644 index 0000000..4c6370f --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "sal/config.h" + +#include <cassert> + +#include "cppu/macros.hxx" +#include "sal/types.h" +#include "typelib/typeclass.h" +#include "typelib/typedescription.h" + +#include "callvirtualmethod.hxx" + +// The call instruction within the asm block of callVirtualMethod may throw +// exceptions. At least GCC 4.7.0 with -O0 would create (unnecessary) +// .gcc_exception_table call-site table entries around all other calls in this +// function that can throw, leading to std::terminate if the asm call throws an +// exception and the unwinding C++ personality routine finds the unexpected hole +// in the .gcc_exception_table. Therefore, make sure this function explicitly +// only calls nothrow-functions (so GCC 4.7.0 with -O0 happens to not create a +// .gcc_exception_table section at all for this function). For some reason, +// this also needs to be in a source file of its own. +// +// Also, this file should be compiled with -fnon-call-exceptions, and ideally +// there would be a way to tell the compiler that the asm block contains calls +// to functions that can potentially throw; see the mail thread starting at +// <http://gcc.gnu.org/ml/gcc/2012-03/msg00454.html> "C++: Letting compiler know +// asm block can call function that can throw?" + +void CPPU_CURRENT_NAMESPACE::callVirtualMethod( + void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn, + typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, + sal_Int32 * pStackLongs, sal_Int32 nStackLongs) +{ + // parameter list is mixed list of * and values + // reference parameters are pointers + + assert(pStackLongs && pAdjustedThisPtr); + assert(sizeof (void *) == 4 && sizeof (sal_Int32) == 4); + // unexpected size of int + assert(nStackLongs && pStackLongs); // no stack + + volatile long edx = 0, eax = 0; // for register returns + void * stackptr; + asm volatile ( + "mov %%esp, %6\n\t" + // preserve potential 128bit stack alignment + "and $0xfffffff0, %%esp\n\t" + "mov %0, %%eax\n\t" + "lea -4(,%%eax,4), %%eax\n\t" + "and $0xf, %%eax\n\t" + "sub $0xc, %%eax\n\t" + "add %%eax, %%esp\n\t" + // copy values + "mov %0, %%eax\n\t" + "mov %%eax, %%edx\n\t" + "dec %%edx\n\t" + "shl $2, %%edx\n\t" + "add %1, %%edx\n" + "Lcopy:\n\t" + "pushl 0(%%edx)\n\t" + "sub $4, %%edx\n\t" + "dec %%eax\n\t" + "jne Lcopy\n\t" + // do the actual call + "mov %2, %%edx\n\t" + "mov 0(%%edx), %%edx\n\t" + "mov %3, %%eax\n\t" + "shl $2, %%eax\n\t" + "add %%eax, %%edx\n\t" + "mov 0(%%edx), %%edx\n\t" + "call *%%edx\n\t" + // save return registers + "mov %%eax, %4\n\t" + "mov %%edx, %5\n\t" + // cleanup stack + "mov %6, %%esp\n\t" + : + : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr), + "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr) + : "eax", "ecx", "edx" ); + switch( pReturnTypeDescr->eTypeClass ) + { + case typelib_TypeClass_VOID: + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + ((long*)pRegisterReturn)[1] = edx; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_ENUM: + ((long*)pRegisterReturn)[0] = eax; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(unsigned short*)pRegisterReturn = eax; + break; + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + *(unsigned char*)pRegisterReturn = eax; + break; + case typelib_TypeClass_FLOAT: + asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) ); + break; + case typelib_TypeClass_DOUBLE: + asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); + break; + default: + { +#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ + defined(DRAGONFLY) + sal_Int32 const nRetSize = pReturnTypeDescr->nSize; + if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0) + { + if (nRetSize > 4) + static_cast<long *>(pRegisterReturn)[1] = edx; + static_cast<long *>(pRegisterReturn)[0] = eax; + } +#else + (void)bSimpleReturn; +#endif + break; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx new file mode 100644 index 0000000..de498a3 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX +#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX + +#include "sal/config.h" + +#include "cppu/macros.hxx" +#include "sal/types.h" +#include "typelib/typedescription.h" + +namespace CPPU_CURRENT_NAMESPACE { + +void callVirtualMethod( + void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn, + typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, + sal_Int32 * pStackLongs, sal_Int32 nStackLongs); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx index 26755f3..5ad3698 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx @@ -33,6 +33,9 @@ #include <boost/unordered_map.hpp> #include <cxxabi.h> +#ifndef _GLIBCXX_CDTOR_CALLABI // new in GCC 4.7 cxxabi.h +#define _GLIBCXX_CDTOR_CALLABI +#endif #include <rtl/instance.hxx> #include <rtl/strbuf.hxx> @@ -57,10 +60,6 @@ using namespace ::__cxxabiv1; namespace CPPU_CURRENT_NAMESPACE { -void dummy_can_throw_anything( char const * ) -{ -} - //================================================================================================== static OUString toUNOname( char const * p ) SAL_THROW( () ) { @@ -217,7 +216,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR struct RTTISingleton: public rtl::Static< RTTI, RTTISingleton > {}; //-------------------------------------------------------------------------------------------------- -static void deleteException( void * pExc ) +extern "C" { +static void _GLIBCXX_CDTOR_CALLABI deleteException( void * pExc ) { __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); typelib_TypeDescription * pTD = 0; @@ -230,6 +230,7 @@ static void deleteException( void * pExc ) ::typelib_typedescription_release( pTD ); } } +} //================================================================================================== void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk index 10d24a3..c814132 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk +++ b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk @@ -58,6 +58,7 @@ CFLAGSNOOPT=-O0 SLOFILES= \ $(SLO)$/except.obj \ + $(SLO)$/callvirtualmethod.obj \ $(SLO)$/cpp2uno.obj \ $(SLO)$/uno2cpp.obj \ $(SLO)$/call.obj diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx index 8a3e136..2eff557 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx @@ -35,8 +35,6 @@ namespace CPPU_CURRENT_NAMESPACE { -void dummy_can_throw_anything( char const * ); - // ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h struct _Unwind_Exception @@ -68,17 +66,30 @@ struct __cxa_exception _Unwind_Exception unwindHeader; }; -extern "C" void *__cxa_allocate_exception( - std::size_t thrown_size ) 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" CPPU_CURRENT_NAMESPACE::__cxa_eh_globals *__cxa_get_globals () throw(); + +namespace CPPU_CURRENT_NAMESPACE +{ + +// The following are in cxxabi.h since GCC 4.7 (they are wrapped in +// CPPU_CURRENT_NAMESPACE here as different GCC versions have slightly different +// declarations for them, e.g., with or without throw() specification, so would +// complain about redeclarations of these somewhat implicitly declared +// functions): +#if __GNUC__ == 4 && __GNUC_MINOR__ <= 6 +extern "C" void *__cxa_allocate_exception( + std::size_t thrown_size ) throw(); +extern "C" void __cxa_throw ( + void *thrown_exception, void *tinfo, void (*dest) (void *) ) __attribute__((noreturn)); +#endif // ----- diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx index 49bac65..64d401b 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx @@ -30,7 +30,7 @@ #if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DRAGONFLY) #include <stdlib.h> #else -#include <malloc.h> +#include <alloca.h> #endif #include <com/sun/star/uno/genfunc.hxx> @@ -42,6 +42,7 @@ #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" #include "bridges/cpp_uno/shared/vtables.hxx" +#include "callvirtualmethod.hxx" #include "share.hxx" using namespace ::rtl; @@ -50,125 +51,6 @@ using namespace ::com::sun::star::uno; namespace { -//================================================================================================== -// The call instruction within the asm section of callVirtualMethod may throw -// exceptions. So that the compiler handles this correctly, it is important -// that (a) callVirtualMethod might call dummy_can_throw_anything (although this -// never happens at runtime), which in turn can throw exceptions, and (b) -// callVirtualMethod is not inlined at its call site (so that any exceptions are -// caught which are thrown from the instruction calling callVirtualMethod): -void callVirtualMethod( - void * pAdjustedThisPtr, - sal_Int32 nVtableIndex, - void * pRegisterReturn, - typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, - sal_Int32 * pStackLongs, - sal_Int32 nStackLongs ) __attribute__((noinline)); - -void callVirtualMethod( - void * pAdjustedThisPtr, - sal_Int32 nVtableIndex, - void * pRegisterReturn, - typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, - sal_Int32 * pStackLongs, - sal_Int32 nStackLongs ) -{ - // parameter list is mixed list of * and values - // reference parameters are pointers - - OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" ); - OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); - OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" ); - - // never called - if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something - - volatile long edx = 0, eax = 0; // for register returns - void * stackptr; - asm volatile ( - "mov %%esp, %6\n\t" - // preserve potential 128bit stack alignment - "and $0xfffffff0, %%esp\n\t" - "mov %0, %%eax\n\t" - "lea -4(,%%eax,4), %%eax\n\t" - "and $0xf, %%eax\n\t" - "sub $0xc, %%eax\n\t" - "add %%eax, %%esp\n\t" - // copy values - "mov %0, %%eax\n\t" - "mov %%eax, %%edx\n\t" - "dec %%edx\n\t" - "shl $2, %%edx\n\t" - "add %1, %%edx\n" - "Lcopy:\n\t" - "pushl 0(%%edx)\n\t" - "sub $4, %%edx\n\t" - "dec %%eax\n\t" - "jne Lcopy\n\t" - // do the actual call - "mov %2, %%edx\n\t" - "mov 0(%%edx), %%edx\n\t" - "mov %3, %%eax\n\t" - "shl $2, %%eax\n\t" - "add %%eax, %%edx\n\t" - "mov 0(%%edx), %%edx\n\t" - "call *%%edx\n\t" - // save return registers - "mov %%eax, %4\n\t" - "mov %%edx, %5\n\t" - // cleanup stack - "mov %6, %%esp\n\t" - : - : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr), - "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr) - : "eax", "ecx", "edx" ); - switch( pReturnTypeDescr->eTypeClass ) - { - case typelib_TypeClass_VOID: - break; - case typelib_TypeClass_HYPER: - case typelib_TypeClass_UNSIGNED_HYPER: - ((long*)pRegisterReturn)[1] = edx; - case typelib_TypeClass_LONG: - case typelib_TypeClass_UNSIGNED_LONG: - case typelib_TypeClass_CHAR: - case typelib_TypeClass_ENUM: - ((long*)pRegisterReturn)[0] = eax; - break; - case typelib_TypeClass_SHORT: - case typelib_TypeClass_UNSIGNED_SHORT: - *(unsigned short*)pRegisterReturn = eax; - break; - case typelib_TypeClass_BOOLEAN: - case typelib_TypeClass_BYTE: - *(unsigned char*)pRegisterReturn = eax; - break; - case typelib_TypeClass_FLOAT: - asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) ); - break; - case typelib_TypeClass_DOUBLE: - asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); - break; - default: - { -#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ - defined(DRAGONFLY) - sal_Int32 const nRetSize = pReturnTypeDescr->nSize; - if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0) - { - if (nRetSize > 4) - static_cast<long *>(pRegisterReturn)[1] = edx; - static_cast<long *>(pRegisterReturn)[0] = eax; - } -#else - (void)bSimpleReturn; -#endif - break; - } - } -} - -//================================================================================================== static void cpp_call( bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, bridges::cpp_uno::shared::VtableSlot aVtableSlot, @@ -287,7 +169,7 @@ static void cpp_call( try { OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); - callVirtualMethod( + CPPU_CURRENT_NAMESPACE::callVirtualMethod( pAdjustedThisPtr, aVtableSlot.index, pCppReturn, pReturnTypeDescr, bSimpleReturn, (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); @@ -330,7 +212,7 @@ static void cpp_call( catch (...) { // fill uno exception - fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); + fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); // temporary params for ( ; nTempIndizes--; ) -- 1.7.10.2
>From f1c8b6c93cd3603bd6eebbf208c429f3346cfe23 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann <sberg...@redhat.com> Date: Wed, 4 Apr 2012 15:02:51 +0200 Subject: [PATCH 07/11] Fixed include guard copy/paste error (cherry picked from commit 932f5a4b1f001c11bab8fb10d3be324ded13193f) Signed-off-by: Michael Stahl <mst...@redhat.com> --- bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx index de498a3..5159f94 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx @@ -26,8 +26,8 @@ * ************************************************************************/ -#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX -#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_X86_64_CALLVIRTUALMETHOD_HXX +#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_INTEL_CALLVIRTUALMETHOD_HXX +#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_INTEL_CALLVIRTUALMETHOD_HXX #include "sal/config.h" -- 1.7.10.2
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice