Make exceptions work better in the x86-64 MacOSX C++-UNO bridge
Putting the privateSnippetExecutor() assembly code as inline asm inside an otherwise empty C++ function helps, for some reason. Use the actual _Unwnd_Exception and __cxa_exception definitions as used by Apple (from opensource.apple.com libunwind and libcppabi sources) instead of guessing. Change-Id: I1ef22a9c0c664d3a357b9a6474406141f53cc490
This commit is contained in:
@@ -46,12 +46,9 @@ $(eval $(call gb_Library_use_libraries,gcc3_uno,\
|
||||
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/call \
|
||||
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 \
|
||||
|
73
bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
Normal file
73
bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
Normal file
@@ -0,0 +1,73 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* 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 .
|
||||
*/
|
||||
|
||||
extern "C" void
|
||||
privateSnippetExecutor()
|
||||
{
|
||||
asm volatile
|
||||
(
|
||||
" subq $160, %rsp\n"
|
||||
|
||||
" movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex\n"
|
||||
|
||||
" movq %rdi, -112(%rbp) # Save GP registers\n"
|
||||
" movq %rsi, -104(%rbp)\n"
|
||||
" movq %rdx, -96(%rbp)\n"
|
||||
" movq %rcx, -88(%rbp)\n"
|
||||
" movq %r8 , -80(%rbp)\n"
|
||||
" movq %r9 , -72(%rbp)\n"
|
||||
|
||||
" movsd %xmm0, -64(%rbp) # Save FP registers\n"
|
||||
" movsd %xmm1, -56(%rbp)\n"
|
||||
" movsd %xmm2, -48(%rbp)\n"
|
||||
" movsd %xmm3, -40(%rbp)\n"
|
||||
" movsd %xmm4, -32(%rbp)\n"
|
||||
" movsd %xmm5, -24(%rbp)\n"
|
||||
" movsd %xmm6, -16(%rbp)\n"
|
||||
" movsd %xmm7, -8(%rbp)\n"
|
||||
|
||||
" leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn\n"
|
||||
" leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw\n"
|
||||
" leaq -64(%rbp), %rcx # 4th param: void ** fpreg\n"
|
||||
" leaq -112(%rbp), %rdx # 3rd param: void ** gpreg\n"
|
||||
" movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset\n"
|
||||
" movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex\n"
|
||||
|
||||
" call _cpp_vtable_call\n"
|
||||
|
||||
" cmp $10, %rax # typelib_TypeClass_FLOAT\n"
|
||||
" je .Lfloat\n"
|
||||
" cmp $11, %rax # typelib_TypeClass_DOUBLE\n"
|
||||
" je .Lfloat\n"
|
||||
|
||||
" movq -144(%rbp), %rax # Return value (int case)\n"
|
||||
" movq -136(%rbp), %rdx # Return value (int case)\n"
|
||||
" movq -144(%rbp), %xmm0 # Return value (int case)\n"
|
||||
" movq -136(%rbp), %xmm1 # Return value (int case)\n"
|
||||
" jmp .Lfinish\n"
|
||||
|
||||
".Lfloat:\n"
|
||||
" movlpd -144(%rbp), %xmm0 # Return value (float/double case)\n"
|
||||
|
||||
".Lfinish:\n"
|
||||
" addq $160, %rsp\n"
|
||||
);
|
||||
}
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* 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
|
@@ -396,7 +396,7 @@ extern "C" typelib_TypeClass cpp_vtable_call(
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
extern "C" void privateSnippetExecutor( ... );
|
||||
extern "C" void privateSnippetExecutor();
|
||||
|
||||
const int codeSnippetSize = 24;
|
||||
|
||||
|
@@ -35,41 +35,102 @@
|
||||
namespace CPPU_CURRENT_NAMESPACE
|
||||
{
|
||||
|
||||
// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
|
||||
// From opensource.apple.com: libunwind-35.1/include/unwind.h
|
||||
|
||||
typedef enum {
|
||||
_URC_NO_REASON = 0,
|
||||
_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
|
||||
_URC_FATAL_PHASE2_ERROR = 2,
|
||||
_URC_FATAL_PHASE1_ERROR = 3,
|
||||
_URC_NORMAL_STOP = 4,
|
||||
_URC_END_OF_STACK = 5,
|
||||
_URC_HANDLER_FOUND = 6,
|
||||
_URC_INSTALL_CONTEXT = 7,
|
||||
_URC_CONTINUE_UNWIND = 8
|
||||
} _Unwind_Reason_Code;
|
||||
|
||||
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__));
|
||||
uint64_t exception_class;
|
||||
void (*exception_cleanup)(_Unwind_Reason_Code reason, struct _Unwind_Exception* exc);
|
||||
uintptr_t private_1; // non-zero means forced unwind
|
||||
uintptr_t private_2; // holds sp that phase1 found for phase2 to use
|
||||
#if !__LP64__
|
||||
// The gcc implementation of _Unwind_Exception used attribute mode on the above fields
|
||||
// which had the side effect of causing this whole struct to round up to 32 bytes in size.
|
||||
// To be more explicit, we add pad fields added for binary compatibility.
|
||||
uint32_t reserved[3];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// From libcppabi-24.2/include/unwind-cxx.h
|
||||
|
||||
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
|
||||
|
||||
// A C++ exception object consists of a header, which is a wrapper around
|
||||
// an unwind object header with additional C++ specific information,
|
||||
// followed by the exception object itself.
|
||||
|
||||
struct __cxa_exception
|
||||
{
|
||||
::std::type_info *exceptionType;
|
||||
void (*exceptionDestructor)(void *);
|
||||
#if __LP64__
|
||||
// This is a new field to support C++ 0x exception_ptr.
|
||||
// For binary compatibility it is at the start of this
|
||||
// struct which is prepended to the object thrown in
|
||||
// __cxa_allocate_exception.
|
||||
size_t referenceCount;
|
||||
#endif
|
||||
// Manage the exception object itself.
|
||||
std::type_info *exceptionType;
|
||||
void (*exceptionDestructor)(void *);
|
||||
|
||||
::std::unexpected_handler unexpectedHandler;
|
||||
::std::terminate_handler terminateHandler;
|
||||
// The C++ standard has entertaining rules wrt calling set_terminate
|
||||
// and set_unexpected in the middle of the exception cleanup process.
|
||||
std::unexpected_handler unexpectedHandler;
|
||||
std::terminate_handler terminateHandler;
|
||||
|
||||
__cxa_exception *nextException;
|
||||
// The caught exception stack threads through here.
|
||||
__cxa_exception *nextException;
|
||||
|
||||
int handlerCount;
|
||||
// How many nested handlers have caught this exception. A negated
|
||||
// value is a signal that this object has been rethrown.
|
||||
int handlerCount;
|
||||
|
||||
int handlerSwitchValue;
|
||||
const unsigned char *actionRecord;
|
||||
const unsigned char *languageSpecificData;
|
||||
void *catchTemp;
|
||||
void *adjustedPtr;
|
||||
#ifdef __ARM_EABI_UNWINDER__
|
||||
// Stack of exceptions in cleanups.
|
||||
__cxa_exception* nextPropagatingException;
|
||||
|
||||
_Unwind_Exception unwindHeader;
|
||||
// The nuber of active cleanup handlers for this exception.
|
||||
int propagationCount;
|
||||
#else
|
||||
// Cache parsed handler data from the personality routine Phase 1
|
||||
// for Phase 2 and __cxa_call_unexpected.
|
||||
int handlerSwitchValue;
|
||||
const unsigned char *actionRecord;
|
||||
const unsigned char *languageSpecificData;
|
||||
_Unwind_Ptr catchTemp;
|
||||
void *adjustedPtr;
|
||||
#endif
|
||||
#if !__LP64__
|
||||
// This is a new field to support C++ 0x exception_ptr.
|
||||
// For binary compatibility it is placed where the compiler
|
||||
// previously adding padded to 64-bit align unwindHeader.
|
||||
size_t referenceCount;
|
||||
#endif
|
||||
|
||||
// The generic exception header. Must be last.
|
||||
_Unwind_Exception unwindHeader;
|
||||
};
|
||||
|
||||
// Each thread in a C++ program has access to a __cxa_eh_globals object.
|
||||
struct __cxa_eh_globals
|
||||
{
|
||||
__cxa_exception *caughtExceptions;
|
||||
unsigned int uncaughtExceptions;
|
||||
__cxa_exception *caughtExceptions;
|
||||
unsigned int uncaughtExceptions;
|
||||
#ifdef __ARM_EABI_UNWINDER__
|
||||
__cxa_exception* propagatingExceptions;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user