Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index



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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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 <sbergman@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 <mstahl@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


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.