1ac60e8b6acb07698eb8765718e8d093b519dc86.patch 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979
  1. From 1ac60e8b6acb07698eb8765718e8d093b519dc86 Mon Sep 17 00:00:00 2001
  2. From: Sakura286 <sakura286@outlook.com>
  3. Date: Tue, 26 Jul 2022 02:18:23 +0000
  4. Subject: [PATCH] Add riscv64 support
  5. 1. Configure gbuild to compile on riscv64
  6. 2. Add UNO Bridge for riscv64
  7. Now the welcome page could be established and files could be saved
  8. with Writer on riscv64. Test on Debian sid.
  9. Credits:
  10. - Heiher <r@hev.cc> and Stephan Bergmann <sbergman@redhat.com>
  11. contributes the code of UNO bridge for MIPS64 and AArch64,
  12. which I refer to.
  13. - Bo Yu <tsu.yubo@gmail.com> configures gbuild for riscv64.
  14. - WANG Xuerui <xen0n@gentoo.org> gives lots of guiding tips.
  15. - wjh-la <wujiahuan@loongson.cn> contributes the code of UNO-
  16. bridge for Loongarch64, which inspired me.
  17. Change-Id: Ifad3b0de8b2c9e7328627ed03396bbd45a9c71e4
  18. ---
  19. bridges/Library_cpp_uno.mk | 9 +
  20. .../cpp_uno/gcc3_linux_riscv64/call.hxx | 35 +
  21. .../source/cpp_uno/gcc3_linux_riscv64/call.s | 72 ++
  22. .../cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx | 723 ++++++++++++++++++
  23. .../cpp_uno/gcc3_linux_riscv64/except.cxx | 297 +++++++
  24. .../cpp_uno/gcc3_linux_riscv64/share.hxx | 89 +++
  25. .../cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx | 595 ++++++++++++++
  26. configure.ac | 10 +-
  27. jvmfwk/inc/vendorbase.hxx | 2 +
  28. solenv/gbuild/platform/LINUX_RISCV64_GCC.mk | 15 +
  29. 10 files changed, 1845 insertions(+), 2 deletions(-)
  30. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx
  31. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/call.s
  32. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
  33. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx
  34. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx
  35. create mode 100644 bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx
  36. create mode 100644 solenv/gbuild/platform/LINUX_RISCV64_GCC.mk
  37. diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
  38. index e2de3c1678b45..27e1249f31a35 100644
  39. --- a/bridges/Library_cpp_uno.mk
  40. +++ b/bridges/Library_cpp_uno.mk
  41. @@ -114,6 +114,15 @@ bridge_noopt_objects := cpp2uno uno2cpp
  42. bridge_exception_objects := except
  43. endif
  44. +else ifeq ($(CPUNAME),RISCV64)
  45. +
  46. +ifneq ($(filter LINUX,$(OS)),)
  47. +bridges_SELECTED_BRIDGE := gcc3_linux_riscv64
  48. +bridge_asm_objects := call
  49. +bridge_noopt_objects := cpp2uno uno2cpp
  50. +bridge_exception_objects := except
  51. +endif
  52. +
  53. else ifeq ($(CPUNAME),POWERPC)
  54. ifneq ($(filter DRAGONFLY FREEBSD LINUX NETBSD OPENBSD,$(OS)),)
  55. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx
  56. new file mode 100644
  57. index 0000000000000..dc84d56b88aec
  58. --- /dev/null
  59. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/call.hxx
  60. @@ -0,0 +1,35 @@
  61. +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  62. +/*
  63. + * This file is part of the LibreOffice project.
  64. + *
  65. + * This Source Code Form is subject to the terms of the Mozilla Public
  66. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  67. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  68. + *
  69. + * This file incorporates work covered by the following license notice:
  70. + *
  71. + * Licensed to the Apache Software Foundation (ASF) under one or more
  72. + * contributor license agreements. See the NOTICE file distributed
  73. + * with this work for additional information regarding copyright
  74. + * ownership. The ASF licenses this file to you under the Apache
  75. + * License, Version 2.0 (the "License"); you may not use this file
  76. + * except in compliance with the License. You may obtain a copy of
  77. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  78. + */
  79. +
  80. +#pragma once
  81. +
  82. +#include <sal/config.h>
  83. +
  84. +#include <sal/types.h>
  85. +
  86. +namespace {
  87. +
  88. + extern "C" typelib_TypeClass cpp_vtable_call(
  89. + sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
  90. + void ** gpreg, void ** fpreg, void ** ovrflw,
  91. + sal_uInt64 * pRegisterReturn /* space for register return */ );
  92. +
  93. +}
  94. +
  95. +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
  96. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/call.s b/bridges/source/cpp_uno/gcc3_linux_riscv64/call.s
  97. new file mode 100644
  98. index 0000000000000..2bddfc1dcbf4a
  99. --- /dev/null
  100. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/call.s
  101. @@ -0,0 +1,72 @@
  102. +/*
  103. + * This file is part of the LibreOffice project.
  104. + *
  105. + * This Source Code Form is subject to the terms of the Mozilla Public
  106. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  107. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  108. + *
  109. + * This file incorporates work covered by the following license notice:
  110. + *
  111. + * Licensed to the Apache Software Foundation (ASF) under one or more
  112. + * contributor license agreements. See the NOTICE file distributed
  113. + * with this work for additional information regarding copyright
  114. + * ownership. The ASF licenses this file to you under the Apache
  115. + * License, Version 2.0 (the "License"); you may not use this file
  116. + * except in compliance with the License. You may obtain a copy of
  117. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  118. + */
  119. +// https://cgit.freedesktop.org/libreoffice/core/tree/bridges/source/cpp_uno/gcc3_linux_mips64/call.s
  120. +
  121. + .text
  122. + .align 2
  123. + .global privateSnippetExecutor
  124. + .hidden privateSnippetExecutor
  125. + .type privateSnippetExecutor, %function
  126. +privateSnippetExecutor:
  127. + .cfi_startproc
  128. + addi sp,sp,-160
  129. + .cfi_def_cfa_offset 160
  130. + sd ra,152(sp)
  131. + .cfi_offset 1, -8
  132. + fsd fa0,80(sp)
  133. + fsd fa1,88(sp)
  134. + fsd fa2,96(sp)
  135. + fsd fa3,104(sp)
  136. + fsd fa4,112(sp)
  137. + fsd fa5,120(sp)
  138. + fsd fa6,128(sp)
  139. + fsd fa7,136(sp)
  140. + sd a0,16(sp)
  141. + sd a1,24(sp)
  142. + sd a2,32(sp)
  143. + sd a3,40(sp)
  144. + sd a4,48(sp)
  145. + sd a5,56(sp)
  146. + sd a6,64(sp)
  147. + sd a7,72(sp)
  148. + // a0 = functionIndex
  149. + // a1 = vtableOffset
  150. + // a2 = gpreg
  151. + // a3 = fpreg
  152. + // a4 = overflw
  153. + // a5 = pRegisterReturn
  154. + add a0,t4,zero
  155. + add a1,t5,zero
  156. + addi a2,sp,16
  157. + addi a3,sp,80
  158. + addi a4,sp,160
  159. + add a5,sp,zero
  160. + // jump to cpp_vtable_call
  161. + jalr ra,t6,0
  162. + ld a0,0(sp)
  163. + ld a1,8(sp)
  164. + fld fa0,0(sp)
  165. + fld fa1,8(sp)
  166. + ld ra,152(sp)
  167. + .cfi_restore 1
  168. + addi sp,sp,160
  169. + .cfi_def_cfa_offset 0
  170. + jalr zero,ra,0
  171. + .cfi_endproc
  172. + .size privateSnippetExecutor, .-privateSnippetExecutor
  173. + .section .note.GNU-stack, "", @progbits
  174. \ No newline at end of file
  175. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
  176. new file mode 100644
  177. index 0000000000000..4ee41ab486a80
  178. --- /dev/null
  179. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
  180. @@ -0,0 +1,723 @@
  181. +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  182. +/*
  183. + * This file is part of the LibreOffice project.
  184. + *
  185. + * This Source Code Form is subject to the terms of the Mozilla Public
  186. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  187. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  188. + *
  189. + * This file incorporates work covered by the following license notice:
  190. + *
  191. + * Licensed to the Apache Software Foundation (ASF) under one or more
  192. + * contributor license agreements. See the NOTICE file distributed
  193. + * with this work for additional information regarding copyright
  194. + * ownership. The ASF licenses this file to you under the Apache
  195. + * License, Version 2.0 (the "License"); you may not use this file
  196. + * except in compliance with the License. You may obtain a copy of
  197. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  198. + */
  199. +#include <com/sun/star/uno/genfunc.hxx>
  200. +#include <sal/log.hxx>
  201. +#include <typelib/typedescription.hxx>
  202. +#include <uno/data.h>
  203. +#include <osl/endian.h>
  204. +#include "bridge.hxx"
  205. +#include "cppinterfaceproxy.hxx"
  206. +#include "types.hxx"
  207. +#include "vtablefactory.hxx"
  208. +#include "call.hxx"
  209. +#include "share.hxx"
  210. +
  211. +#include <stdio.h>
  212. +#include <string.h>
  213. +
  214. +using namespace com::sun::star::uno;
  215. +
  216. +//#define BRDEBUG
  217. +
  218. +#ifdef BRDEBUG
  219. +#include <rtl/strbuf.hxx>
  220. +#include <rtl/ustrbuf.hxx>
  221. +using namespace ::std;
  222. +using namespace ::osl;
  223. +using namespace ::rtl;
  224. +#endif
  225. +
  226. +namespace CPPU_CURRENT_NAMESPACE
  227. +{
  228. + bool is_complex_struct(const typelib_TypeDescription * type)
  229. + {
  230. + const typelib_CompoundTypeDescription * p
  231. + = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
  232. + for (sal_Int32 i = 0; i < p->nMembers; ++i)
  233. + {
  234. + if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
  235. + p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
  236. + {
  237. + typelib_TypeDescription * t = 0;
  238. + TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
  239. + bool b = is_complex_struct(t);
  240. + TYPELIB_DANGER_RELEASE(t);
  241. + if (b) {
  242. + return true;
  243. + }
  244. + }
  245. + else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
  246. + return true;
  247. + }
  248. + if (p->pBaseTypeDescription != 0)
  249. + return is_complex_struct(&p->pBaseTypeDescription->aBase);
  250. + return false;
  251. + }
  252. +
  253. + bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
  254. + {
  255. + if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
  256. + return false;
  257. + else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
  258. + pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
  259. + {
  260. + typelib_TypeDescription * pTypeDescr = 0;
  261. + TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
  262. +
  263. + //A Composite Type not larger than 16 bytes is returned in up to two GPRs
  264. + bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
  265. +
  266. + TYPELIB_DANGER_RELEASE( pTypeDescr );
  267. + return bRet;
  268. + }
  269. + return true;
  270. + }
  271. +}
  272. +
  273. +namespace
  274. +{
  275. +
  276. + static typelib_TypeClass cpp2uno_call(
  277. + bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
  278. + const typelib_TypeDescription * pMemberTypeDescr,
  279. + typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
  280. + sal_Int32 nParams, typelib_MethodParameter * pParams,
  281. + void ** gpreg, void ** fpreg, void ** ovrflw,
  282. + sal_uInt64 * pRegisterReturn /* space for register return */ )
  283. + {
  284. + /* Most MIPS ABIs view the arguments as a struct, of which the
  285. + first N words go in registers and the rest go on the stack. If I < N, the
  286. + With word might go in With integer argument register or the With
  287. + floating-point one. For these ABIs, we only need to remember the number
  288. + of words passed so far. We are interested only in n64 ABI,so it is the
  289. + case.
  290. + */
  291. + unsigned int nREG = 0;
  292. +
  293. +#ifdef BRDEBUG
  294. + fprintf(stdout, "cpp2uno_call:begin\n");
  295. +#endif
  296. + // return
  297. + typelib_TypeDescription * pReturnTypeDescr = 0;
  298. + if (pReturnTypeRef)
  299. + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
  300. +
  301. + void * pUnoReturn = 0;
  302. + void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
  303. +
  304. + if (pReturnTypeDescr)
  305. + {
  306. + if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
  307. + {
  308. + pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
  309. + nREG++;
  310. +
  311. + pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
  312. + ? alloca( pReturnTypeDescr->nSize )
  313. + : pCppReturn); // direct way
  314. +#ifdef BRDEBUG
  315. + fprintf(stdout, "cpp2uno_call:complexreturn\n");
  316. +#endif
  317. + }
  318. + else
  319. + {
  320. + pUnoReturn = pRegisterReturn; // direct way for simple types
  321. +#ifdef BRDEBUG
  322. + fprintf(stdout, "cpp2uno_call:simplereturn\n");
  323. +#endif
  324. + }
  325. + }
  326. +
  327. + // pop this
  328. + nREG++;
  329. +
  330. + // stack space
  331. + static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
  332. + // parameters
  333. + void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
  334. + void ** pCppArgs = pUnoArgs + nParams;
  335. + // indices of values this have to be converted (interface conversion cpp<=>uno)
  336. + sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
  337. + // type descriptions for reconversions
  338. + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
  339. +
  340. + sal_Int32 nTempIndices = 0;
  341. +
  342. +#ifdef BRDEBUG
  343. + fprintf(stdout, "cpp2uno_call:nParams=%d\n", nParams);
  344. +#endif
  345. + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
  346. + {
  347. + const typelib_MethodParameter & rParam = pParams[nPos];
  348. +
  349. + typelib_TypeDescription * pParamTypeDescr = 0;
  350. + TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
  351. +
  352. + if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
  353. + {
  354. +#ifdef BRDEBUG
  355. + fprintf(stdout, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
  356. +#endif
  357. + switch (pParamTypeDescr->eTypeClass)
  358. + {
  359. + case typelib_TypeClass_FLOAT:
  360. + case typelib_TypeClass_DOUBLE:
  361. + if (nREG < MAX_FP_REGS) {
  362. +#ifdef BRDEBUG
  363. + fprintf(stdout, "cpp2uno_call:fpr=%p\n", fpreg[nREG]);
  364. +#endif
  365. + pCppArgs[nPos] = &(fpreg[nREG]);
  366. + pUnoArgs[nPos] = &(fpreg[nREG]);
  367. + } else {
  368. +#ifdef BRDEBUG
  369. + fprintf(stdout, "cpp2uno_call:fpr=%p\n", ovrflw[nREG - MAX_FP_REGS]);
  370. +#endif
  371. + pCppArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
  372. + pUnoArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
  373. + }
  374. + nREG++;
  375. + break;
  376. +
  377. +
  378. + default:
  379. + if (nREG < MAX_GP_REGS) {
  380. +#ifdef BRDEBUG
  381. + fprintf(stdout, "cpp2uno_call:gpr=%p\n", gpreg[nREG]);
  382. +#endif
  383. + pCppArgs[nPos] = &(gpreg[nREG]);
  384. + pUnoArgs[nPos] = &(gpreg[nREG]);
  385. + } else {
  386. +#ifdef BRDEBUG
  387. + fprintf(stdout, "cpp2uno_call:gpr=%p\n", ovrflw[nREG - MAX_GP_REGS]);
  388. +#endif
  389. + pCppArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
  390. + pUnoArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
  391. + }
  392. + nREG++;
  393. + break;
  394. +
  395. + }
  396. + // no longer needed
  397. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  398. + }
  399. + else // ptr to complex value | ref
  400. + {
  401. +#ifdef BRDEBUG
  402. + fprintf(stdout,"cpp2uno_call:ptr|ref\n");
  403. +#endif
  404. + void *pCppStack;
  405. + if (nREG < MAX_GP_REGS) {
  406. + pCppArgs[nPos] = pCppStack = gpreg[nREG];
  407. + } else {
  408. + pCppArgs[nPos] = pCppStack = ovrflw[nREG - MAX_GP_REGS];
  409. + }
  410. + nREG++;
  411. +#ifdef BRDEBUG
  412. + fprintf(stdout, "cpp2uno_call:pCppStack=%p\n", pCppStack);
  413. +#endif
  414. +
  415. + if (! rParam.bIn) // is pure out
  416. + {
  417. + // uno out is unconstructed mem!
  418. + pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
  419. + pTempIndices[nTempIndices] = nPos;
  420. + // will be released at reconversion
  421. + ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
  422. + }
  423. + // is in/inout
  424. + else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
  425. + {
  426. + uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
  427. + pCppStack, pParamTypeDescr,
  428. + pThis->getBridge()->getCpp2Uno() );
  429. + pTempIndices[nTempIndices] = nPos; // has to be reconverted
  430. + // will be released at reconversion
  431. + ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
  432. +#ifdef BRDEBUG
  433. + fprintf(stdout, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
  434. + pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
  435. +#endif
  436. + }
  437. + else // direct way
  438. + {
  439. + pUnoArgs[nPos] = pCppStack;
  440. +#ifdef BRDEBUG
  441. + fprintf(stdout, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
  442. +#endif
  443. + // no longer needed
  444. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  445. + }
  446. + }
  447. + }
  448. +#ifdef BRDEBUG
  449. + fprintf(stdout, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
  450. +#endif
  451. +
  452. + // ExceptionHolder
  453. + uno_Any aUnoExc; // Any will be constructed by callee
  454. + uno_Any * pUnoExc = &aUnoExc;
  455. +
  456. + // invoke uno dispatch call
  457. + (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
  458. +#ifdef BRDEBUG
  459. + fprintf(stdout, "cpp2uno_call2,after dispatch\n");
  460. +#endif
  461. +
  462. + // in case an exception occurred...
  463. + if (pUnoExc)
  464. + {
  465. + fflush(stdout);
  466. + // destruct temporary in/inout params
  467. + for ( ; nTempIndices--; )
  468. + {
  469. + sal_Int32 nIndex = pTempIndices[nTempIndices];
  470. +
  471. + if (pParams[nIndex].bIn) // is in/inout => was constructed
  472. + uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
  473. + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
  474. + }
  475. + if (pReturnTypeDescr)
  476. + TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
  477. +
  478. + CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
  479. + // has to destruct the any
  480. + // is here for dummy
  481. + return typelib_TypeClass_VOID;
  482. + }
  483. + else // else no exception occurred...
  484. + {
  485. + // temporary params
  486. + for ( ; nTempIndices--; )
  487. + {
  488. + sal_Int32 nIndex = pTempIndices[nTempIndices];
  489. + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
  490. +
  491. + if (pParams[nIndex].bOut) // inout/out
  492. + {
  493. + // convert and assign
  494. + uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
  495. + uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
  496. + pThis->getBridge()->getUno2Cpp() );
  497. + }
  498. + // destroy temp uno param
  499. + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
  500. +
  501. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  502. + }
  503. + // return
  504. + if (pCppReturn) // has complex return
  505. + {
  506. + if (pUnoReturn != pCppReturn) // needs reconversion
  507. + {
  508. + uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
  509. + pThis->getBridge()->getUno2Cpp() );
  510. + // destroy temp uno return
  511. + uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
  512. + }
  513. + // complex return ptr is set to return reg
  514. + *(void **)pRegisterReturn = pCppReturn;
  515. + }
  516. + if (pReturnTypeDescr)
  517. + {
  518. + typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
  519. + TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
  520. + return eRet;
  521. + }
  522. + else
  523. + return typelib_TypeClass_VOID;
  524. + }
  525. + }
  526. +
  527. +
  528. + /**
  529. + * is called on incoming vtable calls
  530. + * (called by asm snippets)
  531. + */
  532. + typelib_TypeClass cpp_vtable_call(
  533. + sal_Int32 nFunctionIndex,
  534. + sal_Int32 nVtableOffset,
  535. + void ** gpreg, void ** fpreg, void ** ovrflw,
  536. + sal_uInt64 * pRegisterReturn /* space for register return */ )
  537. + {
  538. + static_assert( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
  539. +
  540. +#ifdef BRDEBUG
  541. + fprintf(stdout, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
  542. + fprintf(stdout, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
  543. + fprintf(stdout, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
  544. +#endif
  545. +
  546. + // gpreg: [ret *], this, [other gpr params]
  547. + // fpreg: [fpr params]
  548. + // ovrflw: [gpr or fpr params (properly aligned)]
  549. + void * pThis;
  550. + if (nFunctionIndex & 0x80000000 )
  551. + {
  552. + nFunctionIndex &= 0x7fffffff;
  553. + pThis = gpreg[1];
  554. + }
  555. + else
  556. + {
  557. + pThis = gpreg[0];
  558. + }
  559. +#ifdef BRDEBUG
  560. + fprintf(stdout, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
  561. + pThis, nFunctionIndex, nVtableOffset);
  562. +#endif
  563. +
  564. + pThis = static_cast< char * >(pThis) - nVtableOffset;
  565. + bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
  566. + bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
  567. +#ifdef BRDEBUG
  568. + fprintf(stdout, "cpp_vtable_call, pCppI=%p\n", pCppI);
  569. +#endif
  570. +
  571. + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
  572. +
  573. + if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
  574. + {
  575. + SAL_WARN(
  576. + "bridges",
  577. + "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
  578. + << " vtable index " << nFunctionIndex << "/"
  579. + << pTypeDescr->nMapFunctionIndexToMemberIndex);
  580. + throw RuntimeException(
  581. + ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
  582. + + " vtable index " + OUString::number(nFunctionIndex) + "/"
  583. + + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
  584. + (XInterface *)pThis);
  585. + }
  586. +
  587. + // determine called method
  588. + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
  589. + assert(nMemberPos < pTypeDescr->nAllMembers);
  590. +
  591. + TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
  592. +
  593. +#ifdef BRDEBUG
  594. + //OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
  595. + //fprintf(stdout, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
  596. +#endif
  597. + typelib_TypeClass eRet;
  598. + switch (aMemberDescr.get()->eTypeClass)
  599. + {
  600. + case typelib_TypeClass_INTERFACE_ATTRIBUTE:
  601. + {
  602. +#ifdef BRDEBUG
  603. + fprintf(stdout, "cpp_vtable_call interface attribute\n");
  604. +#endif
  605. + typelib_TypeDescriptionReference *pAttrTypeRef =
  606. + reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
  607. +
  608. + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
  609. + {
  610. + // is GET method
  611. + eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
  612. + 0, 0, // no params
  613. + gpreg, fpreg, ovrflw, pRegisterReturn );
  614. + }
  615. + else
  616. + {
  617. + // is SET method
  618. + typelib_MethodParameter aParam;
  619. + aParam.pTypeRef = pAttrTypeRef;
  620. + aParam.bIn = sal_True;
  621. + aParam.bOut = sal_False;
  622. +
  623. + eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
  624. + 0, // indicates void return
  625. + 1, &aParam,
  626. + gpreg, fpreg, ovrflw, pRegisterReturn );
  627. + }
  628. + break;
  629. + }
  630. + case typelib_TypeClass_INTERFACE_METHOD:
  631. + {
  632. +#ifdef BRDEBUG
  633. + fprintf(stdout, "cpp_vtable_call interface method\n");
  634. +#endif
  635. + // is METHOD
  636. + switch (nFunctionIndex)
  637. + {
  638. + case 1: // acquire()
  639. +#ifdef BRDEBUG
  640. + fprintf(stdout, "cpp_vtable_call method acquire\n");
  641. +#endif
  642. + pCppI->acquireProxy(); // non virtual call!
  643. + eRet = typelib_TypeClass_VOID;
  644. + break;
  645. + case 2: // release()
  646. +#ifdef BRDEBUG
  647. + fprintf(stdout, "cpp_vtable_call method release\n");
  648. +#endif
  649. + pCppI->releaseProxy(); // non virtual call!
  650. + eRet = typelib_TypeClass_VOID;
  651. + break;
  652. + case 0: // queryInterface() opt
  653. + {
  654. +#ifdef BRDEBUG
  655. + fprintf(stdout, "cpp_vtable_call method query interface opt\n");
  656. +#endif
  657. + typelib_TypeDescription * pTD = 0;
  658. + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
  659. + if (pTD)
  660. + {
  661. + XInterface * pInterface = 0;
  662. + (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
  663. + ( pCppI->getBridge()->getCppEnv(),
  664. + (void **)&pInterface,
  665. + pCppI->getOid().pData,
  666. + reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
  667. +
  668. + if (pInterface)
  669. + {
  670. + ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
  671. + &pInterface, pTD, cpp_acquire );
  672. +
  673. + pInterface->release();
  674. + TYPELIB_DANGER_RELEASE( pTD );
  675. +
  676. + reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
  677. + eRet = typelib_TypeClass_ANY;
  678. + break;
  679. + }
  680. + TYPELIB_DANGER_RELEASE( pTD );
  681. + }
  682. + } // else perform queryInterface()
  683. + default:
  684. +#ifdef BRDEBUG
  685. + fprintf(stdout, "cpp_vtable_call method query interface\n");
  686. +#endif
  687. + typelib_InterfaceMethodTypeDescription *pMethodTD =
  688. + reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
  689. +
  690. + eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
  691. + pMethodTD->pReturnTypeRef,
  692. + pMethodTD->nParams,
  693. + pMethodTD->pParams,
  694. + gpreg, fpreg, ovrflw, pRegisterReturn );
  695. + }
  696. + break;
  697. + }
  698. + default:
  699. + {
  700. +#ifdef BRDEBUG
  701. + fprintf(stdout, "cpp_vtable_call no member\n");
  702. +#endif
  703. + throw RuntimeException( "no member description found!", (XInterface *)pThis );
  704. + }
  705. + }
  706. +
  707. + return eRet;
  708. + }
  709. +
  710. + extern "C" void privateSnippetExecutor( ... );
  711. +
  712. + int const codeSnippetSize = 0x6c;
  713. +
  714. + unsigned char * codeSnippet( unsigned char * code,
  715. + sal_Int32 functionIndex, sal_Int32 vtableOffset,
  716. + bool bHasHiddenParam )
  717. + {
  718. +#ifdef BRDEBUG
  719. + fprintf(stdout,"in codeSnippet functionIndex is %d\n", functionIndex);
  720. + fprintf(stdout,"in codeSnippet vtableOffset is %d\n", vtableOffset);
  721. + fprintf(stdout,"in codeSnippet privateSnippetExecutor is %lx\n", (unsigned long)privateSnippetExecutor);
  722. + fprintf(stdout,"in codeSnippet cpp_vtable_call is %lx\n", (unsigned long)cpp_vtable_call);
  723. +
  724. + fflush(stdout);
  725. +#endif
  726. +
  727. + if ( bHasHiddenParam )
  728. + functionIndex |= 0x80000000;
  729. +
  730. + unsigned int * p = (unsigned int *) code;
  731. +
  732. + assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
  733. +
  734. + /* generate this code */
  735. + /*
  736. + # load functionIndex to t4
  737. + 00000eb7 lui t4,0x0
  738. + 000eee93 ori t4,t4,0x0
  739. + # load privateSnippetExecutor to t0
  740. + 000002b7 lui t0,0x0
  741. + 02429293 slli t0,t0,36
  742. + 00000337 lui t1,0x0
  743. + 01431313 slli t1,t1,20
  744. + 0062e2b3 or t0,t0,t1
  745. + 00000337 lui t1,0x0
  746. + 00431313 slli t1,t1,4
  747. + 0062e2b3 or t0,t0,t1
  748. + 00000337 lui t1,0x0
  749. + 00c35313 srli t1,t1,12
  750. + 0062e2b3 or t0,t0,t1
  751. + # load cpp_vtable_call to t6
  752. + 00000fb7 lui t6,0x0
  753. + 024f9f93 slli t6,t6,36
  754. + 00000337 lui t1,0x0
  755. + 01431313 slli t1,t1,20
  756. + 006fefb3 or t6,t6,t1
  757. + 00000337 lui t1,0x0
  758. + 00431313 slli t1,t1,4
  759. + 006fefb3 or t6,t6,t1
  760. + 00000337 lui t1,0x0
  761. + 00c35313 srli t1,t1,12
  762. + 006fefb3 or t6,t6,t1
  763. + # load vtableOffset to t5
  764. + 00000f37 lui t5,0x0
  765. + 000f6f13 ori t5,t5,0x0
  766. + # jump to privateSnippetExecutor
  767. + 00028067 jalr zero,t0,0x0
  768. + */
  769. +
  770. + * p++ = 0x00000eb7 | ((functionIndex) & 0xfffff000);
  771. + * p++ = 0x000eee93 | ((functionIndex << 20 ) & 0xfff00000);
  772. +
  773. + // load privateSnippetExecutor to t0
  774. + unsigned long functionEntry = ((unsigned long)privateSnippetExecutor);
  775. + * p++ = 0x000002b7 | ((functionEntry >> 36) & 0x000000000ffff000);
  776. + * p++ = 0x02429293;
  777. + * p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
  778. + * p++ = 0x01431313;
  779. + * p++ = 0x0062e2b3;
  780. + * p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
  781. + * p++ = 0x00431313;
  782. + * p++ = 0x0062e2b3;
  783. + * p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
  784. + * p++ = 0x00c35313;
  785. + * p++ = 0x0062e2b3;
  786. + // load cpp_vtable_call to t6
  787. + functionEntry = (unsigned long) cpp_vtable_call;
  788. + * p++ = 0x00000fb7 | ((functionEntry >> 36) & 0x000000000ffff000);
  789. + * p++ = 0x024f9f93;
  790. + * p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
  791. + * p++ = 0x01431313;
  792. + * p++ = 0x006fefb3;
  793. + * p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
  794. + * p++ = 0x00431313;
  795. + * p++ = 0x006fefb3;
  796. + * p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
  797. + * p++ = 0x00c35313;
  798. + * p++ = 0x006fefb3;
  799. + // load vtableOffset to t5
  800. + * p++ = 0x00000f37 | ((vtableOffset) & 0xfffff000);
  801. + * p++ = 0x000f6f13 | ((vtableOffset << 20 ) & 0xfff00000);
  802. + // jump to privateSnippetExecutor
  803. + * p++ = 0x00028067;
  804. + return (code + codeSnippetSize);
  805. +
  806. + }
  807. +
  808. +}
  809. +
  810. +
  811. +void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr, unsigned char const *eptr)
  812. +{
  813. + asm volatile(
  814. + "fence":::
  815. + );
  816. +}
  817. +
  818. +struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
  819. +
  820. +bridges::cpp_uno::shared::VtableFactory::Slot *
  821. +bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
  822. +{
  823. + return static_cast< Slot * >(block) + 2;
  824. +}
  825. +
  826. +
  827. +std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
  828. + sal_Int32 slotCount)
  829. +{
  830. + return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
  831. +}
  832. +
  833. +bridges::cpp_uno::shared::VtableFactory::Slot *
  834. +bridges::cpp_uno::shared::VtableFactory::initializeBlock(
  835. + void * block, sal_Int32 slotCount, sal_Int32,
  836. + typelib_InterfaceTypeDescription *)
  837. +{
  838. + Slot * slots = mapBlockToVtable(block);
  839. + slots[-2].fn = 0; //null
  840. + slots[-1].fn = 0; //destructor
  841. + return slots + slotCount;
  842. +}
  843. +
  844. +unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
  845. + Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
  846. + typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
  847. + sal_Int32 functionCount, sal_Int32 vtableOffset)
  848. +{
  849. + (*slots) -= functionCount;
  850. + Slot * s = *slots;
  851. +
  852. +#ifdef BRDEBUG
  853. + fprintf(stdout, "in addLocalFunctions functionOffset is %d\n", functionOffset);
  854. + fprintf(stdout, "in addLocalFunctions vtableOffset is %d\n", vtableOffset);
  855. + fprintf(stdout, "nMembers=%d\n", type->nMembers);
  856. + fflush(stdout);
  857. +#endif
  858. +
  859. + for (sal_Int32 i = 0; i < type->nMembers; ++i) {
  860. + typelib_TypeDescription * member = 0;
  861. + TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
  862. + assert(member != 0);
  863. + switch (member->eTypeClass) {
  864. + case typelib_TypeClass_INTERFACE_ATTRIBUTE:
  865. + // Getter:
  866. + (s++)->fn = code + writetoexecdiff;
  867. + code = codeSnippet(
  868. + code, functionOffset++, vtableOffset,
  869. + CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
  870. + reinterpret_cast<
  871. + typelib_InterfaceAttributeTypeDescription * >(
  872. + member)->pAttributeTypeRef));
  873. +
  874. + // Setter:
  875. + if (!reinterpret_cast<
  876. + typelib_InterfaceAttributeTypeDescription * >(
  877. + member)->bReadOnly)
  878. + {
  879. + (s++)->fn = code + writetoexecdiff;
  880. + code = codeSnippet(code, functionOffset++, vtableOffset, false);
  881. + }
  882. + break;
  883. +
  884. + case typelib_TypeClass_INTERFACE_METHOD:
  885. + (s++)->fn = code + writetoexecdiff;
  886. + code = codeSnippet(
  887. + code, functionOffset++, vtableOffset,
  888. + CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
  889. + reinterpret_cast<
  890. + typelib_InterfaceMethodTypeDescription * >(
  891. + member)->pReturnTypeRef));
  892. + break;
  893. +
  894. + default:
  895. + assert(false);
  896. + break;
  897. + }
  898. + TYPELIB_DANGER_RELEASE(member);
  899. + }
  900. + return code;
  901. +}
  902. +
  903. +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
  904. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx
  905. new file mode 100644
  906. index 0000000000000..e37e5d8e3a85f
  907. --- /dev/null
  908. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/except.cxx
  909. @@ -0,0 +1,297 @@
  910. +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  911. +/*
  912. + * This file is part of the LibreOffice project.
  913. + *
  914. + * This Source Code Form is subject to the terms of the Mozilla Public
  915. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  916. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  917. + *
  918. + * This file incorporates work covered by the following license notice:
  919. + *
  920. + * Licensed to the Apache Software Foundation (ASF) under one or more
  921. + * contributor license agreements. See the NOTICE file distributed
  922. + * with this work for additional information regarding copyright
  923. + * ownership. The ASF licenses this file to you under the Apache
  924. + * License, Version 2.0 (the "License"); you may not use this file
  925. + * except in compliance with the License. You may obtain a copy of
  926. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  927. + */
  928. +#include <stdio.h>
  929. +#include <string.h>
  930. +#include <dlfcn.h>
  931. +#include <cxxabi.h>
  932. +#include <rtl/strbuf.hxx>
  933. +#include <rtl/ustrbuf.hxx>
  934. +#include <sal/log.hxx>
  935. +#include <osl/mutex.hxx>
  936. +
  937. +#include <com/sun/star/uno/genfunc.hxx>
  938. +#include <typelib/typedescription.hxx>
  939. +#include <uno/any2.h>
  940. +
  941. +#include <unordered_map>
  942. +#include "share.hxx"
  943. +
  944. +using namespace ::std;
  945. +using namespace ::osl;
  946. +using namespace ::com::sun::star::uno;
  947. +using namespace ::__cxxabiv1;
  948. +
  949. +//#define BRIDGES_DEBUG
  950. +
  951. +namespace CPPU_CURRENT_NAMESPACE
  952. +{
  953. +
  954. +void dummy_can_throw_anything( char const * )
  955. +{
  956. +}
  957. +
  958. +static OUString toUNOname( char const * p )
  959. +{
  960. +#if defined BRIDGES_DEBUG
  961. + char const * start = p;
  962. +#endif
  963. +
  964. + // example: N3com3sun4star4lang24IllegalArgumentExceptionE
  965. +
  966. + OUStringBuffer buf( 64 );
  967. + assert( 'N' == *p );
  968. + ++p; // skip N
  969. +
  970. + while ('E' != *p)
  971. + {
  972. + // read chars count
  973. + long n = (*p++ - '0');
  974. + while ('0' <= *p && '9' >= *p)
  975. + {
  976. + n *= 10;
  977. + n += (*p++ - '0');
  978. + }
  979. + buf.appendAscii( p, n );
  980. + p += n;
  981. + if ('E' != *p)
  982. + buf.append( '.' );
  983. + }
  984. +
  985. +#if defined BRIDGES_DEBUG
  986. + OUString ret( buf.makeStringAndClear() );
  987. + OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
  988. + fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
  989. + return ret;
  990. +#else
  991. + return buf.makeStringAndClear();
  992. +#endif
  993. +}
  994. +
  995. +class RTTI
  996. +{
  997. + typedef std::unordered_map< OUString, type_info * > t_rtti_map;
  998. +
  999. + Mutex m_mutex;
  1000. + t_rtti_map m_rttis;
  1001. + t_rtti_map m_generatedRttis;
  1002. +
  1003. + void * m_hApp;
  1004. +
  1005. +public:
  1006. + RTTI();
  1007. + ~RTTI();
  1008. +
  1009. + type_info * getRTTI( typelib_CompoundTypeDescription * );
  1010. +};
  1011. +
  1012. +RTTI::RTTI()
  1013. + : m_hApp( dlopen( 0, RTLD_LAZY ) )
  1014. +{
  1015. +}
  1016. +
  1017. +RTTI::~RTTI()
  1018. +{
  1019. + dlclose( m_hApp );
  1020. +}
  1021. +
  1022. +
  1023. +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
  1024. +{
  1025. + type_info * rtti;
  1026. +
  1027. + OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
  1028. +
  1029. + MutexGuard guard( m_mutex );
  1030. + t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
  1031. + if (iRttiFind == m_rttis.end())
  1032. + {
  1033. + // RTTI symbol
  1034. + OStringBuffer buf( 64 );
  1035. + buf.append( "_ZTIN" );
  1036. + sal_Int32 index = 0;
  1037. + do
  1038. + {
  1039. + OUString token( unoName.getToken( 0, '.', index ) );
  1040. + buf.append( token.getLength() );
  1041. + OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
  1042. + buf.append( c_token );
  1043. + }
  1044. + while (index >= 0);
  1045. + buf.append( 'E' );
  1046. +
  1047. + OString symName( buf.makeStringAndClear() );
  1048. + rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
  1049. +
  1050. + if (rtti)
  1051. + {
  1052. + pair< t_rtti_map::iterator, bool > insertion(
  1053. + m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
  1054. + assert(insertion.second && "### inserting new rtti failed?!");
  1055. + }
  1056. + else
  1057. + {
  1058. + // try to lookup the symbol in the generated rtti map
  1059. + t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
  1060. + if (iFind == m_generatedRttis.end())
  1061. + {
  1062. + // we must generate it !
  1063. + // symbol and rtti-name is nearly identical,
  1064. + // the symbol is prefixed with _ZTI
  1065. + char const * rttiName = symName.getStr() +4;
  1066. +#if defined BRIDGES_DEBUG
  1067. + fprintf( stderr,"generated rtti for %s\n", rttiName );
  1068. +#endif
  1069. + if (pTypeDescr->pBaseTypeDescription)
  1070. + {
  1071. + // ensure availability of base
  1072. + type_info * base_rtti = getRTTI(
  1073. + (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
  1074. + rtti = new __si_class_type_info(
  1075. + strdup( rttiName ), (__class_type_info *)base_rtti );
  1076. + }
  1077. + else
  1078. + {
  1079. + // this class has no base class
  1080. + rtti = new __class_type_info( strdup( rttiName ) );
  1081. + }
  1082. +
  1083. + pair< t_rtti_map::iterator, bool > insertion(
  1084. + m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
  1085. + assert(insertion.second && "### inserting new generated rtti failed?!");
  1086. + }
  1087. + else // taking already generated rtti
  1088. + {
  1089. + rtti = iFind->second;
  1090. + }
  1091. + }
  1092. + }
  1093. + else
  1094. + {
  1095. + rtti = iRttiFind->second;
  1096. + }
  1097. +
  1098. + return rtti;
  1099. +}
  1100. +
  1101. +
  1102. +static void deleteException( void * pExc )
  1103. +{
  1104. + fprintf( stderr, "in deleteException: pExc = %p\n",pExc );
  1105. + __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
  1106. + typelib_TypeDescription * pTD = 0;
  1107. + OUString unoName( toUNOname( header->exceptionType->name() ) );
  1108. + ::typelib_typedescription_getByName( &pTD, unoName.pData );
  1109. + assert(pTD && "### unknown exception type! leaving out destruction => leaking!!!");
  1110. + if (pTD)
  1111. + {
  1112. + ::uno_destructData( pExc, pTD, cpp_release );
  1113. + ::typelib_typedescription_release( pTD );
  1114. + }
  1115. +}
  1116. +
  1117. +
  1118. +
  1119. +//extern "C" {
  1120. +// void __cxa_throw(void* ex, void* info, void (*dest)(void*)) { ::abort(); }
  1121. +//}
  1122. +
  1123. +
  1124. +void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
  1125. +{
  1126. +#if defined BRIDGES_DEBUG
  1127. + OString cstr(
  1128. + OUStringToOString(
  1129. + OUString::unacquired( &pUnoExc->pType->pTypeName ),
  1130. + RTL_TEXTENCODING_ASCII_US ) );
  1131. + fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
  1132. +#endif
  1133. + void * pCppExc;
  1134. + type_info * rtti;
  1135. +
  1136. + {
  1137. + // construct cpp exception object
  1138. + typelib_TypeDescription * pTypeDescr = 0;
  1139. + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
  1140. + assert(pTypeDescr);
  1141. + if (! pTypeDescr)
  1142. + {
  1143. + throw RuntimeException(
  1144. + OUString("cannot get typedescription for type ") +
  1145. + OUString::unacquired( &pUnoExc->pType->pTypeName ) );
  1146. + }
  1147. +
  1148. + pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
  1149. + ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
  1150. +
  1151. + // destruct uno exception
  1152. + ::uno_any_destruct( pUnoExc, 0 );
  1153. + // avoiding locked counts
  1154. + static RTTI rtti_data;
  1155. + rtti = (type_info*)rtti_data.getRTTI((typelib_CompoundTypeDescription*)pTypeDescr);
  1156. + TYPELIB_DANGER_RELEASE( pTypeDescr );
  1157. + assert(rtti && "### no rtti for throwing exception!");
  1158. + if (! rtti)
  1159. + {
  1160. + throw RuntimeException(
  1161. + OUString("no rtti for type ") +
  1162. + OUString::unacquired( &pUnoExc->pType->pTypeName ) );
  1163. + }
  1164. + }
  1165. + __cxa_throw( pCppExc, rtti, deleteException );
  1166. +}
  1167. +
  1168. +void fillUnoException(uno_Any * pUnoExc, uno_Mapping * pCpp2Uno)
  1169. +{
  1170. + __cxa_exception * header = __cxa_get_globals()->caughtExceptions;
  1171. + if (! header)
  1172. + {
  1173. + RuntimeException aRE( "no exception header!" );
  1174. + Type const & rType = cppu::UnoType<decltype(aRE)>::get();
  1175. + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
  1176. + SAL_WARN("bridges", aRE.Message);
  1177. + return;
  1178. + }
  1179. +
  1180. + std::type_info *exceptionType = __cxa_current_exception_type();
  1181. +
  1182. + typelib_TypeDescription * pExcTypeDescr = 0;
  1183. + OUString unoName( toUNOname( exceptionType->name() ) );
  1184. +#if defined BRIDGES_DEBUG
  1185. + OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
  1186. + fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() );
  1187. +#endif
  1188. + typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
  1189. + if (0 == pExcTypeDescr)
  1190. + {
  1191. + RuntimeException aRE( OUString("exception type not found: ") + unoName );
  1192. + Type const & rType = cppu::UnoType<decltype(aRE)>::get();
  1193. + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
  1194. + SAL_WARN("bridges", aRE.Message);
  1195. + }
  1196. + else
  1197. + {
  1198. + // construct uno exception any
  1199. + uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
  1200. + typelib_typedescription_release( pExcTypeDescr );
  1201. + }
  1202. +}
  1203. +
  1204. +}
  1205. +
  1206. +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
  1207. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx
  1208. new file mode 100644
  1209. index 0000000000000..ee2235e4fc4b6
  1210. --- /dev/null
  1211. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/share.hxx
  1212. @@ -0,0 +1,89 @@
  1213. +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  1214. +/*
  1215. + * This file is part of the LibreOffice project.
  1216. + *
  1217. + * This Source Code Form is subject to the terms of the Mozilla Public
  1218. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  1219. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  1220. + *
  1221. + * This file incorporates work covered by the following license notice:
  1222. + *
  1223. + * Licensed to the Apache Software Foundation (ASF) under one or more
  1224. + * contributor license agreements. See the NOTICE file distributed
  1225. + * with this work for additional information regarding copyright
  1226. + * ownership. The ASF licenses this file to you under the Apache
  1227. + * License, Version 2.0 (the "License"); you may not use this file
  1228. + * except in compliance with the License. You may obtain a copy of
  1229. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  1230. + */
  1231. +#pragma once
  1232. +
  1233. +#include "uno/mapping.h"
  1234. +
  1235. +#include <typeinfo>
  1236. +#include <exception>
  1237. +#include <cstddef>
  1238. +
  1239. +#define MAX_GP_REGS (8)
  1240. +#define MAX_FP_REGS (8)
  1241. +
  1242. +namespace CPPU_CURRENT_NAMESPACE
  1243. +{
  1244. +
  1245. + void dummy_can_throw_anything( char const * );
  1246. +
  1247. +
  1248. +// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
  1249. +
  1250. +struct _Unwind_Exception
  1251. +{
  1252. + unsigned exception_class __attribute__((__mode__(__DI__)));
  1253. + void * exception_cleanup;
  1254. + unsigned private_1 __attribute__((__mode__(__word__)));
  1255. + unsigned private_2 __attribute__((__mode__(__word__)));
  1256. +} __attribute__((__aligned__));
  1257. +
  1258. +struct __cxa_exception
  1259. +{
  1260. + std::type_info *exceptionType;
  1261. + void (*exceptionDestructor)(void *);
  1262. +
  1263. + void (*unexpectedHandler)(); // std::unexpected_handler dropped from C++17
  1264. + std::terminate_handler terminateHandler;
  1265. +
  1266. + __cxa_exception *nextException;
  1267. +
  1268. + int handlerCount;
  1269. +
  1270. + int handlerSwitchValue;
  1271. + const unsigned char *actionRecord;
  1272. + const unsigned char *languageSpecificData;
  1273. + void *catchTemp;
  1274. + void *adjustedPtr;
  1275. +
  1276. + _Unwind_Exception unwindHeader;
  1277. +};
  1278. +
  1279. +extern "C" void *__cxa_allocate_exception(
  1280. + std::size_t thrown_size ) throw();
  1281. +extern "C" void __cxa_throw (
  1282. + void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
  1283. +
  1284. +struct __cxa_eh_globals
  1285. +{
  1286. + __cxa_exception *caughtExceptions;
  1287. + unsigned int uncaughtExceptions;
  1288. +};
  1289. +
  1290. +extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
  1291. +extern "C" std::type_info *__cxa_current_exception_type() throw();
  1292. +
  1293. +void raiseException(
  1294. + uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
  1295. +
  1296. +void fillUnoException(uno_Any *, uno_Mapping * pCpp2Uno);
  1297. +
  1298. +bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
  1299. +}
  1300. +
  1301. +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
  1302. diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx
  1303. new file mode 100644
  1304. index 0000000000000..cae7507669122
  1305. --- /dev/null
  1306. +++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/uno2cpp.cxx
  1307. @@ -0,0 +1,595 @@
  1308. +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  1309. +/*
  1310. + * This file is part of the LibreOffice project.
  1311. + *
  1312. + * This Source Code Form is subject to the terms of the Mozilla Public
  1313. + * License, v. 2.0. If a copy of the MPL was not distributed with this
  1314. + * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  1315. + *
  1316. + * This file incorporates work covered by the following license notice:
  1317. + *
  1318. + * Licensed to the Apache Software Foundation (ASF) under one or more
  1319. + * contributor license agreements. See the NOTICE file distributed
  1320. + * with this work for additional information regarding copyright
  1321. + * ownership. The ASF licenses this file to you under the Apache
  1322. + * License, Version 2.0 (the "License"); you may not use this file
  1323. + * except in compliance with the License. You may obtain a copy of
  1324. + * the License at http://www.apache.org/licenses/LICENSE-2.0 .
  1325. + */
  1326. +
  1327. +#include <sal/config.h>
  1328. +
  1329. +#include <exception>
  1330. +#include <malloc.h>
  1331. +#include <cstring>
  1332. +#include <typeinfo>
  1333. +
  1334. +#include <com/sun/star/uno/Exception.hpp>
  1335. +#include <com/sun/star/uno/RuntimeException.hpp>
  1336. +#include <com/sun/star/uno/genfunc.hxx>
  1337. +#include <o3tl/runtimetooustring.hxx>
  1338. +#include <uno/data.h>
  1339. +
  1340. +#include "bridge.hxx"
  1341. +#include "types.hxx"
  1342. +#include "unointerfaceproxy.hxx"
  1343. +#include "vtables.hxx"
  1344. +
  1345. +#include "share.hxx"
  1346. +
  1347. +//#define BRDEBUG
  1348. +#ifdef BRDEBUG
  1349. +#include <stdio.h>
  1350. +#endif
  1351. +
  1352. +#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
  1353. + if ( nr < MAX_FP_REGS ) \
  1354. + pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
  1355. + else \
  1356. + *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
  1357. +
  1358. +#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
  1359. + if ( nr < MAX_GP_REGS ) \
  1360. + pGPR[nr++] = *reinterpret_cast<sal_Int64 *>( pSV ); \
  1361. + else \
  1362. + *pDS++ = *reinterpret_cast<sal_Int64 *>( pSV );
  1363. +
  1364. +#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
  1365. + if ( nr < MAX_GP_REGS ) \
  1366. + pGPR[nr++] = *reinterpret_cast<sal_Int32 *>( pSV ); \
  1367. + else \
  1368. + *pDS++ = *reinterpret_cast<sal_Int32 *>( pSV );
  1369. +
  1370. +#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
  1371. + if ( nr < MAX_GP_REGS ) \
  1372. + pGPR[nr++] = *reinterpret_cast<sal_Int16 *>( pSV ); \
  1373. + else \
  1374. + *pDS++ = *reinterpret_cast<sal_Int16 *>( pSV );
  1375. +
  1376. +#define INSERT_UINT16( pSV, nr, pGPR, pDS ) \
  1377. + if ( nr < MAX_GP_REGS ) \
  1378. + pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
  1379. + else \
  1380. + *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
  1381. +
  1382. +#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
  1383. + if ( nr < MAX_GP_REGS ) \
  1384. + pGPR[nr++] = *reinterpret_cast<sal_Int8 *>( pSV ); \
  1385. + else \
  1386. + *pDS++ = *reinterpret_cast<sal_Int8 *>( pSV );
  1387. +
  1388. +using namespace ::com::sun::star::uno;
  1389. +
  1390. +namespace
  1391. +{
  1392. +
  1393. + bool isReturnInFPR(const typelib_TypeDescription * pTypeDescr, sal_uInt32 & nSize)
  1394. + {
  1395. + const typelib_CompoundTypeDescription *p =
  1396. + reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
  1397. +
  1398. + for (sal_Int32 i = 0; i < p->nMembers; ++i)
  1399. + {
  1400. + typelib_TypeDescriptionReference *pTypeInStruct = p->ppTypeRefs[ i ];
  1401. +
  1402. + switch (pTypeInStruct->eTypeClass)
  1403. + {
  1404. + case typelib_TypeClass_STRUCT:
  1405. + case typelib_TypeClass_EXCEPTION:
  1406. + {
  1407. + typelib_TypeDescription * t = 0;
  1408. + TYPELIB_DANGER_GET(&t, pTypeInStruct);
  1409. + bool isFPR = isReturnInFPR(t, nSize);
  1410. + TYPELIB_DANGER_RELEASE(t);
  1411. + if (!isFPR)
  1412. + return false;
  1413. + }
  1414. + break;
  1415. + case typelib_TypeClass_FLOAT:
  1416. + case typelib_TypeClass_DOUBLE:
  1417. + if (nSize >= 16)
  1418. + return false;
  1419. + nSize += 8;
  1420. + break;
  1421. + default:
  1422. + return false;
  1423. + }
  1424. + }
  1425. + return true;
  1426. + }
  1427. +
  1428. + void fillReturn(const typelib_TypeDescription * pTypeDescr,
  1429. + sal_Int64 * gret, double * fret, void * pRegisterReturn)
  1430. + {
  1431. + sal_uInt32 nSize = 0;
  1432. + if (isReturnInFPR(pTypeDescr, nSize))
  1433. + {
  1434. + reinterpret_cast<double *>( pRegisterReturn )[0] = fret[0];
  1435. + reinterpret_cast<double *>( pRegisterReturn )[1] = fret[1];
  1436. + }
  1437. + else
  1438. + {
  1439. + reinterpret_cast<sal_Int64 *>( pRegisterReturn )[0] = gret[0];
  1440. + reinterpret_cast<sal_Int64 *>( pRegisterReturn )[1] = gret[1];
  1441. + }
  1442. + }
  1443. +
  1444. + static void callVirtualMethod(
  1445. + void * pAdjustedThisPtr,
  1446. + sal_Int32 nVtableIndex,
  1447. + void * pRegisterReturn,
  1448. + typelib_TypeDescriptionReference * pReturnTypeRef,
  1449. + bool bSimpleReturn,
  1450. + sal_uInt64 *pStack,
  1451. + sal_uInt32 nStack,
  1452. + sal_uInt64 *pGPR,
  1453. + double *pFPR,
  1454. + sal_uInt32 nREG)
  1455. + {
  1456. + // Should not happen, but...
  1457. + static_assert(MAX_GP_REGS == MAX_FP_REGS, "must be the same size");
  1458. + if ( nREG > MAX_GP_REGS )
  1459. + nREG = MAX_GP_REGS;
  1460. +
  1461. + // Get pointer to method
  1462. + sal_uInt64 pMethod = *((sal_uInt64 *)pAdjustedThisPtr);
  1463. + pMethod += 8 * nVtableIndex;
  1464. + void *mfunc = (void *) *((sal_uInt64 *)pMethod);
  1465. +#ifdef BRDEBUG
  1466. + fprintf(stdout, "calling function %p\n", mfunc);
  1467. +#endif
  1468. +
  1469. + // Load parameters to stack, if necessary
  1470. + sal_uInt64* pCallStack = NULL;
  1471. + if ( nStack )
  1472. + {
  1473. + // 16-bytes aligned
  1474. + sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
  1475. + pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes );
  1476. + std::memcpy( pCallStack, pStack, nStackBytes );
  1477. + }
  1478. +
  1479. + sal_Int64 gret[2];
  1480. + double fret[2];
  1481. + asm volatile (
  1482. + //".set push \n\t"
  1483. + //".set riscv64 \n\t"
  1484. + // Fill the general purpose registers
  1485. + "ld a0, 0(%[gpr]) \n\t"
  1486. + "ld a1, 8(%[gpr]) \n\t"
  1487. + "ld a2, 16(%[gpr]) \n\t"
  1488. + "ld a3, 24(%[gpr]) \n\t"
  1489. + "ld a4, 32(%[gpr]) \n\t"
  1490. + "ld a5, 40(%[gpr]) \n\t"
  1491. + "ld a6, 48(%[gpr]) \n\t"
  1492. + "ld a7, 56(%[gpr]) \n\t"
  1493. + // Fill the floating pointer registers
  1494. + "fld fa0, 0(%[fpr]) \n\t"
  1495. + "fld fa1, 8(%[fpr]) \n\t"
  1496. + "fld fa2, 16(%[fpr]) \n\t"
  1497. + "fld fa3, 24(%[fpr]) \n\t"
  1498. + "fld fa4, 32(%[fpr]) \n\t"
  1499. + "fld fa5, 40(%[fpr]) \n\t"
  1500. + "fld fa6, 48(%[fpr]) \n\t"
  1501. + "fld fa7, 56(%[fpr]) \n\t"
  1502. + // Perform the call
  1503. + "jalr ra,%[mfunc],0 \n\t"
  1504. + // Fill the return values
  1505. + "add %[gret1], a0,zero \n\t"
  1506. + "add %[gret2], a1,zero \n\t"
  1507. + "fcvt.d.l ft7,zero \n\t"
  1508. + "fadd.d %[fret1], fa0,ft7 \n\t"
  1509. + "fadd.d %[fret2], fa1,ft7 \n\t"
  1510. + //".set pop \n\t"
  1511. + :[gret1]"=r"(gret[0]), [gret2]"=r"(gret[1]),
  1512. + [fret1]"=f"(fret[0]), [fret2]"=f"(fret[1])
  1513. + :[gpr]"r"(pGPR), [fpr]"r"(pFPR), [mfunc]"r"(mfunc),
  1514. + [stack]"m"(pCallStack) // dummy input to prevent the compiler from optimizing the alloca out
  1515. + :"a0", "a1", "a2", "a3", "a4", "a5", "a6","a7",
  1516. + "ra",
  1517. + "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6","fa7", "memory",
  1518. + "ft7"
  1519. + );
  1520. +
  1521. + switch (pReturnTypeRef->eTypeClass)
  1522. + {
  1523. + case typelib_TypeClass_HYPER:
  1524. + case typelib_TypeClass_UNSIGNED_HYPER:
  1525. + case typelib_TypeClass_LONG:
  1526. + case typelib_TypeClass_UNSIGNED_LONG:
  1527. + case typelib_TypeClass_ENUM:
  1528. + case typelib_TypeClass_CHAR:
  1529. + case typelib_TypeClass_SHORT:
  1530. + case typelib_TypeClass_UNSIGNED_SHORT:
  1531. + case typelib_TypeClass_BOOLEAN:
  1532. + case typelib_TypeClass_BYTE:
  1533. + *reinterpret_cast<sal_Int64 *>( pRegisterReturn ) = gret[0];
  1534. + break;
  1535. + case typelib_TypeClass_FLOAT:
  1536. + case typelib_TypeClass_DOUBLE:
  1537. + *reinterpret_cast<double *>( pRegisterReturn ) = fret[0];
  1538. + break;
  1539. + case typelib_TypeClass_STRUCT:
  1540. + case typelib_TypeClass_EXCEPTION:
  1541. + {
  1542. + sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
  1543. + if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
  1544. + {
  1545. + typelib_TypeDescription * pTypeDescr = 0;
  1546. + TYPELIB_DANGER_GET( &pTypeDescr, pReturnTypeRef );
  1547. + fillReturn(pTypeDescr, gret, fret, pRegisterReturn);
  1548. + TYPELIB_DANGER_RELEASE( pTypeDescr );
  1549. + }
  1550. + break;
  1551. + }
  1552. + default:
  1553. +#ifdef BRDEBUG
  1554. + fprintf(stdout,"unhandled return type %u\n", pReturnTypeRef->eTypeClass);
  1555. +#endif
  1556. + break;
  1557. + }
  1558. + }
  1559. +
  1560. +
  1561. + static void cpp_call(
  1562. + bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
  1563. + bridges::cpp_uno::shared::VtableSlot aVtableSlot,
  1564. + typelib_TypeDescriptionReference * pReturnTypeRef,
  1565. + sal_Int32 nParams, typelib_MethodParameter * pParams,
  1566. + void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
  1567. + {
  1568. + // max space for: [complex ret ptr], values|ptr ...
  1569. + sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( ((nParams+3) * sizeof(sal_Int64)) );
  1570. + sal_uInt64 *pStackStart = pStack;
  1571. +
  1572. + sal_uInt64 pGPR[MAX_GP_REGS];
  1573. + double pFPR[MAX_FP_REGS];
  1574. + sal_uInt32 nREG = 0;
  1575. +
  1576. +#ifdef BRDEBUG
  1577. + fprintf(stdout, "in cpp_call\n");
  1578. +#endif
  1579. +
  1580. + // return
  1581. + typelib_TypeDescription * pReturnTypeDescr = 0;
  1582. + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
  1583. + assert(pReturnTypeDescr);
  1584. +
  1585. + void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
  1586. +
  1587. + bool bSimpleReturn = true;
  1588. + if (pReturnTypeDescr)
  1589. + {
  1590. + if ( CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
  1591. + {
  1592. + bSimpleReturn = false;
  1593. + // complex return via ptr
  1594. + pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
  1595. + __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
  1596. + INSERT_INT64( &pCppReturn, nREG, pGPR, pStack );
  1597. + }
  1598. + else
  1599. + {
  1600. + pCppReturn = pUnoReturn; // direct way for simple types
  1601. + }
  1602. + }
  1603. +
  1604. + // push this
  1605. + void* pAdjustedThisPtr = reinterpret_cast< void **>( pThis->getCppI() ) + aVtableSlot.offset;
  1606. + INSERT_INT64( &pAdjustedThisPtr, nREG, pGPR, pStack );
  1607. +
  1608. + // args
  1609. + void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
  1610. + // indices of values this have to be converted (interface conversion cpp<=>uno)
  1611. + sal_Int32 * pTempIndices = (sal_Int32 *)(pCppArgs + nParams);
  1612. + // type descriptions for reconversions
  1613. + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
  1614. +
  1615. + sal_Int32 nTempIndices = 0;
  1616. +
  1617. + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
  1618. + {
  1619. + const typelib_MethodParameter & rParam = pParams[nPos];
  1620. + typelib_TypeDescription * pParamTypeDescr = 0;
  1621. + TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
  1622. +
  1623. + if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
  1624. + {
  1625. + uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
  1626. + pThis->getBridge()->getUno2Cpp() );
  1627. +
  1628. + switch (pParamTypeDescr->eTypeClass)
  1629. + {
  1630. + case typelib_TypeClass_LONG:
  1631. + case typelib_TypeClass_UNSIGNED_LONG:
  1632. + INSERT_INT64( pCppArgs[nPos], nREG, pGPR, pStack );
  1633. + break;
  1634. + case typelib_TypeClass_ENUM:
  1635. + INSERT_INT32( pCppArgs[nPos], nREG, pGPR, pStack );
  1636. + break;
  1637. + case typelib_TypeClass_CHAR:
  1638. + case typelib_TypeClass_SHORT:
  1639. + INSERT_INT16( pCppArgs[nPos], nREG, pGPR, pStack );
  1640. + break;
  1641. + case typelib_TypeClass_UNSIGNED_SHORT:
  1642. + INSERT_UINT16( pCppArgs[nPos], nREG, pGPR, pStack );
  1643. + break;
  1644. + case typelib_TypeClass_BOOLEAN:
  1645. + case typelib_TypeClass_BYTE:
  1646. + INSERT_INT8( pCppArgs[nPos], nREG, pGPR, pStack );
  1647. + break;
  1648. + case typelib_TypeClass_FLOAT:
  1649. + case typelib_TypeClass_DOUBLE:
  1650. + INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nREG, pFPR, pStack );
  1651. + break;
  1652. + case typelib_TypeClass_HYPER:
  1653. + case typelib_TypeClass_UNSIGNED_HYPER:
  1654. + INSERT_INT64( pCppArgs[nPos], nREG, pGPR, pStack );
  1655. + break;
  1656. + default:
  1657. + break;
  1658. + }
  1659. +
  1660. + // no longer needed
  1661. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  1662. + }
  1663. + else // ptr to complex value | ref
  1664. + {
  1665. + if (! rParam.bIn) // is pure out
  1666. + {
  1667. + // cpp out is constructed mem, uno out is not!
  1668. + uno_constructData(
  1669. + pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
  1670. + pParamTypeDescr );
  1671. + pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
  1672. + // will be released at reconversion
  1673. + ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
  1674. + }
  1675. + // is in/inout
  1676. + else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
  1677. + {
  1678. + uno_copyAndConvertData(
  1679. + pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
  1680. + pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
  1681. +
  1682. + pTempIndices[nTempIndices] = nPos; // has to be reconverted
  1683. + // will be released at reconversion
  1684. + ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
  1685. + }
  1686. + else // direct way
  1687. + {
  1688. + pCppArgs[nPos] = pUnoArgs[nPos];
  1689. + // no longer needed
  1690. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  1691. + }
  1692. + INSERT_INT64( &(pCppArgs[nPos]), nREG, pGPR, pStack );
  1693. + }
  1694. + }
  1695. +
  1696. + try
  1697. + {
  1698. + try {
  1699. + callVirtualMethod(
  1700. + pAdjustedThisPtr, aVtableSlot.index,
  1701. + pCppReturn, pReturnTypeRef, bSimpleReturn,
  1702. + pStackStart, ( pStack - pStackStart ),
  1703. + pGPR, pFPR, nREG);
  1704. + } catch (css::uno::Exception &) {
  1705. + throw;
  1706. + } catch (std::exception & e) {
  1707. + throw css::uno::RuntimeException(
  1708. + "C++ code threw " + o3tl::runtimeToOUString(typeid(e).name()) + ": "
  1709. + + o3tl::runtimeToOUString(e.what()));
  1710. + } catch (...) {
  1711. + throw css::uno::RuntimeException("C++ code threw unknown exception");
  1712. + }
  1713. + // NO exception occurred...
  1714. + *ppUnoExc = 0;
  1715. +
  1716. + // reconvert temporary params
  1717. + for ( ; nTempIndices--; )
  1718. + {
  1719. + sal_Int32 nIndex = pTempIndices[nTempIndices];
  1720. + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
  1721. +
  1722. + if (pParams[nIndex].bIn)
  1723. + {
  1724. + if (pParams[nIndex].bOut) // inout
  1725. + {
  1726. + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
  1727. + uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
  1728. + pThis->getBridge()->getCpp2Uno() );
  1729. + }
  1730. + }
  1731. + else // pure out
  1732. + {
  1733. + uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
  1734. + pThis->getBridge()->getCpp2Uno() );
  1735. + }
  1736. + // destroy temp cpp param => cpp: every param was constructed
  1737. + uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
  1738. +
  1739. + TYPELIB_DANGER_RELEASE( pParamTypeDescr );
  1740. + }
  1741. + // return value
  1742. + if (pCppReturn && pUnoReturn != pCppReturn)
  1743. + {
  1744. + uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
  1745. + pThis->getBridge()->getCpp2Uno() );
  1746. + uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
  1747. + }
  1748. + }
  1749. + catch (...)
  1750. + {
  1751. + // fill uno exception
  1752. + CPPU_CURRENT_NAMESPACE::fillUnoException(*ppUnoExc, pThis->getBridge()->getCpp2Uno());
  1753. +
  1754. + // temporary params
  1755. + for ( ; nTempIndices--; )
  1756. + {
  1757. + sal_Int32 nIndex = pTempIndices[nTempIndices];
  1758. + // destroy temp cpp param => cpp: every param was constructed
  1759. + uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
  1760. + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
  1761. + }
  1762. + // return type
  1763. + if (pReturnTypeDescr)
  1764. + TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
  1765. + }
  1766. + }
  1767. +
  1768. +}
  1769. +
  1770. +
  1771. +namespace bridges::cpp_uno::shared {
  1772. +
  1773. +void unoInterfaceProxyDispatch(
  1774. + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
  1775. + void * pReturn, void * pArgs[], uno_Any ** ppException )
  1776. +{
  1777. + // is my surrogate
  1778. + bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
  1779. + = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
  1780. + //typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
  1781. +
  1782. +#ifdef BRDEBUG
  1783. + fprintf(stdout, "in dispatch\n");
  1784. +#endif
  1785. +
  1786. + switch (pMemberDescr->eTypeClass)
  1787. + {
  1788. + case typelib_TypeClass_INTERFACE_ATTRIBUTE:
  1789. + {
  1790. +
  1791. + VtableSlot aVtableSlot(
  1792. + getVtableSlot(
  1793. + reinterpret_cast<
  1794. + typelib_InterfaceAttributeTypeDescription const * >(
  1795. + pMemberDescr)));
  1796. +
  1797. + if (pReturn)
  1798. + {
  1799. + // dependent dispatch
  1800. + cpp_call(
  1801. + pThis, aVtableSlot,
  1802. + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
  1803. + 0, 0, // no params
  1804. + pReturn, pArgs, ppException );
  1805. + }
  1806. + else
  1807. + {
  1808. + // is SET
  1809. + typelib_MethodParameter aParam;
  1810. + aParam.pTypeRef =
  1811. + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
  1812. + aParam.bIn = sal_True;
  1813. + aParam.bOut = sal_False;
  1814. +
  1815. + typelib_TypeDescriptionReference * pReturnTypeRef = 0;
  1816. + OUString aVoidName("void");
  1817. + typelib_typedescriptionreference_new(
  1818. + &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
  1819. +
  1820. + // dependent dispatch
  1821. + aVtableSlot.index += 1; //get then set method
  1822. + cpp_call(
  1823. + pThis, aVtableSlot,
  1824. + pReturnTypeRef,
  1825. + 1, &aParam,
  1826. + pReturn, pArgs, ppException );
  1827. +
  1828. + typelib_typedescriptionreference_release( pReturnTypeRef );
  1829. + }
  1830. +
  1831. + break;
  1832. + }
  1833. + case typelib_TypeClass_INTERFACE_METHOD:
  1834. + {
  1835. +
  1836. + VtableSlot aVtableSlot(
  1837. + getVtableSlot(
  1838. + reinterpret_cast<
  1839. + typelib_InterfaceMethodTypeDescription const * >(
  1840. + pMemberDescr)));
  1841. + switch (aVtableSlot.index)
  1842. + {
  1843. + // standard calls
  1844. + case 1: // acquire uno interface
  1845. + (*pUnoI->acquire)( pUnoI );
  1846. + *ppException = 0;
  1847. + break;
  1848. + case 2: // release uno interface
  1849. + (*pUnoI->release)( pUnoI );
  1850. + *ppException = 0;
  1851. + break;
  1852. + case 0: // queryInterface() opt
  1853. + {
  1854. + typelib_TypeDescription * pTD = 0;
  1855. + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
  1856. + if (pTD)
  1857. + {
  1858. + uno_Interface * pInterface = 0;
  1859. + (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(pThis->pBridge->getUnoEnv(),
  1860. + (void **)&pInterface, pThis->oid.pData,
  1861. + (typelib_InterfaceTypeDescription *)pTD );
  1862. +
  1863. + if (pInterface)
  1864. + {
  1865. + ::uno_any_construct(
  1866. + reinterpret_cast< uno_Any * >( pReturn ),
  1867. + &pInterface, pTD, 0 );
  1868. + (*pInterface->release)( pInterface );
  1869. + TYPELIB_DANGER_RELEASE( pTD );
  1870. + *ppException = 0;
  1871. + break;
  1872. + }
  1873. + TYPELIB_DANGER_RELEASE( pTD );
  1874. + }
  1875. + } // else perform queryInterface()
  1876. + default:
  1877. + // dependent dispatch
  1878. + cpp_call(
  1879. + pThis, aVtableSlot,
  1880. + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
  1881. + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
  1882. + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
  1883. + pReturn, pArgs, ppException );
  1884. + }
  1885. + break;
  1886. + }
  1887. + default:
  1888. + {
  1889. + ::com::sun::star::uno::RuntimeException aExc(
  1890. + "illegal member type description!",
  1891. + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
  1892. +
  1893. + Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
  1894. + // binary identical null reference
  1895. + ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
  1896. + }
  1897. + }
  1898. +}
  1899. +
  1900. +}
  1901. +
  1902. +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
  1903. diff --git a/configure.ac b/configure.ac
  1904. index 33dc0fb963162..a6abeb1af9a0c 100644
  1905. --- a/configure.ac
  1906. +++ b/configure.ac
  1907. @@ -5213,6 +5213,12 @@ linux-gnu*|linux-musl*)
  1908. EPM_FLAGS="-a mipsel"
  1909. PLATFORMID=linux_mips_el
  1910. ;;
  1911. + riscv64)
  1912. + CPUNAME=RISCV64
  1913. + RTL_ARCH=RISCV64
  1914. + EPM_FLAGS="-a riscv64"
  1915. + PLATFORMID=linux_riscv64
  1916. + ;;
  1917. m68k)
  1918. CPUNAME=M68K
  1919. RTL_ARCH=M68K
  1920. @@ -8608,7 +8614,7 @@ if test "$ENABLE_JAVA" != ""; then
  1921. JAVAINTERPRETER=`win_short_path_for_make "$JAVAINTERPRETER"`
  1922. elif test "$cross_compiling" != "yes"; then
  1923. case $CPUNAME in
  1924. - AARCH64|AXP|X86_64|HPPA|IA64|POWERPC64|S390X|SPARC64|GODSON64)
  1925. + AARCH64|AXP|X86_64|HPPA|IA64|POWERPC64|S390X|SPARC64|GODSON64|RISCV64)
  1926. if test -f "$JAVAINTERPRETER" -a "`$JAVAINTERPRETER -version 2>&1 | $GREP -i 64-bit`" = "" >/dev/null; then
  1927. AC_MSG_WARN([You are building 64-bit binaries but the JDK $JAVAINTERPRETER is 32-bit])
  1928. AC_MSG_ERROR([You should pass the --with-jdk-home option pointing to a 64-bit JDK])
  1929. @@ -12871,7 +12877,7 @@ AC_SUBST(RHINO_JAR)
  1930. # platforms there.
  1931. supports_multilib=
  1932. case "$host_cpu" in
  1933. -x86_64 | powerpc64 | powerpc64le | s390x | aarch64 | mips64 | mips64el)
  1934. +x86_64 | powerpc64 | powerpc64le | s390x | aarch64 | mips64 | mips64el | riscv64)
  1935. if test "$SAL_TYPES_SIZEOFLONG" = "8"; then
  1936. supports_multilib="yes"
  1937. fi
  1938. diff --git a/jvmfwk/inc/vendorbase.hxx b/jvmfwk/inc/vendorbase.hxx
  1939. index 779fc8f7a46f2..ef60720768f44 100644
  1940. --- a/jvmfwk/inc/vendorbase.hxx
  1941. +++ b/jvmfwk/inc/vendorbase.hxx
  1942. @@ -59,6 +59,8 @@ OpenJDK at least, but probably not true for Lemotes JDK */
  1943. #else
  1944. #define JFW_PLUGIN_ARCH "mips64el"
  1945. #endif
  1946. +#elif defined RISCV64
  1947. +#define JFW_PLUGIN_ARCH "riscv64"
  1948. #elif defined S390X
  1949. #define JFW_PLUGIN_ARCH "s390x"
  1950. #elif defined S390
  1951. diff --git a/solenv/gbuild/platform/LINUX_RISCV64_GCC.mk b/solenv/gbuild/platform/LINUX_RISCV64_GCC.mk
  1952. new file mode 100644
  1953. index 0000000000000..9e007101d8ac7
  1954. --- /dev/null
  1955. +++ b/solenv/gbuild/platform/LINUX_RISCV64_GCC.mk
  1956. @@ -0,0 +1,15 @@
  1957. +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
  1958. +#
  1959. +# This file is part of the LibreOffice project.
  1960. +#
  1961. +# This Source Code Form is subject to the terms of the Mozilla Public
  1962. +# License, v. 2.0. If a copy of the MPL was not distributed with this
  1963. +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
  1964. +#
  1965. +
  1966. +#please make generic modifications to unxgcc.mk or linux.mk
  1967. +gb_COMPILEROPTFLAGS := -Os
  1968. +
  1969. +include $(GBUILDDIR)/platform/linux.mk
  1970. +
  1971. +# vim: set noet sw=4: