- riscv64-support.patch: Add backport of riscv64 support - No gold on riscv64 OBS-URL: https://build.opensuse.org/request/show/1062439 OBS-URL: https://build.opensuse.org/package/show/LibreOffice:Factory/libreoffice?expand=0&rev=1063
2176 lines
81 KiB
Diff
2176 lines
81 KiB
Diff
From bc9487f745befde6534fd46058e119256952323d Mon Sep 17 00:00:00 2001
|
|
From: Sakura286 <sakura286@outlook.com>
|
|
Date: Tue, 26 Jul 2022 02:18:23 +0000
|
|
Subject: [PATCH] Add riscv64 support
|
|
|
|
1. Configure gbuild
|
|
2. Add UNO Bridge for riscv64
|
|
|
|
Till now base function works well on riscv64. The bridgetest has passed.
|
|
Test on Debian, Gentoo and openEuler.
|
|
|
|
Credits:
|
|
|
|
- Heiher <r@hev.cc> and Stephan Bergmann <sbergman@redhat.com>
|
|
The riscv64 bridge implementation refers to mips64 and
|
|
AArch64 bridges.
|
|
- Bo Yu <tsu.yubo@gmail.com> configures gbuild for riscv64.
|
|
- WANG Xuerui <xen0n@gentoo.org> provides lots of guiding tips.
|
|
|
|
Change-Id: Ifad3b0de8b2c9e7328627ed03396bbd45a9c71e4
|
|
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137445
|
|
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
|
|
Tested-by: Jenkins
|
|
---
|
|
|
|
Index: libreoffice-7.4.3.2/bridges/Library_cpp_uno.mk
|
|
===================================================================
|
|
--- libreoffice-7.4.3.2.orig/bridges/Library_cpp_uno.mk
|
|
+++ libreoffice-7.4.3.2/bridges/Library_cpp_uno.mk
|
|
@@ -114,6 +114,15 @@ bridge_noopt_objects := cpp2uno uno2cpp
|
|
bridge_exception_objects := except
|
|
endif
|
|
|
|
+else ifeq ($(CPUNAME),RISCV64)
|
|
+
|
|
+ifneq ($(filter LINUX,$(OS)),)
|
|
+bridges_SELECTED_BRIDGE := gcc3_linux_riscv64
|
|
+bridge_asm_objects := call
|
|
+bridge_noopt_objects := abi cpp2uno uno2cpp
|
|
+bridge_exception_objects := except
|
|
+endif
|
|
+
|
|
else ifeq ($(CPUNAME),POWERPC)
|
|
|
|
ifneq ($(filter DRAGONFLY FREEBSD LINUX NETBSD OPENBSD,$(OS)),)
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/abi.cxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/abi.cxx
|
|
@@ -0,0 +1,95 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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/.
|
|
+ */
|
|
+
|
|
+#include <com/sun/star/uno/genfunc.hxx>
|
|
+#include <uno/data.h>
|
|
+#include <typelib/typedescription.hxx>
|
|
+#include "types.hxx"
|
|
+#include "abi.hxx"
|
|
+#include <stdio.h>
|
|
+#include <cstring>
|
|
+
|
|
+//#define BRIDGE_DEBUG
|
|
+
|
|
+namespace abi_riscv64
|
|
+{
|
|
+void countnGreg(sal_Int32& nGreg, sal_Int32& nFreg,
|
|
+ const typelib_CompoundTypeDescription* pTypeDescr)
|
|
+{
|
|
+ for (int i = 0; i < pTypeDescr->nMembers; i++)
|
|
+ {
|
|
+ typelib_TypeDescriptionReference* pTypeInStruct = pTypeDescr->ppTypeRefs[i];
|
|
+ switch (pTypeInStruct->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_STRUCT:
|
|
+ case typelib_TypeClass_EXCEPTION:
|
|
+ {
|
|
+ typelib_TypeDescription* childTypeDescr = nullptr;
|
|
+ TYPELIB_DANGER_GET(&childTypeDescr, pTypeInStruct);
|
|
+ countnGreg(
|
|
+ nGreg, nFreg,
|
|
+ reinterpret_cast<typelib_CompoundTypeDescription const*>(childTypeDescr));
|
|
+ TYPELIB_DANGER_RELEASE(childTypeDescr);
|
|
+ }
|
|
+ break;
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ nFreg++;
|
|
+ break;
|
|
+ default:
|
|
+ nGreg++;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void fillStruct(const typelib_TypeDescription* pTypeDescr, sal_Int64* gret, double* fret,
|
|
+ void* pRegisterReturn)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In fillStruct, pTypeDescr = %p, gret = %p, fret = %p, pRegisterReturn = %p\n",
|
|
+ pTypeDescr, gret, fret, pRegisterReturn);
|
|
+#endif
|
|
+ sal_Int32 nGreg = 0;
|
|
+ sal_Int32 nFreg = 0;
|
|
+ countnGreg(nGreg, nFreg, reinterpret_cast<typelib_CompoundTypeDescription const*>(pTypeDescr));
|
|
+ char* pAdjust = reinterpret_cast<char*>(pRegisterReturn);
|
|
+ if (nGreg == 0 && nFreg <= 2)
|
|
+ {
|
|
+ if (pTypeDescr->nSize <= 8 && nFreg == 2)
|
|
+ {
|
|
+ std::memcpy(pAdjust, fret, 4);
|
|
+ std::memcpy(pAdjust + 4, fret + 1, 4);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::memcpy(pAdjust, fret, 16);
|
|
+ }
|
|
+ }
|
|
+ else if (nFreg == 1 && nGreg == 1)
|
|
+ {
|
|
+ if (pTypeDescr->nSize > 8)
|
|
+ {
|
|
+ std::memcpy(pAdjust, gret, 8);
|
|
+ std::memcpy(pAdjust + 8, fret, 8);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::memcpy(pAdjust, gret, 4);
|
|
+ std::memcpy(pAdjust + 4, fret, 4);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ std::memcpy(pAdjust, gret, 16);
|
|
+ }
|
|
+}
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/abi.hxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/abi.hxx
|
|
@@ -0,0 +1,23 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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/.
|
|
+ */
|
|
+
|
|
+//#pragma once
|
|
+#include <uno/data.h>
|
|
+#include <typelib/typedescription.hxx>
|
|
+
|
|
+namespace abi_riscv64
|
|
+{
|
|
+void countnGreg(sal_Int32& nGreg, sal_Int32& nFreg,
|
|
+ const typelib_CompoundTypeDescription* pTypeDescr);
|
|
+
|
|
+void fillStruct(const typelib_TypeDescription* pTypeDescr, sal_Int64* gret, double* fret,
|
|
+ void* pRegisterReturn);
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx
|
|
@@ -0,0 +1,33 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+#include <sal/config.h>
|
|
+
|
|
+#include <sal/types.h>
|
|
+
|
|
+namespace
|
|
+{
|
|
+extern "C" sal_Int32 cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
|
|
+ void** gpreg, void** fpreg, void** ovrflw,
|
|
+ sal_uInt64* pRegisterReturn /* space for register return */);
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/call.s
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/call.s
|
|
@@ -0,0 +1,81 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+
|
|
+ .text
|
|
+ .align 2
|
|
+ .global privateSnippetExecutor
|
|
+ .hidden privateSnippetExecutor
|
|
+ .type privateSnippetExecutor, %function
|
|
+privateSnippetExecutor:
|
|
+ .cfi_startproc
|
|
+ addi sp,sp,-160
|
|
+ .cfi_def_cfa_offset 160
|
|
+ sd ra,152(sp)
|
|
+ .cfi_offset 1, -8
|
|
+ fsd fa0,80(sp)
|
|
+ fsd fa1,88(sp)
|
|
+ fsd fa2,96(sp)
|
|
+ fsd fa3,104(sp)
|
|
+ fsd fa4,112(sp)
|
|
+ fsd fa5,120(sp)
|
|
+ fsd fa6,128(sp)
|
|
+ fsd fa7,136(sp)
|
|
+ sd a0,16(sp)
|
|
+ sd a1,24(sp)
|
|
+ sd a2,32(sp)
|
|
+ sd a3,40(sp)
|
|
+ sd a4,48(sp)
|
|
+ sd a5,56(sp)
|
|
+ sd a6,64(sp)
|
|
+ sd a7,72(sp)
|
|
+ // a0 = functionIndex
|
|
+ // a1 = vtableOffset
|
|
+ // a2 = gpreg
|
|
+ // a3 = fpreg
|
|
+ // a4 = overflw
|
|
+ // a5 = pRegisterReturn
|
|
+ add a0,t4,zero
|
|
+ add a1,t5,zero
|
|
+ addi a2,sp,16
|
|
+ addi a3,sp,80
|
|
+ addi a4,sp,160
|
|
+ add a5,sp,zero
|
|
+ // jump to cpp_vtable_call
|
|
+ jalr ra,t6,0
|
|
+
|
|
+ bne a0,zero,.OneFloatOneInt
|
|
+ ld a0,0(sp)
|
|
+ ld a1,8(sp)
|
|
+ fld fa0,0(sp)
|
|
+ fld fa1,8(sp)
|
|
+ jal zero,.EndProgram
|
|
+.OneFloatOneInt:
|
|
+ ld a0,0(sp)
|
|
+ fld fa0,8(sp)
|
|
+.EndProgram:
|
|
+ ld ra,152(sp)
|
|
+ .cfi_restore 1
|
|
+ addi sp,sp,160
|
|
+ .cfi_def_cfa_offset 0
|
|
+ jalr zero,ra,0
|
|
+ .cfi_endproc
|
|
+ .size privateSnippetExecutor, .-privateSnippetExecutor
|
|
+ .section .note.GNU-stack, "", @progbits
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
|
|
@@ -0,0 +1,795 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+#include <com/sun/star/uno/genfunc.hxx>
|
|
+#include <sal/log.hxx>
|
|
+#include <typelib/typedescription.hxx>
|
|
+#include <uno/data.h>
|
|
+#include <osl/endian.h>
|
|
+#include "bridge.hxx"
|
|
+#include "cppinterfaceproxy.hxx"
|
|
+#include "types.hxx"
|
|
+#include "vtablefactory.hxx"
|
|
+#include "call.hxx"
|
|
+#include "share.hxx"
|
|
+#include "abi.hxx"
|
|
+
|
|
+#include <stdio.h>
|
|
+//#include <string.h>
|
|
+#include <cstring>
|
|
+
|
|
+using namespace com::sun::star::uno;
|
|
+
|
|
+//#define BRIDGE_DEBUG
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+#include <rtl/strbuf.hxx>
|
|
+#include <rtl/ustrbuf.hxx>
|
|
+using namespace ::std;
|
|
+using namespace ::osl;
|
|
+using namespace ::rtl;
|
|
+#endif
|
|
+
|
|
+namespace CPPU_CURRENT_NAMESPACE
|
|
+{
|
|
+bool is_complex_struct(const typelib_TypeDescription* type)
|
|
+{
|
|
+ const typelib_CompoundTypeDescription* p
|
|
+ = reinterpret_cast<const typelib_CompoundTypeDescription*>(type);
|
|
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
|
|
+ {
|
|
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT
|
|
+ || p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
|
|
+ {
|
|
+ typelib_TypeDescription* t = 0;
|
|
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
|
|
+ bool b = is_complex_struct(t);
|
|
+ TYPELIB_DANGER_RELEASE(t);
|
|
+ if (b)
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
|
|
+ return true;
|
|
+ }
|
|
+ if (p->pBaseTypeDescription != 0)
|
|
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
|
|
+ return false;
|
|
+}
|
|
+
|
|
+bool return_in_hidden_param(typelib_TypeDescriptionReference* pTypeRef)
|
|
+{
|
|
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
|
|
+ return false;
|
|
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT
|
|
+ || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
|
|
+ {
|
|
+ typelib_TypeDescription* pTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pTypeDescr, pTypeRef);
|
|
+
|
|
+ //A Composite Type not larger than 16 bytes is returned in up to two GPRs
|
|
+ bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
|
|
+
|
|
+ TYPELIB_DANGER_RELEASE(pTypeDescr);
|
|
+ return bRet;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+}
|
|
+
|
|
+namespace
|
|
+{
|
|
+static sal_Int32
|
|
+cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|
+ const typelib_TypeDescription* pMemberTypeDescr,
|
|
+ typelib_TypeDescriptionReference* pReturnTypeRef, // 0 indicates void return
|
|
+ sal_Int32 nParams, typelib_MethodParameter* pParams, void** gpreg, void** fpreg,
|
|
+ void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In cpp2uno_call, pThis = %p, pMemberTypeDescr = %p, pReturnTypeRef = %p\n", pThis,
|
|
+ pMemberTypeDescr, pReturnTypeRef);
|
|
+ printf("In cpp2uno_call, nParams = %d, pParams = %p, pRegisterReturn = %p\n", nParams, pParams,
|
|
+ pRegisterReturn);
|
|
+ printf("In cpp2uno_call, gpreg = %p, fpreg = %p, ovrflw = %p\n", gpreg, fpreg, ovrflw);
|
|
+#endif
|
|
+ unsigned int nr_gpr = 0;
|
|
+ unsigned int nr_fpr = 0;
|
|
+
|
|
+ char* gpreg_t = reinterpret_cast<char*>(gpreg);
|
|
+ char* fpreg_t = reinterpret_cast<char*>(fpreg);
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:begin\n");
|
|
+#endif
|
|
+ // return
|
|
+ typelib_TypeDescription* pReturnTypeDescr = 0;
|
|
+ if (pReturnTypeRef)
|
|
+ TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
|
|
+
|
|
+ void* pUnoReturn = 0;
|
|
+ void* pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
|
|
+
|
|
+ if (pReturnTypeDescr)
|
|
+ {
|
|
+ if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param(pReturnTypeRef))
|
|
+ {
|
|
+ pCppReturn = *gpreg++; // complex return via ptr (pCppReturn)
|
|
+ nr_gpr++;
|
|
+
|
|
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
|
|
+ ? alloca(pReturnTypeDescr->nSize)
|
|
+ : pCppReturn); // direct way
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:complexreturn\n");
|
|
+#endif
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pUnoReturn = pRegisterReturn; // direct way for simple types
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:simplereturn\n");
|
|
+#endif
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // pop this
|
|
+ gpreg++;
|
|
+ nr_gpr++;
|
|
+
|
|
+ // stack space
|
|
+ static_assert(sizeof(void*) == sizeof(sal_Int64), "### unexpected size!");
|
|
+ // parameters
|
|
+ void** pUnoArgs = (void**)alloca(4 * sizeof(void*) * nParams);
|
|
+ void** pCppArgs = pUnoArgs + nParams;
|
|
+ // indices of values this have to be converted (interface conversion cpp<=>uno)
|
|
+ sal_Int32* pTempIndices = (sal_Int32*)(pUnoArgs + (2 * nParams));
|
|
+ // type descriptions for reconversions
|
|
+ typelib_TypeDescription** ppTempParamTypeDescr
|
|
+ = (typelib_TypeDescription**)(pUnoArgs + (3 * nParams));
|
|
+
|
|
+ sal_Int32 nTempIndices = 0;
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:nParams=%d\n", nParams);
|
|
+#endif
|
|
+ for (sal_Int32 nPos = 0; nPos < nParams; ++nPos)
|
|
+ {
|
|
+ const typelib_MethodParameter& rParam = pParams[nPos];
|
|
+
|
|
+ typelib_TypeDescription* pParamTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pParamTypeDescr, rParam.pTypeRef);
|
|
+
|
|
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType(pParamTypeDescr)) // value
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
|
|
+#endif
|
|
+ switch (pParamTypeDescr->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ if (nr_fpr < MAX_FP_REGS)
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:fpr=%p\n", *fpreg);
|
|
+#endif
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
|
|
+ nr_fpr++;
|
|
+ }
|
|
+ else if (nr_gpr < MAX_GP_REGS)
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:fpr=%p\n", *gpreg);
|
|
+#endif
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
|
|
+ nr_gpr++;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:fpr=%p\n", *ovrflw);
|
|
+#endif
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
|
|
+ }
|
|
+
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ if (nr_gpr < MAX_GP_REGS)
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:gpr=%p\n", *gpreg);
|
|
+#endif
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
|
|
+ nr_gpr++;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:gpr=%p\n", *ovrflw);
|
|
+#endif
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ // no longer needed
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ else // ptr to complex value | ref
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:ptr|ref\n");
|
|
+#endif
|
|
+ void* pCppStack;
|
|
+ if (nr_gpr < MAX_GP_REGS)
|
|
+ {
|
|
+ pCppArgs[nPos] = pCppStack = *gpreg++;
|
|
+ nr_gpr++;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
|
|
+ }
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:pCppStack=%p\n", pCppStack);
|
|
+#endif
|
|
+
|
|
+ if (!rParam.bIn) // is pure out
|
|
+ {
|
|
+ // uno out is unconstructed mem!
|
|
+ pUnoArgs[nPos] = alloca(pParamTypeDescr->nSize);
|
|
+ pTempIndices[nTempIndices] = nPos;
|
|
+ // will be released at reconversion
|
|
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
|
|
+ }
|
|
+ // is in/inout
|
|
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(pParamTypeDescr))
|
|
+ {
|
|
+ uno_copyAndConvertData(pUnoArgs[nPos] = alloca(pParamTypeDescr->nSize), pCppStack,
|
|
+ pParamTypeDescr, pThis->getBridge()->getCpp2Uno());
|
|
+ pTempIndices[nTempIndices] = nPos; // has to be reconverted
|
|
+ // will be released at reconversion
|
|
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
|
|
+ pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
|
|
+#endif
|
|
+ }
|
|
+ else // direct way
|
|
+ {
|
|
+ pUnoArgs[nPos] = pCppStack;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
|
|
+#endif
|
|
+ // no longer needed
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
|
|
+ printf("pMemberTypeDescr=%p,pUnoReturn=%p\n", pMemberTypeDescr, pUnoReturn);
|
|
+#endif
|
|
+
|
|
+ // ExceptionHolder
|
|
+ uno_Any aUnoExc; // Any will be constructed by callee
|
|
+ uno_Any* pUnoExc = &aUnoExc;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("pThis=%p,pThis->getUnoI()=%p,pMemberTypeDescr=%p\npUnoReturn=%p,pUnoArgs=%p", pThis,
|
|
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs);
|
|
+#endif
|
|
+ // invoke uno dispatch call
|
|
+ (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs,
|
|
+ &pUnoExc);
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp2uno_call2,after dispatch\n");
|
|
+#endif
|
|
+
|
|
+ // in case an exception occurred...
|
|
+ if (pUnoExc)
|
|
+ {
|
|
+ fflush(stdout);
|
|
+ // destruct temporary in/inout params
|
|
+ for (; nTempIndices--;)
|
|
+ {
|
|
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
|
|
+
|
|
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
|
|
+ uno_destructData(pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0);
|
|
+ TYPELIB_DANGER_RELEASE(ppTempParamTypeDescr[nTempIndices]);
|
|
+ }
|
|
+ if (pReturnTypeDescr)
|
|
+ TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
|
|
+
|
|
+ CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp());
|
|
+ // has to destruct the any
|
|
+ // is here for dummy
|
|
+ return typelib_TypeClass_VOID;
|
|
+ }
|
|
+ else // else no exception occurred...
|
|
+ {
|
|
+ // temporary params
|
|
+ for (; nTempIndices--;)
|
|
+ {
|
|
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
|
|
+ typelib_TypeDescription* pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
|
|
+
|
|
+ if (pParams[nIndex].bOut) // inout/out
|
|
+ {
|
|
+ // convert and assign
|
|
+ uno_destructData(pCppArgs[nIndex], pParamTypeDescr, cpp_release);
|
|
+ uno_copyAndConvertData(pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
|
|
+ pThis->getBridge()->getUno2Cpp());
|
|
+ }
|
|
+ // destroy temp uno param
|
|
+ uno_destructData(pUnoArgs[nIndex], pParamTypeDescr, 0);
|
|
+
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ void* retout = nullptr; // avoid false -Werror=maybe-uninitialized
|
|
+ // return
|
|
+ sal_Int32 returnType = 0;
|
|
+ if (pReturnTypeDescr)
|
|
+ {
|
|
+ char* pReturn = reinterpret_cast<char*>(pRegisterReturn);
|
|
+ if (!bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr))
|
|
+ {
|
|
+ switch (pReturnTypeDescr == nullptr ? typelib_TypeClass_VOID
|
|
+ : pReturnTypeDescr->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_HYPER:
|
|
+ case typelib_TypeClass_UNSIGNED_HYPER:
|
|
+ case typelib_TypeClass_LONG:
|
|
+ case typelib_TypeClass_UNSIGNED_LONG:
|
|
+ case typelib_TypeClass_ENUM:
|
|
+ case typelib_TypeClass_CHAR:
|
|
+ case typelib_TypeClass_SHORT:
|
|
+ case typelib_TypeClass_UNSIGNED_SHORT:
|
|
+ case typelib_TypeClass_BOOLEAN:
|
|
+ case typelib_TypeClass_BYTE:
|
|
+ std::memcpy(pReturn, pUnoReturn, 8);
|
|
+ break;
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ std::memcpy(pReturn, pUnoReturn, 4);
|
|
+ std::memset(pReturn + 4, 0xFF, 4);
|
|
+ break;
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ std::memcpy(pReturn, pUnoReturn, 8);
|
|
+ break;
|
|
+ case typelib_TypeClass_STRUCT:
|
|
+ case typelib_TypeClass_EXCEPTION:
|
|
+ {
|
|
+ std::memcpy(pReturn, pUnoReturn, 16);
|
|
+ sal_Int32 nGreg = 0;
|
|
+ sal_Int32 nFreg = 0;
|
|
+ abi_riscv64::countnGreg(
|
|
+ nGreg, nFreg,
|
|
+ reinterpret_cast<typelib_CompoundTypeDescription const*>(
|
|
+ pReturnTypeDescr));
|
|
+ if (pReturnTypeDescr->nSize <= 8 && nFreg == 2 && nGreg == 0)
|
|
+ {
|
|
+ std::memcpy(pReturn + 8, pReturn + 4, 4);
|
|
+ std::memset(pReturn + 4, 0xFF, 4);
|
|
+ std::memset(pReturn + 12, 0xFF, 4);
|
|
+ }
|
|
+ else if (nGreg == 1 && nFreg == 1)
|
|
+ {
|
|
+ returnType = 1;
|
|
+ if (pReturnTypeDescr->nSize <= 8)
|
|
+ {
|
|
+ std::memcpy(pReturn + 8, pReturn + 4, 4);
|
|
+ std::memset(pReturn + 12, 0xFF, 4);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ case typelib_TypeClass_VOID:
|
|
+ break;
|
|
+ default:
|
|
+ if (pUnoReturn)
|
|
+ {
|
|
+ std::memcpy(pRegisterReturn, pUnoReturn, 16);
|
|
+ }
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("Unhandled Type: %d\n", pReturnTypeDescr->eTypeClass);
|
|
+#endif
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ uno_copyAndConvertData(pCppReturn, pUnoReturn, pReturnTypeDescr,
|
|
+ pThis->getBridge()->getUno2Cpp());
|
|
+ // destroy temp uno return
|
|
+ uno_destructData(pUnoReturn, pReturnTypeDescr, 0);
|
|
+ // complex return ptr is set to return reg
|
|
+ *(void**)pRegisterReturn = pCppReturn;
|
|
+ }
|
|
+ TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
|
|
+ }
|
|
+ return returnType;
|
|
+ }
|
|
+}
|
|
+
|
|
+/**
|
|
+ * is called on incoming vtable calls
|
|
+ * (called by asm snippets)
|
|
+ */
|
|
+sal_Int32 cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg,
|
|
+ void** fpreg, void** ovrflw,
|
|
+ sal_uInt64* pRegisterReturn /* space for register return */)
|
|
+{
|
|
+ static_assert(sizeof(sal_Int64) == sizeof(void*), "### unexpected!");
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
|
|
+ fprintf(stdout, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
|
|
+ fprintf(stdout, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
|
|
+#endif
|
|
+
|
|
+ // gpreg: [ret *], this, [other gpr params]
|
|
+ // fpreg: [fpr params]
|
|
+ // ovrflw: [gpr or fpr params (properly aligned)]
|
|
+ void* pThis;
|
|
+ if (nFunctionIndex & 0x80000000)
|
|
+ {
|
|
+ nFunctionIndex &= 0x7fffffff;
|
|
+ pThis = gpreg[1];
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pThis = gpreg[0];
|
|
+ }
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n", pThis,
|
|
+ nFunctionIndex, nVtableOffset);
|
|
+#endif
|
|
+
|
|
+ pThis = static_cast<char*>(pThis) - nVtableOffset;
|
|
+ bridges::cpp_uno::shared::CppInterfaceProxy* pCppI
|
|
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(pThis);
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call, pCppI=%p\n", pCppI);
|
|
+#endif
|
|
+
|
|
+ typelib_InterfaceTypeDescription* pTypeDescr = pCppI->getTypeDescr();
|
|
+
|
|
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
|
|
+ {
|
|
+ SAL_WARN("bridges", "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
|
|
+ << " vtable index " << nFunctionIndex << "/"
|
|
+ << pTypeDescr->nMapFunctionIndexToMemberIndex);
|
|
+ throw RuntimeException(("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
|
|
+ + " vtable index " + OUString::number(nFunctionIndex) + "/"
|
|
+ + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
|
|
+ (XInterface*)pThis);
|
|
+ }
|
|
+
|
|
+ // determine called method
|
|
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
|
|
+ assert(nMemberPos < pTypeDescr->nAllMembers);
|
|
+
|
|
+ TypeDescription aMemberDescr(pTypeDescr->ppAllMembers[nMemberPos]);
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ //OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
|
|
+ //fprintf(stdout, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
|
|
+#endif
|
|
+ sal_Int32 eRet;
|
|
+ switch (aMemberDescr.get()->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call interface attribute\n");
|
|
+#endif
|
|
+ typelib_TypeDescriptionReference* pAttrTypeRef
|
|
+ = reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(aMemberDescr.get())
|
|
+ ->pAttributeTypeRef;
|
|
+
|
|
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
|
|
+ {
|
|
+ // is GET method
|
|
+ eRet = cpp2uno_call(pCppI, aMemberDescr.get(), pAttrTypeRef, 0, 0, // no params
|
|
+ gpreg, fpreg, ovrflw, pRegisterReturn);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // is SET method
|
|
+ typelib_MethodParameter aParam;
|
|
+ aParam.pTypeRef = pAttrTypeRef;
|
|
+ aParam.bIn = sal_True;
|
|
+ aParam.bOut = sal_False;
|
|
+
|
|
+ eRet = cpp2uno_call(pCppI, aMemberDescr.get(),
|
|
+ 0, // indicates void return
|
|
+ 1, &aParam, gpreg, fpreg, ovrflw, pRegisterReturn);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ case typelib_TypeClass_INTERFACE_METHOD:
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call interface method\n");
|
|
+#endif
|
|
+ // is METHOD
|
|
+ switch (nFunctionIndex)
|
|
+ {
|
|
+ case 1: // acquire()
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call method acquire\n");
|
|
+#endif
|
|
+ pCppI->acquireProxy(); // non virtual call!
|
|
+ eRet = 0;
|
|
+ break;
|
|
+ case 2: // release()
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call method release\n");
|
|
+#endif
|
|
+ pCppI->releaseProxy(); // non virtual call!
|
|
+ eRet = 0;
|
|
+ break;
|
|
+ case 0: // queryInterface() opt
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call method query interface opt\n");
|
|
+#endif
|
|
+ typelib_TypeDescription* pTD = 0;
|
|
+ TYPELIB_DANGER_GET(&pTD, reinterpret_cast<Type*>(gpreg[2])->getTypeLibType());
|
|
+ if (pTD)
|
|
+ {
|
|
+ XInterface* pInterface = 0;
|
|
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
|
|
+ pCppI->getBridge()->getCppEnv(), (void**)&pInterface,
|
|
+ pCppI->getOid().pData,
|
|
+ reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD));
|
|
+
|
|
+ if (pInterface)
|
|
+ {
|
|
+ ::uno_any_construct(reinterpret_cast<uno_Any*>(gpreg[0]), &pInterface,
|
|
+ pTD, cpp_acquire);
|
|
+
|
|
+ pInterface->release();
|
|
+ TYPELIB_DANGER_RELEASE(pTD);
|
|
+
|
|
+ reinterpret_cast<void**>(pRegisterReturn)[0] = gpreg[0];
|
|
+ eRet = 0;
|
|
+ break;
|
|
+ }
|
|
+ TYPELIB_DANGER_RELEASE(pTD);
|
|
+ }
|
|
+ } // else perform queryInterface()
|
|
+ default:
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call method query interface\n");
|
|
+#endif
|
|
+ typelib_InterfaceMethodTypeDescription* pMethodTD
|
|
+ = reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(
|
|
+ aMemberDescr.get());
|
|
+
|
|
+ eRet = cpp2uno_call(pCppI, aMemberDescr.get(), pMethodTD->pReturnTypeRef,
|
|
+ pMethodTD->nParams, pMethodTD->pParams, gpreg, fpreg,
|
|
+ ovrflw, pRegisterReturn);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "cpp_vtable_call no member\n");
|
|
+#endif
|
|
+ throw RuntimeException("no member description found!", (XInterface*)pThis);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return eRet;
|
|
+}
|
|
+
|
|
+extern "C" void privateSnippetExecutor(...);
|
|
+
|
|
+int const codeSnippetSize = 0x6c;
|
|
+
|
|
+unsigned char* codeSnippet(unsigned char* code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
|
|
+ bool bHasHiddenParam)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "in codeSnippet functionIndex is %d\n", functionIndex);
|
|
+ fprintf(stdout, "in codeSnippet vtableOffset is %d\n", vtableOffset);
|
|
+ fprintf(stdout, "in codeSnippet privateSnippetExecutor is %lx\n",
|
|
+ (unsigned long)privateSnippetExecutor);
|
|
+ fprintf(stdout, "in codeSnippet cpp_vtable_call is %lx\n", (unsigned long)cpp_vtable_call);
|
|
+
|
|
+ fflush(stdout);
|
|
+#endif
|
|
+
|
|
+ if (bHasHiddenParam)
|
|
+ functionIndex |= 0x80000000;
|
|
+
|
|
+ unsigned int* p = (unsigned int*)code;
|
|
+
|
|
+ assert((((unsigned long)code) & 0x3) == 0); //aligned to 4 otherwise a mistake
|
|
+
|
|
+ /* generate this code */
|
|
+ /*
|
|
+ It is complex to load a 64bit address because uou cannot load
|
|
+ an unsigned number to register on RISC-V.
|
|
+ # load functionIndex to t4
|
|
+ 00000eb7 lui t4,0x0
|
|
+ 000eee93 ori t4,t4,0x0
|
|
+ # load privateSnippetExecutor to t0
|
|
+ 000002b7 lui t0,0x0
|
|
+ 02429293 slli t0,t0,36
|
|
+ 00000337 lui t1,0x0
|
|
+ 01431313 slli t1,t1,20
|
|
+ 0062e2b3 or t0,t0,t1
|
|
+ 00000337 lui t1,0x0
|
|
+ 00431313 slli t1,t1,4
|
|
+ 0062e2b3 or t0,t0,t1
|
|
+ 00000337 lui t1,0x0
|
|
+ 00c35313 srli t1,t1,12
|
|
+ 0062e2b3 or t0,t0,t1
|
|
+ # load cpp_vtable_call to t6
|
|
+ 00000fb7 lui t6,0x0
|
|
+ 024f9f93 slli t6,t6,36
|
|
+ 00000337 lui t1,0x0
|
|
+ 01431313 slli t1,t1,20
|
|
+ 006fefb3 or t6,t6,t1
|
|
+ 00000337 lui t1,0x0
|
|
+ 00431313 slli t1,t1,4
|
|
+ 006fefb3 or t6,t6,t1
|
|
+ 00000337 lui t1,0x0
|
|
+ 00c35313 srli t1,t1,12
|
|
+ 006fefb3 or t6,t6,t1
|
|
+ # load vtableOffset to t5
|
|
+ 00000f37 lui t5,0x0
|
|
+ 000f6f13 ori t5,t5,0x0
|
|
+ # jump to privateSnippetExecutor
|
|
+ 00028067 jalr zero,t0,0x0
|
|
+ */
|
|
+
|
|
+ *p++ = 0x00000eb7 | ((functionIndex)&0xfffff000);
|
|
+ *p++ = 0x000eee93 | ((functionIndex << 20) & 0xfff00000);
|
|
+
|
|
+ // load privateSnippetExecutor to t0
|
|
+ unsigned long functionEntry = ((unsigned long)privateSnippetExecutor);
|
|
+ *p++ = 0x000002b7 | ((functionEntry >> 36) & 0x000000000ffff000);
|
|
+ *p++ = 0x02429293;
|
|
+ *p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
|
|
+ *p++ = 0x01431313;
|
|
+ *p++ = 0x0062e2b3;
|
|
+ *p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
|
|
+ *p++ = 0x00431313;
|
|
+ *p++ = 0x0062e2b3;
|
|
+ *p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
|
|
+ *p++ = 0x00c35313;
|
|
+ *p++ = 0x0062e2b3;
|
|
+ // load cpp_vtable_call to t6
|
|
+ functionEntry = (unsigned long)cpp_vtable_call;
|
|
+ *p++ = 0x00000fb7 | ((functionEntry >> 36) & 0x000000000ffff000);
|
|
+ *p++ = 0x024f9f93;
|
|
+ *p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
|
|
+ *p++ = 0x01431313;
|
|
+ *p++ = 0x006fefb3;
|
|
+ *p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
|
|
+ *p++ = 0x00431313;
|
|
+ *p++ = 0x006fefb3;
|
|
+ *p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
|
|
+ *p++ = 0x00c35313;
|
|
+ *p++ = 0x006fefb3;
|
|
+ // load vtableOffset to t5
|
|
+ *p++ = 0x00000f37 | ((vtableOffset)&0xfffff000);
|
|
+ *p++ = 0x000f6f13 | ((vtableOffset << 20) & 0xfff00000);
|
|
+ // jump to privateSnippetExecutor
|
|
+ *p++ = 0x00028067;
|
|
+ return (code + codeSnippetSize);
|
|
+}
|
|
+}
|
|
+
|
|
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const* bptr,
|
|
+ unsigned char const* eptr)
|
|
+{
|
|
+ asm volatile("fence" :::);
|
|
+}
|
|
+
|
|
+struct bridges::cpp_uno::shared::VtableFactory::Slot
|
|
+{
|
|
+ void* fn;
|
|
+};
|
|
+
|
|
+bridges::cpp_uno::shared::VtableFactory::Slot*
|
|
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void* block)
|
|
+{
|
|
+ return static_cast<Slot*>(block) + 2;
|
|
+}
|
|
+
|
|
+std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(sal_Int32 slotCount)
|
|
+{
|
|
+ return (slotCount + 2) * sizeof(Slot) + slotCount * codeSnippetSize;
|
|
+}
|
|
+
|
|
+bridges::cpp_uno::shared::VtableFactory::Slot*
|
|
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32 slotCount,
|
|
+ sal_Int32,
|
|
+ typelib_InterfaceTypeDescription*)
|
|
+{
|
|
+ Slot* slots = mapBlockToVtable(block);
|
|
+ slots[-2].fn = 0; //null
|
|
+ slots[-1].fn = 0; //destructor
|
|
+ return slots + slotCount;
|
|
+}
|
|
+
|
|
+unsigned char* bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|
+ Slot** slots, unsigned char* code, sal_PtrDiff writetoexecdiff,
|
|
+ typelib_InterfaceTypeDescription const* type, sal_Int32 functionOffset, sal_Int32 functionCount,
|
|
+ sal_Int32 vtableOffset)
|
|
+{
|
|
+ (*slots) -= functionCount;
|
|
+ Slot* s = *slots;
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "in addLocalFunctions functionOffset is %d\n", functionOffset);
|
|
+ fprintf(stdout, "in addLocalFunctions vtableOffset is %d\n", vtableOffset);
|
|
+ fprintf(stdout, "nMembers=%d\n", type->nMembers);
|
|
+ fflush(stdout);
|
|
+#endif
|
|
+
|
|
+ for (sal_Int32 i = 0; i < type->nMembers; ++i)
|
|
+ {
|
|
+ typelib_TypeDescription* member = 0;
|
|
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
|
|
+ assert(member != 0);
|
|
+ switch (member->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
|
+ // Getter:
|
|
+ (s++)->fn = code + writetoexecdiff;
|
|
+ code = codeSnippet(
|
|
+ code, functionOffset++, vtableOffset,
|
|
+ CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
|
|
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(member)
|
|
+ ->pAttributeTypeRef));
|
|
+
|
|
+ // Setter:
|
|
+ if (!reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(member)
|
|
+ ->bReadOnly)
|
|
+ {
|
|
+ (s++)->fn = code + writetoexecdiff;
|
|
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case typelib_TypeClass_INTERFACE_METHOD:
|
|
+ (s++)->fn = code + writetoexecdiff;
|
|
+ code = codeSnippet(
|
|
+ code, functionOffset++, vtableOffset,
|
|
+ CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
|
|
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(member)
|
|
+ ->pReturnTypeRef));
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ assert(false);
|
|
+ break;
|
|
+ }
|
|
+ TYPELIB_DANGER_RELEASE(member);
|
|
+ }
|
|
+ return code;
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx
|
|
@@ -0,0 +1,282 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <dlfcn.h>
|
|
+#include <cxxabi.h>
|
|
+#include <rtl/strbuf.hxx>
|
|
+#include <rtl/ustrbuf.hxx>
|
|
+#include <sal/log.hxx>
|
|
+#include <osl/mutex.hxx>
|
|
+
|
|
+#include <com/sun/star/uno/genfunc.hxx>
|
|
+#include <typelib/typedescription.hxx>
|
|
+#include <uno/any2.h>
|
|
+
|
|
+#include <unordered_map>
|
|
+#include "share.hxx"
|
|
+
|
|
+using namespace ::std;
|
|
+using namespace ::osl;
|
|
+using namespace ::com::sun::star::uno;
|
|
+using namespace ::__cxxabiv1;
|
|
+
|
|
+//#define BRIDGE_DEBUG
|
|
+
|
|
+namespace CPPU_CURRENT_NAMESPACE
|
|
+{
|
|
+void dummy_can_throw_anything(char const*) {}
|
|
+
|
|
+static OUString toUNOname(char const* p)
|
|
+{
|
|
+#if defined BRIDGE_DEBUG
|
|
+ char const* start = p;
|
|
+#endif
|
|
+
|
|
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
|
|
+
|
|
+ OUStringBuffer buf(64);
|
|
+ assert('N' == *p);
|
|
+ ++p; // skip N
|
|
+
|
|
+ while ('E' != *p)
|
|
+ {
|
|
+ // read chars count
|
|
+ long n = (*p++ - '0');
|
|
+ while ('0' <= *p && '9' >= *p)
|
|
+ {
|
|
+ n *= 10;
|
|
+ n += (*p++ - '0');
|
|
+ }
|
|
+ buf.appendAscii(p, n);
|
|
+ p += n;
|
|
+ if ('E' != *p)
|
|
+ buf.append('.');
|
|
+ }
|
|
+
|
|
+#if defined BRIDGE_DEBUG
|
|
+ OUString ret(buf.makeStringAndClear());
|
|
+ OString c_ret(OUStringToOString(ret, RTL_TEXTENCODING_ASCII_US));
|
|
+ fprintf(stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr());
|
|
+ return ret;
|
|
+#else
|
|
+ return buf.makeStringAndClear();
|
|
+#endif
|
|
+}
|
|
+
|
|
+class RTTI
|
|
+{
|
|
+ typedef std::unordered_map<OUString, type_info*> t_rtti_map;
|
|
+
|
|
+ Mutex m_mutex;
|
|
+ t_rtti_map m_rttis;
|
|
+ t_rtti_map m_generatedRttis;
|
|
+
|
|
+ void* m_hApp;
|
|
+
|
|
+public:
|
|
+ RTTI();
|
|
+ ~RTTI();
|
|
+
|
|
+ type_info* getRTTI(typelib_CompoundTypeDescription*);
|
|
+};
|
|
+
|
|
+RTTI::RTTI()
|
|
+ : m_hApp(dlopen(0, RTLD_LAZY))
|
|
+{
|
|
+}
|
|
+
|
|
+RTTI::~RTTI() { dlclose(m_hApp); }
|
|
+
|
|
+type_info* RTTI::getRTTI(typelib_CompoundTypeDescription* pTypeDescr)
|
|
+{
|
|
+ type_info* rtti;
|
|
+
|
|
+ OUString const& unoName = *(OUString const*)&pTypeDescr->aBase.pTypeName;
|
|
+
|
|
+ MutexGuard guard(m_mutex);
|
|
+ t_rtti_map::const_iterator iRttiFind(m_rttis.find(unoName));
|
|
+ if (iRttiFind == m_rttis.end())
|
|
+ {
|
|
+ // RTTI symbol
|
|
+ OStringBuffer buf(64);
|
|
+ buf.append("_ZTIN");
|
|
+ sal_Int32 index = 0;
|
|
+ do
|
|
+ {
|
|
+ OUString token(unoName.getToken(0, '.', index));
|
|
+ buf.append(token.getLength());
|
|
+ OString c_token(OUStringToOString(token, RTL_TEXTENCODING_ASCII_US));
|
|
+ buf.append(c_token);
|
|
+ } while (index >= 0);
|
|
+ buf.append('E');
|
|
+
|
|
+ OString symName(buf.makeStringAndClear());
|
|
+ rtti = (type_info*)dlsym(m_hApp, symName.getStr());
|
|
+
|
|
+ if (rtti)
|
|
+ {
|
|
+ pair<t_rtti_map::iterator, bool> insertion(
|
|
+ m_rttis.insert(t_rtti_map::value_type(unoName, rtti)));
|
|
+ assert(insertion.second && "### inserting new rtti failed?!");
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // try to lookup the symbol in the generated rtti map
|
|
+ t_rtti_map::const_iterator iFind(m_generatedRttis.find(unoName));
|
|
+ if (iFind == m_generatedRttis.end())
|
|
+ {
|
|
+ // we must generate it !
|
|
+ // symbol and rtti-name is nearly identical,
|
|
+ // the symbol is prefixed with _ZTI
|
|
+ char const* rttiName = symName.getStr() + 4;
|
|
+#if defined BRIDGE_DEBUG
|
|
+ fprintf(stderr, "generated rtti for %s\n", rttiName);
|
|
+#endif
|
|
+ if (pTypeDescr->pBaseTypeDescription)
|
|
+ {
|
|
+ // ensure availability of base
|
|
+ type_info* base_rtti = getRTTI(
|
|
+ (typelib_CompoundTypeDescription*)pTypeDescr->pBaseTypeDescription);
|
|
+ rtti
|
|
+ = new __si_class_type_info(strdup(rttiName), (__class_type_info*)base_rtti);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // this class has no base class
|
|
+ rtti = new __class_type_info(strdup(rttiName));
|
|
+ }
|
|
+
|
|
+ pair<t_rtti_map::iterator, bool> insertion(
|
|
+ m_generatedRttis.insert(t_rtti_map::value_type(unoName, rtti)));
|
|
+ assert(insertion.second && "### inserting new generated rtti failed?!");
|
|
+ }
|
|
+ else // taking already generated rtti
|
|
+ {
|
|
+ rtti = iFind->second;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ rtti = iRttiFind->second;
|
|
+ }
|
|
+
|
|
+ return rtti;
|
|
+}
|
|
+
|
|
+static void deleteException(void* pExc)
|
|
+{
|
|
+#if defined BRIDGE_DEBUG
|
|
+ fprintf(stderr, "in deleteException: pExc = %p\n", pExc);
|
|
+#endif
|
|
+ __cxa_exception const* header = ((__cxa_exception const*)pExc - 1);
|
|
+ typelib_TypeDescription* pTD = 0;
|
|
+ OUString unoName(toUNOname(header->exceptionType->name()));
|
|
+ ::typelib_typedescription_getByName(&pTD, unoName.pData);
|
|
+ assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
|
|
+ if (pTD)
|
|
+ {
|
|
+ ::uno_destructData(pExc, pTD, cpp_release);
|
|
+ ::typelib_typedescription_release(pTD);
|
|
+ }
|
|
+}
|
|
+
|
|
+//extern "C" {
|
|
+// void __cxa_throw(void* ex, void* info, void (*dest)(void*)) { ::abort(); }
|
|
+//}
|
|
+
|
|
+void raiseException(uno_Any* pUnoExc, uno_Mapping* pUno2Cpp)
|
|
+{
|
|
+#if defined BRIDGE_DEBUG
|
|
+ OString cstr(OUStringToOString(OUString::unacquired(&pUnoExc->pType->pTypeName),
|
|
+ RTL_TEXTENCODING_ASCII_US));
|
|
+ fprintf(stderr, "> uno exception occurred: %s\n", cstr.getStr());
|
|
+#endif
|
|
+ void* pCppExc;
|
|
+ type_info* rtti;
|
|
+
|
|
+ {
|
|
+ // construct cpp exception object
|
|
+ typelib_TypeDescription* pTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pTypeDescr, pUnoExc->pType);
|
|
+ assert(pTypeDescr);
|
|
+ if (!pTypeDescr)
|
|
+ {
|
|
+ throw RuntimeException(OUString("cannot get typedescription for type ")
|
|
+ + OUString::unacquired(&pUnoExc->pType->pTypeName));
|
|
+ }
|
|
+
|
|
+ pCppExc = __cxa_allocate_exception(pTypeDescr->nSize);
|
|
+ ::uno_copyAndConvertData(pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp);
|
|
+
|
|
+ // destruct uno exception
|
|
+ ::uno_any_destruct(pUnoExc, 0);
|
|
+ // avoiding locked counts
|
|
+ static RTTI rtti_data;
|
|
+ rtti = (type_info*)rtti_data.getRTTI((typelib_CompoundTypeDescription*)pTypeDescr);
|
|
+ TYPELIB_DANGER_RELEASE(pTypeDescr);
|
|
+ assert(rtti && "### no rtti for throwing exception!");
|
|
+ if (!rtti)
|
|
+ {
|
|
+ throw RuntimeException(OUString("no rtti for type ")
|
|
+ + OUString::unacquired(&pUnoExc->pType->pTypeName));
|
|
+ }
|
|
+ }
|
|
+ __cxa_throw(pCppExc, rtti, deleteException);
|
|
+}
|
|
+
|
|
+void fillUnoException(uno_Any* pUnoExc, uno_Mapping* pCpp2Uno)
|
|
+{
|
|
+ __cxa_exception* header = __cxa_get_globals()->caughtExceptions;
|
|
+ if (!header)
|
|
+ {
|
|
+ RuntimeException aRE("no exception header!");
|
|
+ Type const& rType = cppu::UnoType<decltype(aRE)>::get();
|
|
+ uno_type_any_constructAndConvert(pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno);
|
|
+ SAL_WARN("bridges", aRE.Message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ std::type_info* exceptionType = __cxa_current_exception_type();
|
|
+
|
|
+ typelib_TypeDescription* pExcTypeDescr = 0;
|
|
+ OUString unoName(toUNOname(exceptionType->name()));
|
|
+#if defined BRIDGE_DEBUG
|
|
+ OString cstr_unoName(OUStringToOString(unoName, RTL_TEXTENCODING_ASCII_US));
|
|
+ fprintf(stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr());
|
|
+#endif
|
|
+ typelib_typedescription_getByName(&pExcTypeDescr, unoName.pData);
|
|
+ if (0 == pExcTypeDescr)
|
|
+ {
|
|
+ RuntimeException aRE(OUString("exception type not found: ") + unoName);
|
|
+ Type const& rType = cppu::UnoType<decltype(aRE)>::get();
|
|
+ uno_type_any_constructAndConvert(pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno);
|
|
+ SAL_WARN("bridges", aRE.Message);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // construct uno exception any
|
|
+ uno_any_constructAndConvert(pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno);
|
|
+ typelib_typedescription_release(pExcTypeDescr);
|
|
+ }
|
|
+}
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx
|
|
@@ -0,0 +1,85 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+#pragma once
|
|
+
|
|
+#include "uno/mapping.h"
|
|
+
|
|
+#include <typeinfo>
|
|
+#include <exception>
|
|
+#include <cstddef>
|
|
+
|
|
+#define MAX_GP_REGS (8)
|
|
+#define MAX_FP_REGS (8)
|
|
+
|
|
+namespace CPPU_CURRENT_NAMESPACE
|
|
+{
|
|
+void dummy_can_throw_anything(char const*);
|
|
+
|
|
+// ----- 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*);
|
|
+
|
|
+ void (*unexpectedHandler)(); // std::unexpected_handler dropped from C++17
|
|
+ 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;
|
|
+};
|
|
+
|
|
+extern "C" void* __cxa_allocate_exception(std::size_t thrown_size) throw();
|
|
+extern "C" void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*))
|
|
+ __attribute__((noreturn));
|
|
+
|
|
+struct __cxa_eh_globals
|
|
+{
|
|
+ __cxa_exception* caughtExceptions;
|
|
+ unsigned int uncaughtExceptions;
|
|
+};
|
|
+
|
|
+extern "C" __cxa_eh_globals* __cxa_get_globals() throw();
|
|
+extern "C" std::type_info* __cxa_current_exception_type() throw();
|
|
+
|
|
+void raiseException(uno_Any* pUnoExc, uno_Mapping* pUno2Cpp);
|
|
+
|
|
+void fillUnoException(uno_Any*, uno_Mapping* pCpp2Uno);
|
|
+
|
|
+bool return_in_hidden_param(typelib_TypeDescriptionReference* pTypeRef);
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx
|
|
@@ -0,0 +1,616 @@
|
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 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 .
|
|
+ */
|
|
+
|
|
+#include <sal/config.h>
|
|
+
|
|
+#include <exception>
|
|
+#include <malloc.h>
|
|
+#include <cstring>
|
|
+#include <typeinfo>
|
|
+
|
|
+#include <com/sun/star/uno/Exception.hpp>
|
|
+#include <com/sun/star/uno/RuntimeException.hpp>
|
|
+#include <com/sun/star/uno/genfunc.hxx>
|
|
+#include <o3tl/runtimetooustring.hxx>
|
|
+#include <uno/data.h>
|
|
+
|
|
+#include "bridge.hxx"
|
|
+#include "types.hxx"
|
|
+#include "unointerfaceproxy.hxx"
|
|
+#include "vtables.hxx"
|
|
+
|
|
+#include "share.hxx"
|
|
+#include "abi.hxx"
|
|
+
|
|
+//#define BRIDGE_DEBUG
|
|
+#ifdef BRIDGE_DEBUG
|
|
+#include <stdio.h>
|
|
+#endif
|
|
+
|
|
+// FP reg -> GP reg -> stack
|
|
+#define INSERT_FLOAT_DOUBLE(pSV, nfr, pFPR, ngr, pGPR, pDS) \
|
|
+ if (nfr < MAX_FP_REGS) \
|
|
+ pFPR[nfr++] = *reinterpret_cast<double*>(pSV); \
|
|
+ else if (ngr < MAX_FP_REGS) \
|
|
+ pGPR[ngr++] = *reinterpret_cast<sal_Int64*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_uInt64*>(pSV); // verbatim!
|
|
+
|
|
+#define INSERT_INT64(pSV, nr, pGPR, pDS) \
|
|
+ if (nr < MAX_GP_REGS) \
|
|
+ pGPR[nr++] = *reinterpret_cast<sal_Int64*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_Int64*>(pSV);
|
|
+
|
|
+#define INSERT_INT32(pSV, nr, pGPR, pDS) \
|
|
+ if (nr < MAX_GP_REGS) \
|
|
+ pGPR[nr++] = *reinterpret_cast<sal_Int32*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_Int32*>(pSV);
|
|
+
|
|
+#define INSERT_INT16(pSV, nr, pGPR, pDS) \
|
|
+ if (nr < MAX_GP_REGS) \
|
|
+ pGPR[nr++] = *reinterpret_cast<sal_Int16*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_Int16*>(pSV);
|
|
+
|
|
+#define INSERT_UINT16(pSV, nr, pGPR, pDS) \
|
|
+ if (nr < MAX_GP_REGS) \
|
|
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_uInt16*>(pSV);
|
|
+
|
|
+#define INSERT_INT8(pSV, nr, pGPR, pDS) \
|
|
+ if (nr < MAX_GP_REGS) \
|
|
+ pGPR[nr++] = *reinterpret_cast<sal_Int8*>(pSV); \
|
|
+ else \
|
|
+ *pDS++ = *reinterpret_cast<sal_Int8*>(pSV);
|
|
+
|
|
+using namespace ::com::sun::star::uno;
|
|
+
|
|
+namespace
|
|
+{
|
|
+bool isReturnInFPR(const typelib_TypeDescription* pTypeDescr, sal_uInt32& nSize)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In isReturnInFPR, pTypeDescr = %p, nSize = %d\n", pTypeDescr, nSize);
|
|
+#endif
|
|
+ const typelib_CompoundTypeDescription* p
|
|
+ = reinterpret_cast<const typelib_CompoundTypeDescription*>(pTypeDescr);
|
|
+
|
|
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
|
|
+ {
|
|
+ typelib_TypeDescriptionReference* pTypeInStruct = p->ppTypeRefs[i];
|
|
+
|
|
+ switch (pTypeInStruct->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_STRUCT:
|
|
+ case typelib_TypeClass_EXCEPTION:
|
|
+ {
|
|
+ typelib_TypeDescription* t = 0;
|
|
+ TYPELIB_DANGER_GET(&t, pTypeInStruct);
|
|
+ bool isFPR = isReturnInFPR(t, nSize);
|
|
+ TYPELIB_DANGER_RELEASE(t);
|
|
+ if (!isFPR)
|
|
+ return false;
|
|
+ }
|
|
+ break;
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ if (nSize >= 16)
|
|
+ return false;
|
|
+ nSize += 8;
|
|
+ break;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void fillReturn(const typelib_TypeDescription* pTypeDescr, sal_Int64* gret, double* fret,
|
|
+ void* pRegisterReturn)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In fillReturn, pTypeDescr = %p, gret = %p, fret = %p, pRegisterReturn = %p\n",
|
|
+ pTypeDescr, gret, fret, pRegisterReturn);
|
|
+#endif
|
|
+ sal_uInt32 nSize = 0;
|
|
+ if (isReturnInFPR(pTypeDescr, nSize))
|
|
+ {
|
|
+ reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
|
|
+ reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
|
|
+ reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
|
|
+ }
|
|
+}
|
|
+
|
|
+static void callVirtualMethod(void* pAdjustedThisPtr, sal_Int32 nVtableIndex, void* pRegisterReturn,
|
|
+ typelib_TypeDescriptionReference* pReturnTypeRef, bool bSimpleReturn,
|
|
+ sal_uInt64* pStack, sal_uInt32 nStack, sal_uInt64* pGPR, double* pFPR,
|
|
+ typelib_TypeDescription* pReturnTypeDescr)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In callVirtualMethod:\n");
|
|
+ printf("pAdjustedThisPtr = %p, nVtableIndex = %d, pRegisterReturn = %p, pReturnTypeRef = %p\n",
|
|
+ pAdjustedThisPtr, nVtableIndex, pRegisterReturn, pReturnTypeRef);
|
|
+ printf("bSimpleReturn = %d, pStack = %p, nStack = %d, pGPR = %p, pFPR = %p, pReturnTypeDescr = "
|
|
+ "%p\n",
|
|
+ bSimpleReturn, pStack, nStack, pGPR, pFPR, pReturnTypeDescr);
|
|
+#endif
|
|
+ // Get pointer to method
|
|
+ sal_uInt64 pMethod = *((sal_uInt64*)pAdjustedThisPtr);
|
|
+ pMethod += 8 * nVtableIndex;
|
|
+ void* mfunc = (void*)*((sal_uInt64*)pMethod);
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "calling function %p\n", mfunc);
|
|
+#endif
|
|
+
|
|
+ // Load parameters to stack, if necessary
|
|
+ sal_uInt64* pCallStack = NULL;
|
|
+ if (nStack)
|
|
+ {
|
|
+ // 16-bytes aligned
|
|
+ sal_uInt32 nStackBytes = ((nStack + 1) >> 1) * 16;
|
|
+ pCallStack = (sal_uInt64*)__builtin_alloca(nStackBytes);
|
|
+ std::memcpy(pCallStack, pStack, nStackBytes);
|
|
+ }
|
|
+
|
|
+ sal_Int64* gret = (sal_Int64*)malloc(2 * sizeof(sal_Int64));
|
|
+ sal_Int64* gret1 = gret;
|
|
+ sal_Int64* gret2 = gret + 1;
|
|
+ double* fret = (double*)malloc(2 * sizeof(double));
|
|
+ double* fret1 = fret;
|
|
+ double* fret2 = fret + 1;
|
|
+ asm volatile(
|
|
+ //".set push \n\t"
|
|
+ //".set riscv64 \n\t"
|
|
+ // Fill the general purpose registers
|
|
+ "ld a0, 0(%[gpr]) \n\t"
|
|
+ "ld a1, 8(%[gpr]) \n\t"
|
|
+ "ld a2, 16(%[gpr]) \n\t"
|
|
+ "ld a3, 24(%[gpr]) \n\t"
|
|
+ "ld a4, 32(%[gpr]) \n\t"
|
|
+ "ld a5, 40(%[gpr]) \n\t"
|
|
+ "ld a6, 48(%[gpr]) \n\t"
|
|
+ "ld a7, 56(%[gpr]) \n\t"
|
|
+ // Fill the floating pointer registers
|
|
+ "fld fa0, 0(%[fpr]) \n\t"
|
|
+ "fld fa1, 8(%[fpr]) \n\t"
|
|
+ "fld fa2, 16(%[fpr]) \n\t"
|
|
+ "fld fa3, 24(%[fpr]) \n\t"
|
|
+ "fld fa4, 32(%[fpr]) \n\t"
|
|
+ "fld fa5, 40(%[fpr]) \n\t"
|
|
+ "fld fa6, 48(%[fpr]) \n\t"
|
|
+ "fld fa7, 56(%[fpr]) \n\t"
|
|
+ // Perform the call
|
|
+ "jalr ra,%[mfunc],0 \n\t"
|
|
+ // Fill the return values
|
|
+ "add %[gret1], a0,zero \n\t"
|
|
+ "add %[gret2], a1,zero \n\t"
|
|
+ "fmv.d %[fret1], fa0 \n\t"
|
|
+ "fmv.d %[fret2], fa1 \n\t"
|
|
+ //".set pop \n\t"
|
|
+ : [gret1] "=&r"(*gret1), [gret2] "=&r"(*gret2), [fret1] "=&f"(*fret1), [fret2] "=&f"(*fret2)
|
|
+ : [gpr] "r"(pGPR), [fpr] "r"(pFPR), [mfunc] "r"(mfunc),
|
|
+ [stack] "m"(
|
|
+ pCallStack) // dummy input to prevent the compiler from optimizing the alloca out
|
|
+ : "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "ra", "fa0", "fa1", "fa2", "fa3", "fa4",
|
|
+ "fa5", "fa6", "fa7", "memory");
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In callVirtualMethod, fret = %p, gret = %p\n", fret, gret);
|
|
+#endif
|
|
+
|
|
+ switch (pReturnTypeRef->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_HYPER:
|
|
+ case typelib_TypeClass_UNSIGNED_HYPER:
|
|
+ case typelib_TypeClass_LONG:
|
|
+ case typelib_TypeClass_UNSIGNED_LONG:
|
|
+ case typelib_TypeClass_ENUM:
|
|
+ case typelib_TypeClass_CHAR:
|
|
+ case typelib_TypeClass_SHORT:
|
|
+ case typelib_TypeClass_UNSIGNED_SHORT:
|
|
+ case typelib_TypeClass_BOOLEAN:
|
|
+ case typelib_TypeClass_BYTE:
|
|
+ *reinterpret_cast<sal_Int64*>(pRegisterReturn) = gret[0];
|
|
+ break;
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ *reinterpret_cast<double*>(pRegisterReturn) = fret[0];
|
|
+ break;
|
|
+ case typelib_TypeClass_STRUCT:
|
|
+ case typelib_TypeClass_EXCEPTION:
|
|
+ {
|
|
+ sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("nRetSize = %d\n", nRetSize);
|
|
+#endif
|
|
+ if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
|
|
+ {
|
|
+ typelib_TypeDescription* pTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pTypeDescr, pReturnTypeRef);
|
|
+ abi_riscv64::fillStruct(pTypeDescr, gret, fret, pRegisterReturn);
|
|
+ TYPELIB_DANGER_RELEASE(pTypeDescr);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "unhandled return type %u\n", pReturnTypeRef->eTypeClass);
|
|
+#endif
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
|
|
+ typelib_TypeDescriptionReference* pReturnTypeRef, sal_Int32 nParams,
|
|
+ typelib_MethodParameter* pParams, void* pUnoReturn, void* pUnoArgs[],
|
|
+ uno_Any** ppUnoExc)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In cpp_call\n");
|
|
+ printf("pThis = %p, aVtableSlot = %p, pReturnTypeRef = %p, nParams = %d\n", pThis, aVtableSlot,
|
|
+ pReturnTypeRef, nParams);
|
|
+ printf("pParams = %p , pUnoReturn = %p, pUnoArgs = %p\n", pParams, pUnoReturn, pUnoArgs);
|
|
+#endif
|
|
+ // max space for: [complex ret ptr], values|ptr ...
|
|
+ sal_uInt64* pStack = (sal_uInt64*)__builtin_alloca(((nParams + 3) * sizeof(sal_Int64)));
|
|
+ sal_uInt64* pStackStart = pStack;
|
|
+
|
|
+ sal_uInt64 pGPR[MAX_GP_REGS];
|
|
+ sal_uInt64 nREG = 0;
|
|
+
|
|
+ double pFPR[MAX_FP_REGS];
|
|
+ sal_uInt32 nFPR = 0;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("pGPR = %p, pFPR = %p\n", pGPR, pFPR);
|
|
+#endif
|
|
+
|
|
+ // return
|
|
+ typelib_TypeDescription* pReturnTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
|
|
+ assert(pReturnTypeDescr);
|
|
+
|
|
+ void* pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
|
|
+
|
|
+ bool bSimpleReturn = true;
|
|
+ if (pReturnTypeDescr)
|
|
+ {
|
|
+ if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param(pReturnTypeRef))
|
|
+ {
|
|
+ bSimpleReturn = false;
|
|
+ // complex return via ptr
|
|
+ pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
|
|
+ ? __builtin_alloca(pReturnTypeDescr->nSize)
|
|
+ : pUnoReturn;
|
|
+ INSERT_INT64(&pCppReturn, nREG, pGPR, pStack);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pCppReturn = pUnoReturn; // direct way for simple types
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // push this
|
|
+ void* pAdjustedThisPtr = reinterpret_cast<void**>(pThis->getCppI()) + aVtableSlot.offset;
|
|
+ INSERT_INT64(&pAdjustedThisPtr, nREG, pGPR, pStack);
|
|
+
|
|
+ // args
|
|
+ void** pCppArgs = (void**)alloca(3 * sizeof(void*) * nParams);
|
|
+ // indices of values this have to be converted (interface conversion cpp<=>uno)
|
|
+ sal_Int32* pTempIndices = (sal_Int32*)(pCppArgs + nParams);
|
|
+ // type descriptions for reconversions
|
|
+ typelib_TypeDescription** ppTempParamTypeDescr
|
|
+ = (typelib_TypeDescription**)(pCppArgs + (2 * nParams));
|
|
+
|
|
+ sal_Int32 nTempIndices = 0;
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In cpp_call, nParams = %d\n", nParams);
|
|
+ printf("pCppArgs = %p, pStack = %p\n", pCppArgs, pStack);
|
|
+#endif
|
|
+ for (sal_Int32 nPos = 0; nPos < nParams; ++nPos)
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In cpp_call, nPos = %d\n", nPos);
|
|
+#endif
|
|
+ const typelib_MethodParameter& rParam = pParams[nPos];
|
|
+ typelib_TypeDescription* pParamTypeDescr = 0;
|
|
+ TYPELIB_DANGER_GET(&pParamTypeDescr, rParam.pTypeRef);
|
|
+
|
|
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType(pParamTypeDescr))
|
|
+ {
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("Before uno_copyAndConvertData and tons of switch.\n");
|
|
+#endif
|
|
+ uno_copyAndConvertData(pCppArgs[nPos] = alloca(8), pUnoArgs[nPos], pParamTypeDescr,
|
|
+ pThis->getBridge()->getUno2Cpp());
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("Type = %d, Param = 0x%lx\n", pParamTypeDescr->eTypeClass,
|
|
+ *reinterpret_cast<sal_uInt64*>(pCppArgs[nPos]));
|
|
+#endif
|
|
+ switch (pParamTypeDescr->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_LONG:
|
|
+ case typelib_TypeClass_UNSIGNED_LONG:
|
|
+ case typelib_TypeClass_ENUM:
|
|
+ INSERT_INT32(pCppArgs[nPos], nREG, pGPR, pStack);
|
|
+ break;
|
|
+ case typelib_TypeClass_CHAR:
|
|
+ case typelib_TypeClass_SHORT:
|
|
+ INSERT_INT16(pCppArgs[nPos], nREG, pGPR, pStack);
|
|
+ break;
|
|
+ case typelib_TypeClass_UNSIGNED_SHORT:
|
|
+ INSERT_UINT16(pCppArgs[nPos], nREG, pGPR, pStack);
|
|
+ break;
|
|
+ case typelib_TypeClass_BOOLEAN:
|
|
+ case typelib_TypeClass_BYTE:
|
|
+ INSERT_INT8(pCppArgs[nPos], nREG, pGPR, pStack);
|
|
+ break;
|
|
+ case typelib_TypeClass_FLOAT:
|
|
+ case typelib_TypeClass_DOUBLE:
|
|
+ INSERT_FLOAT_DOUBLE(pCppArgs[nPos], nFPR, pFPR, nREG, pGPR, pStack);
|
|
+ break;
|
|
+ case typelib_TypeClass_HYPER:
|
|
+ case typelib_TypeClass_UNSIGNED_HYPER:
|
|
+ INSERT_INT64(pCppArgs[nPos], nREG, pGPR, pStack);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // no longer needed
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ else // ptr to complex value | ref
|
|
+ {
|
|
+ if (!rParam.bIn) // is pure out
|
|
+ {
|
|
+ // cpp out is constructed mem, uno out is not!
|
|
+ uno_constructData(pCppArgs[nPos] = alloca(pParamTypeDescr->nSize), pParamTypeDescr);
|
|
+ pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
|
|
+ // will be released at reconversion
|
|
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
|
|
+ }
|
|
+ // is in/inout
|
|
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(pParamTypeDescr))
|
|
+ {
|
|
+ uno_copyAndConvertData(pCppArgs[nPos] = alloca(pParamTypeDescr->nSize),
|
|
+ pUnoArgs[nPos], pParamTypeDescr,
|
|
+ pThis->getBridge()->getUno2Cpp());
|
|
+
|
|
+ pTempIndices[nTempIndices] = nPos; // has to be reconverted
|
|
+ // will be released at reconversion
|
|
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
|
|
+ }
|
|
+ else // direct way
|
|
+ {
|
|
+ pCppArgs[nPos] = pUnoArgs[nPos];
|
|
+ // no longer needed
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ INSERT_INT64(&(pCppArgs[nPos]), nREG, pGPR, pStack);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ try
|
|
+ {
|
|
+ try
|
|
+ {
|
|
+ callVirtualMethod(pAdjustedThisPtr, aVtableSlot.index, pCppReturn, pReturnTypeRef,
|
|
+ bSimpleReturn, pStackStart, (pStack - pStackStart), pGPR, pFPR,
|
|
+ pReturnTypeDescr);
|
|
+ }
|
|
+ catch (css::uno::Exception&)
|
|
+ {
|
|
+ throw;
|
|
+ }
|
|
+ catch (std::exception& e)
|
|
+ {
|
|
+ throw css::uno::RuntimeException("C++ code threw "
|
|
+ + o3tl::runtimeToOUString(typeid(e).name()) + ": "
|
|
+ + o3tl::runtimeToOUString(e.what()));
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ throw css::uno::RuntimeException("C++ code threw unknown exception");
|
|
+ }
|
|
+ // NO exception occurred...
|
|
+ *ppUnoExc = 0;
|
|
+
|
|
+ // reconvert temporary params
|
|
+ for (; nTempIndices--;)
|
|
+ {
|
|
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
|
|
+ typelib_TypeDescription* pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
|
|
+
|
|
+ if (pParams[nIndex].bIn)
|
|
+ {
|
|
+ if (pParams[nIndex].bOut) // inout
|
|
+ {
|
|
+ uno_destructData(pUnoArgs[nIndex], pParamTypeDescr, 0); // destroy uno value
|
|
+ uno_copyAndConvertData(pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
|
|
+ pThis->getBridge()->getCpp2Uno());
|
|
+ }
|
|
+ }
|
|
+ else // pure out
|
|
+ {
|
|
+ uno_copyAndConvertData(pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
|
|
+ pThis->getBridge()->getCpp2Uno());
|
|
+ }
|
|
+ // destroy temp cpp param => cpp: every param was constructed
|
|
+ uno_destructData(pCppArgs[nIndex], pParamTypeDescr, cpp_release);
|
|
+
|
|
+ TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
|
+ }
|
|
+ // return value
|
|
+ if (pCppReturn && pUnoReturn != pCppReturn)
|
|
+ {
|
|
+ uno_copyAndConvertData(pUnoReturn, pCppReturn, pReturnTypeDescr,
|
|
+ pThis->getBridge()->getCpp2Uno());
|
|
+ uno_destructData(pCppReturn, pReturnTypeDescr, cpp_release);
|
|
+ }
|
|
+ }
|
|
+ catch (...)
|
|
+ {
|
|
+ // fill uno exception
|
|
+ CPPU_CURRENT_NAMESPACE::fillUnoException(*ppUnoExc, pThis->getBridge()->getCpp2Uno());
|
|
+
|
|
+ // temporary params
|
|
+ for (; nTempIndices--;)
|
|
+ {
|
|
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
|
|
+ // destroy temp cpp param => cpp: every param was constructed
|
|
+ uno_destructData(pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release);
|
|
+ TYPELIB_DANGER_RELEASE(ppTempParamTypeDescr[nTempIndices]);
|
|
+ }
|
|
+ // return type
|
|
+ if (pReturnTypeDescr)
|
|
+ TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
|
|
+ }
|
|
+}
|
|
+}
|
|
+
|
|
+namespace bridges::cpp_uno::shared
|
|
+{
|
|
+void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescription* pMemberDescr,
|
|
+ void* pReturn, void* pArgs[], uno_Any** ppException)
|
|
+{
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ printf("In unoInterfaceProxyDispatch:\n");
|
|
+ printf("pMemberDescr = %p, pReturn = %p, pArgs = %p, ppExeption = %p\n", pMemberDescr, pReturn,
|
|
+ pArgs, ppException);
|
|
+#endif
|
|
+ // is my surrogate
|
|
+ bridges::cpp_uno::shared::UnoInterfaceProxy* pThis
|
|
+ = static_cast<bridges::cpp_uno::shared::UnoInterfaceProxy*>(pUnoI);
|
|
+ //typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
|
|
+
|
|
+#ifdef BRIDGE_DEBUG
|
|
+ fprintf(stdout, "in dispatch\n");
|
|
+#endif
|
|
+
|
|
+ switch (pMemberDescr->eTypeClass)
|
|
+ {
|
|
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
|
+ {
|
|
+ VtableSlot aVtableSlot(getVtableSlot(
|
|
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription const*>(pMemberDescr)));
|
|
+
|
|
+ if (pReturn)
|
|
+ {
|
|
+ // dependent dispatch
|
|
+ cpp_call(
|
|
+ pThis, aVtableSlot,
|
|
+ ((typelib_InterfaceAttributeTypeDescription*)pMemberDescr)->pAttributeTypeRef,
|
|
+ 0, 0, // no params
|
|
+ pReturn, pArgs, ppException);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // is SET
|
|
+ typelib_MethodParameter aParam;
|
|
+ aParam.pTypeRef
|
|
+ = ((typelib_InterfaceAttributeTypeDescription*)pMemberDescr)->pAttributeTypeRef;
|
|
+ aParam.bIn = sal_True;
|
|
+ aParam.bOut = sal_False;
|
|
+
|
|
+ typelib_TypeDescriptionReference* pReturnTypeRef = 0;
|
|
+ OUString aVoidName("void");
|
|
+ typelib_typedescriptionreference_new(&pReturnTypeRef, typelib_TypeClass_VOID,
|
|
+ aVoidName.pData);
|
|
+
|
|
+ // dependent dispatch
|
|
+ aVtableSlot.index += 1; //get then set method
|
|
+ cpp_call(pThis, aVtableSlot, pReturnTypeRef, 1, &aParam, pReturn, pArgs,
|
|
+ ppException);
|
|
+
|
|
+ typelib_typedescriptionreference_release(pReturnTypeRef);
|
|
+ }
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ case typelib_TypeClass_INTERFACE_METHOD:
|
|
+ {
|
|
+ VtableSlot aVtableSlot(getVtableSlot(
|
|
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription const*>(pMemberDescr)));
|
|
+ switch (aVtableSlot.index)
|
|
+ {
|
|
+ // standard calls
|
|
+ case 1: // acquire uno interface
|
|
+ (*pUnoI->acquire)(pUnoI);
|
|
+ *ppException = 0;
|
|
+ break;
|
|
+ case 2: // release uno interface
|
|
+ (*pUnoI->release)(pUnoI);
|
|
+ *ppException = 0;
|
|
+ break;
|
|
+ case 0: // queryInterface() opt
|
|
+ {
|
|
+ typelib_TypeDescription* pTD = 0;
|
|
+ TYPELIB_DANGER_GET(&pTD, reinterpret_cast<Type*>(pArgs[0])->getTypeLibType());
|
|
+ if (pTD)
|
|
+ {
|
|
+ uno_Interface* pInterface = 0;
|
|
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
|
|
+ pThis->pBridge->getUnoEnv(), (void**)&pInterface, pThis->oid.pData,
|
|
+ (typelib_InterfaceTypeDescription*)pTD);
|
|
+
|
|
+ if (pInterface)
|
|
+ {
|
|
+ ::uno_any_construct(reinterpret_cast<uno_Any*>(pReturn), &pInterface,
|
|
+ pTD, 0);
|
|
+ (*pInterface->release)(pInterface);
|
|
+ TYPELIB_DANGER_RELEASE(pTD);
|
|
+ *ppException = 0;
|
|
+ break;
|
|
+ }
|
|
+ TYPELIB_DANGER_RELEASE(pTD);
|
|
+ }
|
|
+ } // else perform queryInterface()
|
|
+ default:
|
|
+ // dependent dispatch
|
|
+ cpp_call(
|
|
+ pThis, aVtableSlot,
|
|
+ ((typelib_InterfaceMethodTypeDescription*)pMemberDescr)->pReturnTypeRef,
|
|
+ ((typelib_InterfaceMethodTypeDescription*)pMemberDescr)->nParams,
|
|
+ ((typelib_InterfaceMethodTypeDescription*)pMemberDescr)->pParams, pReturn,
|
|
+ pArgs, ppException);
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ {
|
|
+ ::com::sun::star::uno::RuntimeException aExc(
|
|
+ "illegal member type description!",
|
|
+ ::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface>());
|
|
+
|
|
+ Type const& rExcType = cppu::UnoType<decltype(aExc)>::get();
|
|
+ // binary identical null reference
|
|
+ ::uno_type_any_construct(*ppException, &aExc, rExcType.getTypeLibType(), 0);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+}
|
|
+
|
|
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
Index: libreoffice-7.4.3.2/configure.ac
|
|
===================================================================
|
|
--- libreoffice-7.4.3.2.orig/configure.ac
|
|
+++ libreoffice-7.4.3.2/configure.ac
|
|
@@ -5216,6 +5216,11 @@ linux-gnu*|linux-musl*)
|
|
RTL_ARCH=PowerPC_64_LE
|
|
PLATFORMID=linux_powerpc64_le
|
|
;;
|
|
+ riscv64)
|
|
+ CPUNAME=RISCV64
|
|
+ RTL_ARCH=RISCV64
|
|
+ PLATFORMID=linux_riscv64
|
|
+ ;;
|
|
sparc)
|
|
CPUNAME=SPARC
|
|
RTL_ARCH=SPARC
|
|
@@ -8579,7 +8584,7 @@ if test "$ENABLE_JAVA" != ""; then
|
|
JAVAINTERPRETER=`win_short_path_for_make "$JAVAINTERPRETER"`
|
|
elif test "$cross_compiling" != "yes"; then
|
|
case $CPUNAME in
|
|
- AARCH64|AXP|X86_64|HPPA|IA64|POWERPC64|S390X|SPARC64|GODSON64)
|
|
+ AARCH64|AXP|X86_64|HPPA|IA64|POWERPC64|S390X|SPARC64|GODSON64|RISCV64)
|
|
if test -f "$JAVAINTERPRETER" -a "`$JAVAINTERPRETER -version 2>&1 | $GREP -i 64-bit`" = "" >/dev/null; then
|
|
AC_MSG_WARN([You are building 64-bit binaries but the JDK $JAVAINTERPRETER is 32-bit])
|
|
AC_MSG_ERROR([You should pass the --with-jdk-home option pointing to a 64-bit JDK])
|
|
@@ -12876,7 +12881,7 @@ AC_SUBST(RHINO_JAR)
|
|
# platforms there.
|
|
supports_multilib=
|
|
case "$host_cpu" in
|
|
-x86_64 | powerpc64 | powerpc64le | s390x | aarch64 | mips64 | mips64el)
|
|
+x86_64 | powerpc64 | powerpc64le | s390x | aarch64 | mips64 | mips64el | riscv64)
|
|
if test "$SAL_TYPES_SIZEOFLONG" = "8"; then
|
|
supports_multilib="yes"
|
|
fi
|
|
Index: libreoffice-7.4.3.2/jvmfwk/inc/vendorbase.hxx
|
|
===================================================================
|
|
--- libreoffice-7.4.3.2.orig/jvmfwk/inc/vendorbase.hxx
|
|
+++ libreoffice-7.4.3.2/jvmfwk/inc/vendorbase.hxx
|
|
@@ -59,6 +59,8 @@ OpenJDK at least, but probably not true
|
|
#else
|
|
#define JFW_PLUGIN_ARCH "mips64el"
|
|
#endif
|
|
+#elif defined RISCV64
|
|
+#define JFW_PLUGIN_ARCH "riscv64"
|
|
#elif defined S390X
|
|
#define JFW_PLUGIN_ARCH "s390x"
|
|
#elif defined S390
|
|
Index: libreoffice-7.4.3.2/m4/ax_boost_base.m4
|
|
===================================================================
|
|
--- libreoffice-7.4.3.2.orig/m4/ax_boost_base.m4
|
|
+++ libreoffice-7.4.3.2/m4/ax_boost_base.m4
|
|
@@ -91,7 +91,7 @@ if test "x$want_boost" = "xyes"; then
|
|
dnl are found, e.g. when only header-only libraries are installed!
|
|
libsubdirs="lib"
|
|
ax_arch=`uname -m`
|
|
- if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = ppc64le -o $ax_arch = s390x -o $ax_arch = sparc64 -o $ax_arch = aarch64; then
|
|
+ if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = ppc64le -o $ax_arch = s390x -o $ax_arch = sparc64 -o $ax_arch = aarch64 -o $ax_arch = riscv64; then
|
|
libsubdirs="lib64 lib lib64"
|
|
fi
|
|
|
|
Index: libreoffice-7.4.3.2/solenv/gbuild/platform/LINUX_RISCV64_GCC.mk
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ libreoffice-7.4.3.2/solenv/gbuild/platform/LINUX_RISCV64_GCC.mk
|
|
@@ -0,0 +1,15 @@
|
|
+# -*- 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/.
|
|
+#
|
|
+
|
|
+#please make generic modifications to unxgcc.mk or linux.mk
|
|
+gb_COMPILEROPTFLAGS := -Os
|
|
+
|
|
+include $(GBUILDDIR)/platform/linux.mk
|
|
+
|
|
+# vim: set noet sw=4:
|