diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-07-29 02:50:32 -0400 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2020-08-04 13:47:33 +0200 |
commit | 61b3d406ae4122bdf3d2d36679fb81077834d3ba (patch) | |
tree | 168e028bdc159290441ac0de5f313a4d07403eb8 | |
parent | b7ea898726f29cdd3d6c3929c790371de3d1dfcb (diff) |
Replace brittle gcc3_linux_aarch64 vtableSlotCall with pure assembler code
* For one, as discussed in the comment at <https://gerrit.libreoffice.org/c/
core/+/91978/2#message-97da6c6ece7ae7bd49e9eb4843be333192fcc057> "Port to
FreeBSD aarch64":
"So it looks like Clang does not treat those register asm as we expect it would,
at least on aarch64.
"Witness a local Linux recent master --with-distro=LibreOfficeAndroidAarch64
[i.e., using Clang] build's
> $ llvm-objdump --disassemble instdir/program/libgcc3_uno.a
[...]
> 0000000000000000 <vtableSlotCall>:
> 0: ff 43 03 d1 sub sp, sp, #208
> 4: f4 4f 0b a9 stp x20, x19, [sp, #176]
> 8: fd 7b 0c a9 stp x29, x30, [sp, #192]
> c: fd 03 03 91 add x29, sp, #192
> 10: a8 43 00 91 add x8, x29, #16
> 14: bf 83 1d f8 stur xzr, [x29, #-40]
> 18: e0 07 04 a9 stp x0, x1, [sp, #64]
> 1c: e2 0f 05 a9 stp x2, x3, [sp, #80]
> 20: e4 17 06 a9 stp x4, x5, [sp, #96]
> 24: e6 1f 07 a9 stp x6, x7, [sp, #112]
> 28: e0 07 00 6d stp d0, d1, [sp]
> 2c: e2 0f 01 6d stp d2, d3, [sp, #16]
> 30: e4 17 02 6d stp d4, d5, [sp, #32]
> 34: e6 1f 03 6d stp d6, d7, [sp, #48]
> 38: a8 03 1c f8 stur x8, [x29, #-64]
> 3c: a0 43 5e b8 ldur w0, [x29, #-28]
> 40: a1 03 5e b8 ldur w1, [x29, #-32]
> 44: a5 83 5e f8 ldur x5, [x29, #-24]
> 48: e4 03 08 aa mov x4, x8
> 4c: e2 03 01 91 add x2, sp, #64
> 50: e3 03 00 91 mov x3, sp
> 54: f3 03 01 91 add x19, sp, #64
> 58: f4 03 00 91 mov x20, sp
> 5c: 00 00 00 94 bl 0x5c <vtableSlotCall+0x5c>
> 60: 60 06 40 a9 ldp x0, x1, [x19]
> 64: 80 06 40 6d ldp d0, d1, [x20]
> 68: 82 0e 41 6d ldp d2, d3, [x20, #16]
> 6c: fd 7b 4c a9 ldp x29, x30, [sp, #192]
> 70: f4 4f 4b a9 ldp x20, x19, [sp, #176]
> 74: ff 43 03 91 add sp, sp, #208
> 78: c0 03 5f d6 ret
[...]
vs. [this commit's vtableslotcall.s; see below for details].
"And also latest Clang 12 trunk still does e.g.
> $ cat test.c
> void f(long);
> void g() {
> register long volatile a asm ("x8");
> f(a);
> }
> $ clang --target=unknown-linux-aarch64 -S -O2 test.c
> $ cat test.s
> .text
> .file "test.c"
> .globl g // -- Begin function g
> .p2align 2
> .type g,@function
> g: // @g
> // %bb.0: // %entry
> sub sp, sp, #16 // =16
> ldr x0, [sp, #8]
> add sp, sp, #16 // =16
> b f
> .Lfunc_end0:
> .size g, .Lfunc_end0-g
> // -- End function
> .ident "clang version 12.0.0 (git@github.com:llvm/llvm-project eb31ddd71eb44d53ebe12a09c9587198bb6f2a2e)"
> .section ".note.GNU-stack","",@progbits
> .addrsig
"(This is probably also the underlying issue that
eb15ac837e06087fb8148330e9171d6697d89ee6 'android: Avoid throwing exceptions
through the bridges' tries to hack arond.)"
* For another, this also gets rid of the
dddb527db1562f30a2a2b20338dfc8458086a4a9 "Again, no -fstack-protector-strong for
gcc3_linux_aarch64/cpp2uno.cxx" hack.
The contents of the new vtableslotcall.s is effectively the GCC 10 -S output of
the old vtableSlotCall C++ function from cpp2uno.cxx. (And as cpp2uno.cxx only
takes the address of vtableSlotCall, never calls it directly, it does not matter
that it declares it with an imprecise
extern "C" void vtableSlotCall();
signature.)
Change-Id: Icfbf0622a47825ff7cf21008de27d3da6a2f0ebd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99660
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100017
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
-rw-r--r-- | bridges/Library_cpp_uno.mk | 9 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx | 60 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s | 72 |
3 files changed, 75 insertions, 66 deletions
diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk index 7074b042ba0a..cb9af9aa9424 100644 --- a/bridges/Library_cpp_uno.mk +++ b/bridges/Library_cpp_uno.mk @@ -30,18 +30,13 @@ else ifeq ($(CPUNAME),AARCH64) ifneq ($(filter ANDROID DRAGONFLY FREEBSD LINUX NETBSD OPENBSD,$(OS)),) bridges_SELECTED_BRIDGE := gcc3_linux_aarch64 -bridge_exception_objects := abi uno2cpp +bridge_asm_objects := vtableslotcall +bridge_exception_objects := abi cpp2uno uno2cpp $(eval $(call gb_Library_add_exception_objects,$(gb_CPPU_ENV)_uno, \ bridges/source/cpp_uno/$(bridges_SELECTED_BRIDGE)/callvirtualfunction, \ $(if $(HAVE_GCC_STACK_CLASH_PROTECTION),-fno-stack-clash-protection) \ )) - -$(eval $(call gb_Library_add_cxxobjects,$(gb_CPPU_ENV)_uno, \ - bridges/source/cpp_uno/$(bridges_SELECTED_BRIDGE)/cpp2uno, \ - $(gb_LinkTarget_EXCEPTIONFLAGS) \ - $(call gb_LinkTarget__get_cxxflags,$(gb_CPPU_ENV)_uno) -fstack-protector \ -)) endif else ifeq ($(CPUNAME),AXP) diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx index f9396321cb14..f9f26419b381 100644 --- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx @@ -42,7 +42,7 @@ #include "abi.hxx" -extern "C" void vtableSlotCall_(); +extern "C" void vtableSlotCall(); namespace { @@ -304,64 +304,6 @@ extern "C" void vtableCall( } } -struct aarch64_va_list { - void * stack; - void * gr_top; - void * vr_top; - int gr_offs; - int vr_offs; -}; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wuninitialized" -#pragma GCC diagnostic ignored "-Wvolatile-register-var" -extern "C" void vtableSlotCall( - unsigned long gpr0, unsigned long gpr1, unsigned long gpr2, - unsigned long gpr3, unsigned long gpr4, unsigned long gpr5, - unsigned long gpr6, unsigned long gpr7, double fpr0, double fpr1, - double fpr2, double fpr3, double fpr4, double fpr5, double fpr6, - double fpr7, ...) -{ - register void * volatile indirectRet asm ("x8"); - register sal_Int32 volatile functionIndex asm ("x9"); - register sal_Int32 volatile vtableOffset asm ("x10"); - va_list ap; - va_start(ap, fpr7); - assert(sizeof (va_list) == sizeof (aarch64_va_list)); - unsigned long gpr[8]; - gpr[0] = gpr0; - gpr[1] = gpr1; - gpr[2] = gpr2; - gpr[3] = gpr3; - gpr[4] = gpr4; - gpr[5] = gpr5; - gpr[6] = gpr6; - gpr[7] = gpr7; - double fpr[8]; - fpr[0] = fpr0; - fpr[1] = fpr1; - fpr[2] = fpr2; - fpr[3] = fpr3; - fpr[4] = fpr4; - fpr[5] = fpr5; - fpr[6] = fpr6; - fpr[7] = fpr7; - vtableCall( - functionIndex, vtableOffset, gpr, - reinterpret_cast<unsigned long *>(fpr), - static_cast<unsigned long *>( - reinterpret_cast<aarch64_va_list *>(&ap)->stack), - indirectRet); - asm volatile( - "ldp x0, x1, [%[gpr_]]\n\t" - "ldp d0, d1, [%[fpr_]]\n\t" - "ldp d2, d3, [%[fpr_], #16]\n\t" - :: [gpr_]"r" (gpr), [fpr_]"r" (fpr) - : "r0", "r1", "v0", "v1", "v2", "v3"); - va_end(ap); -} -#pragma GCC diagnostic pop - std::size_t const codeSnippetSize = 8 * 4; unsigned char * generateCodeSnippet( diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s new file mode 100644 index 000000000000..39873b64d7a6 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s @@ -0,0 +1,72 @@ +/* -*- tab-width: 4; indent-tabs-mode: nil; fill-column: 100 -*- */ +/* + * 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 . + */ + + .arch armv8-a + .text + .align 2 + .global vtableSlotCall + .hidden vtableSlotCall + .type vtableSlotCall, %function +vtableSlotCall: + .cfi_startproc + stp x29, x30, [sp, -192]! + .cfi_def_cfa_offset 192 + .cfi_offset 29, -192 + .cfi_offset 30, -184 + add x11, sp, 192 + mov x29, sp + stp x19, x20, [sp, 16] + .cfi_offset 19, -176 + .cfi_offset 20, -168 + add x20, sp, 128 + add x19, sp, 64 + stp x11, x11, [sp, 32] + str x11, [sp, 48] + stp wzr, wzr, [sp, 56] + stp x0, x1, [sp, 64] + mov w0, w9 + mov w1, w10 + stp x2, x3, [sp, 80] + mov x3, x20 + mov x2, x19 + stp x4, x5, [sp, 96] + mov x5, x8 + mov x4, x11 + stp x6, x7, [sp, 112] + stp d0, d1, [sp, 128] + stp d2, d3, [sp, 144] + stp d4, d5, [sp, 160] + stp d6, d7, [sp, 176] + bl vtableCall + ldp x0, x1, [x19] + ldp d0, d1, [x20] + ldp d2, d3, [x20, #16] + ldp x19, x20, [sp, 16] + ldp x29, x30, [sp], 192 + .cfi_restore 30 + .cfi_restore 29 + .cfi_restore 19 + .cfi_restore 20 + .cfi_def_cfa_offset 0 + ret + .cfi_endproc + .size vtableSlotCall, .-vtableSlotCall + .section .note.GNU-stack, "", @progbits + +/* vim:set shiftwidth=4 softtabstop=4 expandtab */ |