summaryrefslogtreecommitdiff
path: root/bridges/source
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2012-09-27 22:27:49 +0300
committerTor Lillqvist <tml@iki.fi>2012-09-27 23:52:22 +0300
commit9f5227d66bfca9dd2ffc338f68001ad6ba3b485d (patch)
tree63be70bee1d5c72707740d1c6d6f6e10061f384c /bridges/source
parent6beb0d37b03253be3aa42189b9995b512d9d8f72 (diff)
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
Diffstat (limited to 'bridges/source')
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx73
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_x86-64/call.s79
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx2
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_x86-64/share.hxx105
4 files changed, 157 insertions, 102 deletions
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx b/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
new file mode 100644
index 000000000000..96834dae6e51
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.cxx
@@ -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: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.s b/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.s
deleted file mode 100644
index 8b8072ff049c..000000000000
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/call.s
+++ /dev/null
@@ -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
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
index 89ab4624911a..bc194c4342e4 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
@@ -396,7 +396,7 @@ extern "C" typelib_TypeClass cpp_vtable_call(
}
//==================================================================================================
-extern "C" void privateSnippetExecutor( ... );
+extern "C" void privateSnippetExecutor();
const int codeSnippetSize = 24;
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_x86-64/share.hxx
index f84958b96368..910a5e46c6cd 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/share.hxx
@@ -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
+};
-struct __cxa_exception
-{
- ::std::type_info *exceptionType;
- void (*exceptionDestructor)(void *);
- ::std::unexpected_handler unexpectedHandler;
- ::std::terminate_handler terminateHandler;
+// From libcppabi-24.2/include/unwind-cxx.h
- __cxa_exception *nextException;
+typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
- int handlerCount;
+// 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.
- int handlerSwitchValue;
- const unsigned char *actionRecord;
- const unsigned char *languageSpecificData;
- void *catchTemp;
- void *adjustedPtr;
+struct __cxa_exception
+{
+#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 *);
+
+ // 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;
+
+ // The caught exception stack threads through here.
+ __cxa_exception *nextException;
+
+ // How many nested handlers have caught this exception. A negated
+ // value is a signal that this object has been rethrown.
+ int handlerCount;
+
+#ifdef __ARM_EABI_UNWINDER__
+ // Stack of exceptions in cleanups.
+ __cxa_exception* nextPropagatingException;
+
+ // 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
- _Unwind_Exception unwindHeader;
+ // 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
};
}