[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 8 commits - bridges/source

Petr Mladek pmladek at kemper.freedesktop.org
Wed May 23 06:24:50 PDT 2012


 bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx  |  157 +++++++++
 bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.hxx  |   49 ++
 bridges/source/cpp_uno/gcc3_linux_intel/except.cxx             |    8 
 bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk            |    1 
 bridges/source/cpp_uno/gcc3_linux_intel/share.hxx              |   27 +
 bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx            |  126 -------
 bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx               |   13 
 bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx               |    6 
 bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx |  173 ++++++++++
 bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.hxx |   50 ++
 bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx            |   15 
 bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk           |    1 
 bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx             |   27 +
 bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx           |  158 ---------
 14 files changed, 504 insertions(+), 307 deletions(-)

New commits:
commit 4d69337c172c2f24af5c0795449ec52f959747e1
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Wed Apr 4 21:41:49 2012 +0200

    adjust gcc3_linux_intel bridge to work with clang
    
    Otherwise exception throwing seems to be broken.
    This is a partial revert of b0515ea5fa6c29faebed616ae3e0213c72d24904.
    
    Signed-off-by: Petr Mladek <pmladek at suse.cz>

diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx
index 4c6370f..34f261a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/callvirtualmethod.cxx
@@ -36,6 +36,7 @@
 #include "typelib/typedescription.h"
 
 #include "callvirtualmethod.hxx"
+#include "share.hxx"
 
 // The call instruction within the asm block of callVirtualMethod may throw
 // exceptions.  At least GCC 4.7.0 with -O0 would create (unnecessary)
@@ -66,6 +67,8 @@ void CPPU_CURRENT_NAMESPACE::callVirtualMethod(
         // unexpected size of int
     assert(nStackLongs && pStackLongs); // no stack
 
+    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 (
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
index 5ad3698..87d6beb 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
@@ -46,7 +46,6 @@
 #include <com/sun/star/uno/genfunc.hxx>
 #include "com/sun/star/uno/RuntimeException.hpp"
 #include <typelib/typedescription.hxx>
-#include <uno/any2.h>
 
 #include "share.hxx"
 
@@ -60,6 +59,10 @@ using namespace ::__cxxabiv1;
 namespace CPPU_CURRENT_NAMESPACE
 {
 
+void dummy_can_throw_anything( char const * )
+{
+}
+
 //==================================================================================================
 static OUString toUNOname( char const * p ) SAL_THROW( () )
 {
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
index 2eff557..dfa1bf9 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
@@ -32,9 +32,13 @@
 #include <exception>
 #include <cstddef>
 
+#include <uno/any2.h>
+
 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
commit 7b28b662a90f7bfc80682c61dae2229abd3b236d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Wed Apr 4 15:02:51 2012 +0200

    Fixed include guard copy/paste error (cherry picked from commit 932f5a4b1f001c11bab8fb10d3be324ded13193f)
    
    Signed-off-by: Michael Stahl <mstahl at redhat.com>

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"
 
commit 560d289f4e66be15055f27d803952801ecb5864c
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Wed Apr 4 13:02:44 2012 +0200

    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 at redhat.com>

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--; )
commit e00888c34bdfb758f24966ee737feb7cef81d5a7
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Mar 30 16:32:53 2012 +0200

    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 at redhat.com>

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
-{
-
 // -----
 
 //==================================================================================================
commit e6bff9d0b1d7ccff6f1c870126b4dcfe7303c91d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Mar 30 14:01:23 2012 +0200

    Missing includes (cherry picked from commit 166be18da0686f2c445f521e3f1a83db8a3c3360)
    
    Signed-off-by: Michael Stahl <mstahl at redhat.com>

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"
 
commit 20e073fda3fab0135d5fb8c5e3b74d5e0d9258ea
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Mar 30 13:58:34 2012 +0200

    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 at redhat.com>

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--; )
commit ef7cfdf7f2129026aa19a395e5f3415aa05921bb
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Mar 29 17:52:13 2012 +0200

    Mark all registered as clobbered that are not saved across call (cherry picked from commit 3db7c67ddda3f6f9f0e6aa70c83ea43db65b325a)
    
    Signed-off-by: Michael Stahl <mstahl at redhat.com>

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)
commit 9fa31b7f2b1bb216205265a09aa200178880153f
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Thu Mar 29 17:50:16 2012 +0200

    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 at redhat.com>

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 ),


More information about the Libreoffice-commits mailing list