Kaydet (Commit) d83de4b1 authored tarafından Tor Lillqvist's avatar Tor Lillqvist

First attempt at C++/UNO bridge for 64-bit OS X

Basically, a 1:1 copy of the Linux x86-64 one. The Apple docs say that
"The OS X x86-64 function calling conventions are the same as the
function calling conventions described in System V Application Binary
Interface AMD64 Architecture Processor Supplement," which should mean
that it's the same as on Linux.

Once this works, the very minor differences to the Linux one will be
merged as ifdefs into the Linux one, and no separate source files will
be needed.

Change-Id: I1ff58f303a7ab7f59ec2ff7a9e24465e89151ec5
üst 30d33b12
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
ifneq ($(strip $(bridges_SELECTED_BRIDGE)),)
$(eval $(call gb_Output_error,cannot build bridge gcc3_linux_x86-64: bridge $(bridges_SELECTED_BRIDGE) already selected))
endif
bridges_SELECTED_BRIDGE := gcc3_macosx_x86-64
$(eval $(call gb_Library_Library,gcc3_uno))
$(eval $(call gb_Library_use_internal_comprehensive_api,gcc3_uno,\
udkapi \
))
$(eval $(call gb_Library_set_include,gcc3_uno,\
-I$(SRCDIR)/bridges/inc \
$$(INCLUDE) \
))
ifeq ($(HAVE_POSIX_FALLOCATE),YES)
$(eval $(call gb_Library_add_defs,gcc3_uno,\
-DHAVE_POSIX_FALLOCATE \
))
endif
# In case someone enabled the non-standard -fomit-frame-pointer which does not
# work with the .cxx sources of this library.
# In case the compiler supports AVX this code segfaults so specifically turn
# it off.
$(eval $(call gb_Library_add_cxxflags,gcc3_uno,\
-fno-omit-frame-pointer \
-fno-strict-aliasing \
$(if $(filter TRUE,$(HAVE_GCC_AVX)),\
-mno-avx \
) \
))
$(eval $(call gb_Library_use_libraries,gcc3_uno,\
cppu \
sal \
))
$(eval $(call gb_Library_add_asmobjects,gcc3_uno,\
bridges/source/cpp_uno/gcc3_macosx_x86-64/call \
))
$(eval $(call gb_Library_add_exception_objects,gcc3_uno,\
bridges/source/cpp_uno/gcc3_macosx_x86-64/abi \
bridges/source/cpp_uno/gcc3_macosx_x86-64/callvirtualmethod \
bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno \
bridges/source/cpp_uno/gcc3_macosx_x86-64/except \
bridges/source/cpp_uno/gcc3_macosx_x86-64/uno2cpp \
bridges/source/cpp_uno/shared/bridge \
bridges/source/cpp_uno/shared/component \
bridges/source/cpp_uno/shared/types \
bridges/source/cpp_uno/shared/unointerfaceproxy \
bridges/source/cpp_uno/shared/vtablefactory \
bridges/source/cpp_uno/shared/vtables \
))
$(eval $(call gb_Library_add_cxxobjects,gcc3_uno,\
bridges/source/cpp_uno/shared/cppinterfaceproxy \
, $(gb_COMPILERNOOPTFLAGS) $(gb_LinkTarget_EXCEPTIONFLAGS) \
))
# vim: set noet sw=4 ts=4:
...@@ -73,6 +73,9 @@ $(eval $(call gb_Module_add_targets,bridges,\ ...@@ -73,6 +73,9 @@ $(eval $(call gb_Module_add_targets,bridges,\
$(if $(filter GCCMACOSXI,$(COM)$(OS)$(CPU)),\ $(if $(filter GCCMACOSXI,$(COM)$(OS)$(CPU)),\
Library_gcc3_macosx_intel \ Library_gcc3_macosx_intel \
) \ ) \
$(if $(filter GCCMACOSXX,$(COM)$(OS)$(CPU)),\
Library_gcc3_macosx_x86-64 \
) \
$(if $(filter GCCMACOSXP,$(COM)$(OS)$(CPU)),\ $(if $(filter GCCMACOSXP,$(COM)$(OS)$(CPU)),\
Library_gcc3_macosx_powerpc \ Library_gcc3_macosx_powerpc \
) \ ) \
......
...@@ -39,7 +39,8 @@ ...@@ -39,7 +39,8 @@
/*See: http://people.redhat.com/drepper/selinux-mem.html*/ /*See: http://people.redhat.com/drepper/selinux-mem.html*/
#if defined(LINUX) || defined(OPENBSD) || defined(FREEBSD) \ #if defined(LINUX) || defined(OPENBSD) || defined(FREEBSD) \
|| defined(NETBSD) || defined(DRAGONFLY) || defined (ANDROID) || defined(NETBSD) || defined(DRAGONFLY) || defined (ANDROID) \
|| (defined(MACOSX) && defined(__LP64__))
#define USE_DOUBLE_MMAP #define USE_DOUBLE_MMAP
#endif #endif
......
This diff is collapsed.
/* -*- 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 _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
#define _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
// This is an implementation of the x86-64 ABI as described in 'System V
// Application Binary Interface, AMD64 Architecture Processor Supplement'
// (http://www.x86-64.org/documentation/abi-0.95.pdf)
#include <typelib/typedescription.hxx>
namespace x86_64
{
/* 6 general purpose registers are used for parameter passing */
const sal_uInt32 MAX_GPR_REGS = 6;
/* 8 SSE registers are used for parameter passing */
const sal_uInt32 MAX_SSE_REGS = 8;
/* Count number of required registers.
Examine the argument and return set number of register required in each
class.
Return false iff parameter should be passed in memory.
*/
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?
The value can be returned either in a hidden 1st parameter (which is a
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 ) throw ();
void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct ) throw ();
} // namespace x86_64
#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
.text
.align 4, 0x90
.globl _privateSnippetExecutor
_privateSnippetExecutor:
.cfi_startproc
.LFB3:
pushq %rbp
.LCFI0:
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.LCFI1:
subq $160, %rsp
.LCFI2:
.cfi_def_cfa_register %rbp
movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
movq %rdi, -112(%rbp) # Save GP registers
movq %rsi, -104(%rbp)
movq %rdx, -96(%rbp)
movq %rcx, -88(%rbp)
movq %r8 , -80(%rbp)
movq %r9 , -72(%rbp)
movsd %xmm0, -64(%rbp) # Save FP registers
movsd %xmm1, -56(%rbp)
movsd %xmm2, -48(%rbp)
movsd %xmm3, -40(%rbp)
movsd %xmm4, -32(%rbp)
movsd %xmm5, -24(%rbp)
movsd %xmm6, -16(%rbp)
movsd %xmm7, -8(%rbp)
leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
leaq -64(%rbp), %rcx # 4th param: void ** fpreg
leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
call _cpp_vtable_call
cmp $10, %rax # typelib_TypeClass_FLOAT
je .Lfloat
cmp $11, %rax # typelib_TypeClass_DOUBLE
je .Lfloat
movq -144(%rbp), %rax # Return value (int case)
movq -136(%rbp), %rdx # Return value (int case)
movq -144(%rbp), %xmm0 # Return value (int case)
movq -136(%rbp), %xmm1 # Return value (int case)
jmp .Lfinish
.Lfloat:
movlpd -144(%rbp), %xmm0 # Return value (float/double case)
.Lfinish:
leave
ret
.cfi_endproc
.subsections_via_symbols
/* -*- 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 "cppu/macros.hxx"
#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", "r10", "r11",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
);
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: */
/* -*- 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 * 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: */
/* -*- 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 "uno/mapping.h"
#include <typeinfo>
#include <exception>
#include <cstddef>
namespace CPPU_CURRENT_NAMESPACE
{
// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
struct _Unwind_Exception
{
unsigned exception_class __attribute__((__mode__(__DI__)));
void * exception_cleanup;
unsigned private_1 __attribute__((__mode__(__word__)));
unsigned private_2 __attribute__((__mode__(__word__)));
} __attribute__((__aligned__));
struct __cxa_exception
{
::std::type_info *exceptionType;
void (*exceptionDestructor)(void *);
::std::unexpected_handler unexpectedHandler;
::std::terminate_handler terminateHandler;
__cxa_exception *nextException;
int handlerCount;
int handlerSwitchValue;
const unsigned char *actionRecord;
const unsigned char *languageSpecificData;
void *catchTemp;
void *adjustedPtr;
_Unwind_Exception unwindHeader;
};
struct __cxa_eh_globals
{
__cxa_exception *caughtExceptions;
unsigned int uncaughtExceptions;
};
}
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
// -----
//==================================================================================================
void raiseException(
uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
//==================================================================================================
void fillUnoException(
__cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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