Kaydet (Commit) 1b6c29d1 authored tarafından Herbert Dürr's avatar Herbert Dürr

#i121715# let the C++ compiler do the C++ exception handling

the manually created exception handling tables are not supported for MACH-objects
used on MacOSX. Rather than porting them manually or half-manually e.g. using
LLVM-intrinsics the compiler is happy to do the work for us for C++ methods
even if they only contain inline assembler (wrapped by the compiler generated
frame setup code, of course).
üst 973209e3
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
.text
.align 2
.globl _privateSnippetExecutor
# .type privateSnippetExecutor, @function
_privateSnippetExecutor:
.LFB3:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $160, %rsp
.LCFI2:
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
.LFE3:
.size _privateSnippetExecutor, .-_privateSnippetExecutor
# TODO: the manually created exceptional handling table below is NOT for MACH-objects (eh_frame is ELF specific)
# better let the C++ compiler handle the creation of C++ exception tables...
# see http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
# for details of the .eh_frame, the "Common Information Entry" and "Frame Description Entry" formats
# and http://mentorembedded.github.io/cxx-abi/exceptions.pdf for more info
# .section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x1
.byte 0x1b
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB3-.
.long .LFE3-.LFB3
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB3
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE1:
# .section .note.GNU-stack,"",@progbits
......@@ -395,17 +395,70 @@ extern "C" typelib_TypeClass cpp_vtable_call(
}
//==================================================================================================
extern "C" void privateSnippetExecutor( ... );
const int codeSnippetSize = 24;
// privateSnippetExecutor() is only called by the trampolines created by codeSnippet()
//
// it saves all the registers used for parameter passing in the x86_64 ABI.
// Then it uses them to provide the parameters to its cpp_vtable_call() and
// to handle the return value.
//
// This method makes assumptions about the stack layout of the stack frame above!
extern "C" void privateSnippetExecutor( void )
{
asm volatile (
"subq $160, %%rsp\n\t"
"movq %%r10, -152(%%rbp)\n\t" // Save (nVtableOffset << 32) + nFunctionIndex
"movq %%rdi, -112(%%rbp)\n\t" // Save GP registers
"movq %%rsi, -104(%%rbp)\n\t"
"movq %%rdx, -96(%%rbp)\n\t"
"movq %%rcx, -88(%%rbp)\n\t"
"movq %%r8 , -80(%%rbp)\n\t"
"movq %%r9 , -72(%%rbp)\n\t"
"movsd %%xmm0, -64(%%rbp)\n\t" // Save FP registers
"movsd %%xmm1, -56(%%rbp)\n\t"
"movsd %%xmm2, -48(%%rbp)\n\t"
"movsd %%xmm3, -40(%%rbp)\n\t"
"movsd %%xmm4, -32(%%rbp)\n\t"
"movsd %%xmm5, -24(%%rbp)\n\t"
"movsd %%xmm6, -16(%%rbp)\n\t"
"movsd %%xmm7, -8(%%rbp)\n\t"
"leaq -144(%%rbp), %%r9\n\t" // 6th param: sal_uInt64* pRegisterReturn
"leaq 16(%%rbp), %%r8\n\t" // 5rd param: void** ovrflw
"leaq -64(%%rbp), %%rcx\n\t" // 4th param: void** fpreg
"leaq -112(%%rbp), %%rdx\n\t" // 3rd param: void** gpreg
"movl -148(%%rbp), %%esi\n\t" // 2nd param: sal_int32 nVtableOffset
"movl -152(%%rbp), %%edi\n\t" // 1st param: sal_int32 nFunctionIndex
"call _cpp_vtable_call\n\t"
"cmp $10, %%rax\n\t" // typelib_TypeClass_FLOAT
"je .Lfloat\n\t"
"cmp $11, %%rax\n\t" // typelib_TypeClass_DOUBLE
"je .Lfloat\n\t"
"movq -144(%%rbp), %%rax\n\t" // Return value (int case)
"movq -136(%%rbp), %%rdx\n\t" // Return value (int case)
"movq -144(%%rbp), %%xmm0\n\t" // Return value (int case)
"movq -136(%%rbp), %%xmm1\n\t" // Return value (int case)
"jmp .Lfinish\n"
".Lfloat:\n\t"
"movlpd -144(%%rbp), %%xmm0\n" // Return value (float/double case)
".Lfinish:\n\t"
"addq $160, %%rsp\n"
:
:
: "rax", "xmm0" );
}
static const int codeSnippetSize = 24;
// Generate a trampoline that redirects method calls to
// privateSnippetExecutor().
//
// privateSnippetExecutor() saves all the registers that are used for
// parameter passing on x86_64, and calls the cpp_vtable_call().
// When it returns, privateSnippetExecutor() sets the return value.
//
// Note: The code snippet we build here must not create a stack frame,
// otherwise the UNO exceptions stop working thanks to non-existing
// unwinding info.
......@@ -462,10 +515,11 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
//==================================================================================================
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
Slot ** slots, unsigned char * code, /*sal_PtrDiff writetoexecdiff,*/
typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
sal_Int32 functionCount, sal_Int32 nVtableOffset )
{
static const sal_PtrDiff writetoexecdiff = 0;
(*slots) -= functionCount;
Slot * s = *slots;
for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
......
......@@ -48,8 +48,7 @@ SLOFILES= \
$(SLO)$/abi.obj \
$(SLO)$/except.obj \
$(SLO)$/cpp2uno.obj \
$(SLO)$/uno2cpp.obj \
$(SLO)$/call.obj
$(SLO)$/uno2cpp.obj
SHL1TARGET= $(TARGET)
......@@ -71,7 +70,3 @@ SHL1STDLIBS= \
.INCLUDE : target.mk
$(SLO)$/%.obj: %.s
$(CC) -c -o $(SLO)$/$(@:b).o $<
touch $@
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