Kaydet (Commit) b0515ea5 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Adapt cpp_uno/gcc3_linux_intel to GCC 4.7

...the same way cpp_uno/gcc3_linux_x86-64 was already adapted.
üst 13191ad7
/* -*- 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: */
/* -*- 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: */
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cxxabi.h> #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/instance.hxx>
#include <rtl/strbuf.hxx> #include <rtl/strbuf.hxx>
...@@ -57,10 +60,6 @@ using namespace ::__cxxabiv1; ...@@ -57,10 +60,6 @@ using namespace ::__cxxabiv1;
namespace CPPU_CURRENT_NAMESPACE 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(())
{ {
...@@ -217,7 +216,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR ...@@ -217,7 +216,8 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
struct RTTISingleton: public rtl::Static< RTTI, RTTISingleton > {}; 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); __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
typelib_TypeDescription * pTD = 0; typelib_TypeDescription * pTD = 0;
...@@ -230,6 +230,7 @@ static void deleteException( void * pExc ) ...@@ -230,6 +230,7 @@ static void deleteException( void * pExc )
::typelib_typedescription_release( pTD ); ::typelib_typedescription_release( pTD );
} }
} }
}
//================================================================================================== //==================================================================================================
void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
......
...@@ -58,6 +58,7 @@ CFLAGSNOOPT=-O0 ...@@ -58,6 +58,7 @@ CFLAGSNOOPT=-O0
SLOFILES= \ SLOFILES= \
$(SLO)$/except.obj \ $(SLO)$/except.obj \
$(SLO)$/callvirtualmethod.obj \
$(SLO)$/cpp2uno.obj \ $(SLO)$/cpp2uno.obj \
$(SLO)$/uno2cpp.obj \ $(SLO)$/uno2cpp.obj \
$(SLO)$/call.obj $(SLO)$/call.obj
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
namespace CPPU_CURRENT_NAMESPACE namespace CPPU_CURRENT_NAMESPACE
{ {
void dummy_can_throw_anything( char const * );
// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h // ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
struct _Unwind_Exception struct _Unwind_Exception
...@@ -68,17 +66,30 @@ struct __cxa_exception ...@@ -68,17 +66,30 @@ struct __cxa_exception
_Unwind_Exception unwindHeader; _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 struct __cxa_eh_globals
{ {
__cxa_exception *caughtExceptions; __cxa_exception *caughtExceptions;
unsigned int uncaughtExceptions; 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
// ----- // -----
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DRAGONFLY) #if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DRAGONFLY)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <alloca.h>
#endif #endif
#include <com/sun/star/uno/genfunc.hxx> #include <com/sun/star/uno/genfunc.hxx>
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
#include "bridges/cpp_uno/shared/vtables.hxx" #include "bridges/cpp_uno/shared/vtables.hxx"
#include "callvirtualmethod.hxx"
#include "share.hxx" #include "share.hxx"
using namespace ::rtl; using namespace ::rtl;
...@@ -50,125 +51,6 @@ using namespace ::com::sun::star::uno; ...@@ -50,125 +51,6 @@ using namespace ::com::sun::star::uno;
namespace 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( static void cpp_call(
bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
bridges::cpp_uno::shared::VtableSlot aVtableSlot, bridges::cpp_uno::shared::VtableSlot aVtableSlot,
...@@ -287,7 +169,7 @@ static void cpp_call( ...@@ -287,7 +169,7 @@ static void cpp_call(
try try
{ {
OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
callVirtualMethod( CPPU_CURRENT_NAMESPACE::callVirtualMethod(
pAdjustedThisPtr, aVtableSlot.index, pAdjustedThisPtr, aVtableSlot.index,
pCppReturn, pReturnTypeDescr, bSimpleReturn, pCppReturn, pReturnTypeDescr, bSimpleReturn,
(sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
...@@ -330,7 +212,7 @@ static void cpp_call( ...@@ -330,7 +212,7 @@ static void cpp_call(
catch (...) catch (...)
{ {
// fill uno exception // 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 // temporary params
for ( ; nTempIndizes--; ) for ( ; nTempIndizes--; )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment