From e352946598d2371bdf7a4fed821b0f8ce891890e Mon Sep 17 00:00:00 2001 From: liuyaning6 Date: Fri, 20 May 2022 15:39:39 +0800 Subject: [PATCH 01/19] fix OAT problems Author @mashuai53 @ya-ning-liu Signed-off-by: FondMemoryVVV --- OAT.xml | 224 ++++++++++++++++++++++++++++++++++++++++++++++ README.OpenSource | 11 +++ README_zh.md | 70 +++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 OAT.xml create mode 100644 README.OpenSource create mode 100644 README_zh.md diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 000000000000..fe34bbf4d4a4 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,224 @@ + + + + + + llvm/LICENSE.TXT|clang/LICENSE.TXT|libcxx/LICENSE.TXT|lldb/LICENSE.TXT|clang-tools-extra/LICENSE.TXT|llvm/utils/lit/LICENSE.TXT|llvm/tools/msbuild/license.txt|llvm/tools/msbuild/license.txt|clang-tools-extra/clang-tidy/cert/LICENSE.TXT|clang-tools-extra/clang-tidy/hicpp/LICENSE.TXT|libclc/LICENSE.TXT|llvm/include/llvm/Support/LICENSE.TXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.OpenSource b/README.OpenSource new file mode 100644 index 000000000000..999365386775 --- /dev/null +++ b/README.OpenSource @@ -0,0 +1,11 @@ +[ + { + "Name": "LLVM", + "License": "Apache License v2.0 with LLVM Exceptions", + "License File": "./libunwind/LICENSE.TXT ./lld/LICENSE.TXT ./polly/tools/GPURuntime/LICENSE.TXT ./libcxxabi/LICENSE.TXT ./llvm/include/llvm/Support/LICENSE.TXT ./llvm/utils/unittest/googletest/LICENSE.TXT ./llvm/LICENSE.TXT ./compiler-rt/LICENSE.TXT ./clang-tools-extra/clang-tidy/cert/LICENSE.TXT ./clang-tools-extra/clang-tidy/hicpp/LICENSE.TXT ./clang-tools-extra/LICENSE.TXT ./lldb/LICENSE.TXT ./llgo/LICENSE.TXT ./libcxx/LICENSE.TXT ./clang/LICENSE.TXT ./libclc/LICENSE.TXT ./parallel-libs/acxxel/LICENSE.TXT", + "Version Number": "12.0.1", + "Owner": "sunqiang13@huawei.com", + "Upstream URL": "http://llvm.org/", + "Description": "The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name \"LLVM\" itself is not an acronym; it is the full name of the project." + } +] diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 000000000000..f58d9cd8a031 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,70 @@ +# LLVM编译器基础架构 + +此目录及其子目录包含LLVM的源代码,LLVM是一个用于构建高度优化的编译器、优化器和运行时环境的工具包。 + +自述文件简要介绍了如何开始构建LLVM。有关如何为LLVM项目做出贡献的更多信息,请查看 [为LLVM做出贡献](https://llvm.org/docs/Contributing.html) 指南。 + +## LLVM系统入门 + +取自 [https://llvm.org/docs/GettingStarted.html](https://gitee.com/link?target=https%3A%2F%2Fllvm.org%2Fdocs%2FGettingStarted.html). + +### 概述 + +欢迎来到LLVM项目! + +LLVM项目有多个组件。该项目的核心本身被称为“LLVM”。这包含处理中间表示并将其转换为对象文件所需的所有工具、库和头文件。工具包括汇编器、反汇编器、位码分析器和位码优化器。它还包含基本的回归测试。 + +类C语言使用 [Clang](https://clang.llvm.org/) 前端。此组件将C、C++、目标-C和目标-C++代码编译为LLVM位码,并使用LLVM将其编译为目标文件。 + +其他组件包括:[libc++ C++ 标准库](https://libcxx.llvm.org/),[LLD链接器](https://lld.llvm.org/) 等。 + +### 获取源代码并构建LLVM + +LLVM入门文档可能已过期。[Clang入门](https://clang.llvm.org/get_started.html) 页面可能有更准确的信息。 + +这是获取和构建LLVM源的示例工作流和配置: + +1. Checkout LLVM (包括Clang等相关子项目): + + - `git clone https://github.com/llvm/llvm-project.git` + - 或 在 Windows上, `git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git` + +2. 配置和构建LLVM和Clang: + + - `cd llvm-project` + + - `mkdir build` + + - `cd build` + + - `cmake -G [options] ../llvm` + + 一些常见的构建系统生成器有: + + - `Ninja`---用于生成 [Ninja](https://ninja-build.org/) 构建文件。大多数llvm开发人员使用Ninja。 + - `Unix Makefiles` --- 用于生成与make兼容的并行makefile。 + - `Visual Studio` --- 用于生成Visual Studio项目和解决方案。 + - `Xcode` --- 用于生成Xcode项目。 + + 一些常见选项: + + - `-DLLVM_ENABLE_PROJECTS='...'` --- 要额外构建的LLVM子项目的分号分隔列表。可以包括:clang、clang-tools-extra、libcxx、libcxxabi、libunwind、lldb、编译器-rt、lld、波莉或调试信息测试中的任何一个。 + + 例如,要构建LLVM、Clang、libcxx和libcxxabi,请使用 `-DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"`. + + - `-DCMAKE_INSTALL_PREFIX=directory` --- 为*目录* 指定要安装LLVM工具和库的完整路径名 (默认 `/usr/local`). + + - `-DCMAKE_BUILD_TYPE=type` --- *类型* 的有效选项为 调试、发布、带调试信息发布 和最小尺寸发布。默认值为调试。 + + - `-DLLVM_ENABLE_ASSERTIONS=On` --- 在启用断言检查的情况下编译(调试编译的默认值为Yes,所有其他编译类型的默认值为No)。 + + - `cmake --build . [-- [options] ]` 或直接在上面指定的构建系统。 + + - 默认目标(即 `ninja` or `make`)将构建所有LLVM。 + - `check-all`目标(即`ninja check-all`)将运行回归测试,以确保一切都正常工作。 + - CMake将为每个工具和库生成目标,大多数LLVM子项目生成自己的`check-`目标。 + - 运行串行构建将是 **缓慢** 。要提高速度,请尝试运行并行构建。在忍者中,默认情况下,这是在“make”中完成的;对于`make`,请使用选项`-j NNN`,其中`NNN`是并行作业的数量,例如您拥有的CPU数量。 + + - 有关详细信息,请参阅 [CMake](https://llvm.org/docs/CMake.html) + +请参阅 [LLVM入门](https://llvm.org/docs/GettingStarted.html#getting-started-with-llvm) 页面,了解有关配置和编译LLVM的详细信息。您可以访问 [目录布局](https://llvm.org/docs/GettingStarted.html#directory-layout) 以了解源代码树的布局。 \ No newline at end of file -- Gitee From 04a38d905ddaee4a0cefe26eb0a143c4cf3ea16f Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Thu, 9 Jun 2022 15:40:01 +0800 Subject: [PATCH 02/19] Add scripts for LLVM toolchain build with instructions Author @chenhao346 @ya-ning-liu @liwentao_uiw Signed-off-by: chenhao Change-Id: I8fb3644575decc5163a2f9007b7fd1991973fdc5 --- data/llvm_build.png | Bin 0 -> 34465 bytes data/one_time_setup.png | Bin 0 -> 21555 bytes llvm-build/Makefile | 204 ++++ llvm-build/OHOS.cmake | 22 + llvm-build/README.md | 126 ++ llvm-build/build.py | 1999 ++++++++++++++++++++++++++++++++ llvm-build/build_musl.sh | 105 ++ llvm-build/env_prepare.sh | 18 + llvm-build/mingw.py | 267 +++++ llvm-build/toolchain_readme.md | 25 + llvm-build/windres.sh | 56 + 11 files changed, 2822 insertions(+) create mode 100644 data/llvm_build.png create mode 100644 data/one_time_setup.png create mode 100644 llvm-build/Makefile create mode 100644 llvm-build/OHOS.cmake create mode 100644 llvm-build/README.md create mode 100644 llvm-build/build.py create mode 100755 llvm-build/build_musl.sh create mode 100755 llvm-build/env_prepare.sh create mode 100644 llvm-build/mingw.py create mode 100644 llvm-build/toolchain_readme.md create mode 100644 llvm-build/windres.sh diff --git a/data/llvm_build.png b/data/llvm_build.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f0bdb0c100cf88771a169dc06772109799650d GIT binary patch literal 34465 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
    a@q@LIokbhw)h zmee8cWnr#IAQS6`R1aus&0)8)CR96GEx^Tv+389hc0wYpY<-yQ(9LbSCAl5&c?t)C zG%phAwydkJ3$4+skJwkQJ=#Ab#f1EYU^@tA ztCpDcQ@C&qOZubtL*pWV6fQCzkN3fee>jyNZvC7={#0LzNjcae_pJS>s4z=eS{sZn zsS2@d0jFY;NxzWhWTWkwVg31$)IqvUn0xE@M&5o!PCKu7f(dDN=?S4gX547|yE!8V zlWOc~uBS`J6M2o%Vd09RF7(p3^!J6#X4Vs7R{K5_)gSaVT>Da|%NoJ-M^d1$EkG~! z!}nXgkl0P)TFG5lJc(_T0N(5ni&vrT413F;n-^yb=Brm#tpYh?Q_Kg0zeoSyzn7#Kes$|lt zVoFBiG@95~D;ja&KH_gl*4m!^RWm)z2m87D{d@9Eb3US?GQ$n^bvo;X>Lx;7e7)hK0klvn}032$5a_346*j7iY|FI7>@-kec$ zSms6A&y|ushoA=N`?q00U~y-3m97vG2lV#FZ~x}TfO!Mr>T=WL?5*7{m!Z*-{QYpH zGvPD66X6r2ey^dTKxGQaqHpQ$UTe}y*3yh2MJsFN!d_UdpA{J&a5pOg)81maY;KOM z1x*M4E)4YvpxfJE*KHk_n(QZEXSN#$n2Wp5J8V<1e<>)aw35rM^K@f^!+-=4D8O)P z%YurZ%r4y}PK|%-eic!?yDopT5N52l_mz0s-w+plYq9UqR2Ys8PAP_WS}d&Sd4)g& zjL9Y@jiaM#T^4~GUw4j2t2u64)xvf@DHaMFl`ecGu33;$K?&2v%Jz=W%l{SlEY0b7 zJ@`cZIJyrPP4F8^xk&)EgA>-w-7DD?iz6#+&^K6_xxQwL%_NOaPlK%y9(w`S!f$T^ zmJM+1lo6>t(Pfq6D#t0QQJQ1oGn|f;_>##R2j!}JIpXYW(BScbHt@ve#>aQr#@F=3$mxu2I39kvPkdu!>a# zss-dGcO`pE#2nQ+iRUgN_Ns9gMFlgDc%IGlv_vASlPDIG!y)PMW1iNORKt&B{7e@~HaC?CO*to?6N153=IZFZG0QJ`tHWG(a z8&#qzTl?gdshgHgP0uKbBLoK@1!+oYNg*9PSz#=R%&cByln{1`#R!S!-m^Ir{mZo| zgfJIWF8%t2w-%NHd%A31wtbFD_&sgag#kH>PB>Y+Ch;@^RSGn>xj1G}rLsNXy2y_S z0y&^iQieujJet=hq$g5zkz}?VU3!XNM2c{B{`bdS5Bu5dV3YyAi~%7;Tdqpj<5sg2 zM^$@-J=!9nerda8=RQKrb|kQSHFy*zvZOqmMbTLtt)kJ^$G9+_Wy@HO1_eFiqATqb z@76-LAhL?RrtGIkBUL+h6u6F$%vJf|%%dLf*~|gA`cHsqBM(yyfu%3*FOvU+8xn;- zy>l_%elN}6{@Ggt{XPhmLrFF_M@wKGLLJ=&Ot0Qg>h7;D;p6eByGjXji7pt{c_mzn zEv7X4l=r?0Rl;6NeHiiO z4*FqQqST0+UPtkfp9n_N08J705GNlCL+>J=?48(nzbnbwU{r zIwk9I>E*ajTN?uoo5`DLPS&;jtZR8%KruGC;Y+USH!BW{Ecb$79I!q>4IME`!`pGQ z-dc&xp~k2x=hS|@50Q(4yffT%CCt-Z!92~Jh~L|~K(^O)yVjI4DpTmie8G|Z{f@rc zOpj(Pd}OnN`4sU2Yt*nwkctVyf8*8YSbI~!c$EW5Qaq^Aj zy5AD(R|tr^9LYE1X16*^O%jXgBxz2=N^v~dTWObSDXi!-iuWRy%5XfT(p-W|QnL|R zeS!>%3UQ3hm>W9nj>^ci+gW)|Y71&A@80PSiFwxI4f0Mzss^H7+?|LNvAndR0+IUm zK(IGEGi3e~3Jh6%wbluDj-RO-N7@G_y)3FLnVtP$`EX)>$fEO|`4z)eR-A`)3QIJI z(Bx$M@kc~8Sxb+RpcPc?dDrCqTk~0E<&X{ap>#u{Cp_i;>qV&QY?C2X!=c&O)nKLZ z>fYdBd)@B8RuJAlTNHdd!^Y*ey>%k}&fcIr!E!;m{vf}gkhjb7?_-(mWF$hauHE|<(kO9GcG( zdVb)MFNK<;F@N?0%_fCW^e6G9#Euk6c~wa<4%-GhTF<0=YUj|=3}qHsldzq%?9KC# zS0ZEY?F#Bvi-FMzUtY?;I2gjKBY1-1pG_tAo^gZ-Ho|>=e@VUrNi>TTD!8Fr03vlb zUz-0Z4~;R5!)-6bcKY|dk`?1D=p|MV0ybcZnLamhrll5XiP4>LYr)D1&)Cqya2}>m z7D`L>ui(P&dRnJe8do-|N6j99)7_3PqKb+4_#>&322}%V->D@4-HL0f(k5RwdG`Al zjU91pUA;+5G%pCYFV>>)mz^nwm^XiA!DKn5FHEeDUO*BaJyB{7{94`zN7V|y$}cZr zRHMM`lvTF8BR!`6&eyvZ_nujIhxo!nEgjo0x$l5W!J{CYWc(QOTS`1G;=nT9(=X@% zc)7Y8WtXy|hMMXl=s!y4b@n{9hayyhM!b-vjU1U1BlSGZas0HSG)CTA2V2uE9r2D$ z+!IE0)(>W$#>KENDEeY)K7uPWLaFoFA1x z_9P2m5MDDYt&UT0q|O(j)C%%M{JdOcS3GDT@~3vQdU-xsUmqL588W!MwoeTe=N?!+ z%5^x`=31cMRr;-Y#p;L%+dXw3o8V0`z0&GR|)trAv>Fj~Og! z*p(D1l%P7E+khPD=V@B-ZB5Ip>1Q$}56!o&j51MgtM=vVz?LGH%e*3r>NAAnkv-P1 z+l+zuY1wIl7mD_?LRhxLv?`!DCylOJNq2R?W3Xl6_=)VVG?rd4?#n6Z%3XO-!OArAUS%J&S{$YT+dDIE`;QZN7J|?1@z&GJxM` z@Gb>%bc@X6%Y|6HO4mFr2TBWa$bxc>3roj$%8f3*9T2y63&`}x%7ZKo&EDw};sWfh zAFgLS;eA z4ds_jTe}ir7JNLF)X+~7?kM_odYpxFGhswdKRJ`jQ8>8^7G`qSZ*V6a{_Av1-P`$k z3$|JCnPmS~y+rewik9a=uI9~BO!|EQwitny_BUeoOEUz+M6A)1tDu-fDI@sI)w^10KLyR`${D!l zTY;uysP|I?68PLvlg=lQiR^sF;{i?r8(A7N5)sJZ(JpkYc68e|Vjs70e?@I)`_GI8Pq5%5Zw58w4dZ zM%^r?#G16W_XMA7TB|jorRSMqP)3qwOZbNAHYI!VBQayyoHJ-TtWruT?5uFBG>4(3 zgKF}M)rf?J!14mR0p55yyVY$l)L=&$!aPzupKV)ydF-Yks6Chl{So_xEmg!H#R!hD zsVdGN5VN)D0iBg*Z}IIQRV;`^-L+OL1!>Z4Pj!UnIW}%?e2=QK8OUA&Q>=T*c?I@`|sAe`SCEY}3jcg-9=tzPTWTRStP1KwA?_IEDZnml_@=o#K@-!&<< z`Mv9fWW!@(9+mrGM@OCpkKEO3S~s^|e(XCl6=N{=L@JW!4&c zF@MQqSOb6NTzfDZWbg7+!K|Juiv+713zWvNVEJ5tv4-Py>TWWgoV)BH)z~D^!^_y1|=L=%8)+3L) zZVO$-KtH%AKViMR=lNXlYc5*7X~1z+E`B(g^2G3TF;Xq%nHtvzFPf7ee0+K$;viP* z&C=&jGbBSR&7+lNYPVZ;3YbiptvYyf<=J8~@nJ8+x$(U5PK)wadY(@%{k6yLgo+QJ z)Y_d75v@>G>o zu-Tg9L*n@4j!)XBsJ$KOzpzGOEB(un@2*9m1$aOAwDZ(7+gz|XsgArIl|qB9{u-DK z?|8!|-q_XM_uKa!;`7>M7;w>b)zj5Nr!;D3ryxE&^ah^qZ}+9Bt-uXhYKHoe&wZV; zF1CA32Re@{#A5h$xnREfN$WMo^Y6f) z@kz?744Ov`-3=tFe->S#yt*B2yZ8H{p^i2@6t3~h0j|MG$Ox32M=rz8m9_98EXTU=gZit>*dV_s4DM&_xb?HA^+FC;+x@hZ{n9WvkRf6D^3wC9 z9A>^6#sYDXKIHyl31)HpNy}CCs>UwKYlx1kPkmVlSM-1G?`zi_xapURiJv@~_zr>S zn#5mNWz5#7Rv8MuJo__dtC|j|k&Pgj$QK2LX_k8_pAX@^HR-C|198ota-5DzRm^aP z1-Wkk@njgp{;~4p1zsa*Q=rd66gx@f!YAD~CU%S+jIk-BgyKf`Y)b03+g+B5ii)V9 zMW4Y@Z)-kBYO+`8Z}p{*0nV(*^SK91#8qOr?jxX+Zi!6=wRE}Imjb(A_3vqD{?cMST^?X|MSe?}g=4*O+vg*sFa zi2t0#R*+iEGo%PSy+z-Clv8CWQUx=0g*Jfb+N25*2!!(ubHS_s&IPczCz=zyjt*>M zc_tLWrmAGaG143ImGpaipfa$j`4(7fOjP0*o2Xb-bnK4t=l$NK#ir1zuGgnC*GK#I z$;8TW2gj?^t%*qIAUNpPFV=uHrvOm7IsbJF4`(Xb_4;Sd)w$kct4h7j4$5R);9cPZ ze^~H#*Sze{iOonWdk2L$7*J6ubaT!;g8VB)&=o@u@*`HMFeFy9lxr+reOS}*u4#2~ z{M?$V=(yvp9p>Zi4t4xx*0ZD@_Qi|7IM^?8rM)re0W&uM8y zn!38Z_DH+j;<|}F=TMx{6t~XpGu)-1#F!!ckeikLXzEI!Hnm^BMo102oYS_g9IW$T zv11%FqD5li-Wh2b@4!d~2ma{fcW!ySoo3h8KUWZ*w?h6D^^|*)Ozz&8{rUWT2?LT{ z>3)lolN6s~cZF!+>f?=f`X+BRcFvxpgoCSMrT6CYtP+f-^wa&OH8TCgc(cn-x|3(` z<#&DZU~E1a&`i%eZ#}BL)e%jLjMy%dr>fX2OP+B=e=}$n?D^Ie=YCb@Y=q6HN2q6M z17EaG>*B+hq?J7(s*RFg$cApeaZQ1Hk-M>SXSgy}- zk9qhTeM&ewW)^!@Qi@VS5^04=UAfRwd=DY=4#JV{^zrm4x2?v`MtY3)?2qKtj^p+g zT1#?AjYQPEgGB@rFWP|)Y{H4pIUjMx)rp=zRw*q^{XI^>S6BE>h4ylP6FG=y~+7Osn8o$tC`llcwxHfM4)NxbmDhcaF%8dp_ou7tvG1>#lRhPAY7DieKza zar3&z?GYaH!Z(Rmg1D{+uU_n9Bwg^Gb&O=G<8W3)pABY}vwpJQHW>5kd{6yX+u!M4 zd7ka}e=Bo(6!X4h(KKb+FhTG?!9S)$A|u^@#y6eYv-X%GDfQG2Z?u zy;QlrQ|3(dOT)29o0U#!t}WDsn+6$w3p`h-+P%jH>v_7K&kQ4Kc8=z4_|_NvjoC}Q zK^*vY)pi^m|5-NS;)ymbCN_IM(>I*PD|x45sVe99-bAyTDyk`dm3aC**ggY(e}kvF zQjvOgxou_SVj4E)`+NHDQ>bwt+u!ix3!I%a6J9Hw){|@BWe$qzXXP)hjl3LlQ&W2; zb!zoz0C&)^)=>@lZ;${3kZg6JH8Oe_Qn1Vmf+mIN!uD zFxHxR)y2#&;K!Ikp{*n}FKGRRH5i8RKS*o(EcF`{ z7DT^aF0O`^@gI8Mza7`|)jW|?xj2XZc@LrsP}I-V=1iztMIW7m zk;wADjS0EYfFJwJ*qlv&&fAqFt$WXgLm>5LNV9y+KtkDQet76DJnC#IEUG<9NCESU z#MytT+h;d+SmB5n+%Pk}!fWFyLZ+)f3jROZ`|7tU+OOXY2r3QI9U>_qo9;#>M3C;1 z24S-SNkO_nQo6fCT4_Wiwsd!FHr;s!^?Ba!d9U}Jf8d<^2WFUS_RKx2?$27YX06@; z>nZiFi-{CUgU-3J7?72*`)!E{WU5K7STY7!gu9Chp5u>te!&ZU;Z?Q)(z(hR1`TNypmQ^RRFK0AoCf==eyxL=GVzlpEf6(wR0%*Zl5>A7VSH&Z1gu+s!5_70&8FAf0y!N})#Fo! zu>*;!7%=c1x0bNSou!>jfz@6g#^|7})|lnim`7Y%4qcZ63R#>WaE3i9C6B)Eb@MWg zi#!(D?XKhFQzL%9slQzf@Gr!_LT70$LUcG9zr`*93X?lTfJU9E=iHPD^Iv$v`?zv;V$h*gn1AM|rMpmprI^BWqmj?aEr^;!){9LFl&y+*AnG^gcP*_WF$Z(knVU|Cfpe zJFh4WhU66wNS$KWwZ_-jy&^$>(G8!Dox*kM6Gs}0cQ9DV!G~60*IbX{mA?UCT5Lx<)SZSK{~PodcP^?>0z1!&G|T7Gzic)G;0@ zgiUUqNBL?~eNmb@h1G6<$*RKBJxj#sTdkGr4OlAXc+nF5!ZK_HSJUzfXLpEJAaO3| z#WOG>WtPBJdJ^=e{{!>s5cy}hH-2WL`#sdmQ(6yuMB)7Uxh>M6PX?VJf~i`864Esj z+a$R`Zz)lSYuU67!mZiy@rD^%C`&zE59Zqz?Qf5{shT$=XD1}^-Loxu2FLm(&+3pA z<09+#?Qc))&(1fIKnq1LkDL$L(V|}Q<(Z+whj<>65Nr@F?-nFO*RBqViqaZ+82dq{ zgj=S_PBj^t=L5(`(HBpS43c}*h=ooyXeo&{7FPsAJ!?czZq2~?WeKh?l4!!_QASv1 zVkh+`eb?Dg{IJ^{F5;CE+5+wBapcJ$wg<3h;Es=(<309S&&iYqU74if89=LX-l}wT zS=6(L8kwIH39~-+ue&bu#iWWqJ6sWEK?9cXU%oI1&H0uX6Apu5;iEBy7!g%`#+vp> zhBgl5|H4WPz(zC&CN~N+qAcuvgmI)aSs}8>W}pB7HY%Ks#5xGIVqo zbMY0>`M}&%4@Dr+Z3qj){Cc`x`TLJRGtq7xH`LGJxS1+F!(W?)EA|(f z*PIx0U=Q8glP~7QBwz|D-z|&}UhUc4=f#fZRWAPqX}t3Mvk2eL01L=T~%BkxKa}w4EhVnNAAV+#KUZ=d^6p;%(ybxfXIr?Zj;zTPM-0r5GY-kkO#; z%-oG9{rEoj+C<0sszjP68*tonY zk)ol?dbyd&gpJhaW2Q9s;CpmVI*3ir4es26{qX*Vx!%{Ll>X+>W+70H;1O%dx~tQR zBRM!tID-J3YKh5j6Kpui{HexgO~#=X!-fk3?}i6t_1TqxUo}7XX*Fn$n)0zxSo`_d zuUeKZXVkM|@v)~!2-6IP#^)bvUK#RZLw+91NQ3zz?7mc|OB;mCj>f6RKv!3^{ZyIA zF#G+DCOI<}$BAt_-7xBT9c+eV=1@6@!&ncHQ9x4`v|WuVfk$T|2h6suUURZ3#~I1& z+tozECFBJ!2Z#G!uT(I)+&{WxB3vbZE?1ZEz(J2V&+?}r<{eL+LdP_k0JL?{+Qun{ zhBq83@gYn8YX)ECj!|&)D*etIq)$Dn`dC=`&sut?Btll(i;#Dxk)|G5qa4SA_T4kA z1S`zn`^ibPlp*;M80m(!WKYo|Yjk}}FW*z=9kw7Lc8zI`d>ph-g|B{1_Q*~c70Bew7Q`;OsHgW164r+|hziYC7(jG;yeQ_94+ERmeIuvF4!^qf>MuEmhvL z{4n9NzaZgLBFy+|z}H0nt3;T&T3DOLn#Cj;f$jHqOv-i7IVSa4+&7?35DaW5-N$9{ ztVx?Y!elj-BgD(pGWc5OD&$27<3i9lMBe9y##eMdoIo>(T_7!%vvDC{-eJp0iXJ!oWo}zVWWq4yyyvFkkMrL zDqFEPs#}Alr1NLaqeG>oA*U90A5XFse_h&wZ+5;~OK(_VJ+?%Nhlx9t1^|G4USS9& z;}WTE+-l=3t#;{y=et)uuq`|C$vOH7?GIlT+nq(gOUTLB58SoL=M?g#DOD&tCq>g{ z_&_M>Mq6BZeGHN!9p;iETxE8jpU-mZ-#E8Q2dTRu#f z6e~Awjno87x9oBuGz@Z!r&}8N*y3xG3r^a+WK(gwS4|)rw2iCw;!RwKGe(@?)fX&- zKD;yb8F#E2cQRfV{G4xRek#u8;Wqa7BgUkfM#Z!7=$<-%QGRWjc{~tDvf3C3tqYV> zqP)&|xV!5eI35(mN(9w6mnXjnzP5DGRxIH_ar-6BYLh*Ee?lKH6pbQ{#PrXX&c8%T zNt>`pKH!4W5Oobt;mD}`0Apu0ZRe+Z`QrMH58oT(kRI>3FcZAn@+luIRkB z0{{>P9^Qm})zM!5*Pox^nT68aULYR_+DFy@O!mqMjW1h1E%Q&f=Cx5m;Y=ZV(-ip2 z)tBx#fZJJbL-U5jRdGH|NbIi8m8ljloD-lNFwB2)Vv+;^PHj+-7l~V1Hf;09oeuj$ z-UHtvKYInmyCj0V`M}oy3JmzJqy{LYpdl%;_Z1MV5H=}wwL9MvIGg{mNs0o#_Q#)^1r~Z)H@%lV({Abo3m+g=?Gc4Lu3o9Co)5LQ5eQ zv4FFarD5l$XH&|YArc5S?E>nuvv%YxYO#bL2!m5GpL+5?uKGc?mvySC?H$ky16e$1 zzwGsLL!S>ds!LszmmmmgM!R9tsGvk;9J3J(#neI@+NE=#I08Z??;f$d??tA*fw@;? zW|C7WKAe}E=H7=NQdwEEYb!dPO@2X|9%ZkKa4N?dJlSU)+hYn|92M9;bl0hAok~>( zP~^X37{_=>;>j+Zazu=~&w6syvB93O6|J4-9ymjRY|nr~eAXkFtuAuh^zEq)6_X% zd4lBE5&7xu^%TOpq!Z8a&jcTZLOfl(wAFqyEYR0XMh9F-oCU2faRDr6zz=hI~0nU%yb@Zg>tiEj{ zJs52tpnL(lZIa%#!3CDOHUx{6gkR=5T~-7kipUotN3yWulaYI~NUvOU!`4yXOr-he z9zs>t9@vmah6>hA+k)9+uO18Dm-|cG;qXIGY9MvH3n<`KB1M~p`sg0g#kD=Vg^aXx z=!+3Ug`_c67>_)^xXKZzcLRFqV=6xWM2uOATS1|Wpoe zy=ciQj|%sNbhE>yN)}aqktkoS;x%*1xEWhYHSAJjt#@ z0@BX2{;KI`;v5oJN2u7!&5ujR7Sn<1d&Fd${A@Th%B(?b=?&p_8|^|AvQf28N4D@E z2e^7;sp&+uOy~qMziq;A6QKmFDO3hO!W%}&!w4jU?wp__Kjt3UdsLeV44{WqbSSTA z0L&Aq=8h~GNOdl0wIhmF+kRP&^%d>0stj`}Gbdb2+!mTYkWcJj%)IZTYA4-MIDkczf!@F-0_^?}j{^?)Xq(JI}39GF5s4TCI7ZRI}s2zq-FG#S;c!TpT#Eut5 zyl|XZr40*TrGmcY`PN73oo)7sIO8>n-fWj=5uO*Y3SRa0ytq|9vkPJt7_^2dpg4o< zmo1DRn-LpDg(`@L1u1iQ=vUvyvFz7ZzzOMzueI2 z>B!9NzsU#I9Z=^x;bnP;W|H-qhREOzW3P)%#s{>nl!}Jek`T`lgFKVFEf7O8)j|Vt zVw!YE{~#W7zFWwhQ!SGLRZa}l(Qe&cMoiaF%+IGgGnK%D?7jk#`R2S}V2Ll=1eUmK zcnQjvvTW*)zr}q+uAYhV4FIU={tZ4zOFP*OUs$CO#r>-gcRTDWKO=P?|E6u$dF+3< zvOyN#HX23YxOXRcS^Ssm9C~`&jY-pIb>ZLpcIUnUNHBBu{H`d{Z$kr|ZNW}4>+n_# za9S__yU+8Fjk1tn(+-RSaPRMMDDayNY)xP>Yx^Mx`oreGe;dgY|4#1jfh-K8|1xvQ zdAO2ym_u7U&ob+E;oa_CNMbD2zzKjVARi+V?ubA1u&A5h04CacAl$RKNDJion^U3# zx;aq!8yu`;E%SqXvY5=tAN*F>;jpfE!go*Z#nieB;2MV`!aX~Ko!^h6NJw8?(U!<0i8Cd1a8JWu={74M6m#3z8jF`17W#*Sdue|bd3*0 zFWvdU-BGa`p>$og5aTxnp;yIF;L~2ZyWg4?Ly;DNe4|MOmk7W=fZ#ELbFZb?>1$vkzE0n;!M)>8(ud5 zat2;BEG&Tj*q84!M!+>a4_}WX0kUe>F02O&{n*z%uUp%j3LjeH@by+?r$S(4KR3w1T;2xqsVNt4Unmf7!ly8*TEWpQ` zCHxoE{`J@|6SVG&|2gOHUzd(l>IV5g{~R(7I#Ezj8Qa?0j%DHw`wlyM{^8yA&_6<) zMZSJ{GgA^QD;>)4z*j5q?qWw$O^1Cl^QUhqk$>}fSeL(X@uwFM8a!S6OIqM8@H#L{ zbv%!-Pk^!jDn@IOj0OU}8_RnK^07>&_&bM>=Uc_IAH9>DL4W7>X9MBm{AZGXj}rqG z%YWYuZ}tmVQGkI3Zx$T}Rw-1wTM~fK4-VYmE#+5dvw!T-UlAm_1OU&xM%p^RuyE(p z)D(b)0EH8%v+%49`LY}t!#+iq_|KgoyuTffHDkz;aF---^r!`hL;uy1KbuC}yU^Bu zj19>hpv>-{D}cQ{=6j~=?JL{b#Ne+0YjjV-#|zl~?R|IwwSfP?-r?~6LyA+`s?QSus~ z30bHFGI-e7*n5%QS0(_r0h(P${Sm`I7uvWW0;(p{Wmzh~r1N1&_Lg^4)vE*u1^7|J z|6Nf37^na3c>x|rJpBVlZ!po>*}q=o~Hn;ir;`j;K|nSuRJ~(;svT z#qC#!C&Y=L>dDH~4YS+RwvxYwN@-f5CR1i78c`JHXT2V_W6`XP`X?7)yJO+7m<-#uLV>FTs~39kR|i&A`B3!2+juA1ZE;_ zTkA2EnJj$Ej*jJ1vYp*}!=L<%neJTp_H|r8YK0{(p8FaljVnXRv1($w6{Th7)o6C9 zkVnwSR8W4VZqQpfwBP$#(viqa2qiJBzF|$)2eDdGWb+Rs?x1j$sr<8K`FT0_uwXZ+7! zMky0jvJKhsbJmn!zSDjfQiUZap#A8vpFufh zz0m$~vx;2q>kl?PBnIZ?k-cPPZ7%8&MkH+!>iRUcp5cqX8Yb*JR9FiN*kdfkRFWco zs@_K|)1c>A62G4HEz}dc;U0hY<*2eQvcJ$ma9fsqmf4JDy5n#<1brnFOD~QVj^!cZ zf7we<9ic*?p|rYys8?rlDc%3~y5AOhMO#Y)&4f;Q_o z{33+;p%AG!PT#Qo`#G+pSNG6XzTYnFBmI*%U_-~I6yHS}ClgRoP(aSx%$Zu?s_9+BYC|Q5O%QSo|HaNDHxZo#|Kx_^H3YXa@p+!qr|`q7HcGZ^!e@>citrvb-ROFt3D#&RxgrDy&nO!;eJ) zb`6?-7H~(hvjsv(&8<&4WF@g~&JxQm1`=$gRu!J@;cX;vcJ#|Hk61l~S9~Fo8cesc2 z2ArSv$oC7*&`1*S8nHeUF8+{1pY9g{Oo0p^6s}2Why_> zsj^^$Th|YgPDAMQ_gaxU+1dDH%kRK0ufcrNlo__@noU`^Szm#~MFbmUJ(*Fb4w#qhua~p-IEi*e z3v_#=_mSJCe~#xcgCHoHV<^G{W{LVfOy~`Ctq$B)g%i1k#aBBj*{S2<`Iu2rVlw|eFuHOqVPLEK%9*|2km8YXV zo=bP#=HC-0w=4OEG2J^tg4Gf!cI&VZ!IQzBExo40NiDs>!b?_)+tfsxTo&PVao>x_ zRytwsh_Fs;&0-3BX~bt7b3bP@Yi@Vp9EIHO2OG*P=KSez6Dd?V+j`8kcpNnY7Y0YLi?~4KOt0`3#2|A zbh=Zg2k|_V)OM#6rD{2GRF(J9bUQQm_&k#AdSv7gx=U61@FDJ9_9MqUQ?Er+6p(-z zjPRJ7#RW18Z4tp7k`MOH3}(tD3@ufguY?iRF`B8E<|9p%m2?vFSZK=#p`dM{9yJ~%k$fA4w8 zcC(O|?d=VahXN#oZtil}w-K2H?g0sUTK->0Jl|dIy9gPh;*NZm0#ZW*#dbpxW)BwN z_UEgsc?FU{9dyyOvl;G6_UFdeH=dPjPeT#ojCK3(b$&frN`*k!U$EkIecm_hy1AY@ zYdA9}fM0O$tAu$&?X91K`j-}iuW`J`8QytAJj%&$6S5D_z6fjZkB!t+c@Z>`zclI5 zen8tf7hixZSyUF>Cv|3ad&61Rca2UfDmsn((nnLYaZdJ9q?Jg?_0&|gq;#IRiMmsu zH7Mcp8zjr)U&kz>yTOQKp2|umf}Y?*7bll1my2dr-Y1cLNwUtJBYp4JLtR^1*g(%q zM3aT{MS~dOqr) z8ov;#tOk;MS&c7`J2@`Tb0>6t#hs-vInv>Ah~${W+>9|k9No%jKs1NP2-mR`RTcN=nflq=a@dqO{--Z?fK7XW7O zYBKKHXH1KFZPY|m#4jB`vs6>&M!tzeLyApddsW&9{}#huFVF`uQnrz+v?0OYV}2P3 zJLr2N{1)}>6OB!}$CJ`P=%H@Va(GC78{d$ZU7Cszvmu#{D zWVwj&Yvep^1Z_oNEUyF-J__#^RJtLkvg}A9xmL@2_-q4+DF^7%2ywAhe9q(dLF+H_ zrdNO1xNPhpo`l)K8#&m84}#pEOa3T9Mkne<(ogX2;NeIS#;NN)mteL&2TdNMaCE5q zzQMNUDG;Imwx=1H@WvmZr738A7=Yoz_7UImS2xlYr!5vxJ-Ox4t>F}B(bvnz0%;TBwl#-Hk7xbu74Btd z?rk$HaLNchwJ)$iARqc1#KR~ zDB3GA~H(Zz{nTcOf23FKGRDf^-!MG`2S8^>k*R*qmk`SMVYEF(4m@xyqv z6R0F1{>zy+X-uBT9| z5TF-8jM*astYm1zK;c_kIZ}l6uO65Pj`axb2-A&Vx;KYJ3ihj7k%@fXXJzxd*&pxK zik?fLs#k{ttv;5$o2HASD#A+Naws>?$y(Ee(ig@CzX*FKz(TMJ>0WA&t$e}qOLdi0 zQRL$Rf5RA@h(w%>L9n|pKwx`;iWv6MOrHNo%(C-s)nlnbQclRDJfxN9yn^=cy$sDR(d{Mq*Fd zc6om@(W9V*Gc$hC9nVaSR@0ChU(pbOGk^rH~t=A9Vu#{74jNRs$qvPSucn1U99=fp#bj~b1{pQ=8V%h!*m z5&C2}vBvi(0VtH&2n|%tTY^_^5Hekm%z=fRGp!588THv5A@@5Rt@BTqq+sx6xR7{9YI;Lgd}Ma zv(6yqe$g?#)`h3c7v3@F$C_Nox&|QI>wcVqUN~+_QN#cLPqM#E95x!uSi#f?4 zA%ZY*DtIP-VnR9!gj2F7@wQ&mq#>V&IjN-a6B7a{z$kM)v?GpZ`uGg|CE9yR*jW9K za_+|lr%#96KI^#%JA4yAD1h^1elwfxzE6$sWt00|O#P;OmZYn!J>r>ZlaK?1)a{C- zZT1rN_Bs}MzyVKxVe^&NX*2|Q!!#W*ri^#J4{E!)GB{Jt#cmqzt`S}Z${)fmI;^z> zTlb$ebg0a}Q5w@b=qhLE2xvHRhFFU!Mo9&lvG~}1i*lETEz;+^#Vm@C7^SvkYy>}G z&k%0&s1o+#iO*i9Wd+kesbFFc_be-0e%ug~6g75%3z{|SePnXy1A1ryiIRiA7Y@^rOIhmQ0+v;zF+%1MWX_VsPl?VjA8m7a?u;M! zrh#t~>)bvZ7NmHwfATzH9F&>-2xKGPx0SYhc=V`qlQ!N4=OkF^1>bWOd1uYM6UwEw z43+iete%S$EG#(?Hb}AFFnNvic8d|e7#))TfvInpRcv_{p5R(#EBP~h`GXlfTWgDk z7VyTHYs8NFI?}$Pt;w(SJ$3ob8DU=foEP$QQvH5E)xM7CN9+Bj-pB22nKoaa6=e^X zu3DHDKU77bfmdK=d^X?66i;^k(1`W2$?C(CQ&0W#7oV>8LsZlQ#=BPFaskg}HsMl_ z$De-I4O|Vhc#C?GF1Bzy$1Mz$W9IM*G~~w7xoi}16>M4 z_hAK#rzAeZMjid*z+wuoN9{#vo)WXXUSlWWH~FS zQJ!&JoWc(4?aF6af?rtV`cX7kV>FcJL9sBdR5^9$L?sjzvSlwUev6(S)qy#(T+tM( z+TLhoW`j1N6g2hHagK`Cr6i#bmgE5Q1Y$~Xx+-KWN54Y<$f6n;R@`)Ch}w z7mo_^FA7l)b{5ZGI#W7ZYVN>_$>KNG^e}0pV6~q)K4*Qa(5+b_7&a&Lt4AykFZAFY z1*%#Xv$+2NOz!xz4dW^NZW(<;kVgxiL)PT`M&@Ce-FDl7ay!7M3SFswgw~>uvmVGK zRSIOq;#xKZ6K+0=IcvljnC<2bChBbe^_I``E`AVXhaMX`-vx3bz{>X#9+MJ!@h*tv z$Fl#LnnlsQjL^P1RSxWEg_+&fs7BOkG|Vbj4;AZAy}r1UpJeqW;aQ(u^2_#}t=`#y zWGLv#LAA@D*X1Ctb1XThw&3dr-rs!S`fMT&U>t81g16;7E+X4AkGNqsk|J+mAnzDfe*TgFX#kv(YMts@j`pgmq7E~V(Jg<(?>Pci=XoH6J9o3U5)1_p>2WYx?{)nh>bWAn&~nD zi&F(gK41$)8;p%wk&Pl`Zjzg<*&#{2(M4siy%nO!`~c=*j>g_5)c11KyNr9zSjm*B zE!c1@rBG*Hl!z8g%-0`{T$Y5l=+GZwR$xvye5FfYf2D}g_)7*~MjivGKS`Z{uz*+# zSbodTn>FNx8?L(Qs1G6V0V z;<(bliBhT3Ci$O5XOB^1aY#=aQD4Xpu{SO-0FWtl5rp6*-Sz&&ytD#}QqYvc=_q7T zBPD@2L3)zWI+)L}%PQ7CTerN?m361(;>Q1vo$9&w?d? zjT)9h_KSpWK5CCu?Hw*tjinLDx9q!ZS_gy;JsUpOODqcWqN05uNWxZ{J;^UpnhQi{ zl27-FP}KO6zwCieolyeNn+Nbsb5YNO0wOmRUd|&E09I-6*zUh0ju)y*qgaTDAI{U>NxFJEIuS!l) z7|R<(fsd6eo|-_B+6NRh(qla&+w<{;Ce^%i*t%A+Ipg{2?B^)2d9TS!@_BD40vaf# zl2#^rGpP<%R$9Kl#&7P96>m8u`Am-ZmyQ72-c4wp4$4I4r0cxfS2kZ zXlQL838`qXU+J-?o7;Ot_1U>+9&ujw-htNk_G(rYuY2wXkGgBYDeo1NgC%Ib#&y@l zu4EzAOVxq1`2?{Z$T8Dats`bSrL=oB>GUb1iSQ|WKv6D{gq`S$u(5j_{Aj(U1P7VJVNyH38Ja}{p;Gn7@Id|=>={zauj zLx*mWtlNgA4Uh6t4JRecr4iP_)l!3NQtlm*P-~@7M{L{(CSXi0wXjQ*w#*{g^=`T< z<;TZ>D;rl|Fr_IaEL&L8=E(&tZx>L04nICaSQAO4St)=QyE)NrmfXWJh{{fUCYiJzZWaFvk}VN{UfFdbKdxo zH*dln-FeN6b4jQ|4)YS*ZBpOOAS~KFo z^?D_L1)$sC{b%eUGKfvQaWAwW7ZVyUg90X?bhoBcD5p2e0-{WVF+Y zQ`+p=U#}b#atfy95sklwe|MVCTdkZqziDe}z6SWDqoA5T2fuQGmOP7%H)vK&k6bd~ ze^UQGmMAnji!(ugb^r_?x`(X2z6R##qH@2T`IAV4e)#-~}CSBH%ly&MbT{AGDV*^2hBw6W?+*-b#O~irg zcNx(EJs}$ExmNjp?l`b^Z@w;jf}_7NS-Q4@^|;u*`5JrX7VFZy^Wc3oHr*?+DAt^% z3F%}V&$v0gTR~y3w7i38$K~;P6d&q0m6{4&#+B1%M@h3s4&c`WYpQTpKHDG4DUstG z-5%WirI2Os%Vj=G+Z_+xTT7cSS1c`;4qRg;HXiQ>1}YI<{G5DoWth=z=2sVQT7}hx zyhP(1qhBr;kH;G1HhAQacmhUeRBYQW=RCOb@ZDCIhxz{bG{l3ej=D*>LS#;HkosrN z_l@%zF1myR|6#Qxw?tkj2caX^+b@E|7wwt?)@$iMki^8yuYL`(#JzBQ0q4Cw^MqdR zUe2a>fP8>nK@C$apWfSzZk9h2a`)<+T3a(uU?p|XspdKoYwPw4Y#P=AKG~;DtIgKG zD0d~pF>&!;jn{d56MP-Vlt9&Wvm(1~Ke}`By-vTn4L|qRgWx_l$C8E9h5fnpG~z=3 z>J(O;XiwSo{upk>3Yy7AHIlP|u?qSIf@++AYHArpHg;Mhy zI=m?!otT^q*5}WCQ$B8DZ_lA!s$Tz+lbiwruRwn!Rosp)5x5en6`x{g=u0 z{CT2gk++@+7u}MCh`Lqwy9-B#G+l%B66)02Y%U?v(M?%M8T)H|#G3iG9Q%vW*O6Er zrzS0}_-#F|zY;LNXXaDbcE`re(|0Er%b4K#V5~a289pfnU1z{HJ5Nra_5Cz-DIK7U z1gt6D0ic0&iyy+Gbw{@Zua3Cmk@axFb=;$QDHT1f$Sy>mrh#V2B$U4Bx;bZJ$j_Ct zhFYlYhA4Ja>6i8B7cmI_WjSB=Ib6SU!nov@Y@?o;v@}KS=gQH!$P;t!v}-D^)@CXU zA{HMiM*^MW+_PgF;rMa*7#@-jb?@Zl^Axk|>Hf@25;8JJUrG`SfFfT{^Ba0+r{}|R zFF4*k1CyX5(_6f@>*!-tlgg{QM=zDC zxD8+AmbdcZqx=xS1fAVn0KF2Tqk-HGet!N9D@vgIkH^?c>nyB@*a`dHp66@pI9>9E z1gEKHfo@LUwM4tL`{z$3WnIeIm$kstaoB|dJ-6?MY1W@U!oc1LAjZHf zhTOM~-)|!jGR31?Q0A{bmSD1Xj*cUUXTa?=f48-sX;8|4BqSs>%Z@@Kp8L9RngIm5 z8oFq0aCLAPLf`{eec#^OD-X~F$%6x^*D%YD1lm9WW>x)9@93!DfA^lx&)+o;_L);H z9?jA&g*IUtf_VOOjRme9wUhhlb^TpO?S*NqDM2bweW7}BWp(uoW)2ge)B$fdRu+{}KsJp-^oL`Va&XtNCEd z4i!x07Z7NuvNbhbfn_C8r>3L;i98Ma7gn__s(A`Y&&%%L5}*Bf2SbgFqj zZhmf~l9Q9ykMUacX#bs;0KZdh)6gG*)~O%2swLN3m~L#Rr>EaP+h11LW%%D7;5u;< zYy32uI5HG?s!O42;$K#^9Cp+>CQtvKMv>AmrS~P_^^4hmM0&&X|03xC7yiop|KGc# e!2i?KxT4m^X;zt!_MEyS#B&)X=`u+}-~R;#Q#``} literal 0 HcmV?d00001 diff --git a/data/one_time_setup.png b/data/one_time_setup.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7573173460eedb09eef86edbf8562c687c40f4 GIT binary patch literal 21555 zcmeFZcUV(d*EY_KgU+CWkAf&w1q4EG(!oZToD45HK_kkCPT3J@Xm5<~v^yFeSiPX1qml-=j^@LUT3eh?sYF->glMRr(>a`p`kgi zp?=?hhUN?d4b3lnzn`XlQX+xhqQ3p+byoxUJM{?q-R1@L{HnK#k+-3nowuKrr!9@W ztDB3hke9Wmt*xtEjxW#P;F4vJhCW;`hH(n4G|Va6rD2g&U{5&MVPFHj;|VYtTSJEu=r_!oLGy0 zw!f5~AliE6m#;%UdHFJb$iMdUjD|+=Ok~8rPr3CKe*1YQs{fyzWDcchKvmV9-{i++dYh&x&HG@G#Yt9{f!srUWDerj8CNs(mj*0|NtjM<(k1x9->7&3^sbaz9U( z`Xi`1k$>{ODg1R@Z=fbGQzG!|S}@m%dRebAkMv6}=0l1e&iZvKhrPVPeZ0XlH2z6S ziwR2Yb>C)!;kSww^El%HE?GtoEj!Xa|CJ``SAXX3(**Zt&CvgtG7ZfePb2F6Y25Xb ztAx$=?fPW@ z|A!4^sjm8z3d8_bnwYQ{%ce0B>#{SP-H=%mMbP^*zfrlq{!Mq^3H+~mb*TgK z-*&wL%@zOZ2S}@O>UMc}&AwAIQPs zR>*(`4nICmHZ`n8L*&VKI&8%0nnl+{=O}oKhJgGuX}4B(f&q1S7^-T0lcu9eWJJe1 z54OXNHqQO59wBWOU z8yVxzKL4?u8PH^82)p)|*v&Ojnxbn%K5%vJ8G7qQ>eFY&_)}rPe>WvlD}T2}|Jz=e zw?0EZr2xc$6hn{9sGFEa#IFxqB-6BG+GeYpjpXLcX_&*mOY8y`&c{K2`qWN9Lv=IF z>t~)dW@Fa{c{YWgL{SC%by_c&|GVD&r?mvz^xW&&nyYmkv!XG&gI`}JVj#8tTXtjF zf=vH$N66bN)-&{v;4-mX8dQZDlzGyzLVyd1w+gld&;7UM|7Swx4rcbFS+Ekl;t(2Y z8GiTr*B#DGnAz`lt(X7H_IB=`2b&s<@wruz2Tjs2TmWJdJ*{N&XwLj$#g7fq{l!1s z^8Ulh7vJ9y{r%Ug)cKxzL+5D@d3pcF|MlED@%-K3cgOyR)}Gw$4S=NzRDP*!OFP`7 z%`;WU*!M=ZnTxwOA2JWFE`$E9{}k8pLpE2fT$xAT9H2MS5i{4_Pg_-?R0ENGYqx2p zOmD3qdsl?r;y+8|d6raGZW8imW50V#lW3|IfH9!M&&>?f$K9=4eOy(0XZOj>G@a9} zw2{%#DEa98dlN09QddFqQmAJ7j$&s1EL zU?^o%JwyQV>(k4HMl0c-o}L|2KF@Jmo6pd>_iq%oJ}i1_sV|lWCg{A^ktM*POMmw7 z&c+fJ|Gem^JFa3#$tkJ#zWdVKIDA7G~R86jzTn!AZrgb}R z05GD-U54Ia&U}#Jx%ANT%`xSeKj{mD`Qgz0fUVo1+T4k+JC@koT(wwsi0L5(e~g0V zmI+QfK963^K0SaM?>U?Bk0LTO1=2)NeRT7?tZe9b9NZm1*Lu$fogcOy{bw;yuJBRI z(A3$&ysVE~pOg7kkYEC5&>C+E>sKA1aaZEwm@)fvwQO@ucPW|;zKkDnv5e8w(RVjh zo;N4%uXDO^boyNtKqk#q7;c)d(;g~TILXFvPJ(NIL$_fDD*i1}i`tOYskz)Mkggm6{sy2#>Qmf%!um#*x~v=S6B9DX4yR~1_SOIrF~`ORs)9j|&{(V5ynuels2h5I zgr&R$kcCCcXDU`n8WfrsXOuBUMTZvZL}EO>x|a#1}ses#_i2e z?vkd9I;{*z23q>4Y@H8~5039auj)emK(2Az`Jj@-@`6d?ZdgKisRv|r4PR~nCLQmE z5(7NdMx9_V)7qW6mzmyB0;e12d7ucK7`urcFs+4<6WPhzQ-!el-Nyx!no3xV-zk1e zP&1h%?c`~AYESv_RZvZE(Gv&GbM^{AoEg}VM{4BhzOFp9I{uj@77aANKry~=4vJ!; zt;9fcQFaY^+n+W{mruf0>XCj4_bXlaGh;-yjri4scAFXc+2sJrhZSzyqAt_0LU!NcX$<=n$l z*%PxR+2dNo%I{b?zaL6*Xe-jVS+n)&ni@W{HAe~;oTy%CF(E;#rMfKLi3^+RtcZ>t z^zF>8!f8(`jooTbQP>|a>v`|sGNh2=BBN;8=iFsp-Iykb^S57n zo0>E~0q#@3>gBRN-dif4b|zG0d248WoC}wb*gGPHBgZ@0bF5y`5@&5Y<|rxF?vYY- z_a288h%%4X6-swLk2SB7xc1%Kocf^Isj#h}EA2KBEg$VRSUn21pESUm0igX#lh44`9+4|6Fyd*%9QYYqrM03)x3X z>dU<7J-U}M<9p_smq96umYVR?rL|R*X-|(uPo4laF>|$*ADxKH6VJz)L7B3e9p&$Zhf(lIpP;!*(?cF4J1$T^U|L~t-VID>;mt1(%Y*V>VuOA*D7!1vK9lPXD$kI&%`~POj_97)MTv&a(^{_eVrkp24$j z_PuOrkhh5}*(S3}=bh(=K@F|c2aN)3{16oK!-2-rN$@8SL)jV<<14CP2J8(w+>k^h z$X`v%klU|($?d2x;LhFN4ye0EEGRS1-!Zbfvh>i3*xcQ(nf1cDHg7SfXId~l-IMo` z*PIMu`{2;Wl=i1TLv`LRY((aia%+XNvJ;hG?>*cfDD2@xY!OBrj&fY(KU4z^G_8F` zpY9gd*KfATS9pPZB4qbs5F_Iy2cvO2%Pt!2J}wXz=%ALTGk+vK$M(&tHKcjRVtM?> zvr(D$wjCCq-;89g{p)g!$fHWGCkaaH777YS6Gr-y@kQs&w^#v%x*gn$HJnO$HiehV zD-6qu9UEbJdLhF^Vw<&XB>*}QMJO;-qp*Orsu*^oGpvVq&2%VzG7I;uV|a|!TB>#b zG8q`mTzh$iU#|Y0jxqd^c0(I}Bn%CelI9?8mE5QMcOW4+)S0T#frs^lRvmDcQB93VgIF`akm0vpo=g4X zi(!*B39-5Au!?FVP0BJ{yz!2i#}r+|LXt!V(RZkbqbg(CIce8A_Zs|Acm|7RwguF-#4NC)bdB1E8DfQr0vD4K>P+>8i+m>PX z&B*$hv-WEaL4v$0t z*~xV*f)7L&t}dh}<`!}Bv#|+MWVwJ-RRfz8xuZTCnGc`u2e1Lo@xn-afr6!@Eoj1W z-+D&nvpc4%PsoOPk6WaNH zf0i8e!oGpoh138OPvvvCHISwCGFL~X##__X3x8L(_tki+ld?hEI@D65rX{T9-s(V8 zXO+j5?pB#4HBLMTp<*zGiam+9zGEj;@q-LHdm)LLM58tdbX#^+woq}tXl<{lKWf^sQDx zVHp4v>A7hO7jIk|($Ti)083>dR8Li~YM;l^@`SEyZN=>tpO>{#aYYqr$`%3{(WB6% zCIPMGA*an`{flXKxU19%d-2AmYlFoQHSFinxO0K;_g`yDFjNpIq=EFHXWF8C{JF`{ zukert%%hMz&3vSpCJU{L)M2P&;)MRzyO3fhLjJFCb6qAZAFmYnqaziRv~2G(MYA6n z-LM4vA40~1%?xWUw|9)PFw||D2Fu1E>i6SnKzX)&M>S=U%i zU{HW>#Y&!=tKwWH+uR|ukWz*N232+R$3Y%?`m)s7Jv}JEE)X25EM&!U`}iTiB1__I zX5v^0CTK=NU0~VB0E6O#2V++6W_J1m z=SOx6+KY^-erQpJ53VM7d@OX=w_v<~d0AC6b)1)%A`|3d-{j=Rxtc81uD(3K-`^A2 zsnFmz?(9~QR*`4ReN`Yuj5VCyYq|IAmTSpQU6O8R#<&nJUV}wT9PHUuB;rizR;a78 z9!wZ4?-JTt`3$!wcU2U}gl!pX;3`XPOO%7GCX^an#bLwMJC8;-!)q$6t{RWdPcPfg zA5{q9#2P}{I}3(uD(o#nyY(P{&dN-#1bZ8s0Vld_#7_Y7lI7Hfh6ck)uieI^o_gl2 zmDD_&L0xTCw=Nt-y0cqo;8wWg9hvNAp_6~0rE%VzSi!9KIQ zKyPcU<(^lt(|D1wcp1zt*sE*6L@wsy0J%WR6eiLCkJ?EjNFt=Vj^(90bD7)9=9ejFN*UKum_;~Jmq%G|N_54i#JG6P_I6y_do1_p zBwEOm!clBIqN;S=Qi^x-N{jN^i`>!zMLHweLbgYQwjRxY@n&0gy6LFBbvz$i<8hpl za(KleRXz<7Ut!D99jw%5Sr+zKuXNw z#hz0fUYY|Zc7l%`cBdT|GO}JiR`Qp|2Z|x(_NQI*oC3Kj#;|@9Sl2nsCo|ArjfJAf zpnd0UBo?~X=nawHcK)areKw**@&{B)U;HjJg60X)y_!7jI5T3{gWGUZfs=ocDH6Zw$gGJPEL`5$SBg*Yl~_Rx`Pqr%(xS-vCPZ-(wr zvwN=@FL%l1Is8E1Er+P!D~5>9R1Phn>Ms?6e*Gx5tDtq($y{~JtXE%`i4R8L_ z4?Iaab~ityI`+SLM0k|sd;{RDulVt0IUrTL!Ec38m$Vt!W3z9`H1?a_&tkrz*P_7( zf;ug7hQPb-p64M71#hK(QK|{_ZBQR$c5sl;j0zXSl8|rwh;xpa+=-J2p2HYrC6Y zv+|XDqN|gpOQkL-Pm*Wpr*Y8{_rhVf>I+hdW@FQWaj$u>`ywi)sdA!%8RRl-L!gDG0E$0A6;f%rMq7KUHpeCAZb#qki!UU?I-NLdij?97m0shlLotH0ODhj%3bT^PE9Eeo0- z;})sNBbd;R0q#hB`SVh6KzjdSQ+njH4ZRGg<35Ke%3G%;65DieX;lAJ!2%$yk_sZq z?!llL*{z4@^!s;*p`n$B)fk=7oM_X5jXm`&aeP?MIAWBJ$=3-$V$XLr^(E-z$AF=N z{3~cMp+kecbr$9GsC`)7s_Hs6S>7Q@<`WmBNYEj0L}e8-U6A-1w<*`=doTL=k|eb) z3>r!8T?MwIl`G!hk|E${l=LpLSd|h}bXNsV+W}W?j%Bfh3_CtJBin9>W9?=nQfm$gA6 zK+fPJ2xBntp$jV5UTS|T>RHKtf)qS*uZJVcWwcDH7ikER^#r1-K)Nvuk0`75a3+BA ziU0_OG1uj1`GN+A5_N4&hpn{MBop=PiVh|@o$B$$nhj_(lgPLD5g|+En&9v|$6SH& z=SfLg`}s+IyN4wQecpRSBsSG_VD*lPDIA^ZujcFh#cwC9w&~u^C`qfd?PK9)uw{eA zI;&7(#+qq+9WM#wq^w_RnB+&ERP*omr4Ip!I>YCVwnbEyM>m&1r2fj*uvnAg(fv}^ zPhe?1mw33J{bH748nkriX;u`?SMFHWl)Qyci#?1&UxK`m-M$kYm# z*C(0}gFs}N96!3CcBbr^&T!ElGR#e(^b3oR-WlM5a$?VsmI-<<^4j&SL={-YbhcK3wfaX;qz3DTCOqL!l0J*7;W4V*FRA zvU064V|lN_zuHvPRG!=^Au;N^)!mVT5aG0tFb#iJv-^3+nc0mqB_l6de5k8GH%z3n z_@4ec zZQxS;`gfg%Iwz(pY9OKr8}T~b&JBURwP7KgWBaFfUnWu-oSanKUA8`dI-ezm=dHWR zf3td%@iCr5dDdh=CJx!$m`Pnjii~PySg+pEYL6o1S`pG?k zQs>307Aj6EDL*Ol9VfL*!M%KYbWoPz2tT|%?rUqO(WR2^sWpC04-*tLe=qO7@0<)w zHT&(>$3*@WEg&EJBjQQBvs> z*QZ@6eN`1Ka#lWVxCXsMs-W#XH}J>AdqUD22Y&i&Ym#>dfJ51e5TAgsA%QX-ojTeJ zY#sA@zqtR!&&0}3d&gAb(!HPfs39VQT>yC*6e4PHqyx#&-2EuUf*kiRX-~x%DD^o= z%I%66l*|EgA#`#JWuI=iFGkn7&{FyWP~w5dnq}jWnyh_!lVHCPSwcPUdeBV|Etu*Z zNb}1?p+G_xcTKq_Jm<2lu*L`Z@P2p-pGu(`h<(nhW5jQiPZ{6W>nW>MS<2{E`fOZlT?aaMH!79IRuLVF@H|2xF zvnuqbjlz7jNkL#o`Rw~QvhU9XQr+d_-qi(rwpNekr_V3(!@Dxg*2LlP<$1VPr~|4> z_hP=; zAZjn?X#jiMbG$)F3Q&$ll8m!^P=R)W6z4}M*#(Mv^!Ght76$z%{8 z;|#s6f1a5XC78)nyJE!LXZruv{OF9xiG>eBZxhh2thKWajL+fK1Ob;UXCH z?(I!X?l?VG%2w@dIz>!8%>H$HuWfGwr@|7)8(;}chii5zUr&1Ls&>y7eNcRYm zP(nrhPrUSu8#U)9G(PySsqSXj^ZE(=uFq??Sy4}WvP@L#8I`8a*tH4(A@i~p0FwZj z-z1QfZmE$+?@uW5r-DDb1opB&)IEC`-|EH0O;PY{-jHdH@DThoRH>`M#h-5wHBy*Z z#_f2p@fN}@q>1Q#oO+6R?!ls{w2owEooE!c;~-8!X`DG!DQkd|L>g}?u#Q#=jmA9t zyVp+5#qR_to{$D?Yd#t?VT714u-5GT!`tkQs6n?zqzoHI*&!Y8?Kl9+?d=co)FOw) z)~DRfE$;SzE*qSz$PwBURB<+@A55s^R>9%+>2-r|OvFE1yPfbrCEuEP_rWaXVi`X!)r;Gn^HNfuEXQB4_vNFkD_v!Og6jw&} zR1U&uZ-M+?2sD^gX!4muTtY=w9tS=Fb?F4kO5FC4^QDoQplf=12`$ z_E2cw$AmztG!i#k(ghm~s>ZWYiZ7ivg_citmdEa!?~oG+%v(5|O1C&(#)u-r(FMR7%c^!lJq~WR~AAOWX%u z*l^KgQe>j$)iMg?ylVW$T+oMgiBuzE@wpZsn+5^*ZB=52M?H{W9Of{5J=I~Vr-~Cb zdu9Y;;JRVmp)N;|tCYM76}3#0N1QTkG7GsX7DJd{Z(m8cv)_05?pZ!)4wU@9b6G< zdw5udKd8k5Ymf#&FU`ALh2KBaBgnT|1ZJIDM{KeX0RUNkm0bKt7ve~&+o8=Zoo~dJ z3Qem(n$f({E=~%ciO#!{#-j!e^Bhd)nL{Ile&4vEoVE47&d{n6tA{X?CU*&c=XX9y zPGO=tc%5bEcoN!^AKdhs51CLL5kuJAa&3^2+uh!;rMhS2_V(Qf>?&K}Drth<%f+eR zW{{eeinc9I>1;&|H*CGD5Ar)07wKvq*T&fy->gB1u?~?t<*lRrDV<}ZLdiQ+__U*_ zn7MPUp>V!fYRkr~uTs%ke2ulMqJQv*qv_aTb?P1MI@fZmTI=y{m4a6>?mhLHF&`D`DjWsdZG1Tz zLRZJnZhabzcx>ak z${6eUssbUFHagVRP>4%e2+jDX@6E`=-gp@QMJvK%f4M<_~E-LkQv z#uqq!YGf}FEabIPvDIGJhL4yR?oj!WO_|a=p%e-~EV)SKYdTI_7#a!XA_Nu+@tfqk zv`m+i!}F#6WZwP{4SaWJ-+6YQxxe>7eR9^ zABY|TsZ+6&amW=vnIs*)#`$IP9Aaq)Ybx`daTjadb8qS%H6N`OtXOSspj7l;zz!a% zN;jfi5olmnl})IU5<5+!vjCivmLnVj4f8?3s+o7}z4`yD1fX}EUB=xO6{?!Pla-a2 zB^aJElx{(Pd%9-nXG;zy0w5sNEv9I%%{3n)IZCsIor^~BUxj^OiiydciXs!`{V%Mq zkd}ruEPTOTkTk;eZ^q_PYv;WwYXg7(uGo6Jv8Oa|Z2vMSl>!dzzpY9diF`mY<1+E} z#b<{MPzl1{zHz%R^1mag?Ek^}Ji%P4zF$Ct#aDJ{4O^OtFqLBZH$L{Go_|()(HFVm z|LJRzm^uuB_vGM)fE~@RER@9j|GeWjhIi44PW%UlH#xsL?mI!-(?8ztDek8lUHGS5 z*KZu#bEi+OuCHVC_};P8Jz+}dAkENQ@l(@2f8+3eV}#q2zS3F|R(!Fu>ae$>(NgqN z;&q;+$Y`-KHLd9SvqhJGV)muZ{NJQ|^7>CpMo?4+=jl7wsEqa#?rq63AYT2121Dgu zSM&XZu}|m>KX3hJ_@5S_XiT=Szwt+cF#$&hHB`uYhMx9Kq~onLmbf;Lh*EDVlJ++a zzkt31+qu)!tmap?KgqME`ks*{bp-#W9E%`?zAG+uEdN=$fPx!UdJi8^x#0nyr|wXv zk~GK}dXTMryw`I=L;sV?2tWVx5v1m%zpFts*DSfFQ%O0umUK#;Ciu2ZPx9&l3VH?x2=(D&E$DS{kYOv4i*`CGQ*ruH z^H2otzG4k#e`iarE6L5}8h>K`%M-VM7t^@jEcma=_McT&8k5CxPcRqSN`odXeXh{B zzT(#K4hkv?B(D|AB|1@6=>O{THySetmE`{ElX{*e%@?O1O9qZ|{Kus+82TxIjd4Lj z!X+0Mmtr|a8tLfeS`7WP$&K}2znJ`hs4;Mf)@0Bb594pWNk4?pOr`z1R3+`@|Lia* zIKwF1Oos&ZBgWH&o>C;5o65=q1HE^O3*kAQvTE?{vsFW}HVdAfPQ%1ARnSn3SrTe( zJ`u-N0bwUV28$8!4kkuFF#8`T%SJ=ZbfU~1;WEimYWnfQckT#^A7 zTx%O0^qpE-4*`5@JvG1QN~C7xJ{P+S2>Adov5$5FR)bfi&1#6ZyU}6Bf2ir>avg|P z-&)gHHpN`=PcA@3i(%+z*PXVR=1(86;NdbJ#b5APGvTTw(GvE}waH<<@$$kAbn}}S zmG6ZKM#Zf93iV)B#fs(lgRzBAR(MU`9;4^Y z1iWZlSW)5%(h)Aa`&Va$7@P>~CfQ_F9rSFcZLX%TAdBya=u5eS1V5IoK4X&xRuKD# zVWUWPLiaEo3}0r)SLM**>$LynPfT`M9{RmNs6(OAE+hDoZS%0UZYKLYI&%j;$mOqd zr;<7p1gY(O{#khmy%8i|a%Be2g^A5?u@-W5q2_rC49bT!12%Q@lTo*vO`8SvdH666 zx^bnsS{rW z!K3;QW=^BIQ-o73lxzo_FqiiLS;JL(V-l&Y>(Z2^DknN~HClPzI=w_zU}BJw|0}zP z0!adx%59JEdlk8FZ5od!kKt()-SHz^!NU#Uafa#USYuDSPxAu}snq#ijVxn}L3{d( zwEcMK$8{u!zh}YW?a~ziS6`7JXSLN&vmT2Bi~)s*62VWmQUGS7#e$wJ$&`&_tFh8vRg#|nraWVkj11U5Bqnuz zG2-xnuO5iYk>7EE@p2&a@JmBI(r5lzy3i;>as~A-6(}FD0gk4W71t^o?0>0z3ze(U z`_vLSn4eId-wkuZj^`CmCPFSmWF4>YjAkB;I`Pq^v4s0n^q2Jcn&S-=4>&FLoo+%k z`b5VeW}MUv5eWOd-*Nf*5>Uav>e5bR_Acv76ODUPli4^_P`2un{!SVhw^{6AH|QzBrT%; z^`&;a(}n^fruA$W8AFITqRRw=a{%7em_Mm^<(4ELqPoAmCc{Dmz^^Bh8ngIT@xZ!&q5e`FbWsN8@@lB4 z!1bK=wTrolcloJ#P>k1&Vm0)^`f=`j)2Y=W4T9V9QPWfU5h;KBp+<)iR$t(T!gxrs zrUht+TfYz4E@GoOPkBHoU%l^9jm?A@!hCni#(_rfx3}B$JeD72p-)m)gRjg%Ku-QK zH-7C==x>!}3&#dP6o8H_b#9laY3P$0PuEbmFNWqn#K{dWv?ddoep6oZ@Z-kz>Gh34 zR%}KX?ymYpuw)(S@KH9|7xPAYAGr8^1QiO9whR#6OgC|{eahUtzXL5UFJIH2)9t=4 zjmD%X7~;hCV!4%1Z(^brnqD&rAa{V#P^csaa%ptw_`pqN`sh*UnXkI{#4W7}?(gH* zYy?O#6`AM~^0%jVg+~L$tLP_mEd!l6oJ~|=#*JHj^~!bo6lObVk=zPJFPY%QuEX{m+aztPOcZYN5dYsrinOFXVckZWLZbQGG7|m_%GA4z!V|XGvCUBMC%{Nm!jzmeC zZ|bfb9;tD&=$1NKYA&S~sA5IC^C!lnSrMHh#bM#MCKN`bOh*IfhewBvsAT#&oIKQG z!dx0=TglNNRh?N`S$Ph%X}Z}uHkmv(Sdn3GcN5bfFIuH3URK$;2w59XaG^$fX$%v> z<=bn+-EYg98>G14)a23FZV~&|qy3$u!}iKjZo?6IQHh48#a$lU28zwAq-wqiVN30f z;?_N%K%OUM)C6rl8Zt^9pTtoRLn&;#M;}(;HYWjb-Rt&R`?%(mkcE}VEcmigYu(;M zVU4t^`Ci|Ufb_|%(_*U_#CEC3dNRzWD8v5j-eXk1%mR65Tmom^uD(};-))esmf9Oz zXUoLz62>O~im!08NcTT(u@17gSeY+89CMze?Dp<*D-{RJ^jJ*rUv;!DP!0@r?s2U<0Imub#Y4Dl!P7))#bo>ce|bbNio*> zDBT6Gf4c(l5s;gPm_w6UDa&l>zK5bRThcJreZZoTV_=9*_4yX2_2wtE8ZdLjvQeM= zt0r&0JF?Lgjxq2`If?$4F@5(}tx=4voAxYw5Bx1XWTaht|6r^|4Cuml7Y50XS|pmU zs%j=w#)1%>)MV4j@$Jof{{D+qI`*z~Qd+Kz9T|!=n|Ce!GmxW;I;zSaGtsNDeZJZg zDL!hs@oa7J`K6~D_O4;YyHygN=B5OAHA@iSh&~;|cnL}^6A+X(u3wWWACrO7dWr!V z7-g`=nE%drhR1OXR7k04<%lh5A-2-cT(UX&zW|AqhA|+63$%bvm&S|5mL+>3rp0SU z2xbA{tS;Wl`ol_k21BWN&l*x2UB<8--5tIj*wLqg1T%XI`aWwPC%e?B{Z{Yo)x6wG z9S~b3RL1P18eyv3(rjqaty|W!Y$~PL`dFf4*G@|QZ4aYl({a!+O!7+5;J~=QvVnUg z>KRudU;8Fw7u!8kofe*0_F+S;>$415AokQ{@_SOq4-3EM~a^_M*=#k-Z`Y~l170Yw}blC7&AFzH) zc#UeIA>47>W8}3b@*_@C=TdNeiM&A-vA1-PsTD75C|}M7A%&lgOgM|0eLBDFsnV8` zcEjhDg&W^u1xHAu&GGSaWr$Mzz`A1zzpSnOb&fitL@vjV%3k&RC>Hp`edqV-R8s6o z>BA@G;|2Se{1()1iA?uZl2L_&`Th>CzmD-8GZ5DzA0@$FnTcJ^D=DF{e?cgYedu0p z?}zE>X>@b7Zw{XUqYBjp3qo+YiJ{s(c%@mlDVCU#UP!3uFn(E3Sg6j{ILQ&8gpx+k zkv3-}iQ#2IlL@Bj+S%nx+ek9gDr}qNPi;R(>()wwByrt8V|F3*pP-;YHS=A3Xg=<)JR3O%-n5s9EGjq zM27DT@jAr{|5YTyIQt5Fqz9XQZ!Dv2zULaUyK2FwtPDozxFPj*9p&_z&d&KiRS10L zD%U`={Rm2pfs>oP+yH>*QlML#`>PvdPXay%YOYZy|I(2^(BCpRz^prPl$q*le_hg| zLBH?*cy4Yk@w6C=PNZ4Bxgr#dV4NwSBeg`KnMa=Fitd6GHHlCLDma?2kIoAgbQuF3 z6y}~4ex+x0F+#CnO4g+MA#`-hi9w1bhR5k%poY2rMtuXIJI0Rhy|AG1knsD;f>q7F z*To-?@94%2l~+_@xxGp0cx;`>v1Oy+_z1D3rdr`a?b2y&DHuYoIAWi)cuxbNnHCR? zc@CIZ;SEli5eB#U93MRRQn%#0pr&srO*`BXX;9b_8x?(xa)ax9gmrNJA2x%JboM(3 z)e>e5rzJ*=@m)O9D4BS`9c?vbUZ^dIXoi~9NsQHs6ll6T>9e*gT-N7aX5L{jNLDX9 z3owGIHiy3*C>-SkIPnJTFMsKD@{f62FcbC8m$rRBK|5N9+*mzVJpy2)OXY88QlQPu zUl@k0sTfqK``rJk2EW%uDY%3EOI zF?JgH9RrnwZY}^`h1zmb3#-2_#W&af^2*!oUmxBfy-7M|x}|^4nwDre;8;P#0)Y=q zmkz8PahF4LKKT5iCHz4r@;R3VEt8TzvHIF*WnSrA_0xkr<4@g_pSN!ujoG&M>Lo0% zC!Fm#%*!4uEe|Oy*0J_Y9nwGc5_Sx6Oz#-=%uR(MZ#p6^q(LK4bZ-!vGYp@YkCsVt zKXk3+TTOLz!0e_q;DVbaRd5`!PX-Y{bXmq`ttSO2b}J`IV3e(Vl5X@`05PA zHf!zJ!GBVo4Z1rgL|{-fR`w-!aaRrLLrRwV(|`(-@FjL1wbFDQw6dV?)8m(1_DM{@ zG&(fwd9Y6%YDD8+*Mc(tr}Mof&4SI zjK8+rv6yw$%4pKd$SbDa&*L$QE}7f0er`C}K=<&-sEiG+ENgDA?^<&WRajo%Zpzq&KED%xs!dMGbD3ATHrx1Z%K$TfTLA*^Xi!m|UF!=~0(jV)@dmR#P&zv_}8 zB-k&+1T?fPl+o8}rfN$qc=o&+G7Y*s^-4M=r%XZKrGOpCRIJrlVXBEkn52|nZL3|G z+NCWFwo^8&UN69SdAo7EaU6E7I`a5-IJmzRimx_Vyt`@UHE)`|Ejpx5ABaQT>mS%xjK%}%y zOehF9kr`Z)t-3TAM6Hs7j&}eroTZ!5bDAxYTdg$7xI{WM%JxFN;nk6YR@#Y(#FZgT zusrZE24=n<`;Mr4a7pk8(kVpx%xdJ=qdOtiN1kLOV~lLo(O26?BArR_V4$@Z4dBI_~9-^Do+>6PBp15wiv~!wM^~HATQ-TVFsJy2jBCmM;Nrw!$ZaAf@B^OxS zU23yOSHQJM*OEiWg2~#kQ+pCq3%!YLd{{^8|CCp&ZHe1!l#|M(a2c(&5)i z=qngm)T2G_v|rdySm3BkTe2~bJvWyw%zA!c*>))yX+S>^*#SUU`*hbCw*o%h2=n@; z$?g*4FC4XIWf1EW4E;UV3KUfSLt~ce=4mF-4P6y&;dvhAg!!WCEbMjIul{3u+O}QBaX;kG~e$B$}wczEL%Cq!)-ZfCX=3`y$2(N@Y!$Y za-7cG_sDxAL>N>LE6U}Tg=tm+&tqp2n$SENIkU6Y<8^*+#B4JGBGiX?{orM(jY~T_ za84~Akd1lk@Ja_)QrLzVTpwV}3Q=rOw^}UasB(%-t3*>LX9Fd&F2So3kBbF_vW&LO zbby9t>q{H`>PN_&k0Ko$zC@_64aJn8+}J4*zz#~KK=+gvJw7>JXxn5*O}g;=ADQe@ zi?prn=h=CBz!IN{nAXjx%IC&8shY10(9)$v zYsHvTD6syNdYGhsuA$y*!@mBkg&uj`Y|Fl8aL(?_;%hPz;Z>{rpYs+pa`0>|_6u`s zK+@4?vytFzD}lt~oP!VW!)?@Ew^uUsBqkR}Ng(2;W@eUyOX2@%=S+i|x}rFqf!1{j zYO9q+rwUX@KuSW`WOOVw2nbXxTf(N0Ab}W`gb+{yW-w(WsbX0}uvHd;1P}}$OM-(? z5h4{NlmrqG6Uvq#0RjY)J|<%8w@#aT23Ywy`nYZ_MgaCL|7@a3Ix1 z!_a2>G|Ccd&;?%UD;*k24i8qJY?h8OvVijjihwUGt5eUSM?^Y~{NLf|)WlXOzCmC5ZgP|`% zyZ!s+%d&N6h-NQIGnFwU6y?3qF~{<4>v@a_Y)^A8;hZbjNGZPRuZ+R+&YIN`5?7xa z#gp2>wFx~pAzkz9Lfv>0A-=%N5-1|UEEQdiR;&%A%WX3lY(XD9rFIyOSWT8l7LmQguNltO4{r<3pFib9z-fF+ z1>!l~&B|-$zTOS^(*+Z}vJ$P%8BAcgjm?=)H5}VxCFn33J3N8&^9Ckq1}Ste>UkP1L7& z&=CBul9_i+Ldb4s(h#?{1hMHEDJx+fC%n+}lf~Mpxkd*FgYuC1o}QkM*lhOHx4xC1 zRxXQs@o_H~-IE<>l0qPdN9hwynXT|r;jCMh(+|e;9URjLC4HU?vuMph5By>%n4VuM zdhqi5j-MK;nSnlKh*#j2Z(Yi%NUNLL=C{fDse#+Q&ZjsTMWBE4 zYp`2hNGhAT7dUuv;ZSO?)ShNqE|yo@(6ELM?~oL2P@D28f`;U;cj`SMuoEX|1-Fg&(@f| z6$2H)+!R)Od%F)sXY@v-jiI3)1&G8189*7sD>U2JczY`SPum^BG6V3taG^xPn< zr-IyQAy(pXxMCX*GuIMtSK4?F6Jo5lxVkuM*|#wRA)*S(k&pAp;#ZtNj=%JeSBg`Grfv|EZW+RrN#dgbY(l33&3% +typedef uint32_t __u32, __le32; +#endif +endef +export LINUX_TYPES_H + +ifeq ($(ARCH),arm) +ARCH_CFLAGS = -mfloat-abi=softfp -mcpu=cortex-a7 -mfpu=neon-vfpv4 +else +ifeq ($(ARCH),aarch64) +ARCH_CFLAGS = +else +$(warning *** warning: ARCH $(ARCH) has not been tested yet, use with cautions!) +ARCH_CFLAGS = +endif +endif + +ifeq ($(ARCH),aarch64) +CFLAGS = -march=armv8 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else +CFLAGS = -march=armv7-a -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +endif + +.PHONY: $(TARGETS:%=musl_copy_for_%) +.PHONY: $(TARGETS:%=musl_patch_for_%) +.PHONY: $(TARGETS:%=musl_install_for_%) +.PHONY: $(TARGETS:%=musl_header_install_for_%) +.PHONY: $(TARGETS:%=linux_header_install_for_%) +.PHONY: $(TARGETS:%=nuttx_header_install_for_%) +.PHONY: $(TARGETS:%=optimized_routines_install_for_%) +.PHONY: all clean distclean + +all: $(TARGETS:%=musl_install_for_%) + +$(TARGETS:%=musl_copy_for_%): + $(HIDE) mkdir -p $@ + $(HIDE) cp -rfu $(MUSLDIR)/[^p]* $@ + +optimized_routines_install_for_liteos_a_user: musl_copy_for_liteos_a_user +ifneq ($(ARCH),) + $(HIDE) cp -rfp $(OPTRTDIR)/string/$(ARCH)/* $> $ $ $/dev/null && \ + make -sj install-headers + +musl_install_for_liteos_a_user: musl_patch_for_liteos_a_user + $(HIDE) cd musl_copy_for_liteos_a_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + $(if $(LDFLAGS),LDFLAGS="$(LDFLAGS)",) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +musl_patch_for_linux_user: musl_copy_for_linux_user + $(HIDE) cp -rfp $(MUSLDIR)/porting/linux/user/* $/dev/null && \ + make -sj install-headers + +musl_install_for_linux_user: musl_patch_for_linux_user + $(HIDE) cd musl_copy_for_linux_user && mkdir -p $(MUSLBUILDDIR) && cd $(MUSLBUILDDIR) && \ + ../configure --prefix=$(SYSROOTDIR)/$(TARGET)/usr --target=$(TARGET) \ + --includedir=$(SYSROOTDIR)/$(TARGET)/usr/include \ + --libdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --syslibdir=$(SYSROOTDIR)/$(TARGET)/usr/lib/$(MULTILIB) \ + --build=$(BUILD) \ + CC="$(CC)" CROSS_COMPILE="$(CROSS_COMPILE)" CFLAGS="$(CFLAGS)" >/dev/null && \ + make -sj install + +clean: + $(HIDE) rm -rf musl_copy_for_* linux_header_install_for_* + +distclean: clean + $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr \ No newline at end of file diff --git a/llvm-build/OHOS.cmake b/llvm-build/OHOS.cmake new file mode 100644 index 000000000000..df2c08ce41ba --- /dev/null +++ b/llvm-build/OHOS.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(Platform/Linux) + +# OHOS has soname, but binary names must end in ".so" so we cannot append +# a version number. Also we cannot portably represent symlinks on the host. +set(CMAKE_PLATFORM_NO_VERSIONED_SONAME 1) + +# OHOS reportedly ignores RPATH, and we cannot predict the install +# location anyway. +set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") diff --git a/llvm-build/README.md b/llvm-build/README.md new file mode 100644 index 000000000000..ded1748c725c --- /dev/null +++ b/llvm-build/README.md @@ -0,0 +1,126 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and how to build it + +1. [Build WIKI](#build_wiki) +2. [Function Introduction](#function_introduction) + + +## Build WIKI +
    + +### System Requirements for Toolchain BUild + +Ubuntu >= 16.04 +MacOS X >= 10.15.4 + +
    + +### Get Code +``` +repo init -u https://gitee.com/OpenHarmony/manifest.git -b add_llvm_toolchain-dev (not ready yet) +repo sync -c +repo forall -c 'git lfs pull' +cp -r toolchain/llvm-project/llvm-build toolchain +``` +
    + +### Toolchain build process + +Here is an example of starting build process on Linux or MacOS: +``` +# update prebuilts, no need to run each time +./toolchain/llvm-project/llvm-build/env_prepare.sh +# build +python3 ./toolchain/llvm-project/llvm-build/build.py +``` + +1. env_prepare (one time only) +![输入图片说明](../data/one_time_setup.png) + +2. build +![输入图片说明](../data/llvm_build.png) + +
    + +### Options + +build.py options: + +``` +--skip-build # skip compile and goto package step +--skip-package # do compile without package step +--enable-assertions # enable assertion when compiling +--build-name # specify release package name +--debug # build debug version llvm toolchain +--no-build-arm # skip triplet arm +--no-build-aarch64 # skip triplet arm64 +--no-build-x86_64 # skip triplet x86_64 +--no-lto # disable LTO optimization when build toolchain +--build-instrumented # enable instrument pgo when build toolchain +--xunit-xml-output # specify LLVM unit test XML report path +--no-build # optional, skip some targets + windows + libs + lldb-mi + lldb-server + linux + check-api +``` +
    + +### Output Layout + +When build successfully completed. following artifacts will be available in `out` directory + +`sysroot` -> sysroots for OHOS targets +`install` -> toolchain build +`*.tar.bz2` -> archived versions of toolchain and sysroots +
    + +### OHOS Archive + +1. llvm +``` +contains: +1. toolchain which provides clang compiler, lldb(-mi), clang-tidy etc. tools +2. libc++/clang_rt/asan/fuzzer libs for target device + +OHOS sync from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ +Which is the same as: out/clang-dev-${platform}-${arch}.tar.bz2 +OHOS archive to: prebuilts/clang/ohos//${platform}/llvm + +License: Apache License v2.0 with LLVM Exceptions +``` + +2. libcxx-ndk +``` +contains: provide libc++ for ndk in target device + +OHOS fetch prebuilts from: https://mirrors.huaweicloud.com/openharmony/compiler/clang/ and archive it to prebuilts/clang/ohos//${platform}/libcxx-ndk. This tar is + +License: Apache License v2.0 with LLVM Exceptions +``` + + +## Function Introduction +
    + +### Functionality + +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 10.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
    + +### Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + diff --git a/llvm-build/build.py b/llvm-build/build.py new file mode 100644 index 000000000000..c2dff3deffac --- /dev/null +++ b/llvm-build/build.py @@ -0,0 +1,1999 @@ +#!/usr/bin/env python +# Copyright (C) 2021 Huawei Device Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# 2021.3.15 build for OHOS LLVM. +# Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved. + +import os +import platform +import re +import datetime +import logging +import glob +import subprocess +import shutil +import argparse +import mingw + + +class BuildConfig(): + # Defines public methods and functions and obtains script parameters. + + def __init__(self): + args = self.parse_args() + self.do_build = not args.skip_build + self.do_package = not args.skip_package + self.build_name = args.build_name + self.debug = args.debug + self.no_lto = args.no_lto + self.build_instrumented = args.build_instrumented + self.xunit_xml_output = args.xunit_xml_output + self.enable_assertions = args.enable_assertions + self.need_libs = self.do_build and 'libs' not in args.no_build + self.need_lldb_mi = self.do_build and 'lldb-mi' not in args.no_build + self.need_lldb_server = self.do_build and 'lldb-server' not in args.no_build + + self.no_build_arm = args.skip_build or args.no_build_arm + self.no_build_aarch64 = args.skip_build or args.no_build_aarch64 + self.no_build_x86_64 = args.skip_build or args.no_build_x86_64 + + self.CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) + self.REPOROOT_DIR = os.path.abspath(os.path.join(self.CURRENT_DIR, '../../')) + self.LLVM_PROJECT_DIR = os.path.abspath(os.path.join(self.REPOROOT_DIR, 'toolchain', 'llvm-project')) + self.OUT_PATH = os.path.join(self.REPOROOT_DIR, 'out') + self.TARGETS = 'AArch64;ARM;BPF;X86' + self.ORIG_ENV = dict(os.environ) + self.VERSION = None # autodetected + + self.OPENHOS_SFX = '-linux-ohos' + self.LITEOS_SFX = '-liteos-ohos' + self.LLDB_PY_VERSION = '3.10' + logging.basicConfig(level=logging.INFO) + + @staticmethod + def parse_add_argument(parser): + + parser.add_argument( + '--enable-assertions', + action='store_true', + default=False, + help='Apply assertions, some parameters are affected.') + + parser.add_argument( + '--build-name', + default='dev', + help='Release name for the package.') + + parser.add_argument( + '--debug', + action='store_true', + default=False, + help='Building Clang and LLVM Tools for Debugging (only affects stage2)') + + parser.add_argument( + '--no-build-arm', + action='store_true', + default=False, + help='Omit build os target: arm.') + + parser.add_argument( + '--no-build-aarch64', + action='store_true', + default=False, + help='Omit build os target: aarch64.') + + parser.add_argument( + '--no-build-x86_64', + action='store_true', + default=False, + help='Omit build os target: x86_64.') + + parser.add_argument( + '--no-lto', + action='store_true', + default=False, + help='Accelerate builds by disabling LTO (only affects llvm product)') + + parser.add_argument( + '--build-instrumented', + action='store_true', + default=False, + help='Using the PGO instrumentation to build LLVM tool') + + parser.add_argument( + '--xunit-xml-output', + default=None, + help='Output path for LLVM unit tests XML report') + + def parse_args(self): + + parser = argparse.ArgumentParser(description='Process some integers.') + + # Options to skip build or packaging, can't skip two + build_package_group = parser.add_mutually_exclusive_group() + build_package_group.add_argument( + '--skip-build', + '-sb', + action='store_true', + default=False, + help='Omit the build, perform the packaging step directly.') + + build_package_group.add_argument( + '--skip-package', + '-sp', + action='store_true', + default=False, + help='Omit the packaging, perform the packaging step directly.') + + self.parse_add_argument(parser) + + known_platforms = ('windows', 'libs', 'lldb-mi', 'lldb-server', 'linux', 'check-api') + known_platforms_str = ', '.join(known_platforms) + + class SeparatedListByCommaAction(argparse.Action): + def __call__(self, parser, namespace, vals, option_string): + for val in vals.split(','): + if val in known_platforms: + continue + else: + error = '\'{}\' invalid. Choose from {}'.format(val, known_platforms) + raise argparse.ArgumentError(self, error) + setattr(namespace, self.dest, vals.split(',')) + + parser.add_argument( + '--no-build', + action=SeparatedListByCommaAction, + default=list(), + help='Don\'t build toolchain for specified platforms. Choices: ' + known_platforms_str) + + return parser.parse_args() + + +class ClangVersion(object): + """Parse and save clang version from version file.""" + + def __init__(self, version_file): + self._parse_version_file(version_file) + + @staticmethod + def _parse(text, key): + return re.findall(r'%s\s+(\d+)' % key, text)[0] + + def _parse_version_file(self, version_file): + with open(version_file, 'r') as fp: + text = fp.read() + self.major = self._parse(text, 'CLANG_VERSION_MAJOR') + self.minor = self._parse(text, 'CLANG_VERSION_MINOR') + self.patch = self._parse(text, 'CLANG_VERSION_PATCHLEVEL') + + def long_version(self): + return '.'.join([self.major, self.minor, self.patch]) + + def short_version(self): + return '.'.join([self.major, self.minor]) + + def major_version(self): + return self.major + + +class BuildUtils(object): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_DIR = os.path.abspath( + os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.use_platform()[:-3], 'bin')) + + def open_hos_triple(self, arch): + return arch + self.build_config.OPENHOS_SFX + + def liteos_triple(self, arch): + return arch + self.build_config.LITEOS_SFX + + def set_clang_version(self, install_dir): + self.build_config.VERSION = self.get_clang_version(install_dir).long_version() + + def invoke_ninja(self, + out_path, + env, + target=None, + install=True, + build_threads=False): + + ninja_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'ninja') + + ninja_list = ['-l{}'.format(build_threads)] if build_threads else [] + + ninja_target = [target] if target else [] + + self.check_call([ninja_bin_path] + ninja_list + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([ninja_bin_path, 'install'], cwd=out_path, env=env) + + def invoke_cmake(self, + cmake_path, + out_path, + invoke_defines, + env): + + cmake_bin_path = os.path.join(self.CMAKE_BIN_DIR, 'cmake') + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR] + + for key in invoke_defines: + newdef = ''.join(['-D', key, '=', invoke_defines[key]]) + flags += [newdef] + + flags += [cmake_path] + self.check_create_dir(out_path) + + self.check_call([cmake_bin_path] + flags, cwd=out_path, env=env) + + @staticmethod + def logger(): + """Returns the module level logger.""" + return logging.getLogger(__name__) + + @staticmethod + def get_clang_version(llvm_install): + version_file = os.path.join(llvm_install, 'include', 'clang', 'Basic', + 'Version.inc') + return ClangVersion(version_file) + + def check_create_dir(self, path): + if not os.path.exists(path): + """Proxy for os.makedirs with logging and dry-run support.""" + self.logger().info('makedirs %s', path) + os.makedirs(path) + + def check_rm_tree(self, tree_dir): + """Removes directory tree.""" + def chmod_and_retry(func, path, _): + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWUSR) + return func(path) + raise IOError("rmtree on %s failed" % path) + + if os.path.exists(tree_dir): + self.logger().info('shutil rmtree %s', tree_dir) + shutil.rmtree(tree_dir, onerror=chmod_and_retry) + + def check_copy_tree(self, src_dir, dst_dir): + self.check_rm_tree(dst_dir) + """Proxy for shutil.copytree with logging and dry-run support.""" + self.logger().info('copytree %s %s', src_dir, dst_dir) + shutil.copytree(src_dir, dst_dir, symlinks=True) + + def check_copy_file(self, src_file, dst_file): + if os.path.exists(src_file): + """Proxy for shutil.copy2 with logging and dry-run support.""" + self.logger().info('copy %s %s', src_file, dst_file) + shutil.copy2(src_file, dst_file) + + def check_call(self, cmd, *args, **kwargs): + """subprocess.check_call with logging.""" + self.logger().info('check_call:%s %s', + datetime.datetime.now().strftime("%H:%M:%S"), subprocess.list2cmdline(cmd)) + + subprocess.check_call(cmd, *args, **kwargs) + + def merge_out_path(self, *args): + return os.path.abspath(os.path.join(self.build_config.OUT_PATH, *args)) + + @staticmethod + def use_platform(): + sysstr = platform.system() + if (sysstr == "Linux"): + return 'linux-x86_64' + else: + return 'darwin-x86_64' + + def host_is_linux(self): + return self.use_platform() == 'linux-x86_64' + + def host_is_darwin(self): + return self.use_platform() == 'darwin-x86_64' + + def rm_cmake_cache(self, cache_dir): + for dirpath, dirs, files in os.walk(cache_dir): + if 'CMakeCache.txt' in files: + self.logger().info('rm CMakeCache.txt on %s', cache_dir) + os.remove(os.path.join(dirpath, 'CMakeCache.txt')) + if 'CMakeFiles' in dirs: + self.logger().info('rm CMakeFiles on %s', cache_dir) + self.check_rm_tree(os.path.join(dirpath, 'CMakeFiles')) + + @staticmethod + def find_program(name): + # FIXME: Do we need Windows support here? + return os.popen('which ' + name).read().strip() + + # Base cmake options such as build type that are common across all invocations + def base_cmake_defines(self): + mac_min_version = '10.9' + defines = {} + + defines['CMAKE_BUILD_TYPE'] = 'Release' + defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + defines['LLVM_ENABLE_THREADS'] = 'ON' + defines['LLVM_USE_NEWPM'] = 'ON' + defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + defines['CLANG_REPOSITORY_STRING'] = 'llvm-project' + + if self.host_is_darwin(): + defines['CMAKE_OSX_DEPLOYMENT_TARGET'] = mac_min_version + defines['LLDB_INCLUDE_TESTS'] = 'OFF' + defines['LIBCXX_INCLUDE_TESTS'] = 'OFF' + + defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return defines + + +class LlvmCore(BuildUtils): + + def __init__(self, build_config): + super(LlvmCore, self).__init__(build_config) + + def build_llvm(self, + targets, + build_dir, + install_dir, + build_name, + extra_defines=None, + extra_env=None): + + common_defines = self.base_cmake_defines() + common_defines['CMAKE_INSTALL_PREFIX'] = install_dir + common_defines['LLVM_INSTALL_UTILS'] = 'ON' + common_defines['LLVM_TARGETS_TO_BUILD'] = targets + common_defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON' + + build_number = '' + if re.match(r'\d+-.\D*$', build_name): + build_number, build_name = build_name.split('-', 1) + elif re.match(r'^\d+$', build_name): + build_number = build_name + build_name = '' + elif re.match(r'^\D+$', build_name): + build_name = build_name + else: + raise Exception('Warning! Build name is invalid, because it must not contain digits. ' + 'If you want to pass digit version, please, use follow template: {NUMBER}-{SUFFIX} ' + 'or just pass number. Otherwise unit tests will fail with assertions') + + common_defines['CLANG_VENDOR'] = 'OHOS (%s) ' % build_name + common_defines['CLANG_VENDOR_BUILD_VERSION'] = build_number + common_defines.update(extra_defines) + + env = dict(self.build_config.ORIG_ENV) + if extra_env is not None: + env.update(extra_env) + + llvm_project_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm')) + + self.invoke_cmake(llvm_project_path, + build_dir, + common_defines, + env=env) + + self.invoke_ninja(out_path=build_dir, + env=env, + target=None, + install=True) + + + def llvm_compile_darwin_defines(self, llvm_defines): + if self.host_is_darwin(): + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_NO_DEBUGSERVER'] = 'ON' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + llvm_defines['LLVM_BUILD_EXTERNAL_COMPILER_RT'] = 'ON' + + def llvm_compile_linux_defines(self, + llvm_defines, + debug_build=False, + no_lto=False, + build_instrumented=False): + if self.host_is_linux(): + llvm_defines['LLVM_ENABLE_LLD'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + llvm_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + llvm_defines['LIBCXX_ENABLE_ABI_LINKER_SCRIPT'] = 'OFF' + llvm_defines['EXECUTION_ENGINE_USE_LLVM_UNWINDER'] = '1' + llvm_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + llvm_defines['LIBUNWIND_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXXABI_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + llvm_defines['LIBCXXABI_ENABLE_STATIC_UNWINDER'] = 'ON' + llvm_defines['LIBCXXABI_USE_LLVM_UNWINDER'] = 'YES' + llvm_defines['LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY'] = 'YES' + llvm_defines['LLVM_BINUTILS_INCDIR'] = '/usr/include' + + + if not build_instrumented and not no_lto and not debug_build: + llvm_defines['LLVM_ENABLE_LTO'] = 'Thin' + + @staticmethod + def llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags): + llvm_defines['LLVM_BUILD_RUNTIME'] = 'ON' + llvm_defines['LLVM_ENABLE_PROJECTS'] = \ + 'clang;lld;libunwind;libcxxabi;libcxx;compiler-rt;clang-tools-extra;openmp;lldb' + llvm_defines['LLVM_ENABLE_BINDINGS'] = 'OFF' + llvm_defines['CMAKE_C_COMPILER'] = llvm_cc + llvm_defines['CMAKE_CXX_COMPILER'] = llvm_cxx + llvm_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + llvm_defines['SANITIZER_ALLOW_CXXABI'] = 'OFF' + llvm_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + llvm_defines['OPENMP_TEST_FLAGS'] = '-Wl,-ldl' + llvm_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + llvm_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + llvm_defines['LLDB_ENABLE_PYTHON'] = 'ON' + llvm_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + llvm_defines['COMPILER_RT_BUILD_MEMPROF'] = 'OFF' + llvm_defines['CMAKE_ASM_FLAGS'] = cflags + llvm_defines['CMAKE_C_FLAGS'] = cflags + llvm_defines['CMAKE_CXX_FLAGS'] = '%s -stdlib=libc++' % cflags + llvm_defines['CMAKE_EXE_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_SHARED_LINKER_FLAGS'] = ldflags + llvm_defines['CMAKE_MODULE_LINKER_FLAGS'] = ldflags + + def llvm_compile(self, + build_name, + out_dir, + debug_build=False, + no_lto=False, + build_instrumented=False, + xunit_xml_output=None): + + llvm_clang_install = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), + 'clang-10.0.1')) + llvm_path = self.merge_out_path('llvm_make') + llvm_cc = os.path.join(llvm_clang_install, 'bin', 'clang') + llvm_cxx = os.path.join(llvm_clang_install, 'bin', 'clang++') + llvm_profdata = os.path.join(llvm_clang_install, 'bin', 'llvm-profdata') + + cflags = '' + + if self.host_is_darwin(): + ldflags = '' + else: + ldflags = '-fuse-ld=lld' + ldflags = '%s -L%s' % (ldflags, os.path.join(llvm_clang_install, 'lib')) + + llvm_extra_env = {} + llvm_extra_env['LD_LIBRARY_PATH'] = os.path.join(llvm_clang_install, 'lib') + + llvm_defines = {} + + + self.llvm_compile_darwin_defines(llvm_defines) + self.llvm_compile_linux_defines(llvm_defines, debug_build, no_lto, build_instrumented) + + if self.host_is_linux(): + ldflags += ' -lunwind --rtlib=compiler-rt -stdlib=libc++' + + + if xunit_xml_output: + llvm_defines['LLVM_LIT_ARGS'] = "--xunit-xml-output={} -sv".format(xunit_xml_output) + + if self.build_config.enable_assertions: + llvm_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + if debug_build: + llvm_defines['CMAKE_BUILD_TYPE'] = 'Debug' + + if build_instrumented: + llvm_defines['LLVM_BUILD_INSTRUMENTED'] = 'ON' + llvm_defines['LLVM_PROFDATA'] = llvm_profdata + + resource_dir = "lib/clang/10.0.1/lib/linux/libclang_rt.profile-x86_64.a" + ldflags += ' %s' % os.path.join(llvm_clang_install, resource_dir) + + self.llvm_compile_llvm_defines(llvm_defines, llvm_cc, llvm_cxx, cflags, ldflags) + + self.build_llvm(targets=self.build_config.TARGETS, + build_dir=llvm_path, + install_dir=out_dir, + build_name=build_name, + extra_defines=llvm_defines, + extra_env=llvm_extra_env) + + def llvm_compile_windows_defines(self, + windows_defines, + cc, + cxx, + windows_sysroot): + + if self.build_config.enable_assertions: + + windows_defines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + win_sysroot = self.merge_out_path( + 'clang_mingw', 'clang-10.0.1', 'x86_64-w64-mingw32') + windows_defines['LLDB_ENABLE_PYTHON'] = 'ON' + windows_defines['LLDB_PYTHON_HOME'] = 'python' + windows_defines['LLDB_PYTHON_RELATIVE_PATH'] = 'bin/python/lib/python%s' % (self.build_config.LLDB_PY_VERSION) + windows_defines['PYTHON_INCLUDE_DIRS'] = os.path.join(win_sysroot, + 'include', 'python%s' % self.build_config.LLDB_PY_VERSION) + windows_defines['PYTHON_LIBRARIES'] = os.path.join(win_sysroot, 'lib', 'libpython%s.dll.a' + % self.build_config.LLDB_PY_VERSION) + windows_defines['SWIG_EXECUTABLE'] = self.find_program('swig') + windows_defines['PYTHON_EXECUTABLE'] = self.find_program('python3') + + windows_defines['CMAKE_C_COMPILER'] = cc + windows_defines['CMAKE_CXX_COMPILER'] = cxx + windows_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + windows_defines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + windows_defines['LLVM_BUILD_RUNTIME'] = 'OFF' + windows_defines['LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD'] = 'ON' + windows_defines['LLVM_TOOL_OPENMP_BUILD'] = 'OFF' + windows_defines['LLVM_INCLUDE_TESTS'] = 'OFF' + windows_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + windows_defines['LLVM_ENABLE_PROJECTS'] = 'clang;clang-tools-extra;lld;lldb' + windows_defines['CLANG_BUILD_EXAMPLES'] = 'OFF' + windows_defines['CMAKE_SYSROOT'] = windows_sysroot + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + windows_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + windows_defines['LLDB_ENABLE_LIBEDIT'] = 'OFF' + windows_defines['LLDB_RELOCATABLE_PYTHON'] = 'OFF' + + def llvm_compile_windows_flags(self, + windows_defines, + compiler_rt_path, + native_cmake_file_path, + windowstool_path, + windows64_install, + ldflags, + cflags): + + windows_defines['CROSS_TOOLCHAIN_FLAGS_NATIVE'] = ';'.join([ + '-DCMAKE_PREFIX_PATH=%s' % self.CMAKE_BIN_DIR, + '-DCOMPILER_RT_BUILD_LIBFUZZER=OFF', + '-DCMAKE_TOOLCHAIN_FILE=%s' % native_cmake_file_path, + '-DLLVM_ENABLE_LIBCXX=ON', + '-DCMAKE_BUILD_WITH_INSTALL_RPATH=TRUE', + '-DCMAKE_INSTALL_RPATH=%s' % os.path.join(windowstool_path, 'lib')] + ) + + ldflag = ['-fuse-ld=lld', + '--rtlib=compiler-rt', + '-L%s' % compiler_rt_path, + '-lunwind', '-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-lpthread', + '-L', + os.path.join(windows64_install, 'lib'), + '-Wl,--high-entropy-va'] + ldflags.extend(ldflag) + + cflag = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64'] + cflags.extend(cflag) + + def llvm_compile_windows_cmake(self, + cflags, + cxxflags, + ldflags, + windows_defines): + + + zlib_path = self.merge_out_path('../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', + 'zlib') + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + windows_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + windows_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + windows_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + windows_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + + def llvm_compile_for_windows(self, + targets, + enable_assertions, + build_name): + + self.logger().info('Building llvm for windows.') + + build_dir = self.merge_out_path("windows-x86_64") + windowstool_path = self.merge_out_path('clang_mingw', 'clang-10.0.1') + windows64_install = self.merge_out_path('windows-x86_64-install') + windows_sysroot = os.path.join(windowstool_path, 'x86_64-w64-mingw32') + compiler_rt_path = self.merge_out_path('clang_mingw', 'clang-10.0.1', + 'lib', 'clang', '10.0.1', 'lib', 'windows') + + self.check_create_dir(build_dir) + + # Write a NATIVE.cmake in windows_path that contains the compilers used + # to build native tools such as llvm-tblgen and llvm-config. This is + # used below via the CMake variable CROSS_TOOLCHAIN_FLAGS_NATIVE. + cc = os.path.join(windowstool_path, 'bin', 'clang') + cxx = os.path.join(windowstool_path, 'bin', 'clang++') + + native_cmake_file_path = os.path.join(build_dir, 'NATIVE.cmake') + native_cmake_text = ('set(CMAKE_C_COMPILER {cc})\n' + 'set(CMAKE_CXX_COMPILER {cxx})\n' + 'set(LLVM_ENABLE_PROJECTS "clang;lldb" CACHE STRING "" FORCE)\n' + 'set(LLDB_ENABLE_PYTHON "OFF" CACHE STRING "" FORCE)\n' + 'set(LLDB_DISABLE_CURSES "ON" CACHE STRING "" FORCE)\n' + 'set(LLDB_ENABLE_LIBEDIT "OFF" CACHE STRING "" FORCE)\n' + ).format(cc=cc, cxx=cxx) + + with open(native_cmake_file_path, 'w') as native_cmake_file: + native_cmake_file.write(native_cmake_text) + + # Extra cmake defines to use while building for Windows + windows_defines = {} + self.llvm_compile_windows_defines(windows_defines, cc, cxx, windows_sysroot) + + # Set CMake path, toolchain file for native compilation (to build tablegen + # etc). Also disable libfuzzer build during native compilation. + + ldflags = [] + cflags = [] + + self.llvm_compile_windows_flags(windows_defines, compiler_rt_path, native_cmake_file_path, + windowstool_path, windows64_install, ldflags, cflags) + + cxxflags = list(cflags) + + windows_extra_env = dict() + + cxxflags.append('-fuse-cxa-atexit') + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + self.llvm_compile_windows_cmake(cflags, cxxflags, ldflags, windows_defines) + + self.build_llvm(self.build_config.TARGETS, + build_dir, + windows64_install, + build_name, + extra_defines=windows_defines, + extra_env=windows_extra_env) + + +class SysrootComposer(BuildUtils): + + def __init__(self, build_config): + super(SysrootComposer, self).__init__(build_config) + + def setup_cmake_platform(self, llvm_install): + + # OHOS.cmake already exsit on cmake prebuilts, + # but it didn't contain these two lines, so we still need OHOS.cmake. + ohos_cmake = 'OHOS.cmake' + dst_dir = self.merge_out_path( + '../prebuilts/cmake/linux-x86/share/cmake-3.16/Modules/Platform') + src_file = '%s/%s' % (self.build_config.CURRENT_DIR, ohos_cmake) + if os.path.exists(os.path.join(dst_dir, ohos_cmake)): + os.remove(os.path.join(dst_dir, ohos_cmake)) + shutil.copy2(src_file, dst_dir) + + + def build_musl(self, llvm_install, target, *extra_args): + cur_dir = os.getcwd() + os.chdir(self.build_config.CURRENT_DIR) + self.logger().info('build musl %s', self.merge_out_path('install')) + args = ['./build_musl.sh', '-t', target, '-c', + self.merge_out_path(llvm_install, 'bin'), '-o', self.merge_out_path()] + list(extra_args) + self.check_call(args) + os.chdir(cur_dir) + + def install_linux_headers(self, arch, target): + linux_kernel_dir = os.path.join('kernel_linux_patches', 'linux-5.10') + linux_kernel_path = os.path.join(self.build_config.OUT_PATH, '..', linux_kernel_dir) + ohosmusl_sysroot_dst = self.merge_out_path('sysroot', target, 'usr') + headers_tmp_dir = os.path.join(linux_kernel_path, 'prebuilts', 'usr', 'include') + self.check_copy_tree(os.path.join(headers_tmp_dir, 'linux'), + os.path.join(ohosmusl_sysroot_dst, 'include/linux')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % arch, 'asm'), + os.path.join(ohosmusl_sysroot_dst, 'include', 'asm')) + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-generic'), + os.path.join(ohosmusl_sysroot_dst, 'include/asm-generic')) + + def copy_libz_to_sysroot(self, libz_path, llvm_triple): + # Install to sysroot + dest_usr = self.merge_out_path('sysroot', llvm_triple, 'usr') + dest_usr_include = os.path.join(dest_usr, 'include') + + # Copy over usr/include. + zlib_h = self.merge_out_path('../third_party/zlib', 'zlib.h') + self.check_copy_file(zlib_h, dest_usr_include) + + zconf_h = os.path.join(libz_path, 'zconf.h') + self.check_copy_file(zconf_h, dest_usr_include) + + # Copy over usr/lib. + dest_usr_lib = os.path.join(dest_usr, 'lib') + static_zlib = os.path.join(libz_path, 'libz.a') + self.check_copy_file(static_zlib, dest_usr_lib) + + +class LlvmLibs(BuildUtils): + + def __init__(self, build_config, sysroot_composer, llvm_package): + super(LlvmLibs, self).__init__(build_config) + self.sysroot_composer = sysroot_composer + self.llvm_package = llvm_package + + def build_crt_libs(self, configs, llvm_install, need_lldb_server): + for (arch, target) in configs: + self.sysroot_composer.build_musl(llvm_install, target) + if target.endswith(self.build_config.OPENHOS_SFX): + self.sysroot_composer.install_linux_headers(arch, target) + self.build_libs(need_lldb_server, + llvm_install, + target, + precompilation=True) + self.sysroot_composer.build_musl(llvm_install, target, '-l') + + + + def build_libs_defines(self, + llvm_triple, + defines, + cc, + cxx, + llvm_config, + ldflags, + cflags, + extra_flags): + + sysroot = self.merge_out_path('sysroot') + + defines['CMAKE_C_COMPILER'] = cc + defines['CMAKE_CXX_COMPILER'] = cxx + defines['LLVM_CONFIG_PATH'] = llvm_config + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + ldflag = [ + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-Wl,--build-id=sha1', + '-pie', + '--rtlib=compiler-rt', + '-stdlib=libc++', + '-v', ] + + ldflags.extend(ldflags) + + cflag = [ + '--target=%s' % llvm_triple, + '-ffunction-sections', + '-fdata-sections', + extra_flags, ] + + cflags.extend(cflag) + + def build_need_libs_for_windows(self): + + self.build_libs_for_windows('libcxxabi', self.build_config.enable_assertions) + self.build_libs_for_windows('libcxx', self.build_config.enable_assertions) + self.build_libs_for_windows('libunwind', self.build_config.enable_assertions) + + def build_libs(self, need_lldb_server, llvm_install, llvm_build, precompilation=False): + configs_list = [ + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.liteos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.liteos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + + ('arm', self.open_hos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.open_hos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.open_hos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), + ('arm', self.open_hos_triple('arm'), + '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), + ('aarch64', self.open_hos_triple('aarch64'), '', ''), ] + + cc = os.path.join(llvm_install, 'bin', 'clang') + cxx = os.path.join(llvm_install, 'bin', 'clang++') + llvm_config = os.path.join(llvm_install, 'bin', 'llvm-config') + seen_arch_list = [self.liteos_triple('arm')] + + self.set_clang_version(llvm_install) + for (arch, llvm_triple, extra_flags, multilib_suffix) in configs_list: + if llvm_build != llvm_triple: + continue + + defines = {} + ldflags = [] + cflags = [] + self.logger().info('Build libs for %s', llvm_triple) + self.build_libs_defines(llvm_triple, defines, cc, cxx, llvm_config, ldflags, cflags, extra_flags) + + llvm_path = self.merge_out_path('llvm_make') + arch_list = [self.liteos_triple('arm'), self.open_hos_triple('arm'), self.open_hos_triple('aarch64')] + if precompilation: + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + continue + self.build_libcxxabi(llvm_install, ldflags, cflags, llvm_triple, arch, multilib_suffix, defines) + self.build_libunwind(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libcxx(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libcxx(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, + do_build_system=False) + self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines, + first_time=False) + + if llvm_triple in arch_list: + if need_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, + defines) + seen_arch_list.append(llvm_triple) + continue + + self.build_libomp(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) + self.build_libz(arch, llvm_triple, cflags, ldflags, defines) + if need_lldb_server and llvm_triple not in seen_arch_list: + self.build_lldb_server(llvm_install, llvm_path, arch, llvm_triple, cflags, ldflags, defines) + seen_arch_list.append(llvm_triple) + + def build_libcxxabi(self, + llvm_install, + ldflags, + cflags, + llvm_triple, + arch, + multilib_suffix, + defines): + + self.logger().info('Building libcxxabi for %s', arch) + + out_path = self.merge_out_path('lib', 'libcxxabi-%s' % llvm_triple) + output_intdir = self.merge_out_path(out_path, 'lib') + + libcxxabi_cflags = list(cflags) + libcxxabi_cflags.append('-fstack-protector-strong') + + libcxxabi_defines = defines.copy() + libcxxabi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libcxxabi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libcxxabi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + libcxxabi_includes_str = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx', 'include')) + libcxxabi_defines['LIBCXXABI_LIBCXX_INCLUDES'] = libcxxabi_includes_str + libcxxabi_defines['LIBCXXABI_ENABLE_SHARED'] = 'OFF' + libcxxabi_defines['CMAKE_C_FLAGS'] = ' '.join(libcxxabi_cflags) + libcxxabi_defines['CMAKE_CXX_FLAGS'] = ' '.join(libcxxabi_cflags) + libcxxabi_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + + libcxxabi_defines['OHOS'] = '1' + libcxxabi_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + libcxxabi_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + libcxxabi_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libcxxabi_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libcxxabi_defines['CMAKE_CROSSCOMPILING'] = 'True' + libcxxabi_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + libcxxabi_defines['LLVM_LIBRARY_OUTPUT_INTDIR'] = output_intdir + + libcxxabi_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + libcxxabi_defines['LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL'] = 'OFF' + + self.check_rm_tree(out_path) + cmake_libcxxabi = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxxabi')) + + self.invoke_cmake(cmake_libcxxabi, + out_path, + libcxxabi_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=out_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_crts(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines, + first_time=True): + + self.logger().info('Building compiler-rt for %s', arch) + + suffix = '-' + multilib_suffix if multilib_suffix else '' + crt_path = self.merge_out_path('lib', 'clangrt-%s%s' % (llvm_triple, suffix)) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + + crt_defines = defines.copy() + crt_defines.update(self.base_cmake_defines()) + crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + crt_defines['OHOS'] = '1' + crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = llvm_triple + crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'ON' + crt_defines['CMAKE_INSTALL_PREFIX'] = crt_install + crt_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + if first_time or llvm_triple == self.liteos_triple('arm'): + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + else: + crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'ON' + crt_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + crt_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + crt_defines['COMPILER_RT_HWASAN_WITH_INTERCEPTORS'] = 'OFF' + + if not llvm_triple == self.liteos_triple('arm'): + crt_defines['COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN'] = 'OFF' + if first_time: + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + else: + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'ON' + crt_defines['COMPILER_RT_DEFAULT_TARGET_TRIPLE'] = llvm_triple + else: + crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + + crt_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'compiler-rt')) + self.rm_cmake_cache(crt_path) + + self.invoke_cmake(crt_cmake_path, + crt_path, + crt_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=crt_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libunwind(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines): + + self.logger().info('Building libunwind for %s ', arch) + + lib_path = self.merge_out_path('lib', 'libunwind-%s' % llvm_triple) + out_dir = os.path.join(lib_path, 'lib') + + lib_cflags = list(cflags) + lib_cflags.append('-fPIC') + lib_cflags.append('-fstack-protector-strong') + + lib_defines = defines.copy() + lib_defines.update(self.base_cmake_defines()) + lib_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lib_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lib_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + lib_defines['OHOS'] = '1' + lib_defines['CMAKE_ASM_FLAGS'] = ' '.join(lib_cflags) + lib_defines['CMAKE_C_FLAGS'] = ' '.join(lib_cflags) + lib_defines['CMAKE_CXX_FLAGS'] = ' '.join(lib_cflags) + lib_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + lib_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + lib_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + lib_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + lib_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + lib_defines['CMAKE_CROSSCOMPILING'] = 'True' + lib_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + lib_defines['LLVM_LIBRARY_OUTPUT_INTDIR'] = out_dir + lib_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lib_defines['LIBUNWIND_ENABLE_SHARED'] = 'OFF' + lib_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + lib_defines['_LIBUNWIND_USE_DLADDR'] = 'OFF' + lib_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libunwind')) + + self.rm_cmake_cache(lib_path) + + self.invoke_cmake(lib_cmake_path, + lib_path, + lib_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=lib_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libcxx_defines_parameters(self, + libcxx_defines, + libcxx_ldflags, + libcxx_cflags, + llvm_install, + multilib_suffix, + libcxx_path, + llvm_triple, + out_dir, + libcxx_ndk_install, + do_build_system): + + libcxx_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(libcxx_ldflags) + libcxx_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(libcxx_ldflags) + libcxx_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(libcxx_ldflags) + libcxx_defines['CMAKE_ASM_FLAGS'] = ' '.join(libcxx_cflags) + libcxx_defines['CMAKE_C_FLAGS'] = ' '.join(libcxx_cflags) + libcxx_defines['CMAKE_CXX_FLAGS'] = ' '.join(libcxx_cflags) + libcxx_defines['CMAKE_BUILD_TYPE'] = 'Release' + if do_build_system: + libcxx_defines['LIBCXX_ABI_NAMESPACE'] = '__h' + libcxx_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + libcxx_defines['LIBCXX_INSTALL_HEADER_PREFIX'] = os.path.join(llvm_install, 'include', 'libcxx-ohos', '') + else: + libcxx_defines['LIBCXX_ABI_NAMESPACE'] = '__n1' + libcxx_defines['CMAKE_INSTALL_PREFIX'] = libcxx_ndk_install + libcxx_defines['LIBCXX_INSTALL_HEADER_PREFIX'] = libcxx_ndk_install + '/' + libcxx_defines['LIBCXX_OUTPUT_NAME'] = 'c++_shared' + libcxx_defines['LIBCXX_OUTPUT_STATIC_NAME'] = 'c++_static' + + libcxx_defines['LIBCXX_HEADER_DIR'] = libcxx_path + libcxx_defines['OHOS'] = '1' + libcxx_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + libcxx_defines['LLVM_TARGET_MULTILIB_SUFFIX'] = multilib_suffix + libcxx_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libcxx_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libcxx_defines['CMAKE_CROSSCOMPILING'] = 'True' + libcxx_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + libcxx_defines['LLVM_LIBRARY_OUTPUT_INTDIR'] = out_dir + libcxx_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + libcxx_defines['LIBCXX_CXX_ABI'] = 'libcxxabi' + libcxx_defines['LIBCXX_CXX_ABI_INCLUDE_PATHS'] = os.path.abspath( + os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxxabi', 'include')) + str_cpp = 'c++' + libcxx_defines['LIBCXX_CXX_ABI_LIBRARY_PATH'] = os.path.join(llvm_install, 'lib', llvm_triple, str_cpp) + libcxx_defines['LIBCXX_USE_COMPILER_RT'] = 'ON' + libcxx_defines['LIBCXX_HAS_PTHREAD_LIB'] = 'OFF' + libcxx_defines['LIBCXX_HAS_RT_LIB'] = 'OFF' + libcxx_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + + + + def build_libcxx(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines, + do_build_system=True): + + self.logger().info('Building libcxx for %s', arch) + + suffix = '-' + multilib_suffix if multilib_suffix else '' + libcxx_path = self.merge_out_path('lib', 'libcxx-%s-%s%s' % ('system' if do_build_system else 'ndk', + llvm_triple, suffix)) + + out_dir = os.path.join(libcxx_path, 'lib') + libcxx_ndk_install = self.merge_out_path('libcxx-ndk') + self.check_create_dir(libcxx_ndk_install) + + libcxx_ldflags = list(ldflags) + libcxx_cflags = list(cflags) + libcxx_ldflags.append('-lunwind') + libcxx_cflags.append('-fstack-protector-strong') + libcxx_cflags.append('-fPIC') + + libcxx_defines = defines.copy() + + self.build_libcxx_defines_parameters(libcxx_defines, + libcxx_ldflags, + libcxx_cflags, + llvm_install, + multilib_suffix, + libcxx_path, + llvm_triple, + out_dir, + libcxx_ndk_install, + do_build_system) + + libcxx_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx')) + self.rm_cmake_cache(libcxx_path) + + self.invoke_cmake(libcxx_cmake_path, + libcxx_path, + libcxx_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libcxx_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libomp(self, + llvm_install, + arch, + llvm_triple, + cflags, + ldflags, + multilib_suffix, + defines): + + self.logger().info('Building libomp for %s', arch) + + libomp_path = self.merge_out_path('lib', 'libomp-%s' % llvm_triple) + out_dir = os.path.join(libomp_path, 'lib') + + libomp_cflags = list(cflags) + libomp_cflags.append('-fPIC') + libomp_cflags.append('-fstack-protector-strong') + + libomp_defines = defines.copy() + libomp_defines.update(self.base_cmake_defines()) + libomp_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libomp_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + libomp_defines['OHOS'] = '1' + libomp_defines['CMAKE_ASM_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_C_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['CMAKE_CXX_FLAGS'] = ' '.join(libomp_cflags) + libomp_defines['OPENMP_ENABLE_LIBOMPTARGET'] = 'FALSE' + + libomp_defines['OPENMP_LIBDIR_SUFFIX'] = os.path.join(os.sep, llvm_triple, multilib_suffix) + libomp_defines['LIBOMP_ENABLE_SHARED'] = 'FALSE' + libomp_defines['CMAKE_POLICY_DEFAULT_CMP0056'] = 'NEW' + libomp_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + libomp_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + libomp_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + libomp_defines['CMAKE_CROSSCOMPILING'] = 'True' + libomp_defines['LLVM_LIBRARY_OUTPUT_INTDIR'] = out_dir + libomp_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + libomp_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libomp_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'openmp') + self.rm_cmake_cache(libomp_path) + + self.invoke_cmake(libomp_cmake_path, + libomp_path, + libomp_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libomp_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=True) + + def build_libz(self, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building libz for %s ', arch) + + libz_path = self.merge_out_path('lib', 'libz-%s' % llvm_triple) + if llvm_triple == self.hos_triple('arm'): + ldflags.append('-lunwind') + + + libz_cflags = list(cflags) + libz_cflags.append('-fstack-protector-strong') + libz_cflags.append('-fPIC') + libz_cflags.append('-fuse-ld=lld') + libz_cflags.append('--rtlib=compiler-rt') + + libz_defines = defines.copy() + libz_defines.update(self.base_cmake_defines()) + libz_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + libz_defines['OHOS'] = '1' + libz_defines['CMAKE_ASM_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_C_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_CXX_FLAGS'] = ' '.join(libz_cflags) + libz_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + + libz_cmake_path = os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib') + self.rm_cmake_cache(libz_path) + + self.invoke_cmake(libz_cmake_path, + libz_path, + libz_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=libz_path, + env=dict(self.build_config.ORIG_ENV), + target=None, + install=False) + + self.sysroot_composer.copy_libz_to_sysroot(libz_path, llvm_triple) + + def build_lldb_server(self, + llvm_install, + llvm_path, + arch, + llvm_triple, + cflags, + ldflags, + defines): + + self.logger().info('Building lldb for %s', arch) + + lldb_path = self.merge_out_path('lib', 'lldb-server-%s' % llvm_triple) + crt_install = os.path.join(llvm_install, 'lib', 'clang', self.build_config.VERSION) + out_dir = os.path.join(lldb_path, 'bin') + + lldb_ldflags = list(ldflags) + lldb_cflags = list(cflags) + + lldb_ldflags.append('-lunwind') + lldb_ldflags.append('-static') + lldb_cflags.append('-fstack-protector-strong') + + lldb_defines = defines.copy() + lldb_defines.update(self.base_cmake_defines()) + + lldb_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + lldb_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(lldb_ldflags) + + lldb_defines['OHOS'] = '1' + lldb_defines['CMAKE_C_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_ASM_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_CXX_FLAGS'] = ' '.join(lldb_cflags) + lldb_defines['CMAKE_INSTALL_PREFIX'] = crt_install + lldb_defines['LLVM_ENABLE_PER_TARGET_RUNTIME_DIR'] = 'ON' + lldb_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'ON' + lldb_defines['CMAKE_SYSTEM_NAME'] = 'OHOS' + lldb_defines['CMAKE_CROSSCOMPILING'] = 'True' + lldb_defines['LLVM_DEFAULT_TARGET_TRIPLE'] = llvm_triple + lldb_defines['LLVM_LIBRARY_OUTPUT_INTDIR'] = out_dir + lldb_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_defines['LLVM_ENABLE_PROJECTS'] = 'clang;lldb' + lldb_defines['LLVM_TABLEGEN'] = os.path.join(llvm_install, 'bin', 'llvm-tblgen') + lldb_defines['CLANG_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'clang-tblgen') + lldb_defines['LLDB_TABLEGEN'] = os.path.join(llvm_install, '..', llvm_path, 'bin', 'lldb-tblgen') + lldb_defines['LLVM_HOST_TRIPLE'] = llvm_triple + lldb_defines['LLVM_TARGET_ARCH'] = arch + lldb_defines['LLVM_TARGETS_TO_BUILD'] = self.build_config.TARGETS + + lldb_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, 'llvm') + + self.invoke_cmake(lldb_cmake_path, + lldb_path, + lldb_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path=lldb_path, + env=dict(self.build_config.ORIG_ENV), + target='lldb-server', + install=False) + + self.llvm_package.copy_lldb_server_to_llvm_install(lldb_path, crt_install, llvm_triple) + + @staticmethod + def build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot): + cmake_defines['CMAKE_C_COMPILER_WORKS'] = '1' + cmake_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' + cmake_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + cmake_defines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + cmake_defines['CMAKE_C_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang') + cmake_defines['CMAKE_CXX_COMPILER'] = os.path.join(toolchain_dir, 'bin', 'clang++') + cmake_defines['LLVM_CONFIG_PATH'] = os.path.join(toolchain_dir, 'bin', 'llvm-config') + cmake_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + cmake_defines['CMAKE_SYSROOT'] = windows_sysroot + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + cmake_defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + + def build_libs_for_windows(self, libname, enable_assertions): + + self.logger().info('Building libs for windows.') + toolchain_dir = self.merge_out_path('clang_mingw', 'clang-10.0.1') + install_dir = self.merge_out_path('windows-x86_64-install') + compiler_rt_path = self.merge_out_path('clang_mingw', 'clang-10.0.1', 'lib', 'clang', + '10.0.1', 'lib', 'windows') + windows_sysroot = self.merge_out_path('clang_mingw', 'clang-10.0.1', 'x86_64-w64-mingw32') + + ldflags = ['-fuse-ld=lld', '--rtlib=compiler-rt', '-L%s' % compiler_rt_path, '-lunwind'] + cflags = ['-stdlib=libc++', '--target=x86_64-pc-windows-gnu', '-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', '-D_WIN32_WINNT=0x0600', '-DWINVER=0x0600', '-D__MSVCRT_VERSION__=0x1400'] + + cmake_defines = {} + self.build_libs_windows_cmake_defines(cmake_defines, toolchain_dir, windows_sysroot) + + # Build only the static library. + cmake_defines['%s_ENABLE_SHARED' % libname.upper()] = 'OFF' + if self.build_config.enable_assertions: + cmake_defines['%s_ENABLE_ASSERTIONS' % libname.upper()] = 'ON' + + if libname == 'libcxx': + cmake_defines['LIBCXX_ENABLE_STATIC_ABI_LIBRARY'] = 'ON' + cmake_defines['LIBCXX_CXX_ABI'] = 'libcxxabi' + cmake_defines['LIBCXX_HAS_WIN32_THREAD_API'] = 'ON' + cmake_defines['LIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG'] = 'TRUE' + cmake_defines['LIBCXX_CXX_ABI_INCLUDE_PATHS'] = os.path.abspath( + os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxxabi', 'include')) + cmake_defines['LIBCXX_CXX_ABI_LIBRARY_PATH'] = os.path.join(install_dir, 'lib') + cflags.append('-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS') + + elif libname == 'libcxxabi': + cmake_defines['LIBCXXABI_LIBCXX_INCLUDES'] = os.path.abspath( + os.path.join(self.build_config.LLVM_PROJECT_DIR, 'libcxx', 'include')) + cflags.append('-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS') + cflags.append('-D_LIBCPP_HAS_THREAD_API_WIN32') + + elif libname == 'libunwind': + cmake_defines['CXX_SUPPORTS_CXX11'] = 'TRUE' + cmake_defines['CXX_SUPPORTS_CXX_STD'] = 'TRUE' + + cmake_defines['CMAKE_INSTALL_PREFIX'] = install_dir + cmake_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + cmake_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + cmake_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + cmake_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + out_path = self.merge_out_path('lib', 'windows-%s' % libname) + self.check_rm_tree(out_path) + + libname_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, libname)) + + self.invoke_cmake(libname_cmake_path, + out_path, + cmake_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(out_path, + env=dict(self.build_config.ORIG_ENV), + install=True) + + +class LldbMi(BuildUtils): + + def __init__(self, build_config, llvm_package): + super(LldbMi, self).__init__(build_config) + self.llvm_package = llvm_package + + def build_lldb_mi(self, llvm_install): + self.logger().info('Building lldb-mi for linux.') + + llvm_path = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'prebuilts/clang/ohos', self.use_platform(), 'clang-10.0.1')) + lldb_mi_cmake_path = os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi') + lldb_mi_path = self.merge_out_path('lldb_mi_build') + + self.check_rm_tree(lldb_mi_path) + self.rm_cmake_cache(lldb_mi_path) + + if self.host_is_darwin(): + cflags = [] + ldflags = ['-Wl,-rpath,%s' % '@loader_path/../lib'] + else: + cflags = [] + ldflags = ['-fuse-ld=lld', '-Wl,-rpath,%s' % '\$ORIGIN/../lib'] + + ldflags.append('-L%s' % os.path.join(llvm_path, 'lib')) + + lldb_mi_defines = {} + lldb_mi_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang') + lldb_mi_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang++') + lldb_mi_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_defines['LLVM_DIR'] = os.path.join(llvm_install, 'lib/cmake/llvm/') + lldb_mi_defines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_defines['CMAKE_INSTALL_PREFIX'] = llvm_install + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_path, + lldb_mi_defines, + env=dict(self.build_config.ORIG_ENV)) + + self.invoke_ninja(lldb_mi_path, + env=dict(self.build_config.ORIG_ENV), + install=False) + + self.llvm_package.copy_lldb_mi_to_llvm_install(lldb_mi_path, llvm_install) + + @staticmethod + def ldflags_lists_define(): + ldflags_lists = ['-Wl,--dynamicbase', + '-Wl,--nxcompat', + '-lucrt', + '-lucrtbase', + '-lpthread', + '-L', ] + return ldflags_lists + + @staticmethod + def cflags_lists_define(): + cflags_lists = ['-D_LARGEFILE_SOURCE', + '-D_FILE_OFFSET_BITS=64', + '-D_WIN32_WINNT=0x0600', + '-DWINVER=0x0600', + '-D__MSVCRT_VERSION__=0x1400', + '-DMS_WIN64', ] + return cflags_lists + + # Extra cmake defines to use while building for Windows + def lldb_mi_windefines_dictionary(self, cc, cxx, windows_sysroot, cflags, cxxflags, ldflags): + lldb_mi_windefines = {} + lldb_mi_windefines['CMAKE_C_COMPILER'] = cc + lldb_mi_windefines['CMAKE_CXX_COMPILER'] = cxx + lldb_mi_windefines['CMAKE_C_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_CXX_COMPILER_WORKS'] = '1' + lldb_mi_windefines['CMAKE_SYSTEM_NAME'] = 'Windows' + lldb_mi_windefines['CMAKE_SYSTEM_PROCESSOR'] = 'x86_64' + lldb_mi_windefines['LLVM_ENABLE_LIBCXX'] = 'ON' + lldb_mi_windefines['CMAKE_SYSROOT'] = windows_sysroot + lldb_mi_windefines['LLVM_INSTALL_PREFIX'] = self.merge_out_path('windows-x86_64-install') + lldb_mi_windefines['LLVM_DIR'] = self.merge_out_path('windows-x86_64-install/lib/cmake/llvm/') + lldb_mi_windefines['CMAKE_C_FLAGS'] = ' '.join(cflags) + lldb_mi_windefines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) + lldb_mi_windefines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + lldb_mi_windefines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + + if self.build_config.enable_assertions: + lldb_mi_windefines['LLVM_ENABLE_ASSERTIONS'] = 'ON' + + return lldb_mi_windefines + + + def build_lldb_mi_for_windows(self): + self.logger().info('Building lldb-mi for windows.') + + build_dir = self.merge_out_path('clang_mingw', 'clang-10.0.1') + lldb_mi_windows64_path = self.merge_out_path('windows-x86_64-lldb-mi') + lldb_mi_cmake_path = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, '../lldb-mi')) + windows64_install = self.merge_out_path('windows-x86_64-install') + cc = os.path.join(build_dir, 'bin', 'clang') + cxx = os.path.join(build_dir, 'bin', 'clang++') + + windows_sysroot = self.merge_out_path('clang_mingw', 'clang-10.0.1', 'x86_64-w64-mingw32') + self.check_create_dir(lldb_mi_windows64_path) + compiler_rt_path = self.merge_out_path('clang_mingw', 'clang-10.0.1', + 'lib', 'clang', '10.0.1', 'lib', 'windows') + + ldflags = ['-fuse-ld=lld', + '--rtlib=compiler-rt', + '-L%s' % compiler_rt_path, + '-lunwind', + '-L%s' % os.path.join(windows64_install, 'lib'), + ] + ldflags.extend(self.ldflags_lists_define()) + ldflags.append(os.path.join(windows64_install, 'lib')) + ldflags.append('-Wl,--high-entropy-va') + + + cflags = ['-stdlib=libc++', + '--target=x86_64-pc-windows-gnu', + ] + cflags.extend(self.cflags_lists_define()) + cflags.append('-fno-exceptions') + cflags.append('-fno-rtti') + + cxxflags = list(cflags) + cxxflags.extend(('-I', os.path.join(windows64_install, 'include', 'c++', 'v1'))) + + zlib_path = os.path.abspath( + os.path.join('../../', 'prebuilts', 'clang', 'host', 'windows-x86', 'toolchain-prebuilts', 'zlib')) + zlib_inc = os.path.join(zlib_path, 'include') + zlib_lib = os.path.join(zlib_path, 'lib') + + cflags.extend(['-I', zlib_inc]) + cxxflags.extend(['-I', zlib_inc]) + ldflags.extend(['-L', zlib_lib]) + + + lldb_mi_env = dict(self.build_config.ORIG_ENV) + lldb_mi_env['LD_LIBRARY_PATH'] = os.path.join(build_dir, 'lib') + self.rm_cmake_cache(lldb_mi_windows64_path) + + self.invoke_cmake(lldb_mi_cmake_path, + lldb_mi_windows64_path, + self.lldb_mi_windefines_dictionary(cc, cxx, windows_sysroot, cflags, cxxflags, ldflags), + env=lldb_mi_env) + + self.invoke_ninja(lldb_mi_windows64_path, + env=lldb_mi_env, + install=False) + + self.llvm_package.copy_lldb_mi_to_windows(windows64_install, lldb_mi_windows64_path) + + +class LlvmPackage(BuildUtils): + + def __init__(self, build_config): + super(LlvmPackage, self).__init__(build_config) + + def copy_lldb_server_to_llvm_install(self, lldb_path, crt_install, llvm_triple): + # Copy lldb-server + libname = 'lldb-server' + src_lib = os.path.join(lldb_path, 'bin', libname) + dst_dir = os.path.join(crt_install, 'bin', llvm_triple) + self.check_create_dir(dst_dir) + self.check_copy_file(src_lib, os.path.join(dst_dir, libname)) + + def copy_lldb_mi_to_llvm_install(self, lldb_mi_path, llvm_install): + # Copy lldb-mi + lldb_mi_dst = os.path.join(llvm_install, 'bin', 'lldb-mi') + lldb_mi_src = os.path.join(lldb_mi_path, 'src', 'lldb-mi') + + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def copy_lldb_mi_to_windows(self, windows64_install, lldb_mi_windows64_path): + # Copy lldb-mi for windows + lldb_mi_dst = os.path.join(windows64_install, 'bin', 'lldb-mi.exe') + lldb_mi_src = os.path.join(lldb_mi_windows64_path, 'src', 'lldb-mi.exe') + if os.path.exists(lldb_mi_dst): + os.remove(lldb_mi_dst) + self.check_copy_file(lldb_mi_src, lldb_mi_dst) + + def package_libcxx(self): + libcxx_ndk_install=self.merge_out_path('libcxx-ndk') + libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'c++', 'v1') + hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64'] + + if os.path.exists(libcxx_ndk_install): + for headerfile in os.listdir(libcxx_ndk_install_include): + if not headerfile =='__config': + if os.path.isdir(os.path.join(libcxx_ndk_install_include, headerfile)): + shutil.rmtree(os.path.join(libcxx_ndk_install_include, headerfile)) + else: + os.remove(os.path.join(libcxx_ndk_install_include, headerfile)) + + #Package libcxx-ndk + for host in hosts_list: + tarball_name = 'libcxx-ndk-%s-%s' % (self.build_config.build_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_path, 'libcxx-ndk'] + self.check_call(args) + self.check_rm_tree(libcxx_ndk_install) + + @staticmethod + def merge_tree(src_dir, dst_dir): + for item in os.listdir(src_dir): + src_path = os.path.join(src_dir, item) + dst_path = os.path.join(dst_dir, item) + if os.path.isfile(src_path): + shutil.copyfile(src_path, dst_path) + else: + shutil.copytree(src_path, dst_path) + + + def install_mingw_python(self, install_dir): + py_root = self.merge_out_path('../third_party', 'mingw-w64', 'mingw-w64-python', + self.build_config.LLDB_PY_VERSION) + bin_root = os.path.join(install_dir, 'bin') + py_dll = 'libpython' + self.build_config.LLDB_PY_VERSION + '.dll' + shutil.copyfile(os.path.join(py_root, py_dll), os.path.join(bin_root, py_dll)) + self.merge_tree(os.path.join(py_root, 'lib'), + os.path.join(bin_root, 'python', 'lib', 'python%s' % self.build_config.LLDB_PY_VERSION)) + + + + + + def windows_lib_files_operation(self, lib_files, lib_dir, install_dir): + + # Remove unnecessary Windows lib files. + windows_necessary_lib_files = ['libc++.a', 'libc++abi.a'] + + for lib_file in lib_files: + if lib_file.endswith('.a') and lib_file not in windows_necessary_lib_files: + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + for necessary_lib_file in windows_necessary_lib_files: + if not os.path.isfile(os.path.join(lib_dir, necessary_lib_file)): + raise RuntimeError('Did not find %s under %s' % (necessary_lib_file, lib_dir)) + self.install_mingw_python(install_dir) + + + def darwin_stripped_xargs(self, bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin): + for bin_filename in os.listdir(bin_dir): + binary = os.path.join(bin_dir, bin_filename) + if not os.path.isfile(binary): + continue + if bin_filename not in necessary_bin_files: + os.remove(binary) + elif bin_filename not in script_bins: + if bin_filename not in need_x_bins_darwin and self.host_is_darwin(): + self.check_call(['strip', '-x', binary]) + else: + self.check_call(['strip', binary]) + + + def strip_lldb_server(self, host, install_dir): + clang_version_bin_dir = os.path.join(install_dir, 'lib', 'clang', '10.0.1', 'bin') + + if not host == 'linux-x86_64' or not os.path.exists(clang_version_bin_dir): + return + llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip') + for llvm_triple_dir in os.listdir(clang_version_bin_dir): + llvm_triple_bin_dir = os.path.join(clang_version_bin_dir, llvm_triple_dir) + + if not os.path.isdir(llvm_triple_bin_dir): + continue + + for bin_filename in os.listdir(llvm_triple_bin_dir): + binary = os.path.join(llvm_triple_bin_dir, bin_filename) + if os.path.isfile(binary): + self.check_call([llvm_strip, binary]) + + + def notice_prebuilts_file(self, host, projects, install_dir): + + # Fetch all the LICENSE.* files under our projects and append them into a + # Single NOTICE file for the resulting prebuilts. + notices = [] + for project in projects: + license_pattern = os.path.abspath(os.path.join(self.build_config.LLVM_PROJECT_DIR, project, 'LICENSE.*')) + for license_file in glob.glob(license_pattern): + with open(license_file) as notice_file: + notices.append(notice_file.read()) + + zlib_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/zlib/LICENSE')) + with open(zlib_license_file) as notice_file: + notices.append(notice_file.read()) + + if host == 'windows-x86_64': + mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, + 'third_party/mingw-w64/COPYING')) + with open(mingw_license_file) as notice_file: + notices.append(notice_file.read()) + + with open(os.path.join(install_dir, 'NOTICE'), 'w') as notice_file: + notice_file.write('\n'.join(notices)) + + + def tar_windows_mingw(self, host): + + if host == 'windows-x86_64': + windows64_install = self.merge_out_path('windows-x86_64-install') + clang_mingw_dir = self.merge_out_path('clang_mingw') + clang_mingw_sysroot_dir = os.path.join(clang_mingw_dir, 'clang-10.0.1', 'x86_64-w64-mingw32') + package_name = 'clang-mingw-%s' % self.build_config.build_name + clang_mingw_sysroot_lib_dir = os.path.join(clang_mingw_sysroot_dir, 'lib') + clang_windows_lib_dir = os.path.join(windows64_install, 'lib') + + necessary_lib = {'libc++abi.a', 'libc++.a', 'libunwind.a'} + for libname in necessary_lib: + shutil.copy2(os.path.join(clang_windows_lib_dir, libname), clang_mingw_sysroot_lib_dir) + + self.check_copy_tree(os.path.join(windows64_install, 'include', 'c++'), + os.path.join(clang_mingw_sysroot_dir, 'include', 'c++')) + + lib_files = [] + if os.path.isdir(os.path.join(clang_mingw_dir, 'clang-10.0.1', 'lib')): + lib_files = os.listdir(os.path.join(clang_mingw_dir, 'clang-10.0.1', 'lib')) + for lib_file in lib_files: + if lib_file.endswith('.a'): + static_library = os.path.join(os.path.join(clang_mingw_dir, 'clang-10.0.1', 'lib'), lib_file) + os.remove(static_library) + + self.check_rm_tree(os.path.join(clang_mingw_dir, 'clang-10.0.1', 'include')) + + package_path = '%s%s' % (self.merge_out_path(package_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + toolchain_name = 'clang-%s' % self.build_config.build_name + self.check_copy_tree(os.path.join(clang_mingw_dir, 'clang-10.0.1'), + os.path.join(clang_mingw_dir, toolchain_name)) + args = ['tar', '-cjC', clang_mingw_dir, '-f', package_path, toolchain_name] + self.check_call(args) + self.check_rm_tree(os.path.join(clang_mingw_dir, toolchain_name)) + + def package_clang_bin_file(self, necessary_bin_files, ext): + necessary_bin_file = [ + 'clang%s' % ext, + 'clang++%s' % ext, + 'clang-cpp%s' % ext, + 'clang-%s%s' % (self.build_config.VERSION.split('.')[0], ext), + 'clang-check%s' % ext, + 'clang-cl%s' % ext, + 'clang-format%s' % ext, + 'clang-tidy%s' % ext, + 'clangd%s' % ext, + 'count%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_lldb_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'dsymutil%s' % ext, + 'FileCheck%s' % ext, + 'git-clang-format', + 'ld.lld%s' % ext, + 'ld64.lld%s' % ext, + 'lld%s' % ext, + 'lld-link%s' % ext, + 'lldb%s' % ext, + 'lldb-argdumper%s' % ext, + 'lldb-server%s' % ext, + 'lldb-vscode%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_llvm_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'llvm-addr2line%s' % ext, + 'llvm-ar%s' % ext, + 'llvm-as%s' % ext, + 'llvm-cfi-verify%s' % ext, + 'llvm-config%s' % ext, + 'llvm-cov%s' % ext, + 'llvm-cxxfilt%s' % ext, + 'llvm-dis%s' % ext, + 'llvm-lib%s' % ext, + 'llvm-link%s' % ext, + 'llvm-modextract%s' % ext, + 'llvm-nm%s' % ext, + 'llvm-objcopy%s' % ext, + 'llvm-objdump%s' % ext, + 'llvm-profdata%s' % ext, + 'llvm-ranlib%s' % ext, + 'llvm-readelf%s' % ext, + 'llvm-readobj%s' % ext, + 'llvm-size%s' % ext, + 'llvm-strings%s' % ext, + 'llvm-strip%s' % ext, + 'llvm-symbolizer%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_scan_bin_file(necessary_bin_files, ext): + necessary_bin_file = [ + 'not%s' % ext, + 'sancov%s' % ext, + 'sanstats%s' % ext, + 'scan-build%s' % ext, + 'scan-view%s' % ext, + 'yaml2obj%s' % ext, + ] + necessary_bin_files.extend(necessary_bin_file) + + @staticmethod + def package_license_project_tuple(): + # Install license files as NOTICE in the toolchain install dir. + projects = ( + 'llvm', + 'compiler-rt', + 'libcxx', + 'libcxxabi', + 'openmp', + 'clang', + 'clang-tools-extra', + 'lld', + 'lldb', + 'libunwind', + ) + return projects + + def remove_unnecessary_bin(self, necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext): + + lib_files = [] + if os.path.isdir(lib_dir): + lib_files = os.listdir(lib_dir) + if host == 'windows-x86_64': + vers_major = int(self.build_config.VERSION.split('.')[0]) + # Redefining necessary bin files for Windows. + windows_forbidden_list_bin_files = ['clang-%s%s' % (vers_major, ext), 'scan-build%s' % ext, + 'scan-view%s' % ext] + windows_additional_bin_files = ['liblldb%s' % shlib_ext, 'libpython3.10%s' % shlib_ext, + ('libLLVM%s' if vers_major > 10 else 'LLVM%s') % shlib_ext] + + new_necessary_bin_files = list(set(necessary_bin_files) - set(windows_forbidden_list_bin_files)) + new_necessary_bin_files.extend(windows_additional_bin_files) + del necessary_bin_files[:] + necessary_bin_files.extend(new_necessary_bin_files) + + self.windows_lib_files_operation(lib_files, lib_dir, install_dir) + else: + # Remove unnecessary static libraries. + for lib_file in lib_files: + if lib_file.endswith('.a'): + static_library = os.path.join(lib_dir, lib_file) + os.remove(static_library) + + def package_up_resulting(self, package_name, host, install_host_dir): + # Package up the resulting trimmed install/ directory. + tarball_name = '%s-%s' % (package_name, host) + package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') + self.logger().info('Packaging %s', package_path) + args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name] + if host == 'windows-x86_64': + # windows do not support symlinks, + # replace them with file copies + args.insert(1, '--dereference') + + self.check_call(args) + + # Package ohos NDK + if host == 'linux-x86_64' and os.path.exists(self.merge_out_path('sysroot')): + tarball_ndk_name = 'ohos-sysroot-%s' % self.build_config.build_name + package_ndk_path = '%s%s' % (self.merge_out_path(tarball_ndk_name), '.tar.bz2') + self.logger().info('Packaging %s', package_ndk_path) + args = ['tar', '-chjC', self.build_config.OUT_PATH, '-f', package_ndk_path, 'sysroot'] + self.check_call(args) + + # Packing Operation. + + def package_operation(self, build_dir, host): + + self.logger().info('Packaging for other environments.') + package_name = 'clang-%s' % self.build_config.build_name + self.set_clang_version(build_dir) + + if host == 'windows-x86_64': + ext = '.exe' + shlib_ext = '.dll' + elif host == 'linux-x86_64': + ext = '' + shlib_ext = '.so' + else: + ext = '' + shlib_ext = '.dylib' + + install_dir = self.merge_out_path('install', host, package_name) + bin_dir = os.path.join(install_dir, 'bin') + lib_dir = os.path.join(install_dir, 'lib') + install_host_dir = os.path.abspath(os.path.join(install_dir, '../')) + self.check_rm_tree(install_host_dir) + self.check_copy_tree(build_dir, install_dir) + # copy readme file to install_dir + shutil.copyfile(os.path.join(self.build_config.CURRENT_DIR, "toolchain_readme.md"), + os.path.join(install_dir, "README.md")) + + # Remove unnecessary binaries. + necessary_bin_files = [] + self.package_clang_bin_file(necessary_bin_files, ext) + self.package_lldb_bin_file(necessary_bin_files, ext) + self.package_llvm_bin_file(necessary_bin_files, ext) + self.package_scan_bin_file(necessary_bin_files, ext) + + if self.build_config.need_lldb_mi: + necessary_bin_files.append('lldb-mi%s' % ext) + self.remove_unnecessary_bin(necessary_bin_files, host, lib_dir, install_dir, ext, shlib_ext) + + # Scripts that should not be stripped + script_bins = ['git-clang-format', 'scan-build', 'scan-view'] + need_x_bins_darwin = ['clang', 'clang++', 'clang-9', 'clang-cl', 'clang-cpp'] + + # Bin file in the list should be stripped with -x args when host=darwin + self.darwin_stripped_xargs(bin_dir, necessary_bin_files, script_bins, need_x_bins_darwin) + + # Strip lldb-server + self.strip_lldb_server(host, install_dir) + + for necessary_bin_file in necessary_bin_files: + if not os.path.isfile(os.path.join(bin_dir, necessary_bin_file)): + print('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + raise RuntimeError('Did not find %s in %s' % (necessary_bin_file, bin_dir)) + + cmake_dir = os.path.join(lib_dir, 'cmake') + self.check_rm_tree(cmake_dir) + + self.notice_prebuilts_file(host, self.package_license_project_tuple(), install_dir) + + create_tar = True + if create_tar: + self.package_up_resulting(package_name, host, install_host_dir) + + # Tar windows mingw + self.tar_windows_mingw(host) + return + + + +def main(): + build_config = BuildConfig() + build_utils = BuildUtils(build_config) + sysroot_composer = SysrootComposer(build_config) + llvm_core = LlvmCore(build_config) + llvm_package = LlvmPackage(build_config) + lldb_mi = LldbMi(build_config, llvm_package) + llvm_libs = LlvmLibs(build_config, sysroot_composer, llvm_package) + + args = build_config.parse_args() + need_host = build_utils.host_is_darwin() or ('linux' not in args.no_build) + need_windows = build_utils.host_is_linux() and \ + ('windows' not in args.no_build) + + llvm_install = build_utils.merge_out_path('llvm-install') + windows64_install = build_utils.merge_out_path('windows-x86_64-install') + + configs = [] + if not build_config.no_build_arm: + configs.append(('arm', build_utils.liteos_triple('arm'))) + configs.append(('arm', build_utils.open_hos_triple('arm'))) + + if not build_config.no_build_aarch64: + configs.append(('arm64', build_utils.open_hos_triple('aarch64'))) + + if build_config.do_build and need_host: + llvm_core.llvm_compile( + build_config.build_name, + llvm_install, + build_config.debug, + build_config.no_lto, + build_config.build_instrumented, + build_config.xunit_xml_output) + + llvm_core.set_clang_version(llvm_install) + + if build_config.do_build and build_utils.host_is_linux(): + sysroot_composer.setup_cmake_platform(llvm_install) + llvm_libs.build_crt_libs(configs, llvm_install, build_config.need_lldb_server) + + if build_config.need_libs: + for (arch, target) in configs: + llvm_libs.build_libs(build_config.need_lldb_server, llvm_install, target) + + if build_config.do_build and need_windows: + mingw.main() + llvm_libs.build_need_libs_for_windows() + llvm_core.llvm_compile_for_windows(build_config.TARGETS, + build_config.enable_assertions, + build_config.build_name) + + if build_config.need_lldb_mi: + lldb_mi.build_lldb_mi_for_windows() + + if build_config.do_build and build_config.need_lldb_mi and need_host: + lldb_mi.build_lldb_mi(llvm_install) + + if build_config.do_package: + if build_utils.host_is_linux(): + llvm_package.package_libcxx() + llvm_package.package_operation(llvm_install, build_utils.use_platform()) + if build_config.do_package and need_windows: + llvm_package.package_operation(windows64_install, 'windows-x86_64') + +if __name__ == '__main__': + main() diff --git a/llvm-build/build_musl.sh b/llvm-build/build_musl.sh new file mode 100755 index 000000000000..2d67800641e6 --- /dev/null +++ b/llvm-build/build_musl.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -e + +# This script is used to create musl's libc.so. + +#default variables +CLANG_BIN_ROOT="${PWD}/../../out/install/linux-x86_64/clang-dev/bin/" +TARGET_TRIPLE="" +OUT="${PWD}/../../out" +make_libs=0 + +#argument parser +while getopts "c:t:o:lh" arg +do + case "${arg}" in + "c") + CLANG_BIN_ROOT=${OPTARG} + ;; + "t") + TARGET_TRIPLE=${OPTARG} + ;; + "o") + OUT=${OPTARG} + ;; + "l") + make_libs=1 + ;; + "h") + echo "Usage: ./build_musl.sh [OPTION]" + echo " Build C/C++ dynamic libs and runtime object" + echo " Options are:" + echo " -c Specify clang bin path" + echo " -t Specify target tripple" + echo " -o Specify the build output directory" + echo " -l Install libs" + exit 0 + ;; + ?) + echo "unkown argument" + exit 1 + ;; + esac +done + +if [ -z "${TARGET_TRIPLE}" ] +then + echo "[ERROR] Empty target triple in build_musl.sh" + exit 1 +fi + +# Canonicalize paths +CLANG_BIN_ROOT=$(readlink -f ${CLANG_BIN_ROOT}) + +CFLAGS_FOR_TARGET=("-mfloat-abi=soft" "-mfloat-abi=soft -mcpu=cortex-a7" +"-mfloat-abi=softfp -mfpu=neon-vfpv4 -mcpu=cortex-a7" "-mfloat-abi=hard -mfpu=neon-vfpv4 -mcpu=cortex-a7") + +if [ $TARGET_TRIPLE == "arm-liteos-ohos" ]; then + TARGET_USER="liteos_a_user" + TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "arm-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="arm" +else + TARGET_USER="linux_user" + TARGETS_PREFIX="aarch64" +fi + +echo "CLANG_BIN_ROOT=${CLANG_BIN_ROOT}" +echo "ARCH=${TARGETS_PREFIX}" +echo "TARGET=${TARGET_TRIPLE}" +echo "TOPDIR=${PWD}/../.." +echo "TARGETS=${TARGET_USER}" +echo "OUT=${OUT}" +echo "SYSROOTDIR=${OUT}/sysroot" + +# build musl_headers +make musl_header_install_for_${TARGET_USER} CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../\ + SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER} TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + +# build musl_libs +if ((make_libs == 1)); then + if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ]; then + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile + else + for ARCH_CFLAG in "${CFLAGS_FOR_TARGET[@]}" + do + make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ + TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} ARCH_CFLAGS="${ARCH_CFLAG}" -f Makefile + done + fi +fi +make distclean -f Makefile \ No newline at end of file diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh new file mode 100755 index 000000000000..962777b33850 --- /dev/null +++ b/llvm-build/env_prepare.sh @@ -0,0 +1,18 @@ +llvm_name=llvm +cmake_name=linux-x86 +clang_name=clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04 +llvm_dir=clang/ohos/linux-x86_64 +cmake_dir=cmake +cd prebuilts +mkdir -p $llvm_dir +mkdir -p $cmake_dir + +wget https://mirrors.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz +wget https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/linux/cmake-linux-x86-3.16.5.tar.gz +wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +tar -xvf llvm.tar.gz +tar -xvf cmake-linux-x86-3.16.5.tar.gz +tar -xvf clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +mv $llvm_name $llvm_dir/llvm +mv $cmake_name $cmake_dir/linux-x86 +mv $clang_name $llvm_dir/clang-10.0.1 \ No newline at end of file diff --git a/llvm-build/mingw.py b/llvm-build/mingw.py new file mode 100644 index 000000000000..8b73bca1749a --- /dev/null +++ b/llvm-build/mingw.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""donwload and build mingw64-7.0.0 sysroot""" + +import logging +import os +import shutil +import subprocess +import sys + + +class BuildConfig(): + + def __init__(self): + self.THIS_DIR = os.path.realpath(os.path.dirname(__file__)) + self.OUT_DIR = os.environ.get('OUT_DIR', self.repo_root('out')) + self.MINGW_DIR = self.out_root('clang_mingw', 'clang-10.0.1', 'x86_64-w64-mingw32') + + def repo_root(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../../', *args)) + + def out_root(self, *args): + return os.path.realpath(os.path.join(self.OUT_DIR, *args)) + + def mingw64_dir(self): + if os.path.isdir(self.MINGW_DIR): + shutil.rmtree(self.MINGW_DIR) + os.makedirs(self.MINGW_DIR) + return self.MINGW_DIR + + def llvm_path(self, *args): + return os.path.realpath(os.path.join(self.THIS_DIR, '../llvm-project', *args)) + + +class LlvmMingw(): + + def __init__(self, build_config): + self.build_config = build_config + + self.CMAKE_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'cmake') + self.NINJA_BIN_PATH = os.path.join(self.cmake_prebuilt_bin_dir(), 'ninja') + + self.CLANG_PATH = self.build_config.out_root('clang_mingw', 'clang-10.0.1') + self.LLVM_CONFIG = os.path.join(self.CLANG_PATH, 'bin', 'llvm-config') + self.SYSROOT = self.build_config.out_root('clang_mingw', 'clang-10.0.1', 'x86_64-w64-mingw32') + self.LLVM_TRIPLE = 'x86_64-windows-gnu' + # out path + self.CRT_PATH = self.build_config.out_root('clang_mingw', 'lib', 'clangrt-%s' % self.LLVM_TRIPLE) + # install path + self.CRT_INSTALL = self.build_config.out_root('clang_mingw', 'clang-10.0.1', 'lib', 'clang', '10.0.1') + # prefix & env + self.prefix = build_config.mingw64_dir() + common_flags = "-target x86_64-w64-mingw32 -rtlib=compiler-rt \ + -stdlib=libc++ -fuse-ld=lld -Qunused-arguments -g -O2" + self.env = { + "CC": "%s/../bin/clang" % self.prefix, + "CXX": "%s/../bin/clang" % self.prefix, + "AR": "%s/../bin/llvm-ar" % self.prefix, + "DLLTOOL": "%s/../bin/llvm-dlltool" % self.prefix, + "LD": "%s/../bin/ld.lld" % self.prefix, + "RANLIB": "%s/../bin/llvm-ranlib" % self.prefix, + "STRIP": "%s/../bin/llvm-strip" % self.prefix, + "LDFLAGS": common_flags, + "CFLAGS": common_flags, + "CXXFLAGS": common_flags, + } + + def cmake_prebuilt_bin_dir(self): + return self.build_config.repo_root('prebuilts/cmake', 'linux-x86', 'bin') + + def base_cmake_defines(self): + self.cmake_defines = {} + self.cmake_defines['CMAKE_BUILD_TYPE'] = 'Release' + self.cmake_defines['LLVM_ENABLE_ASSERTIONS'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_TERMINFO'] = 'OFF' + self.cmake_defines['LLVM_ENABLE_THREADS'] = 'ON' + self.cmake_defines['LLVM_USE_NEWPM'] = 'ON' + self.cmake_defines['COMPILER_RT_BUILD_XRAY'] = 'OFF' + return self.cmake_defines + + @staticmethod + def check_create_path(path): + if not os.path.exists(path): + os.makedirs(path) + + @staticmethod + def check_call(cmd, *args, **kwargs): + subprocess.check_call(cmd, *args, **kwargs) + + @staticmethod + def update_cmake_sysroot_flags(defines, sysroot): + defines['CMAKE_SYSROOT'] = sysroot + defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE'] = 'ONLY' + defines['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM'] = 'NEVER' + + def comiler_rt_defines(self): + arch = 'x86_64' + cc = os.path.join(self.CLANG_PATH, 'bin', 'clang') + cxx = os.path.join(self.CLANG_PATH, 'bin', 'clang++') + self.crt_defines = {} + self.crt_defines['CMAKE_C_COMPILER'] = cc + self.crt_defines['CMAKE_CXX_COMPILER'] = cxx + self.crt_defines['LLVM_CONFIG_PATH'] = self.LLVM_CONFIG + clang_libcxx_lib = self.build_config.out_root('clang_mingw', 'clang-10.0.1', 'lib') + ldflags = [ + '-L%s' % clang_libcxx_lib, + '-fuse-ld=lld', + '-Wl,--gc-sections', + '-pie', + '--rtlib=compiler-rt', + '-stdlib=libc++', + '-v', + ] + self.crt_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) + self.crt_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) + self.crt_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) + self.update_cmake_sysroot_flags(self.crt_defines, self.SYSROOT) + cflags = [ + '--target=%s' % self.LLVM_TRIPLE, + '-ffunction-sections', + '-fdata-sections', + ] + cflags.append('-funwind-tables') + cflags.append('-v') + self.crt_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_ASM_FLAGS'] = ' '.join(cflags) + self.crt_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_COMPILER_CFLAGS'] = ' '.join(cflags) + self.crt_defines['COMPILER_RT_TEST_TARGET_TRIPLE'] = self.LLVM_TRIPLE + self.crt_defines['COMPILER_RT_INCLUDE_TESTS'] = 'OFF' + self.crt_defines['CMAKE_INSTALL_PREFIX'] = self.CRT_INSTALL + self.crt_defines['COMPILER_RT_BUILD_LIBFUZZER'] = 'OFF' + self.crt_defines['COMPILER_RT_USE_BUILTINS_LIBRARY'] = 'TRUE' + self.crt_defines['CMAKE_SYSTEM_NAME'] = 'Windows' + self.crt_defines['CMAKE_CROSSCOMPILING'] = 'True' + self.crt_defines['CMAKE_C_COMPILER_WORKS'] = '1' + self.crt_defines['CMAKE_CXX_COMPILER_WORKS'] = '1' + self.crt_defines['SANITIZER_CXX_ABI'] = 'libcxxabi' + self.crt_defines['CMAKE_TRY_COMPILE_TARGET_TYPE'] = 'STATIC_LIBRARY' + self.crt_defines['COMPILER_RT_BUILD_SANITIZERS'] = 'OFF' + self.crt_defines['COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN'] = 'OFF' + #cmake config + self.crt_defines.update(self.base_cmake_defines()) + return self.crt_defines + + def build_comiler_rt(self): + crt_defines = self.comiler_rt_defines() + #environ + crt_env = dict(dict(os.environ)) + #compiler-rt path + crt_cmake_path = self.build_config.llvm_path('compiler-rt') + #cmake + self.invoke_cmake( + out_path=self.CRT_PATH, + defines=crt_defines, + env=crt_env, + cmake_path=crt_cmake_path) + + def invoke_cmake(self, out_path, defines, env, cmake_path, target=None, install=True): + flags = ['-G', 'Ninja'] + flags += ['-DCMAKE_PREFIX_PATH=%s' % self.cmake_prebuilt_bin_dir()] + + for key in defines: + newdef = ''.join(['-D', key, '=', defines[key]]) + flags += [newdef] + flags += [cmake_path] + + self.check_create_path(out_path) + + if target: + ninja_target = [target] + else: + ninja_target = [] + + self.check_call([self.CMAKE_BIN_PATH] + flags, cwd=out_path, env=env) + self.check_call([self.NINJA_BIN_PATH] + ninja_target, cwd=out_path, env=env) + if install: + self.check_call([self.NINJA_BIN_PATH, 'install'], cwd=out_path, env=env) + + def build_clang_mingw(self): + clang_mingw_dir = self.build_config.out_root('clang_mingw') + if os.path.isdir(clang_mingw_dir): + shutil.rmtree(clang_mingw_dir) + os.makedirs(clang_mingw_dir) + shutil.copytree(self.build_config.repo_root('prebuilts/clang/ohos/linux-x86_64/clang-10.0.1'), + '%s/clang-10.0.1' % clang_mingw_dir) + # Replace clang binaries to avoid dependency on libtinfo + # TODO: Use `prebuilts/clang/ohos/linux-x86_64/llvm` instead of + # `prebuilts/clang/ohos/linux-x86_64/clang-10.0.1` + shutil.copy(self.build_config.repo_root('prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang'), + '%s/clang-10.0.1/bin/clang' % clang_mingw_dir) + shutil.copy(self.build_config.repo_root('prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang++'), + '%s/clang-10.0.1/bin/clang++' % clang_mingw_dir) + shutil.copy(self.build_config.repo_root('prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang-10'), + '%s/clang-10.0.1/bin/clang-10' % clang_mingw_dir) + + def build_mingw64_headers(self): + headers_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-headers', 'build') + if os.path.isdir(headers_dir): + shutil.rmtree(headers_dir) + os.makedirs(headers_dir) + os.chdir(headers_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--enable-idl', '--with-default-win32-winnt=0x600', + '--with-default-msvcrt=ucrt'] + self.env['INSTALL'] = "install -C" + self.check_call(cmd, env=self.env) + self.check_call(['make', 'install'], env=self.env) + + def build_mingw64_crtlibs(self): + crtlibs_dir = self.build_config.repo_root('third_party', 'mingw-w64', 'mingw-w64-crt', 'build') + if os.path.isdir(crtlibs_dir): + shutil.rmtree(crtlibs_dir) + os.makedirs(crtlibs_dir) + os.chdir(crtlibs_dir) + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--host=x86_64-w64-mingw32', '--disable-lib32', + '--enable-lib64', '--with-default-msvcrt=ucrt'] + self.check_call(cmd, env=self.env) + self.check_call(['make', '-j4'], env=self.env) + self.check_call(['make', 'install'], env=self.env) + + def build_mingw64_winpthreads(self): + winpthreads_dir = self.build_config.repo_root('third_party', 'mingw-w64', + 'mingw-w64-libraries', 'winpthreads', 'build') + if os.path.isdir(winpthreads_dir): + shutil.rmtree(winpthreads_dir) + os.makedirs(winpthreads_dir) + os.chdir(winpthreads_dir) + self.env['RC'] = "%s/windres.sh" % self.build_config.THIS_DIR + self.env['EXEEXT'] = ".exe" + cmd = ['../configure', '--prefix=%s' % self.prefix, + '--host=x86_64-w64-mingw32', + '--libdir=%s/lib' % self.prefix] + self.check_call(cmd, env=self.env) + self.check_call(['make', '-j4'], env=self.env) + self.check_call(['make', 'install'], env=self.env) + + +def main(): + build_config = BuildConfig() + llvm_mingw = LlvmMingw(build_config) + + llvm_mingw.build_clang_mingw() + llvm_mingw.build_mingw64_headers() + llvm_mingw.build_mingw64_crtlibs() + llvm_mingw.build_comiler_rt() + llvm_mingw.build_mingw64_winpthreads() + return 0 + +if __name__ == '__main__': + main() diff --git a/llvm-build/toolchain_readme.md b/llvm-build/toolchain_readme.md new file mode 100644 index 000000000000..441305ead76d --- /dev/null +++ b/llvm-build/toolchain_readme.md @@ -0,0 +1,25 @@ +## Overview + +This readme briefly describes the functionality of our LLVM toolchain and what we have included specially to the LLVM toolchain. + +## Functionality + +The LLVM toolchain is built based on LLVM 10.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 10.0.1, please refer to [LLVM 10.0.1](https://lists.llvm.org/pipermail/llvm-announce/2020-August/000088.html). + + +## Specifically Included Triplets + +Despite all the components provided by LLVM community, we included several triplets for different types of ohos devices to our LLVM toochain, listed as below. For specification, liteos is a newly included OS name which indicate the simplified linux kernel. + +| Triplet Name | Architecture | System Kernel | System | +| ---------------------- | ------------ | ------------- | --------------- | +| arm-liteos-ohos | ARM 32bits | LiteOS | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Small system | +| arm-linux-ohos | ARM 32bits | Linux | Standard system | +| aarch64-linux-ohos | ARM 64bits | Linux | Standard system | + +For detailed definition of Small System and Standard System, please refer to [System Types](https://gitee.com/openharmony/docs/blob/master/en/device-dev/Readme-EN.md). + +### Specify the triplet + +To build images for different types of platform, you can configure the triplet in the build scripts by setting "--target=xxx" using cflags, xxx should be replaced with a specific triplet name. diff --git a/llvm-build/windres.sh b/llvm-build/windres.sh new file mode 100644 index 000000000000..054bed7b8115 --- /dev/null +++ b/llvm-build/windres.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Copyright (C) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# This script is used to deal version.rc file. +set -e + +#default variables +MYDIR=$(dirname $0) +CLANG_BIN_ROOT="$MYDIR/../../out/clang_mingw/clang-10.0.1/bin/" +CLANG_FLAGS="clang -target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ -fuse-ld=lld -Qunused-arguments -E -xc -DRC_INVOKED=1" +LLVM_RC_FLAGS="llvm-rc -I ../src src/.libs/version.o.preproc.rc -c 1252 -fo src/.libs/version.o.out.res" +LLVM_CVTRES_FLAGS="llvm-cvtres src/.libs/version.o.out.res -machine:X64 -out:" + +while getopts "i:o:h" arg +do + case "${arg}" in + "i") + IN=${OPTARG} + ;; + "o") + OUT=${OPTARG} + ;; + "h") + echo "Usage: ./build_libs.sh [OPTION]" + echo " Build C/C++ dynamic libs and runtime object" + echo " Options are:" + echo " -i Name of the input file." + echo " -o Name of the output file." + echo " -h Display this message and exit." + exit 0 + ;; + ?) + echo "unkown argument" + exit 1 + ;; + esac +done + +CLANG_FLAGS="${CLANG_BIN_ROOT}${CLANG_FLAGS} -v $IN -o src/.libs/version.o.preproc.rc" +LLVM_RC_FLAGS="${CLANG_BIN_ROOT}${LLVM_RC_FLAGS}" +LLVM_CVTRES_FLAGS="${CLANG_BIN_ROOT}${LLVM_CVTRES_FLAGS}${OUT}" + +mkdir src/.libs +${CLANG_FLAGS} +${LLVM_RC_FLAGS} +${LLVM_CVTRES_FLAGS} -- Gitee From 990477c31d20bb7f863704246498bffcae5ad2b4 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Mon, 25 Oct 2021 13:27:00 +0100 Subject: [PATCH 03/19] CodeGenPrep: remove all copies of GEP from list if there are duplicates. Unfortunately ToT has changed enough from the revision where this actually caused problems that the test no longer triggers an assertion failure. --- llvm/lib/CodeGen/CodeGenPrepare.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index b2bc75c19709..1cbef984eab7 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -633,12 +633,8 @@ void CodeGenPrepare::removeAllAssertingVHReferences(Value *V) { return; auto &GEPVector = VecI->second; - const auto &I = - llvm::find_if(GEPVector, [=](auto &Elt) { return Elt.first == GEP; }); - if (I == GEPVector.end()) - return; + llvm::erase_if(GEPVector, [=](auto &Elt) { return Elt.first == GEP; }); - GEPVector.erase(I); if (GEPVector.empty()) LargeOffsetGEPMap.erase(VecI); } -- Gitee From 5fe0c8d4c1cd8f19c7f60c1c9acd9efeadbcd807 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant Date: Thu, 3 Feb 2022 16:36:32 +0300 Subject: [PATCH 04/19] Handle spills of indirect debug values correctly When handling register spill for indirect debug value LiveDebugValues pass doesn't add DW_OP_deref operator which may in some cases cause debugger to return value address, instead of value while machine register holding that address is spilled. Differential revision: https://reviews.llvm.org/D109142 --- llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp | 3 ++- llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp index e2daa46fe6b9..78f2c642f96a 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -451,8 +451,9 @@ private: // on top of. FIXME: spill locations created before this pass runs // are not recognized, and not handled here. auto *TRI = MF.getSubtarget().getRegisterInfo(); + auto Deref = Indirect ? DIExpression::DerefAfter : 0; auto *SpillExpr = TRI->prependOffsetExpression( - DIExpr, DIExpression::ApplyOffset, Loc.SpillLocation.SpillOffset); + DIExpr, DIExpression::ApplyOffset | Deref, Loc.SpillLocation.SpillOffset); unsigned Base = Loc.SpillLocation.SpillBase; return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr); } diff --git a/llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir b/llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir index ded90d4a6815..9a0785053f0f 100644 --- a/llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir +++ b/llvm/test/DebugInfo/MIR/X86/live-debug-values-restore.mir @@ -641,7 +641,7 @@ body: | # CHECK-LABEL: bb.0.entry: # CHECK: DBG_VALUE $rdi, 0, ![[TVAR]], !DIExpression() # CHECK-LABEL: bb.1.if.then: -# CHECK: DBG_VALUE $rsp, 0, ![[TVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus) +# CHECK: DBG_VALUE $rsp, 0, ![[TVAR]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref) # CHECK: INLINEASM # CHECK: DBG_VALUE ${{[a-zA-Z0-9]+}}, 0, ![[TVAR]], !DIExpression() # CHECK-LABEL: bb.2.if.end -- Gitee From d2516f13004fd35655512d948599a4ae39a3441b Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 29 Jun 2021 14:59:12 -0700 Subject: [PATCH 05/19] Change PathMappingList::FindFile to return an optional result (NFC) This is an NFC modernization refactoring that replaces the combination of a bool return + reference argument, with an Optional return value. Differential Revision: https://reviews.llvm.org/D104405 --- lldb/include/lldb/Target/PathMappingList.h | 9 ++------- lldb/source/Core/Module.cpp | 6 +++++- lldb/source/Core/SourceManager.cpp | 18 +++++++++++------- lldb/source/Symbol/LineEntry.cpp | 8 ++++---- lldb/source/Target/PathMappingList.cpp | 18 +++++++++--------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h index 9e1e6eb26eb9..b3b6d50db2bd 100644 --- a/lldb/include/lldb/Target/PathMappingList.h +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -94,14 +94,9 @@ public: /// \param[in] orig_spec /// The original source file path to try and remap. /// - /// \param[out] new_spec - /// The newly remapped filespec that is guaranteed to exist. - /// /// \return - /// /b true if \a orig_spec was successfully located and - /// \a new_spec is filled in with an existing file spec, - /// \b false otherwise. - bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const; + /// The newly remapped filespec that is guaranteed to exist. + llvm::Optional FindFile(const FileSpec &orig_spec) const; uint32_t FindIndexForPath(ConstString path) const; diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 1f9987c21658..eaaa10b11d08 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1595,7 +1595,11 @@ bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) { bool Module::FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const { std::lock_guard guard(m_mutex); - return m_source_mappings.FindFile(orig_spec, new_spec); + if (auto remapped = m_source_mappings.FindFile(orig_spec)) { + new_spec = *remapped; + return true; + } + return false; } bool Module::RemapSourceFile(llvm::StringRef path, diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index e79fcb48742d..61cf91963557 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -441,13 +441,17 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, } // Try remapping if m_file_spec does not correspond to an existing file. if (!FileSystem::Instance().Exists(m_file_spec)) { - FileSpec new_file_spec; - // Check target specific source remappings first, then fall back to - // modules objects can have individual path remappings that were - // detected when the debug info for a module was found. then - if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) || - target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) { - m_file_spec = new_file_spec; + // Check target specific source remappings (i.e., the + // target.source-map setting), then fall back to the module + // specific remapping (i.e., the .dSYM remapping dictionary). + auto remapped = target->GetSourcePathMap().FindFile(m_file_spec); + if (!remapped) { + FileSpec new_spec; + if (target->GetImages().FindSourceFile(m_file_spec, new_spec)) + remapped = new_spec; + } + if (remapped) { + m_file_spec = *remapped; m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); } } diff --git a/lldb/source/Symbol/LineEntry.cpp b/lldb/source/Symbol/LineEntry.cpp index a3907f4dd9c0..165ca607f4d6 100644 --- a/lldb/source/Symbol/LineEntry.cpp +++ b/lldb/source/Symbol/LineEntry.cpp @@ -253,9 +253,9 @@ AddressRange LineEntry::GetSameLineContiguousAddressRange( void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) { if (target_sp) { - // Apply any file remappings to our file - FileSpec new_file_spec; - if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec)) - file = new_file_spec; + // Apply any file remappings to our file. + if (auto new_file_spec = + target_sp->GetSourcePathMap().FindFile(original_file)) + file = *new_file_spec; } } diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index b22673f55471..00a93ae6e002 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -197,16 +197,16 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co return false; } -bool PathMappingList::FindFile(const FileSpec &orig_spec, - FileSpec &new_spec) const { +llvm::Optional +PathMappingList::FindFile(const FileSpec &orig_spec) const { if (m_pairs.empty()) - return false; - + return {}; + std::string orig_path = orig_spec.GetPath(); if (orig_path.empty()) - return false; - + return {}; + bool orig_is_relative = orig_spec.IsRelative(); for (auto entry : m_pairs) { @@ -231,15 +231,15 @@ bool PathMappingList::FindFile(const FileSpec &orig_spec, continue; if (orig_ref.consume_front(prefix_ref)) { + FileSpec new_spec; new_spec.SetFile(entry.second.GetCString(), FileSpec::Style::native); new_spec.AppendPathComponent(orig_ref); if (FileSystem::Instance().Exists(new_spec)) - return true; + return new_spec; } } - new_spec.Clear(); - return false; + return {}; } bool PathMappingList::Replace(ConstString path, -- Gitee From b862942ae06574434c8f996ac5dac77f05f6cdd8 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 29 Jun 2021 15:14:31 -0700 Subject: [PATCH 06/19] Express PathMappingList::FindFile() in terms of PathMappingList::RemapPath() NFC. This patch replaces the function body FindFile() with a call to RemapPath(), since the two functions implement the same functionality. Differential Revision: https://reviews.llvm.org/D104406 --- lldb/source/Target/PathMappingList.cpp | 46 +++----------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 00a93ae6e002..5283f0a5f535 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -197,48 +197,12 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co return false; } -llvm::Optional -PathMappingList::FindFile(const FileSpec &orig_spec) const { - if (m_pairs.empty()) - return {}; - - std::string orig_path = orig_spec.GetPath(); - - if (orig_path.empty()) - return {}; - - bool orig_is_relative = orig_spec.IsRelative(); - - for (auto entry : m_pairs) { - llvm::StringRef orig_ref(orig_path); - llvm::StringRef prefix_ref = entry.first.GetStringRef(); - if (orig_ref.size() < prefix_ref.size()) - continue; - // We consider a relative prefix or one of just "." to - // mean "only apply to relative paths". - bool prefix_is_relative = false; - - if (prefix_ref == ".") { - prefix_is_relative = true; - // Remove the "." since it will have been removed from the - // FileSpec paths already. - prefix_ref = prefix_ref.drop_front(); - } else { - FileSpec prefix_spec(prefix_ref, FileSpec::Style::native); - prefix_is_relative = prefix_spec.IsRelative(); - } - if (prefix_is_relative != orig_is_relative) - continue; - if (orig_ref.consume_front(prefix_ref)) { - FileSpec new_spec; - new_spec.SetFile(entry.second.GetCString(), FileSpec::Style::native); - new_spec.AppendPathComponent(orig_ref); - if (FileSystem::Instance().Exists(new_spec)) - return new_spec; - } - } - +llvm::Optional PathMappingList::FindFile(const FileSpec &orig_spec) const { + if (auto remapped = RemapPath(orig_spec.GetPath())) + if (FileSystem::Instance().Exists(*remapped)) + return remapped; + return {}; } -- Gitee From b3914eec195f289a6c151299ad5cb378297987fc Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 25 Jun 2021 13:49:01 -0700 Subject: [PATCH 07/19] Change PathMappingList::RemapPath to return an optional result (NFC) This is an NFC modernization refactoring that replaces the combination of a bool return + reference argument, with an Optional return value. Differential Revision: https://reviews.llvm.org/D104404 --- lldb/include/lldb/Target/PathMappingList.h | 8 ++------ lldb/source/Core/Module.cpp | 6 +++++- lldb/source/Target/PathMappingList.cpp | 16 +++++++--------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h index b3b6d50db2bd..fc7b23bcfad3 100644 --- a/lldb/include/lldb/Target/PathMappingList.h +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -72,13 +72,9 @@ public: /// \param[in] path /// The original source file path to try and remap. /// - /// \param[out] new_path - /// The newly remapped filespec that is may or may not exist. - /// /// \return - /// /b true if \a path was successfully located and \a new_path - /// is filled in with a new source path, \b false otherwise. - bool RemapPath(llvm::StringRef path, std::string &new_path) const; + /// The remapped filespec that may or may not exist on disk. + llvm::Optional RemapPath(llvm::StringRef path) const; bool RemapPath(const char *, std::string &) const = delete; bool ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const; diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index eaaa10b11d08..17cfaa79e640 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1605,7 +1605,11 @@ bool Module::FindSourceFile(const FileSpec &orig_spec, bool Module::RemapSourceFile(llvm::StringRef path, std::string &new_path) const { std::lock_guard guard(m_mutex); - return m_source_mappings.RemapPath(path, new_path); + if (auto remapped = m_source_mappings.RemapPath(path)) { + new_path = remapped->GetPath(); + return true; + } + return false; } void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 5283f0a5f535..f9888052a60a 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -146,18 +146,17 @@ void PathMappingList::Clear(bool notify) { bool PathMappingList::RemapPath(ConstString path, ConstString &new_path) const { - std::string remapped; - if (RemapPath(path.GetStringRef(), remapped)) { - new_path.SetString(remapped); + if (llvm::Optional remapped = RemapPath(path.GetStringRef())) { + new_path.SetString(remapped->GetPath()); return true; } return false; } -bool PathMappingList::RemapPath(llvm::StringRef path, - std::string &new_path) const { +llvm::Optional +PathMappingList::RemapPath(llvm::StringRef path) const { if (m_pairs.empty() || path.empty()) - return false; + return {}; LazyBool path_is_relative = eLazyBoolCalculate; for (const auto &it : m_pairs) { auto prefix = it.first.GetStringRef(); @@ -178,10 +177,9 @@ bool PathMappingList::RemapPath(llvm::StringRef path, } FileSpec remapped(it.second.GetStringRef()); remapped.AppendPathComponent(path); - new_path = remapped.GetPath(); - return true; + return remapped; } - return false; + return {}; } bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { -- Gitee From 5eb91b11c3886a6bf20cc1ee1d806c5e5356e8ce Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 29 Jun 2021 15:24:36 -0700 Subject: [PATCH 08/19] Improve path remapping in cross-debugging scenarios This patch implements a slight improvement when debugging across platforms and remapping source paths that are in a non-native format. See the unit test for examples. rdar://79205675 Differential Revision: https://reviews.llvm.org/D104407 --- lldb/source/Target/PathMappingList.cpp | 23 +++++++++++++-- lldb/unittests/Target/PathMappingListTest.cpp | 28 ++++++++++++++++++- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index f9888052a60a..0342130a58a0 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -153,6 +153,18 @@ bool PathMappingList::RemapPath(ConstString path, return false; } +/// Append components to path, applying style. +static void AppendPathComponents(FileSpec &path, llvm::StringRef components, + llvm::sys::path::Style style) { + auto component = llvm::sys::path::begin(components, style); + auto e = llvm::sys::path::end(components); + while (component != e && + llvm::sys::path::is_separator(*component->data(), style)) + ++component; + for (; component != e; ++component) + path.AppendPathComponent(*component); +} + llvm::Optional PathMappingList::RemapPath(llvm::StringRef path) const { if (m_pairs.empty() || path.empty()) @@ -176,7 +188,9 @@ PathMappingList::RemapPath(llvm::StringRef path) const { continue; } FileSpec remapped(it.second.GetStringRef()); - remapped.AppendPathComponent(path); + auto orig_style = FileSpec::GuessPathStyle(prefix).getValueOr( + llvm::sys::path::Style::native); + AppendPathComponents(remapped, path, orig_style); return remapped; } return {}; @@ -188,8 +202,11 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co for (const auto &it : m_pairs) { if (!path_ref.consume_front(it.second.GetStringRef())) continue; - fixed.SetFile(it.first.GetStringRef(), FileSpec::Style::native); - fixed.AppendPathComponent(path_ref); + auto orig_file = it.first.GetStringRef(); + auto orig_style = FileSpec::GuessPathStyle(orig_file).getValueOr( + llvm::sys::path::Style::native); + fixed.SetFile(orig_file, orig_style); + AppendPathComponents(fixed, path_ref, orig_style); return true; } return false; diff --git a/lldb/unittests/Target/PathMappingListTest.cpp b/lldb/unittests/Target/PathMappingListTest.cpp index 66fd97c17f62..90b6f1134a2b 100644 --- a/lldb/unittests/Target/PathMappingListTest.cpp +++ b/lldb/unittests/Target/PathMappingListTest.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/ArrayRef.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Utility/FileSpec.h" +#include "llvm/ADT/ArrayRef.h" #include "gtest/gtest.h" #include @@ -19,6 +19,8 @@ struct Matches { FileSpec original; FileSpec remapped; Matches(const char *o, const char *r) : original(o), remapped(r) {} + Matches(const char *o, llvm::sys::path::Style style, const char *r) + : original(o, style), remapped(r) {} }; } // namespace @@ -112,3 +114,27 @@ TEST(PathMappingListTest, RemapRoot) { }; TestPathMappings(map, matches, fails); } + +#ifndef _WIN32 +TEST(PathMappingListTest, CrossPlatformTests) { + PathMappingList map; + map.Append(ConstString(R"(C:\old)"), ConstString("/new"), false); + Matches matches[] = { + {R"(C:\old)", llvm::sys::path::Style::windows, "/new"}, + {R"(C:\old\)", llvm::sys::path::Style::windows, "/new"}, + {R"(C:\old\foo\.)", llvm::sys::path::Style::windows, "/new/foo"}, + {R"(C:\old\foo.c)", llvm::sys::path::Style::windows, "/new/foo.c"}, + {R"(C:\old\foo.c\.)", llvm::sys::path::Style::windows, "/new/foo.c"}, + {R"(C:\old\.\foo.c)", llvm::sys::path::Style::windows, "/new/foo.c"}, + }; + ConstString fails[] = { + ConstString("/foo"), + ConstString("/"), + ConstString("foo.c"), + ConstString("./foo.c"), + ConstString("../foo.c"), + ConstString("../bar/foo.c"), + }; + TestPathMappings(map, matches, fails); +} +#endif -- Gitee From c6679a8cec23ae6202a4d9725d0eb9708b8aa63b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 12 Feb 2021 00:07:23 +0100 Subject: [PATCH 09/19] [OpaquePtrs] Remove some uses of type-less CreateLoad APIs (NFC) Explicitly pass loaded type when creating loads, in preparation for the deprecation of these APIs. There are still a couple of uses left. --- clang/lib/CodeGen/CGBuilder.h | 9 +++---- clang/lib/CodeGen/CGBuiltin.cpp | 3 ++- clang/lib/CodeGen/CGCXX.cpp | 6 ++--- clang/lib/CodeGen/CodeGenFunction.h | 3 ++- llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 17 ++++++------- .../AMDGPU/AMDGPULateCodeGenPrepare.cpp | 2 +- .../Scalar/LowerMatrixIntrinsics.cpp | 11 +++++---- .../lib/Transforms/Utils/AMDGPUEmitPrintf.cpp | 2 +- polly/lib/CodeGen/IslNodeBuilder.cpp | 16 ++++++------- polly/lib/CodeGen/LoopGenerators.cpp | 3 ++- polly/lib/CodeGen/LoopGeneratorsGOMP.cpp | 4 ++-- polly/lib/CodeGen/LoopGeneratorsKMP.cpp | 24 +++++++++++-------- polly/lib/CodeGen/PerfMonitor.cpp | 24 ++++++++++++------- 13 files changed, 70 insertions(+), 54 deletions(-) diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 38e96c0f4ee6..82cdd95ac7e0 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -66,19 +66,20 @@ public: // Note that we intentionally hide the CreateLoad APIs that don't // take an alignment. llvm::LoadInst *CreateLoad(Address Addr, const llvm::Twine &Name = "") { - return CreateAlignedLoad(Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, const char *Name) { // This overload is required to prevent string literals from // ending up in the IsVolatile overload. - return CreateAlignedLoad(Addr.getPointer(), + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), Addr.getAlignment().getAsAlign(), Name); } llvm::LoadInst *CreateLoad(Address Addr, bool IsVolatile, const llvm::Twine &Name = "") { - return CreateAlignedLoad( - Addr.getPointer(), Addr.getAlignment().getAsAlign(), IsVolatile, Name); + return CreateAlignedLoad(Addr.getElementType(), Addr.getPointer(), + Addr.getAlignment().getAsAlign(), IsVolatile, + Name); } using CGBuilderBaseTy::CreateAlignedLoad; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 10e3820d9657..a62e1b0986e9 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -14473,11 +14473,12 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, break; } + llvm::Type *Ty = FixedVectorType::get(Builder.getInt64Ty(), 2); Value *InOps[9]; InOps[0] = Ops[2]; for (int i = 0; i != 8; ++i) { Value *Ptr = Builder.CreateConstGEP1_32(Ops[1], i); - InOps[i + 1] = Builder.CreateAlignedLoad(Ptr, Align(16)); + InOps[i + 1] = Builder.CreateAlignedLoad(Ty, Ptr, Align(16)); } Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), InOps); diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index a4bd2c6d5da0..641740c37a68 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -252,8 +252,8 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, "No kext in Microsoft ABI"); CodeGenModule &CGM = CGF.CGM; llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits()); - Ty = Ty->getPointerTo()->getPointerTo(); - VTable = CGF.Builder.CreateBitCast(VTable, Ty); + Ty = Ty->getPointerTo(); + VTable = CGF.Builder.CreateBitCast(VTable, Ty->getPointerTo()); assert(VTable && "BuildVirtualCall = kext vtbl pointer is null"); uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD); const VTableLayout &VTLayout = CGM.getItaniumVTableContext().getVTableLayout(RD); @@ -264,7 +264,7 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfnkxt"); llvm::Value *VFunc = CGF.Builder.CreateAlignedLoad( - VFuncPtr, llvm::Align(CGF.PointerAlignInBytes)); + Ty, VFuncPtr, llvm::Align(CGF.PointerAlignInBytes)); CGCallee Callee(GD, VFunc); return Callee; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 95c0b7b4d7c0..80b8818fda60 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4775,7 +4775,8 @@ inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, // Otherwise, it should be an alloca instruction, as set up in save(). auto alloca = cast(value.getPointer()); - return CGF.Builder.CreateAlignedLoad(alloca, alloca->getAlign()); + return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, + alloca->getAlign()); } } // end namespace CodeGen diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index 1f67aecb57e9..008aaf83c41d 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -540,11 +540,12 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel( AllocaInst *PrivTIDAddr = Builder.CreateAlloca(Int32, nullptr, "tid.addr.local"); - Instruction *PrivTID = Builder.CreateLoad(PrivTIDAddr, "tid"); + Instruction *PrivTID = Builder.CreateLoad(Int32, PrivTIDAddr, "tid"); // Add some fake uses for OpenMP provided arguments. - ToBeDeleted.push_back(Builder.CreateLoad(TIDAddr, "tid.addr.use")); - Instruction *ZeroAddrUse = Builder.CreateLoad(ZeroAddr, "zero.addr.use"); + ToBeDeleted.push_back(Builder.CreateLoad(Int32, TIDAddr, "tid.addr.use")); + Instruction *ZeroAddrUse = Builder.CreateLoad(Int32, ZeroAddr, + "zero.addr.use"); ToBeDeleted.push_back(ZeroAddrUse); // ThenBB @@ -625,7 +626,7 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel( // Initialize the local TID stack location with the argument value. Builder.SetInsertPoint(PrivTID); Function::arg_iterator OutlinedAI = OutlinedFn.arg_begin(); - Builder.CreateStore(Builder.CreateLoad(OutlinedAI), PrivTIDAddr); + Builder.CreateStore(Builder.CreateLoad(Int32, OutlinedAI), PrivTIDAddr); // If no "if" clause was present we do not need the call created during // outlining, otherwise we reuse it in the serialized parallel region. @@ -743,7 +744,7 @@ IRBuilder<>::InsertPoint OpenMPIRBuilder::createParallel( // Load back next to allocations in the to-be-outlined region. Builder.restoreIP(InnerAllocaIP); - Inner = Builder.CreateLoad(Ptr); + Inner = Builder.CreateLoad(V.getType(), Ptr); } Value *ReplacementValue = nullptr; @@ -1129,8 +1130,8 @@ CanonicalLoopInfo *OpenMPIRBuilder::createStaticWorkshareLoop( Builder.CreateCall(StaticInit, {SrcLoc, ThreadNum, SchedulingType, PLastIter, PLowerBound, PUpperBound, PStride, One, Chunk}); - Value *LowerBound = Builder.CreateLoad(PLowerBound); - Value *InclusiveUpperBound = Builder.CreateLoad(PUpperBound); + Value *LowerBound = Builder.CreateLoad(IVTy, PLowerBound); + Value *InclusiveUpperBound = Builder.CreateLoad(IVTy, PUpperBound); Value *TripCountMinusOne = Builder.CreateSub(InclusiveUpperBound, LowerBound); Value *TripCount = Builder.CreateAdd(TripCountMinusOne, One); setCanonicalLoopTripCount(CLI, TripCount); @@ -1421,7 +1422,7 @@ OpenMPIRBuilder::createCopyPrivate(const LocationDescription &Loc, Value *Ident = getOrCreateIdent(SrcLocStr); Value *ThreadId = getOrCreateThreadID(Ident); - llvm::Value *DidItLD = Builder.CreateLoad(DidIt); + llvm::Value *DidItLD = Builder.CreateLoad(Builder.getInt32Ty(), DidIt); Value *Args[] = {Ident, ThreadId, BufSize, CpyBuf, CpyFn, DidItLD}; diff --git a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp index 8aea33cf289d..e4aa6de10f2d 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp @@ -168,7 +168,7 @@ bool AMDGPULateCodeGenPrepare::visitLoadInst(LoadInst &LI) { IRB.CreateConstGEP1_64(IRB.CreateBitCast(Base, Int8PtrTy), Offset - Adjust), Int32PtrTy); - LoadInst *NewLd = IRB.CreateAlignedLoad(NewPtr, Align(4)); + LoadInst *NewLd = IRB.CreateAlignedLoad(IRB.getInt32Ty(), NewPtr, Align(4)); NewLd->copyMetadata(LI); NewLd->setMetadata(LLVMContext::MD_range, nullptr); diff --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp index 8e251ca940a3..41ce1e341a58 100644 --- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp +++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp @@ -797,15 +797,16 @@ public: /// vectors. MatrixTy loadMatrix(Type *Ty, Value *Ptr, MaybeAlign MAlign, Value *Stride, bool IsVolatile, ShapeInfo Shape, IRBuilder<> &Builder) { - auto VType = cast(Ty); - Value *EltPtr = createElementPtr(Ptr, VType->getElementType(), Builder); + auto *VType = cast(Ty); + Type *EltTy = VType->getElementType(); + Type *VecTy = FixedVectorType::get(EltTy, Shape.getStride()); + Value *EltPtr = createElementPtr(Ptr, EltTy, Builder); MatrixTy Result; for (unsigned I = 0, E = Shape.getNumVectors(); I < E; ++I) { Value *GEP = computeVectorAddr(EltPtr, Builder.getInt64(I), Stride, - Shape.getStride(), VType->getElementType(), - Builder); + Shape.getStride(), EltTy, Builder); Value *Vector = Builder.CreateAlignedLoad( - GEP, getAlignForIndex(I, Stride, VType->getElementType(), MAlign), + VecTy, GEP, getAlignForIndex(I, Stride, EltTy, MAlign), IsVolatile, "col.load"); Result.addVector(Vector); diff --git a/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp b/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp index ccdcf7cbce38..9210096c4f3e 100644 --- a/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp +++ b/llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp @@ -138,7 +138,7 @@ static Value *getStrlenWithNull(IRBuilder<> &Builder, Value *Str) { PtrPhi->addIncoming(PtrNext, While); // Condition for the while loop. - auto Data = Builder.CreateLoad(PtrPhi); + auto Data = Builder.CreateLoad(Builder.getInt8Ty(), PtrPhi); auto Cmp = Builder.CreateICmpEQ(Data, CharZero); Builder.CreateCondBr(Cmp, WhileDone, While); diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index a329661feddf..02e663349f5a 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -1139,22 +1139,22 @@ static Value *buildFADOutermostDimensionLoad(Value *GlobalDescriptor, Builder.getInt64(0), Builder.getInt32(2)}; Value *endPtr = Builder.CreateInBoundsGEP(GlobalDescriptor, endIdx, ArrayName + "_end_ptr"); - Value *end = Builder.CreateLoad(endPtr, ArrayName + "_end"); + Type *type = cast(endPtr)->getResultElementType(); + assert(isa(type) && "expected type of end to be integral"); + + Value *end = Builder.CreateLoad(type, endPtr, ArrayName + "_end"); Value *beginIdx[4] = {Builder.getInt64(0), Builder.getInt32(3), Builder.getInt64(0), Builder.getInt32(1)}; Value *beginPtr = Builder.CreateInBoundsGEP(GlobalDescriptor, beginIdx, ArrayName + "_begin_ptr"); - Value *begin = Builder.CreateLoad(beginPtr, ArrayName + "_begin"); + Value *begin = Builder.CreateLoad(type, beginPtr, ArrayName + "_begin"); Value *size = Builder.CreateNSWSub(end, begin, ArrayName + "_end_begin_delta"); - Type *endType = dyn_cast(end->getType()); - assert(endType && "expected type of end to be integral"); - size = Builder.CreateNSWAdd(end, - ConstantInt::get(endType, 1, /* signed = */ true), - ArrayName + "_size"); + size = Builder.CreateNSWAdd( + end, ConstantInt::get(type, 1, /* signed = */ true), ArrayName + "_size"); return size; } @@ -1211,7 +1211,7 @@ Value *IslNodeBuilder::preloadUnconditionally(isl_set *AccessRange, auto Name = Ptr->getName(); auto AS = Ptr->getType()->getPointerAddressSpace(); Ptr = Builder.CreatePointerCast(Ptr, Ty->getPointerTo(AS), Name + ".cast"); - PreloadVal = Builder.CreateLoad(Ptr, Name + ".load"); + PreloadVal = Builder.CreateLoad(Ty, Ptr, Name + ".load"); if (LoadInst *PreloadInst = dyn_cast(PreloadVal)) PreloadInst->setAlignment(cast(AccInst)->getAlign()); diff --git a/polly/lib/CodeGen/LoopGenerators.cpp b/polly/lib/CodeGen/LoopGenerators.cpp index fca800dd511a..702503908702 100644 --- a/polly/lib/CodeGen/LoopGenerators.cpp +++ b/polly/lib/CodeGen/LoopGenerators.cpp @@ -245,7 +245,8 @@ void ParallelLoopGenerator::extractValuesFromStruct( SetVector OldValues, Type *Ty, Value *Struct, ValueMapT &Map) { for (unsigned i = 0; i < OldValues.size(); i++) { Value *Address = Builder.CreateStructGEP(Ty, Struct, i); - Value *NewValue = Builder.CreateLoad(Address); + Type *ElemTy = cast(Address)->getResultElementType(); + Value *NewValue = Builder.CreateLoad(ElemTy, Address); NewValue->setName("polly.subfunc.arg." + OldValues[i]->getName()); Map[OldValues[i]] = NewValue; } diff --git a/polly/lib/CodeGen/LoopGeneratorsGOMP.cpp b/polly/lib/CodeGen/LoopGeneratorsGOMP.cpp index 66ebd4dee831..294d91f2f398 100644 --- a/polly/lib/CodeGen/LoopGeneratorsGOMP.cpp +++ b/polly/lib/CodeGen/LoopGeneratorsGOMP.cpp @@ -142,8 +142,8 @@ ParallelLoopGeneratorGOMP::createSubFn(Value *Stride, AllocaInst *StructData, // Add code to load the iv bounds for this set of iterations. Builder.SetInsertPoint(PreHeaderBB); - Value *LB = Builder.CreateLoad(LBPtr, "polly.par.LB"); - Value *UB = Builder.CreateLoad(UBPtr, "polly.par.UB"); + Value *LB = Builder.CreateLoad(LongType, LBPtr, "polly.par.LB"); + Value *UB = Builder.CreateLoad(LongType, UBPtr, "polly.par.UB"); // Subtract one as the upper bound provided by OpenMP is a < comparison // whereas the codegenForSequential function creates a <= comparison. diff --git a/polly/lib/CodeGen/LoopGeneratorsKMP.cpp b/polly/lib/CodeGen/LoopGeneratorsKMP.cpp index 1fa3f89bb005..272f8ae828af 100644 --- a/polly/lib/CodeGen/LoopGeneratorsKMP.cpp +++ b/polly/lib/CodeGen/LoopGeneratorsKMP.cpp @@ -181,8 +181,8 @@ ParallelLoopGeneratorKMP::createSubFn(Value *SequentialLoopStride, Map); const auto Alignment = llvm::Align(is64BitArch() ? 8 : 4); - Value *ID = - Builder.CreateAlignedLoad(IDPtr, Alignment, "polly.par.global_tid"); + Value *ID = Builder.CreateAlignedLoad(Builder.getInt32Ty(), IDPtr, Alignment, + "polly.par.global_tid"); Builder.CreateAlignedStore(LB, LBPtr, Alignment); Builder.CreateAlignedStore(UB, UBPtr, Alignment); @@ -223,8 +223,10 @@ ParallelLoopGeneratorKMP::createSubFn(Value *SequentialLoopStride, Builder.CreateCondBr(HasIteration, PreHeaderBB, ExitBB); Builder.SetInsertPoint(PreHeaderBB); - LB = Builder.CreateAlignedLoad(LBPtr, Alignment, "polly.indvar.LB"); - UB = Builder.CreateAlignedLoad(UBPtr, Alignment, "polly.indvar.UB"); + LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment, + "polly.indvar.LB"); + UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment, + "polly.indvar.UB"); } break; case OMPGeneralSchedulingType::StaticChunked: @@ -234,11 +236,13 @@ ParallelLoopGeneratorKMP::createSubFn(Value *SequentialLoopStride, Builder.CreateAlignedStore(AdjustedUB, UBPtr, Alignment); createCallStaticInit(ID, IsLastPtr, LBPtr, UBPtr, StridePtr, ChunkSize); - Value *ChunkedStride = - Builder.CreateAlignedLoad(StridePtr, Alignment, "polly.kmpc.stride"); + Value *ChunkedStride = Builder.CreateAlignedLoad( + LongType, StridePtr, Alignment, "polly.kmpc.stride"); - LB = Builder.CreateAlignedLoad(LBPtr, Alignment, "polly.indvar.LB"); - UB = Builder.CreateAlignedLoad(UBPtr, Alignment, "polly.indvar.UB.temp"); + LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment, + "polly.indvar.LB"); + UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment, + "polly.indvar.UB.temp"); Value *UBInRange = Builder.CreateICmp(llvm::CmpInst::Predicate::ICMP_SLE, UB, AdjustedUB, @@ -252,9 +256,9 @@ ParallelLoopGeneratorKMP::createSubFn(Value *SequentialLoopStride, if (Scheduling == OMPGeneralSchedulingType::StaticChunked) { Builder.SetInsertPoint(PreHeaderBB); - LB = Builder.CreateAlignedLoad(LBPtr, Alignment, + LB = Builder.CreateAlignedLoad(LongType, LBPtr, Alignment, "polly.indvar.LB.entry"); - UB = Builder.CreateAlignedLoad(UBPtr, Alignment, + UB = Builder.CreateAlignedLoad(LongType, UBPtr, Alignment, "polly.indvar.UB.entry"); } diff --git a/polly/lib/CodeGen/PerfMonitor.cpp b/polly/lib/CodeGen/PerfMonitor.cpp index b452dc3bcc09..f6efc532364f 100644 --- a/polly/lib/CodeGen/PerfMonitor.cpp +++ b/polly/lib/CodeGen/PerfMonitor.cpp @@ -138,11 +138,12 @@ Function *PerfMonitor::insertFinalReporting() { // Measure current cycles and compute final timings. Function *RDTSCPFn = getRDTSCP(); + Type *Int64Ty = Builder.getInt64Ty(); Value *CurrentCycles = Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0}); - Value *CyclesStart = Builder.CreateLoad(CyclesTotalStartPtr, true); + Value *CyclesStart = Builder.CreateLoad(Int64Ty, CyclesTotalStartPtr, true); Value *CyclesTotal = Builder.CreateSub(CurrentCycles, CyclesStart); - Value *CyclesInScops = Builder.CreateLoad(CyclesInScopsPtr, true); + Value *CyclesInScops = Builder.CreateLoad(Int64Ty, CyclesInScopsPtr, true); // Print the runtime information. RuntimeDebugBuilder::createCPUPrinter(Builder, "Polly runtime information\n"); @@ -175,11 +176,12 @@ void PerfMonitor::AppendScopReporting() { Builder.SetInsertPoint(FinalStartBB); ReturnFromFinal->eraseFromParent(); + Type *Int64Ty = Builder.getInt64Ty(); Value *CyclesInCurrentScop = - Builder.CreateLoad(this->CyclesInCurrentScopPtr, true); + Builder.CreateLoad(Int64Ty, this->CyclesInCurrentScopPtr, true); Value *TripCountForCurrentScop = - Builder.CreateLoad(this->TripCountForCurrentScopPtr, true); + Builder.CreateLoad(Int64Ty, this->TripCountForCurrentScopPtr, true); std::string EntryName, ExitName; std::tie(EntryName, ExitName) = S.getEntryExitStr(); @@ -231,7 +233,8 @@ Function *PerfMonitor::insertInitFunction(Function *FinalReporting) { // multiple times. To avoid initializations being run multiple times (and // especially to avoid that atExitFn is called more than once), we bail // out if the initializer is run more than once. - Value *HasRunBefore = Builder.CreateLoad(AlreadyInitializedPtr); + Value *HasRunBefore = + Builder.CreateLoad(Builder.getInt1Ty(), AlreadyInitializedPtr); Builder.CreateCondBr(HasRunBefore, EarlyReturn, InitBB); Builder.SetInsertPoint(EarlyReturn); Builder.CreateRetVoid(); @@ -276,20 +279,23 @@ void PerfMonitor::insertRegionEnd(Instruction *InsertBefore) { Builder.SetInsertPoint(InsertBefore); Function *RDTSCPFn = getRDTSCP(); - LoadInst *CyclesStart = Builder.CreateLoad(CyclesInScopStartPtr, true); + Type *Int64Ty = Builder.getInt64Ty(); + LoadInst *CyclesStart = + Builder.CreateLoad(Int64Ty, CyclesInScopStartPtr, true); Value *CurrentCycles = Builder.CreateExtractValue(Builder.CreateCall(RDTSCPFn), {0}); Value *CyclesInScop = Builder.CreateSub(CurrentCycles, CyclesStart); - Value *CyclesInScops = Builder.CreateLoad(CyclesInScopsPtr, true); + Value *CyclesInScops = Builder.CreateLoad(Int64Ty, CyclesInScopsPtr, true); CyclesInScops = Builder.CreateAdd(CyclesInScops, CyclesInScop); Builder.CreateStore(CyclesInScops, CyclesInScopsPtr, true); - Value *CyclesInCurrentScop = Builder.CreateLoad(CyclesInCurrentScopPtr, true); + Value *CyclesInCurrentScop = + Builder.CreateLoad(Int64Ty, CyclesInCurrentScopPtr, true); CyclesInCurrentScop = Builder.CreateAdd(CyclesInCurrentScop, CyclesInScop); Builder.CreateStore(CyclesInCurrentScop, CyclesInCurrentScopPtr, true); Value *TripCountForCurrentScop = - Builder.CreateLoad(TripCountForCurrentScopPtr, true); + Builder.CreateLoad(Int64Ty, TripCountForCurrentScopPtr, true); TripCountForCurrentScop = Builder.CreateAdd(TripCountForCurrentScop, Builder.getInt64(1)); Builder.CreateStore(TripCountForCurrentScop, TripCountForCurrentScopPtr, -- Gitee From b4e87dad4e0f9dd93f467929b9e2951470629bb8 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Sun, 15 Aug 2021 13:35:53 +0100 Subject: [PATCH 10/19] [ExecutionEngine] Check for libunwind before calling __register_frame libgcc and libunwind have different flavours of __register_frame. Both flavours are already correctly handled, except that the code to handle the libunwind flavour is guarded by __APPLE__. This change uses the presence of __unw_add_dynamic_fde in libunwind instead to detect whether libunwind is used, rather than hardcoding it as Apple vs. non-Apple. Fixes PR44074. Thanks to Albert Jin and Chris Schafmeister for identifying the problem. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D106129 --- llvm/cmake/config-ix.cmake | 1 + llvm/cmake/unwind.h | 1 + llvm/include/llvm/Config/config.h.cmake | 3 ++ .../Orc/TargetProcess/RegisterEHFrames.cpp | 28 +++++++++++-------- .../RuntimeDyld/RTDyldMemoryManager.cpp | 4 ++- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake index 818fafbce148..e9224959dd1b 100644 --- a/llvm/cmake/config-ix.cmake +++ b/llvm/cmake/config-ix.cmake @@ -210,6 +210,7 @@ endif() # Determine whether we can register EH tables. check_symbol_exists(__register_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_REGISTER_FRAME) check_symbol_exists(__deregister_frame "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_DEREGISTER_FRAME) +check_symbol_exists(__unw_add_dynamic_fde "${CMAKE_CURRENT_LIST_DIR}/unwind.h" HAVE_UNW_ADD_DYNAMIC_FDE) check_symbol_exists(_Unwind_Backtrace "unwind.h" HAVE__UNWIND_BACKTRACE) check_symbol_exists(getpagesize unistd.h HAVE_GETPAGESIZE) diff --git a/llvm/cmake/unwind.h b/llvm/cmake/unwind.h index e7f53465f9ce..52243f2af787 100644 --- a/llvm/cmake/unwind.h +++ b/llvm/cmake/unwind.h @@ -5,3 +5,4 @@ // exist in the runtime. extern void __register_frame(const void *fde); // NOLINT extern void __deregister_frame(const void *fde); // NOLINT +extern void __unw_add_dynamic_fde(); // NOLINT diff --git a/llvm/include/llvm/Config/config.h.cmake b/llvm/include/llvm/Config/config.h.cmake index 6664ad335584..d54ea9a40c69 100644 --- a/llvm/include/llvm/Config/config.h.cmake +++ b/llvm/include/llvm/Config/config.h.cmake @@ -64,6 +64,9 @@ /* Define to 1 if we can deregister EH frames on this platform. */ #cmakedefine HAVE_DEREGISTER_FRAME ${HAVE_DEREGISTER_FRAME} +/* Define if __unw_add_dynamic_fde() is available on this platform. */ +#cmakedefine HAVE_UNW_ADD_DYNAMIC_FDE ${HAVE_UNW_ADD_DYNAMIC_FDE} + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ERRNO_H ${HAVE_ERRNO_H} diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp index aff7296cb6e3..caa91d8c4866 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp @@ -86,11 +86,11 @@ static Error deregisterFrameWrapper(const void *P) { } #endif -#ifdef __APPLE__ +#ifdef HAVE_UNW_ADD_DYNAMIC_FDE template -Error walkAppleEHFrameSection(const char *const SectionStart, - size_t SectionSize, HandleFDEFn HandleFDE) { +Error walkLibunwindEHFrameSection(const char *const SectionStart, + size_t SectionSize, HandleFDEFn HandleFDE) { const char *CurCFIRecord = SectionStart; const char *End = SectionStart + SectionSize; uint64_t Size = *reinterpret_cast(CurCFIRecord); @@ -124,16 +124,19 @@ Error walkAppleEHFrameSection(const char *const SectionStart, return Error::success(); } -#endif // __APPLE__ +#endif // HAVE_UNW_ADD_DYNAMIC_FDE Error registerEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize) { -#ifdef __APPLE__ - // On Darwin __register_frame has to be called for each FDE entry. - return walkAppleEHFrameSection(static_cast(EHFrameSectionAddr), - EHFrameSectionSize, registerFrameWrapper); + /* libgcc and libunwind __register_frame behave differently. We use the + * presence of __unw_add_dynamic_fde to detect libunwind. */ +#ifdef HAVE_UNW_ADD_DYNAMIC_FDE + // With libunwind, __register_frame has to be called for each FDE entry. + return walkLibunwindEHFrameSection( + static_cast(EHFrameSectionAddr), EHFrameSectionSize, + registerFrameWrapper); #else - // On Linux __register_frame takes a single argument: + // With libgcc, __register_frame takes a single argument: // a pointer to the start of the .eh_frame section. // How can it find the end? Because crtendS.o is linked @@ -144,9 +147,10 @@ Error registerEHFrameSection(const void *EHFrameSectionAddr, Error deregisterEHFrameSection(const void *EHFrameSectionAddr, size_t EHFrameSectionSize) { -#ifdef __APPLE__ - return walkAppleEHFrameSection(static_cast(EHFrameSectionAddr), - EHFrameSectionSize, deregisterFrameWrapper); +#ifdef HAVE_UNW_ADD_DYNAMIC_FDE + return walkLibunwindEHFrameSection( + static_cast(EHFrameSectionAddr), EHFrameSectionSize, + deregisterFrameWrapper); #else return deregisterFrameWrapper(EHFrameSectionAddr); #endif diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp index b6ccd02405c1..252e20c3c38c 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -67,7 +67,9 @@ static void __deregister_frame(void *p) { } #endif -#ifdef __APPLE__ +/* libgcc and libunwind __register_frame behave differently. We use the presence + * of __unw_add_dynamic_fde to detect libunwind. */ +#ifdef HAVE_UNW_ADD_DYNAMIC_FDE static const char *processFDE(const char *Entry, bool isDeregister) { const char *P = Entry; -- Gitee From ec80453de181d3a0c3c5f85b1e7b6ccac40027d2 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 27 Jan 2022 08:09:11 -0800 Subject: [PATCH 11/19] Omit atomic_{,un}signed_lock_free if unsupported On targets that have limited atomic support, e.g. ones that define ATOMIC_*_LOCK_FREE to '1' ("sometimes lock free"), we would end up referencing yet-undefined __libcpp_{,un}signed_lock_free. This commit adds a guard to prevent these references for such targets. Differential Revision: https://reviews.llvm.org/D118391 --- libcxx/include/atomic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 0fc799a24319..57d01ad2791a 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -2791,10 +2791,13 @@ typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::typ typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free; #else // No signed/unsigned lock-free types +#define _LIBCPP_NO_LOCK_FREE_TYPES #endif +#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free; typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free; +#endif #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} -- Gitee From 72f06ccc6812ca8e43efe8f8ab72e8de28a4a4d2 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 12 Aug 2021 13:21:35 +0100 Subject: [PATCH 12/19] Recommit "[Matrix] Overload stride arg in matrix.columnwise.load/store." This reverts the revert 28c04794df74ad3c38155a244729d1f8d57b9400. The failing MLIR test that caused the revert should be fixed in this version. Also includes a PPC test fix previously in 1f87c7c478a6. --- clang/test/CodeGen/matrix-type-builtins.c | 300 +++++++++++------- .../test/CodeGenCXX/matrix-type-builtins.cpp | 22 +- clang/test/CodeGenObjC/matrix-type-builtins.m | 4 +- llvm/docs/LangRef.rst | 14 +- llvm/include/llvm/IR/Intrinsics.td | 4 +- llvm/include/llvm/IR/MatrixBuilder.h | 4 +- .../Scalar/LowerMatrixIntrinsics.cpp | 13 +- .../strided-load-double.ll | 33 +- .../strided-store-double.ll | 33 +- llvm/test/Verifier/matrix-intrinsics.ll | 44 +-- 10 files changed, 289 insertions(+), 182 deletions(-) diff --git a/clang/test/CodeGen/matrix-type-builtins.c b/clang/test/CodeGen/matrix-type-builtins.c index 67f5c7819687..ec0be85b7151 100644 --- a/clang/test/CodeGen/matrix-type-builtins.c +++ b/clang/test/CodeGen/matrix-type-builtins.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK64 %s +// RUN: %clang_cc1 -fenable-matrix -triple i386-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK32 %s // Also check we do not crash when running some middle-end passes. Most // importantly this includes the IR verifier, to ensure we emit valid IR. @@ -15,30 +16,33 @@ typedef unsigned ux1x6_t __attribute__((matrix_type(1, 6))); typedef unsigned ux6x1_t __attribute__((matrix_type(6, 1))); void transpose_double_5x5(dx5x5_t *a) { - // CHECK-LABEL: define{{.*}} void @transpose_double_5x5( - // CHECK: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[TRANS:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[A]], i32 5, i32 5) - // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [25 x double]* %a_t to <25 x double>* - // CHECK-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 8 + // COMMON-LABEL: define{{.*}} void @transpose_double_5x5( + // CHECK32: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK64: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // COMMON-NEXT: [[TRANS:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[A]], i32 5, i32 5) + // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [25 x double]* %a_t to <25 x double>* + // CHECK32-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 4 + // CHECK64-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 8 + dx5x5_t a_t = __builtin_matrix_transpose(*a); } void transpose_float_3x2(fx3x2_t *a) { - // CHECK-LABEL: define{{.*}} void @transpose_float_3x2( - // CHECK: [[A:%.*]] = load <6 x float>, <6 x float>* {{.*}}, align 4 - // CHECK-NEXT: [[TRANS:%.*]] = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[A]], i32 3, i32 2) - // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [6 x float]* %a_t to <6 x float>* - // CHECK-NEXT: store <6 x float> [[TRANS]], <6 x float>* [[AT_ADDR]], align 4 + // COMMON-LABEL: define{{.*}} void @transpose_float_3x2( + // COMMON: [[A:%.*]] = load <6 x float>, <6 x float>* {{.*}}, align 4 + // COMMON-NEXT: [[TRANS:%.*]] = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[A]], i32 3, i32 2) + // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [6 x float]* %a_t to <6 x float>* + // COMMON-NEXT: store <6 x float> [[TRANS]], <6 x float>* [[AT_ADDR]], align 4 fx2x3_t a_t = __builtin_matrix_transpose(*a); } void transpose_int_20x4(ix20x4_t *a) { - // CHECK-LABEL: define{{.*}} void @transpose_int_20x4( - // CHECK: [[A:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 - // CHECK-NEXT: [[TRANS:%.*]] = call <80 x i32> @llvm.matrix.transpose.v80i32(<80 x i32> [[A]], i32 20, i32 4) - // CHECK-NEXT: [[AT_ADDR:%.*]] = bitcast [80 x i32]* %a_t to <80 x i32>* - // CHECK-NEXT: store <80 x i32> [[TRANS]], <80 x i32>* [[AT_ADDR]], align 4 + // COMMON-LABEL: define{{.*}} void @transpose_int_20x4( + // COMMON: [[A:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 + // COMMON-NEXT: [[TRANS:%.*]] = call <80 x i32> @llvm.matrix.transpose.v80i32(<80 x i32> [[A]], i32 20, i32 4) + // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [80 x i32]* %a_t to <80 x i32>* + // COMMON-NEXT: store <80 x i32> [[TRANS]], <80 x i32>* [[AT_ADDR]], align 4 ix4x20_t a_t = __builtin_matrix_transpose(*a); } @@ -49,26 +53,28 @@ struct Foo { }; void transpose_struct_member(struct Foo *F) { - // CHECK-LABEL: define{{.*}} void @transpose_struct_member( - // CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4 - // CHECK-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6) - // CHECK-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8 - // CHECK-NEXT: [[OUT_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 1 - // CHECK-NEXT: [[OUT_PTR_C:%.*]] = bitcast [6 x i32]* [[OUT_PTR]] to <6 x i32>* - // CHECK-NEXT: store <6 x i32> [[M_T]], <6 x i32>* [[OUT_PTR_C]], align 4 + // COMMON-LABEL: define{{.*}} void @transpose_struct_member( + // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4 + // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6) + // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4 + // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8 + // COMMON-NEXT: [[OUT_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 1 + // COMMON-NEXT: [[OUT_PTR_C:%.*]] = bitcast [6 x i32]* [[OUT_PTR]] to <6 x i32>* + // COMMON-NEXT: store <6 x i32> [[M_T]], <6 x i32>* [[OUT_PTR_C]], align 4 F->out = __builtin_matrix_transpose(F->in); } void transpose_transpose_struct_member(struct Foo *F) { - // CHECK-LABEL: define{{.*}} void @transpose_transpose_struct_member( - // CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4 - // CHECK-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6) - // CHECK-NEXT: [[M_T2:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M_T]], i32 6, i32 1) - // CHECK-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8 - // CHECK-NEXT: [[IN_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 0 - // CHECK-NEXT: [[IN_PTR_C:%.*]] = bitcast [6 x i32]* [[IN_PTR]] to <6 x i32>* - // CHECK-NEXT: store <6 x i32> [[M_T2]], <6 x i32>* [[IN_PTR_C]], align 4 + // COMMON-LABEL: define{{.*}} void @transpose_transpose_struct_member( + // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4 + // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6) + // COMMON-NEXT: [[M_T2:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M_T]], i32 6, i32 1) + // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4 + // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8 + // COMMON-NEXT: [[IN_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 0 + // COMMON-NEXT: [[IN_PTR_C:%.*]] = bitcast [6 x i32]* [[IN_PTR]] to <6 x i32>* + // COMMON-NEXT: store <6 x i32> [[M_T2]], <6 x i32>* [[IN_PTR_C]], align 4 F->in = __builtin_matrix_transpose(__builtin_matrix_transpose(F->in)); } @@ -76,13 +82,16 @@ void transpose_transpose_struct_member(struct Foo *F) { dx5x5_t get_matrix(); void transpose_rvalue() { - // CHECK-LABEL: define{{.*}} void @transpose_rvalue() - // CHECK-NEXT: entry: - // CHECK-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8 - // CHECK-NEXT: [[CALL:%.*]] = call <25 x double> (...) @get_matrix() - // CHECK-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[CALL]], i32 5, i32 5) - // CHECK-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>* - // CHECK-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8 + // COMMON-LABEL: define{{.*}} void @transpose_rvalue() + // COMMON-NEXT: entry: + // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4 + // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8 + // CHECK32-NEXT: [[CALL:%.*]] = call <25 x double> bitcast (<25 x double> (...)* @get_matrix to <25 x double> ()*)() + // CHECK64-NEXT: [[CALL:%.*]] = call <25 x double> (...) @get_matrix() + // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[CALL]], i32 5, i32 5) + // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>* + // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4 + // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8 dx5x5_t m_t = __builtin_matrix_transpose(get_matrix()); } @@ -90,162 +99,215 @@ void transpose_rvalue() { const dx5x5_t global_matrix; void transpose_global() { - // CHECK-LABEL: define{{.*}} void @transpose_global() - // CHECK-NEXT: entry: - // CHECK-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8 - // CHECK-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 8 - // CHECK-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[GLOBAL_MATRIX]], i32 5, i32 5) - // CHECK-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>* - // CHECK-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8 + // COMMON-LABEL: define{{.*}} void @transpose_global() + // COMMON-NEXT: entry: + // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4 + // CHECK32-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 4 + // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8 + // CHECK64-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 8 + // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[GLOBAL_MATRIX]], i32 5, i32 5) + // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>* + // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4 + // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8 dx5x5_t m_t = __builtin_matrix_transpose(global_matrix); } void column_major_load_with_const_stride_double(double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_load_with_const_stride_double(double* %Ptr) - // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride_double(double* %Ptr) + // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5) + // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5); } void column_major_load_with_const_stride2_double(double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_load_with_const_stride2_double(double* %Ptr) - // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride2_double(double* %Ptr) + // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5) + // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5) dx5x5_t m_a2 = __builtin_matrix_column_major_load(Ptr, 5, 5, 2 * 3 + 9); } void column_major_load_with_variable_stride_ull_float(float *Ptr, unsigned long long S) { - // CHECK-LABEL: define{{.*}} void @column_major_load_with_variable_stride_ull_float(float* %Ptr, i64 %S) - // CHECK: [[S:%.*]] = load i64, i64* %S.addr, align 8 - // CHECK-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 8 - // CHECK-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32(float* align 4 [[PTR]], i64 [[S]], i1 false, i32 2, i32 3) + // COMMON-LABEL: define{{.*}} void @column_major_load_with_variable_stride_ull_float(float* %Ptr, i64 %S) + // CHECK32: [[S:%.*]] = load i64, i64* %S.addr, align 8 + // CHECK32-NEXT: [[STRIDE_TRUNC:%.*]] = trunc i64 [[S]] to i32 + // CHECK32-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 4 + // CHECK32-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i32(float* align 4 [[PTR]], i32 [[STRIDE_TRUNC]], i1 false, i32 2, i32 3) + + // CHECK64: [[S:%.*]] = load i64, i64* %S.addr, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 8 + // CHECK64-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* align 4 [[PTR]], i64 [[S]], i1 false, i32 2, i32 3) fx2x3_t m_b = __builtin_matrix_column_major_load(Ptr, 2, 3, S); } void column_major_load_with_stride_math_int(int *Ptr, int S) { - // CHECK-LABEL: define{{.*}} void @column_major_load_with_stride_math_int(i32* %Ptr, i32 %S) - // CHECK: [[S:%.*]] = load i32, i32* %S.addr, align 4 - // CHECK-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S]], 32 - // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 - // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20) + // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_int(i32* %Ptr, i32 %S) + // COMMON: [[S:%.*]] = load i32, i32* %S.addr, align 4 + // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S]], 32 + // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4 + // CHECK32-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20) + // + // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 + // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 + // CHECK64-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20) ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32); } void column_major_load_with_stride_math_s_int(int *Ptr, short S) { - // CHECK-LABEL: define{{.*}} void @column_major_load_with_stride_math_s_int(i32* %Ptr, i16 signext %S) - // CHECK: [[S:%.*]] = load i16, i16* %S.addr, align 2 - // CHECK-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32 - // CHECK-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S_EXT]], 32 - // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 - // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20) + // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_s_int(i32* %Ptr, i16 signext %S) + // COMMON: [[S:%.*]] = load i16, i16* %S.addr, align 2 + // COMMON-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32 + // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S_EXT]], 32 + // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4 + // CHECK32-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20) + // + // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 + // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 + // CHECK64-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20) ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32); } void column_major_load_array1(double Ptr[25]) { - // CHECK-LABEL: define{{.*}} void @column_major_load_array1(double* %Ptr) - // CHECK: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[ADDR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_array1(double* %Ptr) + // CHECK32: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[ADDR]], i32 5, i1 false, i32 5, i32 5) + + // CHECK64: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[ADDR]], i64 5, i1 false, i32 5, i32 5) dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5); } void column_major_load_array2() { - // CHECK-LABEL: define{{.*}} void @column_major_load_array2() #0 { - // CHECK-NEXT: entry: - // CHECK-NEXT: [[PTR:%.*]] = alloca [25 x double], align 16 - // CHECK: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i64 0, i64 0 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 16 [[ARRAY_DEC]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_array2() #0 { + // COMMON-NEXT: entry: + // CHECK32-NEXT: [[PTR:%.*]] = alloca [25 x double], align 8 + // CHECK32: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i32 0, i32 0 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 8 [[ARRAY_DEC]], i32 5, i1 false, i32 5, i32 5) + + // CHECK64-NEXT: [[PTR:%.*]] = alloca [25 x double], align 16 + // CHECK64: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i64 0, i64 0 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 16 [[ARRAY_DEC]], i64 5, i1 false, i32 5, i32 5) double Ptr[25]; dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5); } void column_major_load_const(const double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_load_const(double* %Ptr) - // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_const(double* %Ptr) + // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5) + // + // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5); } void column_major_load_volatile(volatile double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_load_volatile(double* %Ptr) - // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64(double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_load_volatile(double* %Ptr) + // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5) + // + // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5) dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5); } void column_major_store_with_const_stride_double(double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_store_with_const_stride_double(double* %Ptr) - // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride_double(double* %Ptr) + // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5) + // + // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) dx5x5_t m; __builtin_matrix_column_major_store(m, Ptr, 5); } void column_major_store_with_const_stride2_double(double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_store_with_const_stride2_double(double* %Ptr) - // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride2_double(double* %Ptr) + // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5) + // + // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5) // dx5x5_t m; __builtin_matrix_column_major_store(m, Ptr, 2 * 3 + 9); } void column_major_store_with_stride_math_int(int *Ptr, int S) { - // CHECK-LABEL: define{{.*}} void @column_major_store_with_stride_math_int(i32* %Ptr, i32 %S) - // CHECK: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 - // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: [[S:%.*]] = load i32, i32* %S.addr, align 4 - // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[S]], 32 - // CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v80i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20) + // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_int(i32* %Ptr, i32 %S) + // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4 + // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 + // COMMON-NEXT: [[S:%.*]] = load i32, i32* %S.addr, align 4 + // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[S]], 32 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20) + // + // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20) ix4x20_t m; __builtin_matrix_column_major_store(m, Ptr, S + 32); } void column_major_store_with_stride_math_s_int(int *Ptr, short S) { - // CHECK-LABEL: define{{.*}} void @column_major_store_with_stride_math_s_int(i32* %Ptr, i16 signext %S) - // CHECK: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 - // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: [[S:%.*]] = load i16, i16* %S.addr, align 2 - // CHECK-NEXT: [[EXT:%.*]] = sext i16 [[S]] to i32 - // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 2 - // CHECK-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v80i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20) + // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_s_int(i32* %Ptr, i16 signext %S) + // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4 + // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 + // COMMON-NEXT: [[S:%.*]] = load i16, i16* %S.addr, align 2 + // COMMON-NEXT: [[EXT:%.*]] = sext i16 [[S]] to i32 + // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 2 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20) + // + // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20) ix4x20_t m; __builtin_matrix_column_major_store(m, Ptr, S + 2); } void column_major_store_array1(double Ptr[25]) { - // CHECK-LABEL: define{{.*}} void @column_major_store_array1(double* %Ptr) - // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_store_array1(double* %Ptr) + // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5) + // + // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5) dx5x5_t m; __builtin_matrix_column_major_store(m, Ptr, 5); } void column_major_store_array2() { - // CHECK-LABEL: define{{.*}} void @column_major_store_array2() - // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i64 0, i64 0 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 16 [[PTR]], i64 5, i1 false, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_store_array2() + // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i32 0, i32 0 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 8 [[PTR]], i32 5, i1 false, i32 5, i32 5) + // + // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i64 0, i64 0 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 16 [[PTR]], i64 5, i1 false, i32 5, i32 5) double Ptr[25]; dx5x5_t m; @@ -253,10 +315,14 @@ void column_major_store_array2() { } void column_major_store_volatile(volatile double *Ptr) { - // CHECK-LABEL: define{{.*}} void @column_major_store_volatile(double* %Ptr) #0 { - // CHECK: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 - // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v25f64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5) + // COMMON-LABEL: define{{.*}} void @column_major_store_volatile(double* %Ptr) #0 { + // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4 + // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4 + // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5) + // + // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8 + // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 + // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5) dx5x5_t m; __builtin_matrix_column_major_store(m, Ptr, 5); diff --git a/clang/test/CodeGenCXX/matrix-type-builtins.cpp b/clang/test/CodeGenCXX/matrix-type-builtins.cpp index 6cae343d2c24..d95774feb7c7 100644 --- a/clang/test/CodeGenCXX/matrix-type-builtins.cpp +++ b/clang/test/CodeGenCXX/matrix-type-builtins.cpp @@ -94,7 +94,7 @@ void test_column_major_load_with_stride_template_double(double *Ptr) { // CHECK-LABEL: define linkonce_odr <40 x double> @_Z29column_major_load_with_strideIdLj10ELj4ELj15EEu11matrix_typeIXT0_EXT1_ET_EPS0_(double* %Ptr) // CHECK: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call <40 x double> @llvm.matrix.column.major.load.v40f64(double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4) + // CHECK-NEXT: call <40 x double> @llvm.matrix.column.major.load.v40f64.i64(double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4) matrix_t M1 = column_major_load_with_stride(Ptr); } @@ -106,7 +106,7 @@ void test_column_major_load_with_stride_template_int(int *Ptr) { // CHECK-LABEL: define linkonce_odr <6 x i32> @_Z29column_major_load_with_strideIiLj3ELj2ELj12EEu11matrix_typeIXT0_EXT1_ET_EPS0_(i32* %Ptr) // CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32(i32* align 4 [[PTR]], i64 12, i1 false, i32 3, i32 2) + // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32.i64(i32* align 4 [[PTR]], i64 12, i1 false, i32 3, i32 2) matrix_t M1 = column_major_load_with_stride(Ptr); } @@ -124,7 +124,7 @@ void test_column_major_load_stride_wrapper(int *Ptr, UnsignedWrapper &W) { // CHECK-NEXT: [[STRIDE:%.*]] = call i32 @_ZN15UnsignedWrappercvjEv(%struct.UnsignedWrapper* {{[^,]*}} [[W]]) // CHECK-NEXT: [[STRIDE_EXT:%.*]] = zext i32 [[STRIDE]] to i64 // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2) + // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2) matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, 2, W); } @@ -133,7 +133,7 @@ constexpr int constexpr3() { return 3; } void test_column_major_load_constexpr_num_rows(int *Ptr) { // CHECK-LABEL: define{{.*}} void @_Z41test_column_major_load_constexpr_num_rowsPi(i32* %Ptr) // CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2) + // CHECK-NEXT: call <6 x i32> @llvm.matrix.column.major.load.v6i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2) matrix_t M1 = __builtin_matrix_column_major_load(Ptr, constexpr3(), 2, 3); } @@ -143,7 +143,7 @@ constexpr int constexpr1() { return 1; } void test_column_major_load_constexpr_num_columns(int *Ptr) { // CHECK-LABEL: define{{.*}} void @_Z44test_column_major_load_constexpr_num_columnsPi(i32* %Ptr) // CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <2 x i32> @llvm.matrix.column.major.load.v2i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 1) + // CHECK-NEXT: call <2 x i32> @llvm.matrix.column.major.load.v2i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 1) matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, constexpr1(), 3); } @@ -153,7 +153,7 @@ constexpr int constexpr_plus1() { return N + 1; } void test_column_major_load_constexpr_num_columns_temp(int *Ptr) { // CHECK-LABEL: define{{.*}} void @_Z49test_column_major_load_constexpr_num_columns_tempPi(i32* %Ptr) // CHECK: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <10 x i32> @llvm.matrix.column.major.load.v10i32(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 5) + // CHECK-NEXT: call <10 x i32> @llvm.matrix.column.major.load.v10i32.i64(i32* align 4 [[PTR]], i64 3, i1 false, i32 2, i32 5) matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, constexpr_plus1<4>(), 3); } @@ -162,7 +162,7 @@ void test_column_major_load_constexpr_stride_constexpr(int *Ptr) { // CHECK: [[STRIDE:%.*]] = call i32 @_Z10constexpr3v() // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2) + // CHECK-NEXT: call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 2, i32 2) matrix_t M1 = __builtin_matrix_column_major_load(Ptr, 2, 2, constexpr3()); } @@ -200,7 +200,7 @@ void test_column_major_store_with_stride_template_double(double *Ptr) { // CHECK-LABEL: define linkonce_odr void @_Z30column_major_store_with_strideIdLj10ELj4ELj15EEvRu11matrix_typeIXT0_EXT1_ET_EPS0_([40 x double]* nonnull align 8 dereferenceable(320) %m, double* %Ptr) // CHECK: [[M:%.*]] = load <40 x double>, <40 x double>* {{.*}}, align 8 // CHECK-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v40f64(<40 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4) + // CHECK-NEXT: call void @llvm.matrix.column.major.store.v40f64.i64(<40 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 10, i32 4) matrix_t M1; column_major_store_with_stride(M1, Ptr); @@ -214,7 +214,7 @@ void test_column_major_store_with_stride_template_int(int *Ptr) { // CHECK-LABEL: define linkonce_odr void @_Z30column_major_store_with_strideIiLj3ELj2ELj3EEvRu11matrix_typeIXT0_EXT1_ET_EPS0_([6 x i32]* nonnull align 4 dereferenceable(24) %m, i32* %Ptr) // CHECK: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4 // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v6i32(<6 x i32> [[M]], i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2) + // CHECK-NEXT: call void @llvm.matrix.column.major.store.v6i32.i64(<6 x i32> [[M]], i32* align 4 [[PTR]], i64 3, i1 false, i32 3, i32 2) matrix_t M1; column_major_store_with_stride(M1, Ptr); @@ -227,7 +227,7 @@ void test_column_major_store_stride_wrapper(int *Ptr, UnsignedWrapper &W) { // CHECK-NEXT: [[W:%.*]] = load %struct.UnsignedWrapper*, %struct.UnsignedWrapper** %W.addr, align 8 // CHECK-NEXT: [[IDX:%.*]] = call i32 @_ZN15UnsignedWrappercvjEv(%struct.UnsignedWrapper* {{[^,]*}} [[W]]) // CHECK-NEXT: [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2) + // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32.i64(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2) matrix_t M1; __builtin_matrix_column_major_store(M1, Ptr, W); @@ -239,7 +239,7 @@ void test_column_major_store_constexpr_stride_constexpr(int *Ptr) { // CHECK-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8 // CHECK-NEXT: [[IDX:%.*]] = call i32 @_Z10constexpr3v() // CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[IDX]] to i64 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2) + // CHECK-NEXT: call void @llvm.matrix.column.major.store.v4i32.i64(<4 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 2, i32 2) matrix_t M; __builtin_matrix_column_major_store(M, Ptr, constexpr3()); diff --git a/clang/test/CodeGenObjC/matrix-type-builtins.m b/clang/test/CodeGenObjC/matrix-type-builtins.m index f0faaace4442..0d517dd4964a 100644 --- a/clang/test/CodeGenObjC/matrix-type-builtins.m +++ b/clang/test/CodeGenObjC/matrix-type-builtins.m @@ -56,7 +56,7 @@ void test_column_major_load(PtrValue *Ptr, IntValue *Stride) { // CHECK: [[STRIDE:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*) // CHECK-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64 // CHECK: [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*) - // CHECK-NEXT: call <12 x i32> @llvm.matrix.column.major.load.v12i32(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 3, i32 4) + // CHECK-NEXT: call <12 x i32> @llvm.matrix.column.major.load.v12i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 3, i32 4) u3x4 m = __builtin_matrix_column_major_load(Ptr.value, 3, 4, Stride.value); } @@ -67,7 +67,7 @@ void test_column_major_store(UnsignedMatrixValue *M, PtrValue *Ptr, IntValue *St // CHECK: [[PTR:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32* (i8*, i8*)*) // CHECK: [[IDX:%.*]] = call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*)*) // CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[IDX]] to i64 - // CHECK-NEXT: call void @llvm.matrix.column.major.store.v12i32(<12 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 3, i32 4) + // CHECK-NEXT: call void @llvm.matrix.column.major.store.v12i32.i64(<12 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX_EXT]], i1 false, i32 3, i32 4) __builtin_matrix_column_major_store(M.value, Ptr.value, Stride.value); } diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index cd3bb0de4f34..eaabf8a0192a 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -16300,11 +16300,12 @@ Overview: The '``llvm.matrix.column.major.load.*``' intrinsics load a `` x `` matrix using a stride of ``%Stride`` to compute the start address of the -different columns. This allows for convenient loading of sub matrixes. If -```` is true, the intrinsic is considered a :ref:`volatile memory -access `. The result matrix is returned in the result vector. If the -``%Ptr`` argument is known to be aligned to some boundary, this can be -specified as an attribute on the argument. +different columns. The offset is computed using ``%Stride``'s bitwidth. This +allows for convenient loading of sub matrixes. If ```` is true, the +intrinsic is considered a :ref:`volatile memory access `. The result +matrix is returned in the result vector. If the ``%Ptr`` argument is known to +be aligned to some boundary, this can be specified as an attribute on the +argument. Arguments: """""""""" @@ -16339,7 +16340,8 @@ Overview: The '``llvm.matrix.column.major.store.*``' intrinsics store the `` x `` matrix in ``%In`` to memory using a stride of ``%Stride`` between -columns. If ```` is true, the intrinsic is considered a +columns. The offset is computed using ``%Stride``'s bitwidth. If +```` is true, the intrinsic is considered a :ref:`volatile memory access `. If the ``%Ptr`` argument is known to be aligned to some boundary, this can be diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 21307ed1bd91..2ea4621415b5 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1560,7 +1560,7 @@ def int_matrix_multiply def int_matrix_column_major_load : DefaultAttrsIntrinsic<[llvm_anyvector_ty], - [LLVMPointerToElt<0>, llvm_i64_ty, llvm_i1_ty, + [LLVMPointerToElt<0>, llvm_anyint_ty, llvm_i1_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrReadMem, NoCapture>, ImmArg>, ImmArg>, @@ -1569,7 +1569,7 @@ def int_matrix_column_major_load def int_matrix_column_major_store : DefaultAttrsIntrinsic<[], [llvm_anyvector_ty, LLVMPointerToElt<0>, - llvm_i64_ty, llvm_i1_ty, llvm_i32_ty, llvm_i32_ty], + llvm_anyint_ty, llvm_i1_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrWriteMem, WriteOnly>, NoCapture>, ImmArg>, ImmArg>, ImmArg>]>; diff --git a/llvm/include/llvm/IR/MatrixBuilder.h b/llvm/include/llvm/IR/MatrixBuilder.h index 084b1d49569e..017c8c5e06b9 100644 --- a/llvm/include/llvm/IR/MatrixBuilder.h +++ b/llvm/include/llvm/IR/MatrixBuilder.h @@ -74,7 +74,7 @@ public: Value *Ops[] = {DataPtr, Stride, B.getInt1(IsVolatile), B.getInt32(Rows), B.getInt32(Columns)}; - Type *OverloadedTypes[] = {RetType}; + Type *OverloadedTypes[] = {RetType, Stride->getType()}; Function *TheFn = Intrinsic::getDeclaration( getModule(), Intrinsic::matrix_column_major_load, OverloadedTypes); @@ -97,7 +97,7 @@ public: Value *Ops[] = {Matrix, Ptr, Stride, B.getInt1(IsVolatile), B.getInt32(Rows), B.getInt32(Columns)}; - Type *OverloadedTypes[] = {Matrix->getType()}; + Type *OverloadedTypes[] = {Matrix->getType(), Stride->getType()}; Function *TheFn = Intrinsic::getDeclaration( getModule(), Intrinsic::matrix_column_major_store, OverloadedTypes); diff --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp index 41ce1e341a58..9ae4fa28ed84 100644 --- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp +++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp @@ -803,8 +803,9 @@ public: Value *EltPtr = createElementPtr(Ptr, EltTy, Builder); MatrixTy Result; for (unsigned I = 0, E = Shape.getNumVectors(); I < E; ++I) { - Value *GEP = computeVectorAddr(EltPtr, Builder.getInt64(I), Stride, - Shape.getStride(), EltTy, Builder); + Value *GEP = computeVectorAddr( + EltPtr, Builder.getIntN(Stride->getType()->getScalarSizeInBits(), I), + Stride, Shape.getStride(), EltTy, Builder); Value *Vector = Builder.CreateAlignedLoad( VecTy, GEP, getAlignForIndex(I, Stride, EltTy, MAlign), IsVolatile, "col.load"); @@ -893,9 +894,11 @@ public: auto VType = cast(Ty); Value *EltPtr = createElementPtr(Ptr, VType->getElementType(), Builder); for (auto Vec : enumerate(StoreVal.vectors())) { - Value *GEP = computeVectorAddr(EltPtr, Builder.getInt64(Vec.index()), - Stride, StoreVal.getStride(), - VType->getElementType(), Builder); + Value *GEP = computeVectorAddr( + EltPtr, + Builder.getIntN(Stride->getType()->getScalarSizeInBits(), + Vec.index()), + Stride, StoreVal.getStride(), VType->getElementType(), Builder); Builder.CreateAlignedStore(Vec.value(), GEP, getAlignForIndex(Vec.index(), Stride, VType->getElementType(), diff --git a/llvm/test/Transforms/LowerMatrixIntrinsics/strided-load-double.ll b/llvm/test/Transforms/LowerMatrixIntrinsics/strided-load-double.ll index aaf1b114cc30..61e95effc0d7 100644 --- a/llvm/test/Transforms/LowerMatrixIntrinsics/strided-load-double.ll +++ b/llvm/test/Transforms/LowerMatrixIntrinsics/strided-load-double.ll @@ -23,11 +23,11 @@ define <9 x double> @strided_load_3x3(double* %in, i64 %stride) { ; CHECK-NEXT: ret <9 x double> [[TMP2]] ; entry: - %load = call <9 x double> @llvm.matrix.column.major.load(double* %in, i64 %stride, i1 false, i32 3, i32 3) + %load = call <9 x double> @llvm.matrix.column.major.load.v9f64.i64(double* %in, i64 %stride, i1 false, i32 3, i32 3) ret <9 x double> %load } -declare <9 x double> @llvm.matrix.column.major.load(double*, i64, i1, i32, i32) +declare <9 x double> @llvm.matrix.column.major.load.v9f64.i64(double*, i64, i1, i32, i32) define <9 x double> @strided_load_9x1(double* %in, i64 %stride) { ; CHECK-LABEL: @strided_load_9x1( @@ -39,12 +39,11 @@ define <9 x double> @strided_load_9x1(double* %in, i64 %stride) { ; CHECK-NEXT: ret <9 x double> [[COL_LOAD]] ; entry: - %load = call <9 x double> @llvm.matrix.column.major.load(double* %in, i64 %stride, i1 false, i32 9, i32 1) + %load = call <9 x double> @llvm.matrix.column.major.load.v9f64.i64(double* %in, i64 %stride, i1 false, i32 9, i32 1) ret <9 x double> %load } -declare <8 x double> @llvm.matrix.column.major.load.v8f64(double*, i64, i1, i32, i32) -; CHECK: declare <8 x double> @llvm.matrix.column.major.load.v8f64(double* nocapture, i64, i1 immarg, i32 immarg, i32 immarg) [[READONLY:#[0-9]]] +declare <8 x double> @llvm.matrix.column.major.load.v8f64.i64(double*, i64, i1, i32, i32) define <8 x double> @strided_load_4x2(double* %in, i64 %stride) { ; CHECK-LABEL: @strided_load_4x2( @@ -61,9 +60,27 @@ define <8 x double> @strided_load_4x2(double* %in, i64 %stride) { ; CHECK-NEXT: ret <8 x double> [[TMP0]] ; entry: - %load = call <8 x double> @llvm.matrix.column.major.load.v8f64(double* %in, i64 %stride, i1 false, i32 4, i32 2) + %load = call <8 x double> @llvm.matrix.column.major.load.v8f64.i64(double* %in, i64 %stride, i1 false, i32 4, i32 2) ret <8 x double> %load } -; CHECK: declare <9 x double> @llvm.matrix.column.major.load.v9f64(double* nocapture, i64, i1 immarg, i32 immarg, i32 immarg) [[READONLY]] -; CHECK: attributes [[READONLY]] = { argmemonly nofree nosync nounwind readonly willreturn } +declare <8 x double> @llvm.matrix.column.major.load.v8f64.i32(double*, i32, i1, i32, i32) + +define <8 x double> @strided_load_4x2_stride_i32(double* %in, i32 %stride) { +; CHECK-LABEL: @strided_load_4x2_stride_i32( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VEC_START:%.*]] = mul i32 0, [[STRIDE:%.*]] +; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr double, double* [[IN:%.*]], i32 [[VEC_START]] +; CHECK-NEXT: [[VEC_CAST:%.*]] = bitcast double* [[VEC_GEP]] to <4 x double>* +; CHECK-NEXT: [[COL_LOAD:%.*]] = load <4 x double>, <4 x double>* [[VEC_CAST]], align 8 +; CHECK-NEXT: [[VEC_START1:%.*]] = mul i32 1, [[STRIDE]] +; CHECK-NEXT: [[VEC_GEP2:%.*]] = getelementptr double, double* [[IN]], i32 [[VEC_START1]] +; CHECK-NEXT: [[VEC_CAST3:%.*]] = bitcast double* [[VEC_GEP2]] to <4 x double>* +; CHECK-NEXT: [[COL_LOAD4:%.*]] = load <4 x double>, <4 x double>* [[VEC_CAST3]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <4 x double> [[COL_LOAD]], <4 x double> [[COL_LOAD4]], <8 x i32> +; CHECK-NEXT: ret <8 x double> [[TMP0]] +; +entry: + %load = call <8 x double> @llvm.matrix.column.major.load.v8f64.i32(double* %in, i32 %stride, i1 false, i32 4, i32 2) + ret <8 x double> %load +} diff --git a/llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll b/llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll index 817f989ba550..5dd1166f1c22 100644 --- a/llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll +++ b/llvm/test/Transforms/LowerMatrixIntrinsics/strided-store-double.ll @@ -13,7 +13,7 @@ define void @strided_store_3x2(<6 x double> %in, double* %out) { ; CHECK-NEXT: store <3 x double> [[SPLIT1]], <3 x double>* [[VEC_CAST2]], align 8 ; CHECK-NEXT: ret void ; - call void @llvm.matrix.column.major.store.v6f64(<6 x double> %in, double* %out, i64 5, i1 false, i32 3, i32 2) + call void @llvm.matrix.column.major.store.v6f64.i64(<6 x double> %in, double* %out, i64 5, i1 false, i32 3, i32 2) ret void } @@ -31,7 +31,25 @@ define void @strided_store_3x2_nonconst_stride(<6 x double> %in, i64 %stride, do ; CHECK-NEXT: store <3 x double> [[SPLIT1]], <3 x double>* [[VEC_CAST4]], align 8 ; CHECK-NEXT: ret void ; - call void @llvm.matrix.column.major.store.v6f64(<6 x double> %in, double* %out, i64 %stride, i1 false, i32 3, i32 2) + call void @llvm.matrix.column.major.store.v6f64.i64(<6 x double> %in, double* %out, i64 %stride, i1 false, i32 3, i32 2) + ret void +} + +define void @strided_store_3x2_nonconst_i32_stride(<6 x double> %in, i32 %stride, double* %out) { +; CHECK-LABEL: @strided_store_3x2_nonconst_i32_stride( +; CHECK-NEXT: [[SPLIT:%.*]] = shufflevector <6 x double> [[IN:%.*]], <6 x double> poison, <3 x i32> +; CHECK-NEXT: [[SPLIT1:%.*]] = shufflevector <6 x double> [[IN]], <6 x double> poison, <3 x i32> +; CHECK-NEXT: [[VEC_START:%.*]] = mul i32 0, [[STRIDE:%.*]] +; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr double, double* [[OUT:%.*]], i32 [[VEC_START]] +; CHECK-NEXT: [[VEC_CAST:%.*]] = bitcast double* [[VEC_GEP]] to <3 x double>* +; CHECK-NEXT: store <3 x double> [[SPLIT]], <3 x double>* [[VEC_CAST]], align 8 +; CHECK-NEXT: [[VEC_START2:%.*]] = mul i32 1, [[STRIDE]] +; CHECK-NEXT: [[VEC_GEP3:%.*]] = getelementptr double, double* [[OUT]], i32 [[VEC_START2]] +; CHECK-NEXT: [[VEC_CAST4:%.*]] = bitcast double* [[VEC_GEP3]] to <3 x double>* +; CHECK-NEXT: store <3 x double> [[SPLIT1]], <3 x double>* [[VEC_CAST4]], align 8 +; CHECK-NEXT: ret void +; + call void @llvm.matrix.column.major.store.v6f64.i32(<6 x double> %in, double* %out, i32 %stride, i1 false, i32 3, i32 2) ret void } @@ -58,13 +76,14 @@ define void @strided_store_2x3(<10 x double> %in, double* %out) { ; CHECK-NEXT: store <2 x double> [[SPLIT4]], <2 x double>* [[VEC_CAST11]], align 8 ; CHECK-NEXT: ret void ; - call void @llvm.matrix.column.major.store.v10f64(<10 x double> %in, double* %out, i64 4, i1 false, i32 2, i32 5) + call void @llvm.matrix.column.major.store.v10f64.i64(<10 x double> %in, double* %out, i64 4, i1 false, i32 2, i32 5) ret void } -declare void @llvm.matrix.column.major.store.v6f64(<6 x double>, double*, i64, i1, i32, i32) -declare void @llvm.matrix.column.major.store.v10f64(<10 x double>, double*, i64, i1, i32, i32) +declare void @llvm.matrix.column.major.store.v6f64.i64(<6 x double>, double*, i64, i1, i32, i32) +declare void @llvm.matrix.column.major.store.v6f64.i32(<6 x double>, double*, i32, i1, i32, i32) +declare void @llvm.matrix.column.major.store.v10f64.i64(<10 x double>, double*, i64, i1, i32, i32) -; CHECK: declare void @llvm.matrix.column.major.store.v6f64(<6 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 -; CHECK: declare void @llvm.matrix.column.major.store.v10f64(<10 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 +; CHECK: declare void @llvm.matrix.column.major.store.v6f64.i64(<6 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 +; CHECK: declare void @llvm.matrix.column.major.store.v10f64.i64(<10 x double>, double* nocapture writeonly, i64, i1 immarg, i32 immarg, i32 immarg) #0 ; CHECK: attributes #0 = { argmemonly nofree nosync nounwind willreturn writeonly } diff --git a/llvm/test/Verifier/matrix-intrinsics.ll b/llvm/test/Verifier/matrix-intrinsics.ll index 4194cfb434f2..6f90fcb5ce92 100644 --- a/llvm/test/Verifier/matrix-intrinsics.ll +++ b/llvm/test/Verifier/matrix-intrinsics.ll @@ -39,11 +39,11 @@ define <4 x float> @column.major_load(float* %m, float* %n, i32 %arg) { ; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector! ; CHECK-NEXT: immarg operand has non-immediate parameter ; CHECK-NEXT: i32 %arg -; CHECK-NEXT: %result.3 = call <6 x float> @llvm.matrix.column.major.load.v6f32(float* %n, i64 2, i1 true, i32 3, i32 %arg) - %result.0 = call <4 x float> @llvm.matrix.column.major.load.v4f32(float* %m, i64 0, i1 false, i32 0, i32 0) - %result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32(float* %m, i64 2, i1 false, i32 1, i32 2) - %result.2 = call <6 x float> @llvm.matrix.column.major.load.v6f32(float* %n, i64 2, i1 true, i32 3, i32 3) - %result.3 = call <6 x float> @llvm.matrix.column.major.load.v6f32(float* %n, i64 2, i1 true, i32 3, i32 %arg) +; CHECK-NEXT: %result.3 = call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* %n, i64 2, i1 true, i32 3, i32 %arg) + %result.0 = call <4 x float> @llvm.matrix.column.major.load.v4f32.i64(float* %m, i64 0, i1 false, i32 0, i32 0) + %result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32.i64(float* %m, i64 2, i1 false, i32 1, i32 2) + %result.2 = call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* %n, i64 2, i1 true, i32 3, i32 3) + %result.3 = call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* %n, i64 2, i1 true, i32 3, i32 %arg) ret <4 x float> %result.1 } @@ -52,10 +52,10 @@ define void @column.major_store(float* %m, float* %n, i64 %arg) { ; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector! ; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector! ; CHECK-NEXT: Result of a matrix operation does not fit in the returned vector! - call void @llvm.matrix.column.major.store.v4f32(<4 x float> zeroinitializer, float* %m, i64 0, i1 false, i32 0, i32 0) - call void @llvm.matrix.column.major.store.v4f32(<4 x float> zeroinitializer, float* %m, i64 2, i1 false, i32 1, i32 2) - call void @llvm.matrix.column.major.store.v6f32(<6 x float> zeroinitializer, float* %n, i64 2, i1 false, i32 3, i32 3) - call void @llvm.matrix.column.major.store.v6f32(<6 x float> zeroinitializer, float* %n, i64 %arg, i1 false, i32 3, i32 3) + call void @llvm.matrix.column.major.store.v4f32.i64(<4 x float> zeroinitializer, float* %m, i64 0, i1 false, i32 0, i32 0) + call void @llvm.matrix.column.major.store.v4f32.i64(<4 x float> zeroinitializer, float* %m, i64 2, i1 false, i32 1, i32 2) + call void @llvm.matrix.column.major.store.v6f32.i64(<6 x float> zeroinitializer, float* %n, i64 2, i1 false, i32 3, i32 3) + call void @llvm.matrix.column.major.store.v6f32.i64(<6 x float> zeroinitializer, float* %n, i64 %arg, i1 false, i32 3, i32 3) ret void } @@ -94,18 +94,18 @@ define <4 x float> @column.major_load_mixed_types(i32* %m, float* %n, i32 %arg) ; CHECK-NEXT: Intrinsic has incorrect argument type! ; CHECK-NEXT: <4 x float> (i32*, i64, i1, i32, i32)* @llvm.matrix.column.major.load.v4f32.pi32 ; CHECK-NEXT: Intrinsic has incorrect argument type! -; CHECK-NEXT: <4 x i32> (float*, i64, i1, i32, i32)* @llvm.matrix.column.major.load.v4i32 +; CHECK-NEXT: <4 x i32> (float*, i64, i1, i32, i32)* @llvm.matrix.column.major.load.v4i32.i64 ; %result.0 = call <4 x float> @llvm.matrix.column.major.load.v4f32.pi32(i32* %m, i64 2, i1 false, i32 2, i32 2) - %result.1 = call <4 x i32> @llvm.matrix.column.major.load.v4i32(float* %n, i64 2, i1 false, i32 2, i32 2) + %result.1 = call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(float* %n, i64 2, i1 false, i32 2, i32 2) ret <4 x float> %result.0 } define void @column.major_store_mixed_types(float* %m, i32* %n, i64 %arg) { ; -; CHECK-NEXT: Intrinsic has incorrect argument type! +; CHECK-NEXT: Intrinsic has incorrect argument type! ; CHECK-NEXT: void (<4 x i32>, float*, i64, i1, i32, i32)* @llvm.matrix.column.major.store.v4i32.vi32 -; CHECK-NEXT: Intrinsic has incorrect argument type! +; CHECK-NEXT: Intrinsic has incorrect argument type! ; CHECK-NEXT: void (<4 x float>, i32*, i64, i1, i32, i32)* @llvm.matrix.column.major.store.v4f32.pi32 ; call void @llvm.matrix.column.major.store.v4i32.vi32(<4 x i32> zeroinitializer, float* %m, i64 2, i1 false, i32 2, i32 2) @@ -125,28 +125,28 @@ define void @column.major_store_non_int_float_type(<4 x float>* %m, <4 x float>* define <4 x float> @column.major_load_stride_too_small(float* %m, i32 %arg) { ; ; CHECK-NEXT: Stride must be greater or equal than the number of rows! -; CHECK-NEXT: <4 x float> (float*, i64, i1, i32, i32)* @llvm.matrix.column.major.load.v4f32 +; CHECK-NEXT: <4 x float> (float*, i64, i1, i32, i32)* @llvm.matrix.column.major.load.v4f32.i64 ; - %result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32(float* %m, i64 1, i1 false, i32 2, i32 2) + %result.1 = call <4 x float> @llvm.matrix.column.major.load.v4f32.i64(float* %m, i64 1, i1 false, i32 2, i32 2) ret <4 x float> %result.1 } define void @column.major_store_stride_too_small(float* %m, i64 %arg) { ; ; CHECK-NEXT: Stride must be greater or equal than the number of rows! -; CHECK-NEXT: void (<4 x float>, float*, i64, i1, i32, i32)* @llvm.matrix.column.major.store.v4f32 +; CHECK-NEXT: void (<4 x float>, float*, i64, i1, i32, i32)* @llvm.matrix.column.major.store.v4f32.i64 ; - call void @llvm.matrix.column.major.store.v4f32(<4 x float> zeroinitializer, float* %m, i64 1, i1 false, i32 2, i32 2) + call void @llvm.matrix.column.major.store.v4f32.i64(<4 x float> zeroinitializer, float* %m, i64 1, i1 false, i32 2, i32 2) ret void } -declare <4 x i32> @llvm.matrix.column.major.load.v4i32(float*, i64, i1, i32, i32) +declare <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(float*, i64, i1, i32, i32) declare <4 x float> @llvm.matrix.column.major.load.v4f32.pi32(i32*, i64, i1, i32, i32) -declare <4 x float> @llvm.matrix.column.major.load.v4f32(float*, i64, i1, i32, i32) -declare <6 x float> @llvm.matrix.column.major.load.v6f32(float*, i64, i1, i32, i32) +declare <4 x float> @llvm.matrix.column.major.load.v4f32.i64(float*, i64, i1, i32, i32) +declare <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float*, i64, i1, i32, i32) -declare void @llvm.matrix.column.major.store.v4f32(<4 x float>, float*, i64, i1, i32, i32) -declare void @llvm.matrix.column.major.store.v6f32(<6 x float>, float*, i64, i1, i32, i32) +declare void @llvm.matrix.column.major.store.v4f32.i64(<4 x float>, float*, i64, i1, i32, i32) +declare void @llvm.matrix.column.major.store.v6f32.i64(<6 x float>, float*, i64, i1, i32, i32) declare void @llvm.matrix.column.major.store.v4i32.vi32(<4 x i32>, float*, i64, i1, i32, i32) declare void @llvm.matrix.column.major.store.v4f32.pi32(<4 x float>, i32*, i64, i1, i32, i32) declare void @llvm.matrix.column.major.store.v4f32p0.p0v4f32(<4 x float*>, <4 x float>*, i64, i1, i32, i32) -- Gitee From 755e704ff2f35b99665a4c5c371dc7017beeeac1 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Wed, 29 Jun 2022 17:34:56 +0800 Subject: [PATCH 13/19] Spport OHOS Customized LLVM Toolchain Author: @Leviant @kosovpavel @xwx1135370 @chenhao346 @liwentao_uiw Signed-off-by: liwentao Change-Id: I9cee44fe2ea65aa05af6223d982e1b379b1c9d1a --- clang/include/clang/Basic/Attr.td | 1 + clang/include/clang/Driver/Options.td | 2 + clang/include/clang/Driver/ToolChain.h | 3 +- clang/lib/Basic/TargetInfo.cpp | 3 +- clang/lib/Basic/Targets.cpp | 18 +- clang/lib/Basic/Targets/ARM.cpp | 2 +- clang/lib/Basic/Targets/OSTargets.h | 63 +++ clang/lib/Basic/Targets/X86.h | 22 + clang/lib/CodeGen/ABIInfo.h | 1 + clang/lib/CodeGen/TargetInfo.cpp | 8 +- clang/lib/Driver/CMakeLists.txt | 1 + clang/lib/Driver/Driver.cpp | 7 +- clang/lib/Driver/ToolChain.cpp | 6 + clang/lib/Driver/ToolChains/Arch/ARM.cpp | 2 + clang/lib/Driver/ToolChains/BareMetal.h | 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 5 +- clang/lib/Driver/ToolChains/CommonArgs.cpp | 19 +- clang/lib/Driver/ToolChains/Gnu.cpp | 14 +- clang/lib/Driver/ToolChains/OHOS.cpp | 439 ++++++++++++++++++ clang/lib/Driver/ToolChains/OHOS.h | 103 ++++ clang/lib/Sema/SemaDecl.cpp | 3 +- .../CodeGen/aarch64-fix-cortex-a53-835769.c | 2 + clang/test/CodeGen/arm64-abi-vector.c | 1 + clang/test/CodeGen/math-builtins.c | 1 + clang/test/CodeGen/merge-functions.c | 22 + clang/test/Driver/as-fno-integrated-as.c | 3 + clang/test/Driver/fenable-merge-functions.cpp | 28 ++ clang/test/Driver/ohos.c | 245 ++++++++++ clang/test/Driver/ohos.cpp | 123 +++++ clang/test/Preprocessor/ohos.c | 11 + clang/unittests/CMakeLists.txt | 4 +- compiler-rt/CMakeLists.txt | 32 +- compiler-rt/cmake/Modules/AddCompilerRT.cmake | 6 +- .../cmake/Modules/CompilerRTUtils.cmake | 12 +- compiler-rt/cmake/base-config-ix.cmake | 3 + compiler-rt/cmake/config-ix.cmake | 47 +- compiler-rt/lib/asan/asan_allocator.h | 2 +- compiler-rt/lib/asan/asan_internal.h | 2 +- compiler-rt/lib/asan/asan_linux.cpp | 7 +- compiler-rt/lib/asan/tests/asan_test.cpp | 4 +- compiler-rt/lib/builtins/CMakeLists.txt | 7 +- compiler-rt/lib/builtins/divtf3.c | 2 +- compiler-rt/lib/builtins/fp_div_impl.inc | 2 +- compiler-rt/lib/builtins/int_util.h | 4 + compiler-rt/lib/cfi/CMakeLists.txt | 2 +- compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp | 1 + compiler-rt/lib/hwasan/hwasan.cpp | 2 +- .../lib/hwasan/hwasan_dynamic_shadow.cpp | 2 +- compiler-rt/lib/interception/interception.h | 4 +- .../interception/interception_type_test.cpp | 4 +- compiler-rt/lib/lsan/lsan_common.h | 2 +- .../sanitizer_common/sanitizer_allocator.cpp | 2 +- .../sanitizer_common_interceptors.inc | 6 +- .../sanitizer_common_interceptors_ioctl.inc | 2 +- .../sanitizer_common_syscalls.inc | 4 +- .../lib/sanitizer_common/sanitizer_errno.h | 3 +- .../lib/sanitizer_common/sanitizer_flags.inc | 9 +- .../sanitizer_internal_defs.h | 4 +- .../lib/sanitizer_common/sanitizer_linux.cpp | 26 +- .../lib/sanitizer_common/sanitizer_linux.h | 2 +- .../sanitizer_linux_libcdep.cpp | 8 +- .../lib/sanitizer_common/sanitizer_platform.h | 15 +- .../sanitizer_platform_interceptors.h | 19 +- .../sanitizer_platform_limits_linux.cpp | 6 +- .../sanitizer_platform_limits_posix.cpp | 34 +- .../sanitizer_platform_limits_posix.h | 39 +- .../lib/sanitizer_common/sanitizer_posix.cpp | 4 +- .../sanitizer_posix_libcdep.cpp | 3 +- .../sanitizer_common/sanitizer_stackdepot.cpp | 3 +- .../sanitizer_common/sanitizer_stackdepot.h | 3 +- .../sanitizer_stoptheworld_linux_libcdep.cpp | 5 + .../sanitizer_symbolizer_report.cpp | 2 +- .../sanitizer_unwind_linux_libcdep.cpp | 2 +- compiler-rt/lib/scudo/scudo_flags.inc | 2 +- compiler-rt/lib/scudo/scudo_platform.h | 8 +- .../lib/ubsan/ubsan_signals_standalone.cpp | 2 +- compiler-rt/test/asan/CMakeLists.txt | 2 +- .../asan/TestCases/Linux/lit.local.cfg.py | 2 +- .../test/asan/TestCases/Linux/odr_c_test.c | 2 +- .../test/asan/TestCases/Linux/shmctl.cpp | 4 +- compiler-rt/test/asan/lit.cfg.py | 2 +- compiler-rt/test/builtins/Unit/divtf3_test.c | 5 + compiler-rt/test/lit.common.cfg.py | 72 +-- compiler-rt/test/lit.common.configured.in | 1 + .../ohos_family_commands/ohos_common.py | 45 ++ .../ohos_family_commands/ohos_compile.py | 52 +++ .../ohos_family_commands/ohos_run.py | 38 ++ libcxx/CMakeLists.txt | 14 +- libcxx/cmake/config-ix.cmake | 2 + libcxx/include/__config | 3 +- libcxx/include/__locale | 3 + libcxx/src/CMakeLists.txt | 10 +- libcxx/src/include/config_elast.h | 2 + libcxxabi/CMakeLists.txt | 13 +- libcxxabi/src/abort_message.cpp | 4 +- libunwind/CMakeLists.txt | 13 +- lld/ELF/Config.h | 2 + lld/ELF/Driver.cpp | 46 +- lld/ELF/LTO.cpp | 2 + lld/ELF/Options.td | 4 + lld/test/ELF/lto/opt-level.ll | 6 +- lldb/CMakeLists.txt | 22 +- lldb/cmake/modules/FindPythonAndSwig.cmake | 11 + lldb/cmake/modules/LLDBConfig.cmake | 2 +- lldb/include/lldb/Host/HostInfo.h | 3 + lldb/include/lldb/Host/MainLoop.h | 3 +- lldb/include/lldb/Host/ohos/HostInfoOHOS.h | 32 ++ .../include/lldb/Target/ThreadPlanStepRange.h | 1 + .../Python/lldbsuite/test/decorators.py | 3 + .../Python/lldbsuite/test/lldbplatformutil.py | 2 + .../Python/lldbsuite/test/lldbtest.py | 5 - lldb/source/Expression/IRInterpreter.cpp | 90 +++- lldb/source/Host/CMakeLists.txt | 7 +- lldb/source/Host/common/MainLoop.cpp | 8 +- lldb/source/Host/common/Socket.cpp | 2 +- lldb/source/Host/common/TCPSocket.cpp | 2 + lldb/source/Host/ohos/HostInfoOHOS.cpp | 94 ++++ lldb/source/Host/posix/DomainSocket.cpp | 2 +- lldb/source/Host/posix/HostInfoPosix.cpp | 2 +- .../Host/posix/ProcessLauncherPosixFork.cpp | 2 +- .../Clang/ClangUserExpression.cpp | 2 +- .../Clang/CppModuleConfiguration.cpp | 43 +- .../Clang/CppModuleConfiguration.h | 8 +- lldb/source/Plugins/Platform/CMakeLists.txt | 1 + .../Plugins/Platform/Linux/PlatformLinux.cpp | 2 +- .../Plugins/Platform/OHOS/CMakeLists.txt | 13 + .../Plugins/Platform/OHOS/HdcClient.cpp | 379 +++++++++++++++ lldb/source/Plugins/Platform/OHOS/HdcClient.h | 90 ++++ .../Plugins/Platform/OHOS/PlatformOHOS.cpp | 266 +++++++++++ .../Plugins/Platform/OHOS/PlatformOHOS.h | 80 ++++ .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 247 ++++++++++ .../OHOS/PlatformOHOSRemoteGDBServer.h | 64 +++ lldb/source/Plugins/Process/CMakeLists.txt | 2 +- .../Linux/NativeRegisterContextLinux_arm64.h | 5 + lldb/source/Plugins/Process/Linux/Procfs.h | 2 +- .../GDBRemoteCommunicationServerCommon.cpp | 14 +- lldb/source/Target/PathMappingList.cpp | 7 +- lldb/source/Target/ThreadPlanStepInRange.cpp | 12 +- lldb/source/Target/ThreadPlanStepRange.cpp | 7 + lldb/source/Utility/ArchSpec.cpp | 4 +- .../Utility/TildeExpressionResolver.cpp | 4 +- .../API/api/command-return-object/Makefile | 1 + .../libstdcpp/list/Makefile | 2 +- .../libstdcpp/map/TestDataFormatterStdMap.py | 3 +- .../plugins/command_plugin/Makefile | 1 + lldb/test/API/lang/c/fpeval/Makefile | 3 + lldb/test/API/lang/c/fpeval/TestFPEval.py | 34 ++ lldb/test/API/lang/c/fpeval/main.c | 10 + .../TestGdbRemoteMemoryAllocation.py | 1 + .../TestPlatformProcessConnect.py | 2 +- .../TestGdbRemote_QPassSignals.py | 1 + .../thread-name/TestGdbRemoteThreadName.py | 1 + .../lldb-vscode/attach/TestVSCode_attach.py | 1 + .../runInTerminal/TestVSCode_runInTerminal.py | 1 + lldb/tools/lldb-server/CMakeLists.txt | 2 +- .../Expression/CppModuleConfigurationTest.cpp | 42 +- lldb/unittests/Target/CMakeLists.txt | 1 + lldb/unittests/Target/FindFileTest.cpp | 97 ++++ llvm-build/build.py | 18 +- llvm-build/env_prepare.sh | 4 +- llvm-build/mingw.py | 0 llvm-build/windres.sh | 0 llvm/include/llvm/ADT/Triple.h | 34 +- .../llvm/BinaryFormat/MinidumpConstants.def | 1 + llvm/include/llvm/LTO/Config.h | 3 + .../LiveDebugValues/VarLocBasedImpl.cpp | 1 - llvm/lib/LTO/LTO.cpp | 2 + llvm/lib/LTO/LTOBackend.cpp | 3 + llvm/lib/Support/AArch64TargetParser.cpp | 2 +- llvm/lib/Support/ARMTargetParser.cpp | 2 +- llvm/lib/Support/Triple.cpp | 80 ++-- .../Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp | 4 +- llvm/lib/Target/ARM/ARMSubtarget.h | 6 +- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 3 +- .../CodeGen/AArch64/arm64-platform-reg.ll | 1 + llvm/test/Transforms/SafeStack/AArch64/abi.ll | 2 + .../Transforms/SafeStack/AArch64/abi_ssp.ll | 2 + .../SafeStack/AArch64/unreachable.ll | 2 + llvm/utils/lit/lit/llvm/config.py | 4 +- .../include/gtest/internal/gtest-port-arch.h | 3 + .../unittest/googletest/src/gtest-port.cc | 2 +- openmp/runtime/src/kmp.h | 3 +- openmp/runtime/src/kmp_i18n.cpp | 3 +- .../tasking/hidden_helper_task/depend.cpp | 4 +- .../test/tasking/hidden_helper_task/gtid.cpp | 4 +- 185 files changed, 3453 insertions(+), 361 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/OHOS.cpp create mode 100644 clang/lib/Driver/ToolChains/OHOS.h create mode 100644 clang/test/CodeGen/merge-functions.c create mode 100644 clang/test/Driver/as-fno-integrated-as.c create mode 100644 clang/test/Driver/fenable-merge-functions.cpp create mode 100644 clang/test/Driver/ohos.c create mode 100644 clang/test/Driver/ohos.cpp create mode 100644 clang/test/Preprocessor/ohos.c create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py create mode 100644 compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py create mode 100644 lldb/include/lldb/Host/ohos/HostInfoOHOS.h create mode 100644 lldb/source/Host/ohos/HostInfoOHOS.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/CMakeLists.txt create mode 100644 lldb/source/Plugins/Platform/OHOS/HdcClient.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/HdcClient.h create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp create mode 100644 lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h create mode 100644 lldb/test/API/lang/c/fpeval/Makefile create mode 100644 lldb/test/API/lang/c/fpeval/TestFPEval.py create mode 100644 lldb/test/API/lang/c/fpeval/main.c create mode 100644 lldb/unittests/Target/FindFileTest.cpp mode change 100644 => 100755 llvm-build/build.py mode change 100644 => 100755 llvm-build/mingw.py mode change 100644 => 100755 llvm-build/windres.sh diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index bfd50f6a6779..f62b547b72f5 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -840,6 +840,7 @@ def Availability : InheritableAttr { .Case("tvos_app_extension", "tvOS (App Extension)") .Case("watchos_app_extension", "watchOS (App Extension)") .Case("swift", "Swift") + .Case("ohos", "OpenHOS") .Default(llvm::StringRef()); } static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 817798926650..9019ea8f7298 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2415,6 +2415,8 @@ def ffinite_loops: Flag<["-"], "ffinite-loops">, Group, def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group, HelpText<"Do not assume that any loop is finite.">, Flags<[CC1Option]>; +def fenable_merge_functions : Flag<["-"], "fenable-merge-functions">, Group, + HelpText<"Enables Merge Functions optimization">; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 28c37a44e1eb..9ead01d68335 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -441,7 +441,8 @@ public: // Returns /lib//. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. - std::string getArchSpecificLibPath() const; + // OHOS specific: make this function virtual to override in OHOS.cpp + virtual std::string getArchSpecificLibPath() const; // Returns part of above. virtual StringRef getOSLibName() const; diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 642ee753d224..d727d9991443 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -68,7 +68,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html. // This alignment guarantee also applies to Windows and Android. - if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid()) + if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() || + T.isOHOSFamily()) NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; else NewAlign = 0; // Infer from basic type alignment. diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 90a67d03b7b2..b0c3e9ce9c97 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -143,7 +143,12 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Fuchsia: return new FuchsiaTargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } case llvm::Triple::NetBSD: return new NetBSDTargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: @@ -183,7 +188,14 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::CloudABI: return new CloudABITargetInfo(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo(Triple, Opts); + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSTargetInfo(Triple, Opts); + } + case llvm::Triple::LiteOS: + return new OHOSTargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo(Triple, Opts); case llvm::Triple::NetBSD: @@ -546,6 +558,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::Android: return new AndroidX86_64TargetInfo(Triple, Opts); + case llvm::Triple::OpenHOS: + return new OHOSX86_64TargetInfo(Triple, Opts); } } case llvm::Triple::DragonFly: diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index a2c96ad12a76..cca55956b2f4 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -305,7 +305,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, default: if (IsNetBSD) setABI("apcs-gnu"); - else if (IsOpenBSD) + else if (IsOpenBSD || Triple.isOHOSFamily()) setABI("aapcs-linux"); else setABI("aapcs"); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 67fa1a537fea..295e68426752 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -947,6 +947,69 @@ public: : WebAssemblyOSTargetInfo(Triple, Opts) {} }; +// OHOS target +template +class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Linux defines; list based off of gcc output + DefineStd(Builder, "unix", Opts); + + Builder.defineMacro("__ELF__"); + + // Generic OHOS target defines + if (Triple.isOHOSFamily()) { + Builder.defineMacro("__OHOS_FAMILY__", "1"); + + unsigned Maj, Min, Rev; + Triple.getEnvironmentVersion(Maj, Min, Rev); + this->PlatformName = "ohos"; + this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); + if (Maj) { + Builder.defineMacro("__OHOS_Major__", Twine(Maj)); + Builder.defineMacro("__OHOS_Minor__", Twine(Min)); + Builder.defineMacro("__OHOS_Micro__", Twine(Rev)); + } + } + + if (Triple.isOpenHOS()) + Builder.defineMacro("__OHOS__"); + + if (Triple.isOSLinux()) { + DefineStd(Builder, "linux", Opts); + } else if (Triple.isOSLiteOS()) { + Builder.defineMacro("__LITEOS__"); + } + + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); + } + +public: + OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo(Triple, Opts) { + this->WIntType = TargetInfo::UnsignedInt; + + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } + } + + const char *getStaticInitSectionSpecifier() const override { + return ".text.startup"; + } +}; + } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 91a365c7d405..2b8e9bbe16b3 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -909,6 +909,28 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEquad(); } }; + +// x86_32 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + SuitableAlign = 32; + LongDoubleWidth = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + } +}; + +// x86_64 OHOS target +class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo + : public OHOSTargetInfo { +public: + OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OHOSTargetInfo(Triple, Opts) { + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + } +}; } // namespace targets } // namespace clang #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h index 56f0dd4322d2..035b6e5a293c 100644 --- a/clang/lib/CodeGen/ABIInfo.h +++ b/clang/lib/CodeGen/ABIInfo.h @@ -89,6 +89,7 @@ namespace swiftcall { QualType Ty) const = 0; bool isAndroid() const; + bool isOHOSFamily() const; /// Emit the target dependent code to load a value of /// \arg Ty from the \c __builtin_ms_va_list pointed to by \arg VAListAddr. diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index bcd24292ff41..4b916b729aeb 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -223,6 +223,10 @@ const CodeGenOptions &ABIInfo::getCodeGenOpts() const { bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); } +bool ABIInfo::isOHOSFamily() const { + return getTarget().getTriple().isOHOSFamily(); +} + bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { return false; } @@ -5607,7 +5611,7 @@ ABIArgInfo AArch64ABIInfo::coerceIllegalVector(QualType Ty) const { uint64_t Size = getContext().getTypeSize(Ty); // Android promotes <2 x i8> to i16, not i32 - if (isAndroid() && (Size <= 16)) { + if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) { llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); return ABIArgInfo::getDirect(ResType); } @@ -6158,7 +6162,7 @@ public: case llvm::Triple::MuslEABIHF: return true; default: - return false; + return getTarget().getTriple().isOHOSFamily(); } } diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index aeffcf0bb43a..7dca74742803 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -63,6 +63,7 @@ add_clang_library(clangDriver ToolChains/Myriad.cpp ToolChains/NaCl.cpp ToolChains/NetBSD.cpp + ToolChains/OHOS.cpp ToolChains/OpenBSD.cpp ToolChains/PS4CPU.cpp ToolChains/RISCVToolchain.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 418e1d3e8ec9..71e3df95cb1f 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -37,6 +37,7 @@ #include "ToolChains/Myriad.h" #include "ToolChains/NaCl.h" #include "ToolChains/NetBSD.h" +#include "ToolChains/OHOS.h" #include "ToolChains/OpenBSD.h" #include "ToolChains/PPCLinux.h" #include "ToolChains/PS4CPU.h" @@ -5118,7 +5119,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, Args); else if (Target.getArch() == llvm::Triple::ve) TC = std::make_unique(*this, Target, Args); - + else if (Target.isOHOSFamily()) + TC = std::make_unique(*this, Target, Args); else TC = std::make_unique(*this, Target, Args); break; @@ -5176,6 +5178,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::Hurd: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::LiteOS: + TC = std::make_unique(*this, Target, Args); + break; case llvm::Triple::ZOS: TC = std::make_unique(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index b2ddef141a75..5dc8f6720b38 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -823,7 +823,13 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, Triple.setEnvironment(isHardFloat ? Triple::MuslEABIHF : Triple::MuslEABI); break; + case Triple::OpenHOS: + break; default: { + if (Triple.isOSLiteOS()) { + Triple.setEnvironment(Triple::OpenHOS); + break; + } arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple); if (DefaultABI != arm::FloatABI::Invalid && isHardFloat != (DefaultABI == arm::FloatABI::Hard)) { diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index ef590db1eecd..a812bcb58873 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -211,6 +211,8 @@ arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) { return FloatABI::SoftFP; default: + if (Triple.isOHOSFamily()) + return FloatABI::Soft; switch (Triple.getEnvironment()) { case llvm::Triple::GNUEABIHF: case llvm::Triple::MuslEABIHF: diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h index a6d4922a380f..c29fe67a898b 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -34,7 +34,7 @@ protected: Tool *buildLinker() const override; public: - bool useIntegratedAs() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } bool isCrossCompiling() const override { return true; } bool isPICDefault() const override { return false; } bool isPIEDefault() const override { return false; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1976b48e0f6a..32397abf1b54 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1702,7 +1702,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1"); else CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=0"); - } else if (Triple.isAndroid()) { + } else if (Triple.isAndroid() || Triple.isOHOSFamily()) { // Enabled A53 errata (835769) workaround by default on android CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-aarch64-fix-cortex-a53-835769=1"); @@ -5627,6 +5627,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, options::OPT_fno_unroll_loops); + if (Args.hasArg(options::OPT_fenable_merge_functions)) + CmdArgs.push_back(Args.MakeArgString("-fmerge-functions")); + Args.AddLastArg(CmdArgs, options::OPT_pthread); if (Args.hasFlag(options::OPT_mspeculative_load_hardening, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index bcaea71dca94..ce90569494c1 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -753,7 +753,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, CmdArgs.push_back(getAsNeededOption(TC, false)); // There's no libpthread or librt on RTEMS & Android. if (TC.getTriple().getOS() != llvm::Triple::RTEMS && - !TC.getTriple().isAndroid()) { + !TC.getTriple().isAndroid() && !TC.getTriple().isOHOSFamily()) { CmdArgs.push_back("-lpthread"); if (!TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lrt"); @@ -1132,6 +1132,18 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { } } + // OHOS-specific defaults for PIC/PIE + if (Triple.isOHOSFamily()) { + switch (Triple.getArch()) { + case llvm::Triple::aarch64: + PIC = true; // "-fpic" + break; + + default: + break; + } + } + // OpenBSD-specific defaults for PIE if (Triple.isOSOpenBSD()) { switch (ToolChain.getArch()) { @@ -1391,6 +1403,11 @@ static LibGccType getLibGccType(const Driver &D, const ArgList &Args) { static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, ArgStringList &CmdArgs, const ArgList &Args) { ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args); + if (TC.getTriple().isOHOSFamily() && UNW != ToolChain::UNW_None) { + CmdArgs.push_back("-l:libunwind.a"); + return; + } + // Targets that don't use unwind libraries. if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() || TC.getTriple().isOSBinFormatWasm() || diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 1d8a3cdce92a..4106cd9cfa68 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -393,6 +393,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); const llvm::Triple::ArchType Arch = ToolChain.getArch(); + const bool isOHOSFamily = ToolChain.getTriple().isOHOSFamily(); const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); const bool IsVE = ToolChain.getTriple().isVE(); @@ -448,7 +449,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Most Android ARM64 targets should enable the linker fix for erratum // 843419. Only non-Cortex-A53 devices are allowed to skip this flag. - if (Arch == llvm::Triple::aarch64 && isAndroid) { + if (Arch == llvm::Triple::aarch64 && (isAndroid || isOHOSFamily)) { std::string CPU = getCPUName(Args, Triple); if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53") CmdArgs.push_back("--fix-cortex-a53-843419"); @@ -456,8 +457,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Android does not allow shared text relocations. Emit a warning if the // user's code contains any. - if (isAndroid) - CmdArgs.push_back("--warn-shared-textrel"); + if (isAndroid || isOHOSFamily) + CmdArgs.push_back("--warn-shared-textrel"); ToolChain.addExtraOpts(CmdArgs); @@ -615,7 +616,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, AddRunTimeLibs(ToolChain, D, CmdArgs, Args); - if (WantPthread && !isAndroid) + // We don't need libpthread neither for bionic nor for musl + if (WantPthread && !isAndroid && !isOHOSFamily) CmdArgs.push_back("-lpthread"); if (Args.hasArg(options::OPT_fsplit_stack)) @@ -2074,8 +2076,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( // lifetime or initialization issues. static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; static const char *const AArch64Triples[] = { - "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", - "aarch64-suse-linux", "aarch64-linux-android"}; + "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-redhat-linux", + "aarch64-suse-linux", "aarch64-linux-android", "aarch64-linux-ohos"}; static const char *const AArch64beLibDirs[] = {"/lib"}; static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", "aarch64_be-linux-gnu"}; diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp new file mode 100644 index 000000000000..0c243a1ef723 --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.cpp @@ -0,0 +1,439 @@ +//===--- OHOS.cpp - OHOS ToolChain Implementations --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "OHOS.h" +#include "Arch/ARM.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "llvm/Option/ArgList.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Support/ScopedPrinter.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; +using namespace clang::driver::tools::arm; + +using tools::addMultilibFlag; +using tools::addPathIfExists; + +static bool findOHOSMuslMultilibs(const Multilib::flags_list &Flags, + DetectedMultilibs &Result) { + MultilibSet Multilibs; + Multilibs.push_back(Multilib()); + // -mcpu=cortex-a7 + // -mfloat-abi=soft -mfloat-abi=softfp -mfloat-abi=hard + // -mfpu=neon-vfpv4 + Multilibs.push_back(Multilib("a7_soft", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=soft")); + + Multilibs.push_back(Multilib("a7_softfp_neon-vfpv4", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=softfp") + .flag("+mfpu=neon-vfpv4")); + + Multilibs.push_back(Multilib("a7_hard_neon-vfpv4", {}, {}, 1) + .flag("+mcpu=cortex-a7") + .flag("+mfloat-abi=hard") + .flag("+mfpu=neon-vfpv4")); + + if (Multilibs.select(Flags, Result.SelectedMultilib)) { + Result.Multilibs = Multilibs; + return true; + } + return false; +} + +static bool findOHOSMultilibs(const Driver &D, + const ToolChain &TC, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + DetectedMultilibs &Result) { + Multilib::flags_list Flags; + bool IsA7 = false; + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + IsA7 = A->getValue() == StringRef("cortex-a7"); + addMultilibFlag(IsA7, "mcpu=cortex-a7", Flags); + + bool IsMFPU = false; + if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) + IsMFPU = A->getValue() == StringRef("neon-vfpv4"); + addMultilibFlag(IsMFPU, "mfpu=neon-vfpv4", Flags); + + tools::arm::FloatABI ARMFloatABI = getARMFloatABI(D, TargetTriple, Args); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Soft), + "mfloat-abi=soft", Flags); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::SoftFP), + "mfloat-abi=softfp", Flags); + addMultilibFlag((ARMFloatABI == tools::arm::FloatABI::Hard), + "mfloat-abi=hard", Flags); + + return findOHOSMuslMultilibs(Flags, Result); +} + +std::string OHOS::getMultiarchTriple(const llvm::Triple &T) const { + // For most architectures, just use whatever we have rather than trying to be + // clever. + switch (T.getArch()) { + default: + break; + + // We use the existence of '/lib/' as a directory to detect some + // common linux triples that don't quite match the Clang triple for both + // 32-bit and 64-bit targets. Multiarch fixes its install triples to these + // regardless of what the actual target triple is. + case llvm::Triple::arm: + case llvm::Triple::thumb: + return T.isOSLiteOS() ? "arm-liteos-ohos" : "arm-linux-ohos"; + case llvm::Triple::riscv32: + return "riscv32-liteos-ohos"; + case llvm::Triple::x86: + return "i686-linux-ohos"; + case llvm::Triple::x86_64: + return "x86_64-linux-ohos"; + case llvm::Triple::aarch64: + return "aarch64-linux-ohos"; + } + return T.str(); +} + +std::string OHOS::getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const { + return getMultiarchTriple(TargetTriple); +} + +static std::string makePath(const std::initializer_list &IL) { + SmallString<128> P; + for (const auto &S : IL) + llvm::sys::path::append(P, S); + return static_cast(P.str()); +} + +/// OHOS Toolchain +OHOS::OHOS(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + std::string SysRoot = computeSysRoot(); + + // Select the correct multilib according to the given arguments. + DetectedMultilibs Result; + findOHOSMultilibs(D, *this, Triple, "", Args, Result); + Multilibs = Result.Multilibs; + SelectedMultilib = Result.SelectedMultilib; + + getFilePaths().clear(); + if (D.CCCIsCXX()) { + if (auto CXXStdlibPath = getCXXStdlibPath()) + getFilePaths().push_back(*CXXStdlibPath); + } + + std::string CandidateLibPath = getArchSpecificLibPath(); + if (getVFS().exists(CandidateLibPath)) + getFilePaths().push_back(CandidateLibPath); + + getLibraryPaths().clear(); + if (auto RuntimePath = getRuntimePath()) + getLibraryPaths().push_back(*RuntimePath); + + // OHOS sysroots contain a library directory for each supported OS + // version as well as some unversioned libraries in the usual multiarch + // directory. Support --target=aarch64-linux-ohosX.Y.Z or + // --target=aarch64-linux-ohosX.Y or --target=aarch64-linux-ohosX + unsigned Major; + unsigned Minor; + unsigned Micro; + Triple.getEnvironmentVersion(Major, Minor, Micro); + path_list &Paths = getFilePaths(); + std::string SysRootLibPath = makePath({SysRoot, "usr", "lib"}); + std::string MultiarchTriple = getMultiarchTriple(getTriple()); + addPathIfExists(D, makePath({SysRootLibPath, SelectedMultilib.gccSuffix()}), + Paths); + addPathIfExists(D, + makePath({D.Dir, "..", "lib", MultiarchTriple, + SelectedMultilib.gccSuffix()}), + Paths); + + // For compatibility with arm-liteos sysroot + // FIXME: Remove this when we'll use arm-liteos sysroot produced by build.py. + addPathIfExists( + D, + makePath({SysRootLibPath, MultiarchTriple, SelectedMultilib.gccSuffix()}), + Paths); +} + +std::string OHOS::ComputeEffectiveClangTriple(const ArgList &Args, + types::ID InputType) const { + // Don't modify this, it is impact of the toolchain and target init process. + return ComputeLLVMTriple(Args, InputType); +} + +ToolChain::RuntimeLibType OHOS::GetRuntimeLibType( + const ArgList &Args) const { + if (Arg *A = Args.getLastArg(clang::driver::options::OPT_rtlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "compiler-rt") + getDriver().Diag(clang::diag::err_drv_invalid_rtlib_name) + << A->getAsString(Args); + } + + return ToolChain::RLT_CompilerRT; +} + +ToolChain::CXXStdlibType +OHOS::GetCXXStdlibType(const ArgList &Args) const { + if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { + StringRef Value = A->getValue(); + if (Value != "libc++") + getDriver().Diag(diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return ToolChain::CST_Libcxx; +} + +void OHOS::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + return; + } + + addExternCSystemInclude(DriverArgs, CC1Args, + SysRoot + "/usr/include/" + + getMultiarchTriple(Triple)); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); + addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); +} + +void OHOS::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: { + std::string Path = makePath({getDriver().Dir, "..", "include", + "libcxx-ohos", "include", "c++", "v1"}); + addSystemInclude(DriverArgs, CC1Args, Path); + break; + } + + default: + llvm_unreachable("invalid stdlib name"); + } +} + +void OHOS::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + switch (GetCXXStdlibType(Args)) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); + break; + + case ToolChain::CST_Libstdcxx: + llvm_unreachable("invalid stdlib name"); + } +} + +std::string OHOS::computeSysRoot() const { + std::string SysRoot = + !getDriver().SysRoot.empty() + ? getDriver().SysRoot + : makePath({getDriver().getInstalledDir(), "..", "..", "sysroot"}); + if (!llvm::sys::fs::exists(SysRoot)) + return std::string(); + + std::string ArchRoot = makePath({SysRoot, getMultiarchTriple(getTriple())}); + return llvm::sys::fs::exists(ArchRoot) ? ArchRoot : SysRoot; +} + +Optional OHOS::getRuntimePath() const { + SmallString<128> P; + const Driver &D = getDriver(); + const llvm::Triple &Triple = getTriple(); + + // First try the triple passed to driver as --target=. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", D.getTargetTriple(), SelectedMultilib.gccSuffix()); + if (getVFS().exists(P)) + return llvm::Optional(static_cast(P.str())); + + // Second try the normalized triple. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", Triple.str(), SelectedMultilib.gccSuffix()); + if (getVFS().exists(P)) + return llvm::Optional(static_cast(P.str())); + + // Third try the effective triple. + P.assign(D.ResourceDir); + std::string SysRoot = computeSysRoot(); + llvm::sys::path::append(P, "lib", getMultiarchTriple(Triple), + SelectedMultilib.gccSuffix()); + if (getVFS().exists(P)) + return llvm::Optional(static_cast(P.str())); + + return None; +} + +Optional OHOS::getCXXStdlibPath() const { + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + const std::string &MultiarchTriple = getMultiarchTriple(getTriple()); + + const std::string &P = makePath({D.Dir, "..", "lib", MultiarchTriple, "c++", + SelectedMultilib.gccSuffix()}); + if (getVFS().exists(P)) + return llvm::Optional(P); + + return None; +} + +std::string OHOS::getDynamicLinker(const ArgList &Args) const { + const llvm::Triple &Triple = getTriple(); + const llvm::Triple::ArchType Arch = getArch(); + + assert(Triple.isMusl()); + std::string ArchName; + bool IsArm = false; + + switch (Arch) { + case llvm::Triple::arm: + case llvm::Triple::thumb: + ArchName = "arm"; + IsArm = true; + break; + case llvm::Triple::armeb: + case llvm::Triple::thumbeb: + ArchName = "armeb"; + IsArm = true; + break; + default: + ArchName = Triple.getArchName().str(); + } + if (IsArm && + (tools::arm::getARMFloatABI(*this, Args) == tools::arm::FloatABI::Hard)) + ArchName += "hf"; + + return "/lib/ld-musl-" + ArchName + ".so.1"; +} + +std::string OHOS::getCompilerRT(const ArgList &Args, StringRef Component, + FileType Type) const { + SmallString<128> Path(getDriver().ResourceDir); + llvm::sys::path::append(Path, "lib", getMultiarchTriple(getTriple()), + SelectedMultilib.gccSuffix()); + const char *Prefix = + Type == ToolChain::FT_Object ? "" : "lib"; + const char *Suffix; + switch (Type) { + case ToolChain::FT_Object: + Suffix = ".o"; + break; + case ToolChain::FT_Static: + Suffix = ".a"; + break; + case ToolChain::FT_Shared: + Suffix = ".so"; + break; + } + llvm::sys::path::append( + Path, Prefix + Twine("clang_rt.") + Component + Suffix); + return static_cast(Path.str()); +} + +void OHOS::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { + CmdArgs.push_back("-z"); + CmdArgs.push_back("now"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("relro"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("max-page-size=4096"); + CmdArgs.push_back("--hash-style=gnu"); + // FIXME: gnu or both??? + CmdArgs.push_back("--hash-style=both"); +#ifdef ENABLE_LINKER_BUILD_ID + CmdArgs.push_back("--build-id"); +#endif + CmdArgs.push_back("--enable-new-dtags"); +} + +SanitizerMask OHOS::getSupportedSanitizers() const { + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; + Res |= SanitizerKind::Fuzzer; + Res |= SanitizerKind::FuzzerNoLink; + Res |= SanitizerKind::Memory; + Res |= SanitizerKind::Vptr; + Res |= SanitizerKind::SafeStack; + Res |= SanitizerKind::Scudo; + // TODO: kASAN for liteos ?? + // TODO: Support TSAN and HWASAN and update mask. + return Res; +} + +// TODO: Make a base class for Linux and OHOS and move this there. +void OHOS::addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const { + // Add linker option -u__llvm_profile_runtime to cause runtime + // initialization module to be linked in. + if (needsProfileRT(Args)) + CmdArgs.push_back(Args.MakeArgString( + Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); + ToolChain::addProfileRTLibs(Args, CmdArgs); +} + +std::string OHOS::getArchSpecificLibPath() const { + llvm::Triple Triple = getTriple(); + return makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)}); +} + +ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { + if (const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ)) + return Generic_ELF::GetUnwindLibType(Args); + return GetDefaultUnwindLibType(); +} \ No newline at end of file diff --git a/clang/lib/Driver/ToolChains/OHOS.h b/clang/lib/Driver/ToolChains/OHOS.h new file mode 100644 index 000000000000..002ee71f7b90 --- /dev/null +++ b/clang/lib/Driver/ToolChains/OHOS.h @@ -0,0 +1,103 @@ +//===--- OHOS.h - OHOS ToolChain Implementations ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H + +#include "Linux.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY OHOS : public Generic_ELF { +public: + OHOS(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool HasNativeLLVMSupport() const override { return true; } + bool IsIntegratedAssemblerDefault() const override { return true; } + bool IsMathErrnoDefault() const override { return false; } + RuntimeLibType GetDefaultRuntimeLibType() const override { + return ToolChain::RLT_CompilerRT; + } + CXXStdlibType GetDefaultCXXStdlibType() const override { + return ToolChain::CST_Libcxx; + } + // Not add -funwind-tables by default + bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override { + return false; + } + bool isPICDefault() const override { return false; } + bool isPIEDefault() const override { return true; } + bool isPICDefaultForced() const override { return false; } + bool isNoExecStackDefault() const override { return true; } + bool useRelaxRelocations() const override { return false; } + UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override; + UnwindLibType GetDefaultUnwindLibType() const override { return UNW_CompilerRT; } + + std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, + types::ID InputType = types::TY_INVALID) const override; + + RuntimeLibType + GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; + CXXStdlibType + GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void + AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + std::string computeSysRoot() const override; + std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override; + + std::string + getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const override; + + const char *getDefaultLinker() const override { + return "ld.lld"; + } + + Tool *buildLinker() const override { + return new tools::gnutools::Linker(*this); + } + Tool *buildAssembler() const override { + return new tools::gnutools::Assembler(*this); + } + + Optional getRuntimePath() const override; + Optional getCXXStdlibPath() const override; + +protected: + std::string getMultiarchTriple(const llvm::Triple &T) const; + std::string getMultiarchTriple(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef SysRoot) const override; + void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override; + SanitizerMask getSupportedSanitizers() const override; + void addProfileRTLibs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + std::string getArchSpecificLibPath() const override; + +private: + Multilib SelectedMultilib; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_OHOS_H diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1f7ab49ccdd7..66826a8b3ba7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14922,7 +14922,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // errno in those environments even though it could set errno based on the // C standard. const llvm::Triple &Trip = Context.getTargetInfo().getTriple(); - if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT()) && + if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT() || + Trip.isOHOSFamily()) && !FD->hasAttr()) { switch (BuiltinID) { case Builtin::BI__builtin_fma: diff --git a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c index c6a38b20074a..74949c91ae6c 100644 --- a/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c +++ b/clang/test/CodeGen/aarch64-fix-cortex-a53-835769.c @@ -9,6 +9,8 @@ // RUN: %clang -O3 -target aarch64-android-eabi %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s +// RUN: %clang -O3 -target aarch64-linux-ohos %s -S -o- \ +// RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mfix-cortex-a53-835769 %s -S -o- \ // RUN: | FileCheck --check-prefix=CHECK-YES --check-prefix=CHECK %s // RUN: %clang -O3 -target aarch64-android-eabi -mno-fix-cortex-a53-835769 %s -S -o- \ diff --git a/clang/test/CodeGen/arm64-abi-vector.c b/clang/test/CodeGen/arm64-abi-vector.c index da4af7a8cc82..56a1d18073e2 100644 --- a/clang/test/CodeGen/arm64-abi-vector.c +++ b/clang/test/CodeGen/arm64-abi-vector.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple aarch64-linux-android -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s +// RUN: %clang_cc1 -triple aarch64-linux-ohos -emit-llvm -o - %s | FileCheck -check-prefix=ANDROID %s #include diff --git a/clang/test/CodeGen/math-builtins.c b/clang/test/CodeGen/math-builtins.c index ac2a7595e1c9..7f595e3b0b67 100644 --- a/clang/test/CodeGen/math-builtins.c +++ b/clang/test/CodeGen/math-builtins.c @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO // RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU // RUN: %clang_cc1 -triple x86_64-unknown-unknown-android -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_ANDROID +// RUN: %clang_cc1 -triple x86_64-unknown-unknown-ohos -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_ANDROID // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN // Test attributes and codegen of math builtins. diff --git a/clang/test/CodeGen/merge-functions.c b/clang/test/CodeGen/merge-functions.c new file mode 100644 index 000000000000..7e382853cc7c --- /dev/null +++ b/clang/test/CodeGen/merge-functions.c @@ -0,0 +1,22 @@ +// Check that code gen really activates function merging. In this case +// just check a trivial functions merging case. + +// RUN: %clang_cc1 -emit-llvm %s -fmerge-functions -o - | FileCheck %s + +void foo1() {} +void foo2() {} + +int main() { + + // If merge functions pass is enabled, + // then second and first calls will refer to foo1 + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo1(); + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo2(); + + return 0; +} + diff --git a/clang/test/Driver/as-fno-integrated-as.c b/clang/test/Driver/as-fno-integrated-as.c new file mode 100644 index 000000000000..866cc421e522 --- /dev/null +++ b/clang/test/Driver/as-fno-integrated-as.c @@ -0,0 +1,3 @@ +// Make sure that for BareMetal toolchain, we able to +// disable the use of integrated assembler. +// RUN: %clang -Werror --target="arm-none-eabi" -fno-integrated-as -c %s diff --git a/clang/test/Driver/fenable-merge-functions.cpp b/clang/test/Driver/fenable-merge-functions.cpp new file mode 100644 index 000000000000..f45cdd3b09e9 --- /dev/null +++ b/clang/test/Driver/fenable-merge-functions.cpp @@ -0,0 +1,28 @@ +// First. Check that option is passed into clangcc1 +// RUN: %clang -fenable-merge-functions -### %s 2>&1 | FileCheck %s -check-prefix=CHECK_CC1 +// CHECK_CC1: "-cc1" {{.*}} "-fmerge-functions" + +// Second. Check that code gen really activates function merging. In this case +// just check a trivial functions merging case. +// One may say, that this is an superfluous check, +// for it is covered by clang/test/CodeGen/merge-functions.c +// But it is worth keeping, because it also checks whole driver + clang interaction chain. + +// RUN: %clang -emit-llvm %s -fenable-merge-functions -c -S -o - | FileCheck %s + +void foo1() {} +void foo2() {} + +int main() { + + // If merge functions pass is enabled, + // then second and first calls will refer to foo1 + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo1(); + + // CHECK: call void @{{[^\(]*}}foo1{{[^\(]*}}() + foo2(); + + return 0; +} diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c new file mode 100644 index 000000000000..170c0da0ce06 --- /dev/null +++ b/clang/test/Driver/ohos.c @@ -0,0 +1,245 @@ +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM %s +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-liteos \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM-A7-SOFT %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK-NOT: "--mrelax-relocations" +// CHECK-NOT: "-munwind-tables" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK-NOT: "-fsanitize=safe-stack" +// CHECK-NOT: "-stack-protector" "2" +// CHECK-NOT: "-fno-common" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-NOT: "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK: "-z" "noexecstack" +// CHECK-NOT: "--build-id" +// CHECK: "--hash-style=gnu" +// CHECK: "--hash-style=both" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" +// CHECK-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" +// CHECK-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-ARM-A7-SOFT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos/a7_soft{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clang %s -### --target=arm-liteos -rtlib=libgcc -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RTLIB +// CHECK-RTLIB: error: invalid runtime library name in argument '-rtlib=libgcc' + +// RUN: %clang %s -### --target=arm-liteos -static -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC: "-Bstatic" +// CHECK-STATIC-NOT: "-Bdynamic" +// CHECK-STATIC: "-l:libunwind.a" +// CHECK-STATIC: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -shared -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-SHARED +// CHECK-SHARED-NOT: "-pie" +// CHECK-SHARED: "-shared" +// CHECK-SHARED: "-lc" +// CHECK-SHARED: "-l:libunwind.a" + +// RUN: %clang %s -### --target=arm-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=aarch64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" +// CHECK-RUNTIME: "-l:libunwind.a" +// CHECK-LIBM: "-lm" + +// RUN: %clang %s -### --target=arm-liteos -r -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RELOCATABLE +// CHECK-RELOCATABLE-NOT: "-pie" +// CHECK-RELOCATABLE-NOT: "--build-id" +// CHECK-RELOCATABLE: "-r" + +// RUN: %clang %s -### --target=arm-liteos -nodefaultlibs -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NODEFAULTLIBS +// CHECK-NODEFAULTLIBS: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NODEFAULTLIBS-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NODEFAULTLIBS-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nostdlib -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIB +// CHECK-NOSTDLIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOSTDLIB-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOSTDLIB-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos -nolibc -fuse-ld=lld 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOLIBC +// CHECK-NOLIBC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-NOLIBC: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK-NOLIBC-NOT: "-lc" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=safe-stack 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK +// CHECK-SAFESTACK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SAFESTACK: "-fsanitize=safe-stack" +// CHECK-SAFESTACK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.safestack.a" +// CHECK-SAFESTACK: "__safestack_init" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-ARM +// CHECK-ASAN-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-ARM: "-fsanitize=address" +// CHECK-ASAN-ARM: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-ARM: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-ASAN-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.a" +// CHECK-ASAN-ARM-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=address -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-ASAN-SHARED +// CHECK-ASAN-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-ASAN-SHARED: "-fsanitize=address" +// CHECK-ASAN-SHARED: "-fsanitize-address-use-after-scope" +// CHECK-ASAN-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan.so" +// CHECK-ASAN-SHARED-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.asan-preinit.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=fuzzer 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-FUZZER-ARM +// CHECK-FUZZER-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-FUZZER-ARM: "-fsanitize=fuzzer,fuzzer-no-link" +// CHECK-FUZZER-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.fuzzer.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-ARM +// CHECK-SCUDO-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-ARM: "-fsanitize=scudo" +// CHECK-SCUDO-ARM: "-pie" +// CHECK-SCUDO-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fsanitize=scudo -fPIC -shared 2>&1 \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -shared-libsan \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-SHARED +// CHECK-SCUDO-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-SCUDO-SHARED: "-fsanitize=scudo" +// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.scudo.so" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -fxray-instrument -fxray-modes=xray-basic \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-XRAY-ARM +// CHECK-XRAY-ARM: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-XRAY-ARM: "-fxray-instrument" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray.a" +// CHECK-XRAY-ARM: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.xray-basic.a" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -O3 -flto -mcpu=cortex-a53 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-LTO +// CHECK-LTO: "-plugin-opt=mcpu=cortex-a53" +// CHECK-LTO: "-plugin-opt=O3" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -flto=thin -flto-jobs=8 -mcpu=cortex-a7 2>&1 \ +// RUN: -fuse-ld=lld \ +// RUN: | FileCheck %s -check-prefix=CHECK-THINLTO +// CHECK-THINLTO: "-plugin-opt=mcpu=cortex-a7" +// CHECK-THINLTO: "-plugin-opt=thinlto" +// CHECK-THINLTO: "-plugin-opt=jobs=8" + +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clang %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" + +// RUN: %clang %s -### -no-canonical-prefixes --target=arm-linux-ohos -fprofile-instr-generate -v \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld -march=armv7-a 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK-PROFILE-RTLIB %s + +// CHECK-PROFILE-RTLIB: -u__llvm_profile_runtime +// CHECK-PROFILE-RTLIB: libclang_rt.profile + +// RUN: %clang %s -### -o %t.o 2>&1 \ +// RUN: --target=armv7-linux-ohos \ +// RUN: | FileCheck --check-prefix=CHECK-OHOS-WARN-SHARED-TEXTREL %s + +// CHECK-OHOS-WARN-SHARED-TEXTREL: "{{.*}}ld{{(.exe)?}}" +// CHECK-OHOS-WARN-SHARED-TEXTREL: "--warn-shared-textrel" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: --target=arm64-linux-ohos -pthread \ +// RUN: --gcc-toolchain="" \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -shared \ +// RUN: | FileCheck --check-prefix=CHECK-OHOS-PTHREAD %s + +// CHECK-OHOS-PTHREAD-NOT: -lpthread + diff --git a/clang/test/Driver/ohos.cpp b/clang/test/Driver/ohos.cpp new file mode 100644 index 000000000000..d0fe244c6e78 --- /dev/null +++ b/clang/test/Driver/ohos.cpp @@ -0,0 +1,123 @@ +// RUN: %clangxx %s -### -no-canonical-prefixes --target=arm-liteos -march=armv7-a \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 | FileCheck %s +// CHECK: {{.*}}clang{{.*}}" "-cc1" +// CHECK: "-triple" "armv7-unknown-liteos-ohos" +// CHECK-NOT: "-fuse-init-array" +// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK: "-internal-isystem" "{{.*[/\\]}}include{{/|\\\\}}c++{{/|\\\\}}v1" +// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" +// CHECK: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK: "-pie" +// CHECK: "-z" "noexecstack" +// CHECK-NOT: "--build-id" +// CHECK: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK: Scrt1.o +// CHECK: crti.o +// CHECK: clang_rt.crtbegin.o +// CHECK: "-L{{.*[/\\]}}lib/arm-liteos-ohos/c++/" +// CHECK-NOT: "--push-state" +// CHECK-NOT: "--as-needed" +// CHECK: "-lc++" +// CHECK: "-lm" +// CHECK-NOT: "--pop-state" +// CHECK: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}libclang_rt.builtins.a" +// CHECK: "-lc" +// CHECK: clang_rt.crtend.o +// CHECK: crtn.o + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -stdlib=libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STDLIB +// CHECK-STDLIB: error: invalid library name in argument '-stdlib=libstdc++' + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static-libstdc++ \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC +// CHECK-STATIC-NOT: "--push-state" +// CHECK-STATIC-NOT: "--as-needed" +// CHECK-STATIC: "-Bstatic" +// CHECK-STATIC: "-lc++" +// CHECK-STATIC: "-Bdynamic" +// CHECK-STATIC: "-lm" +// CHECK-STATIC-NOT: "--pop-state" +// CHECK-STATIC: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -static \ +// RUN: -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC1 +// CHECK-STATIC1-NOT: "-fuse-init-array" +// CHECK-STATIC1: "-Bstatic" +// CHECK-STATIC1: "-lc++" +// CHECK-STATIC1: "-lc++abi" +// CHECK-STATIC1: "-lunwind" +// CHECK-STATIC1: "-lm" +// CHECK-STATIC1: "-lc" + +// RUN: %clangxx %s -### --target=arm-unknown-liteos -march=armv7-a -mfloat-abi=soft -static -fPIE -fPIC -fpic -pie \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-STATIC2 +// CHECK-STATIC2: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-STATIC2: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-STATIC2: "-Bstatic" +// CHECK-STATIC2: "-lc++" +// CHECK-STATIC2: "-lc++abi" +// CHECK-STATIC2: "-lunwind" +// CHECK-STATIC2: "-lm" +// CHECK-STATIC2: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos -nostdlib++ -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIBXX +// CHECK-NOSTDLIBXX-NOT: "-lc++" +// CHECK-NOSTDLIBXX: "-lm" +// CHECK-NOSTDLIBXX: "-lc" + +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFT +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-SF,CHECK-MULTILIB-ARM-A7-SOFTFP +// RUN: %clangxx %s -### --target=arm-liteos \ +// RUN: -ccc-install-dir %S/Inputs/ohos_native_tree/llvm/bin \ +// RUN: -resource-dir=%S/Inputs/ohos_native_tree/llvm/lib/clang/x.y.z \ +// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ +// RUN: -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 2>&1\ +// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB,CHECK-MULTILIB-HF,CHECK-MULTILIB-ARM-A7-HARD +// CHECK-MULTILIB: {{.*}}clang{{.*}}" "-cc1" +// CHECK-MULTILIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" +// CHECK-MULTILIB: "-isysroot" "[[SYSROOT:[^"]+]]" +// CHECK-MULTILIB: {{.*}}ld.lld{{.*}}" "--sysroot=[[SYSROOT]]" +// CHECK-MULTILIB-SF: "-dynamic-linker" "/lib/ld-musl-arm.so.1" +// CHECK-MULTILIB-HF: "-dynamic-linker" "/lib/ld-musl-armhf.so.1" + +// CHECK-MULTILIB-ARM: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}c++/" +// CHECK-MULTILIB-ARM: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/" + +// CHECK-MULTILIB-ARM-A7-SOFT: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}c++/a7_soft" +// CHECK-MULTILIB-ARM-A7-SOFT: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_soft" + +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}c++{{/|\\\\}}a7_softfp_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4" + +// CHECK-MULTILIB-ARM-A7-HARD: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}arm-liteos-ohos{{/|\\\\}}c++{{/|\\\\}}a7_hard_neon-vfpv4" +// CHECK-MULTILIB-ARM-A7-HARD: "-L[[SYSROOT]]/usr/lib/arm-liteos-ohos/a7_hard_neon-vfpv4" + +// CHECK-MULTILIB-ARM: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFT: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_soft/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-SOFTFP: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_softfp_neon-vfpv4/libclang_rt.builtins.a" +// CHECK-MULTILIB-ARM-A7-HARD: "[[RESOURCE_DIR]]/lib/arm-liteos-ohos/a7_hard_neon-vfpv4/libclang_rt.builtins.a" diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c new file mode 100644 index 000000000000..bd1060133c4e --- /dev/null +++ b/clang/test/Preprocessor/ohos.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=aarch64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM64-OHOS-CXX +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS + +// ARM-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// ARM-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// ARM64-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// ARM64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// OHOS-DEFS: __OHOS_FAMILY__ +// OHOS-DEFS: __OHOS__ +// OHOS-DEFS-NOT: __OHOS__ diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index bb635dfff991..bcb84f1d3d7c 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -39,7 +39,9 @@ add_subdirectory(CodeGen) if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD) add_subdirectory(libclang) endif() -add_subdirectory(DirectoryWatcher) +if (NOT APPLE) + add_subdirectory(DirectoryWatcher) +endif() add_subdirectory(Rename) add_subdirectory(Index) add_subdirectory(Serialization) diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index b44ad2c2118e..732e8863ed32 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -120,7 +120,14 @@ if ("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES ".*android.*") string(REGEX MATCH "-target(=| +)[^ ]+android[a-z]*([0-9]+)" ANDROID_API_LEVEL "${CMAKE_C_FLAGS}") set(ANDROID_API_LEVEL ${CMAKE_MATCH_2}) endif() + +# We define OHOS for ohos targets for now +if (OHOS) + set(OHOS_FAMILY 1) +endif() + pythonize_bool(ANDROID) +pythonize_bool(OHOS_FAMILY) set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -131,7 +138,7 @@ pythonize_bool(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) # and target a UNIX-like system or Windows. # We can run tests on Android even when we are cross-compiling. if(("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND (UNIX OR WIN32)) OR ANDROID - OR COMPILER_RT_EMULATOR) + OR COMPILER_RT_EMULATOR OR OHOS) option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" ON) else() option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" OFF) @@ -235,7 +242,7 @@ option(SANITIZER_USE_STATIC_CXX_ABI "Use static libc++abi." ${DEFAULT_SANITIZER_USE_STATIC_CXX_ABI}) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY OFF) -if (FUCHSIA) +if (FUCHSIA OR OHOS) set(DEFAULT_COMPILER_RT_USE_BUILTINS_LIBRARY ON) endif() @@ -441,24 +448,9 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") list(APPEND SANITIZER_COMMON_LINK_LIBS zircon) endif() -# TODO: COMPILER_RT_COMMON_CFLAGS and COMPILER_RT_COMMON_LINK_FLAGS are -# intended for use in non-sanitizer runtimes such as libFuzzer, profile or XRay, -# move these higher to include common flags, then derive SANITIZER_COMMON_CFLAGS -# and SANITIZER_COMMON_LINK_FLAGS from those and append sanitizer-specific flags. -set(COMPILER_RT_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) -set(COMPILER_RT_COMMON_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}) - -# We don't use the C++ standard library, so avoid including it by mistake. -append_list_if(COMPILER_RT_HAS_NOSTDINCXX_FLAG -nostdinc++ SANITIZER_COMMON_CFLAGS) -append_list_if(COMPILER_RT_HAS_NOSTDLIBXX_FLAG -nostdlib++ SANITIZER_COMMON_LINK_FLAGS) - -# Remove -stdlib= which is unused when passing -nostdinc++... -string(REGEX MATCHALL "-stdlib=[a-zA-Z+]*" stdlib_flag "${CMAKE_CXX_FLAGS}") -string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - -# ...we need it to build some runtimes and tests so readd it where appropriate. -list(APPEND COMPILER_RT_COMMON_CFLAGS ${stdlib_flag}) -list(APPEND COMPILER_RT_COMMON_LINK_FLAGS ${stdlib_flag}) +if (OHOS) + list(APPEND SANITIZER_COMMON_LINK_LIBS unwind) +endif() macro(append_libcxx_libs var) if (${var}_INTREE) diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index 361538a58e47..3fb062f78f70 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -239,9 +239,9 @@ function(add_compiler_rt_runtime name type) NOT name STREQUAL "clang_rt.builtins") get_compiler_rt_target(${arch} target) find_compiler_rt_library(builtins ${target} builtins_${libname}) - if(builtins_${libname} STREQUAL "NOTFOUND") - message(FATAL_ERROR "Cannot find builtins library for the target architecture") - endif() + #if(builtins_${libname} STREQUAL "NOTFOUND") + # message(FATAL_ERROR "Cannot find builtins library for the target architecture") + #endif() endif() set(sources_${libname} ${LIB_SOURCES}) format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index f61d487e93a0..00bec8bdb846 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -378,7 +378,11 @@ endfunction() function(get_compiler_rt_install_dir arch install_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${install_dir} ${COMPILER_RT_INSTALL_PATH}/lib/${target} PARENT_SCOPE) + if(OHOS) + set(${install_dir} ${COMPILER_RT_INSTALL_PATH}/lib/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${install_dir} ${COMPILER_RT_INSTALL_PATH}/lib/${target} PARENT_SCOPE) + endif() else() set(${install_dir} ${COMPILER_RT_LIBRARY_INSTALL_DIR} PARENT_SCOPE) endif() @@ -387,7 +391,11 @@ endfunction() function(get_compiler_rt_output_dir arch output_dir) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) get_compiler_rt_target(${arch} target) - set(${output_dir} ${COMPILER_RT_OUTPUT_DIR}/lib/${target} PARENT_SCOPE) + if(OHOS) + set(${output_dir} ${COMPILER_RT_OUTPUT_DIR}/lib/${target}/${LLVM_TARGET_MULTILIB_SUFFIX} PARENT_SCOPE) + else() + set(${output_dir} ${COMPILER_RT_OUTPUT_DIR}/lib/${target} PARENT_SCOPE) + endif() else() set(${output_dir} ${COMPILER_RT_LIBRARY_OUTPUT_DIR} PARENT_SCOPE) endif() diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index 1edab43e7c0d..61e7e0084ba3 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -165,6 +165,9 @@ macro(test_targets) # Examine compiler output to determine target architecture. detect_target_arch() set(COMPILER_RT_OS_SUFFIX "-android") + elseif(OHOS) + detect_target_arch() + set(COMPILER_RT_OS_SUFFIX "") elseif(NOT APPLE) # Supported archs for Apple platforms are generated later if(COMPILER_RT_DEFAULT_TARGET_ONLY) add_default_target_arch(${COMPILER_RT_DEFAULT_TARGET_ARCH}) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index f81b8384cbd5..347de3a08bb6 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -50,6 +50,8 @@ if (COMPILER_RT_HAS_NODEFAULTLIBS_FLAG) shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt) list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) + elseif (OHOS) + list(APPEND CMAKE_REQUIRED_LIBRARIES unwind) endif() endif () @@ -128,9 +130,13 @@ check_include_files("sys/auxv.h" COMPILER_RT_HAS_AUXV) # Libraries. check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) -check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +if (NOT OHOS) + check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) +endif() check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) -check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +if (NOT OHOS) + check_library_exists(pthread pthread_create "" COMPILER_RT_HAS_LIBPTHREAD) +endif() check_library_exists(execinfo backtrace "" COMPILER_RT_HAS_LIBEXECINFO) # Look for terminfo library, used in unittests that depend on LLVMSupport. @@ -159,8 +165,11 @@ check_library_exists(stdc++ __cxa_throw "" COMPILER_RT_HAS_LIBSTDCXX) check_linker_flag("-Wl,-z,text" COMPILER_RT_HAS_Z_TEXT) check_linker_flag("-fuse-ld=lld" COMPILER_RT_HAS_FUSE_LD_LLD_FLAG) -set(VERS_COMPAT_OPTION "-Wl,-z,gnu-version-script-compat") -check_linker_flag("${VERS_COMPAT_OPTION}" COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT) +if (NOT OHOS) + # lld fails to link when this option is passed + set(VERS_COMPAT_OPTION "-Wl,-z,gnu-version-script-compat") + check_linker_flag("${VERS_COMPAT_OPTION}" COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT) +endif() set(DUMMY_VERS ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/dummy.vers) file(WRITE ${DUMMY_VERS} "{};") @@ -312,9 +321,9 @@ if(OS_NAME MATCHES "Linux") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${S390X}) elseif (OS_NAME MATCHES "Windows") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64}) -elseif(OS_NAME MATCHES "Android") +elseif(OS_NAME MATCHES "Android" OR OS_NAME MATCHES "OHOS") set(ALL_FUZZER_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}) -else() +else () set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64}) endif() @@ -646,7 +655,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR + (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|OHOS" OR (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")))) set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) @@ -666,17 +675,17 @@ else() set(COMPILER_RT_HAS_ASAN FALSE) endif() -if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS") +if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS|OHOS") set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE) -else() +else () set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE) endif() # TODO: Add builtins support. -if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER) +if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|OHOS" AND NOT LLVM_USE_SANITIZER) set(COMPILER_RT_HAS_CRT TRUE) -else() +else () set(COMPILER_RT_HAS_CRT FALSE) endif() @@ -702,7 +711,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android") + OS_NAME MATCHES "Linux|Android|OHOS") set(COMPILER_RT_HAS_HWASAN TRUE) else() set(COMPILER_RT_HAS_HWASAN FALSE) @@ -716,28 +725,28 @@ else() endif() if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|OHOS") set(COMPILER_RT_HAS_PROFILE TRUE) else() set(COMPILER_RT_HAS_PROFILE FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Android|NetBSD") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|Android|NetBSD|OHOS") set(COMPILER_RT_HAS_TSAN TRUE) else() set(COMPILER_RT_HAS_TSAN FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS|OHOS") set(COMPILER_RT_HAS_UBSAN TRUE) else() set(COMPILER_RT_HAS_UBSAN FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin") + OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|OHOS") set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE) else() set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE) @@ -765,7 +774,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SCUDO_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android|Fuchsia") + OS_NAME MATCHES "Linux|Android|Fuchsia|OHOS") set(COMPILER_RT_HAS_SCUDO TRUE) else() set(COMPILER_RT_HAS_SCUDO FALSE) @@ -779,14 +788,14 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND FUZZER_SUPPORTED_ARCH AND - OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows") + OS_NAME MATCHES "Android|Darwin|Linux|NetBSD|FreeBSD|Fuchsia|Windows|OHOS") set(COMPILER_RT_HAS_FUZZER TRUE) else() set(COMPILER_RT_HAS_FUZZER FALSE) endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SHADOWCALLSTACK_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Android") + OS_NAME MATCHES "Linux|Android|OHOS") set(COMPILER_RT_HAS_SHADOWCALLSTACK TRUE) else() set(COMPILER_RT_HAS_SHADOWCALLSTACK FALSE) diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 2963e979b55c..a56e1ea43c22 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -128,7 +128,7 @@ typedef DefaultSizeClassMap SizeClassMap; const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__aarch64__) && SANITIZER_ANDROID +#elif defined(__aarch64__) && (SANITIZER_ANDROID || SANITIZER_OHOS) // Android needs to support 39, 42 and 48 bit VMA. const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index cfb54927c6cf..100754da08e4 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -35,7 +35,7 @@ // If set, values like allocator chunk size, as well as defaults for some flags // will be changed towards less memory overhead. #ifndef ASAN_LOW_MEMORY -# if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_RTEMS +#if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_RTEMS || SANITIZER_OHOS # define ASAN_LOW_MEMORY 1 # else # define ASAN_LOW_MEMORY 0 diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index 4bcbe5d02e33..09dc9a798387 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -45,7 +45,8 @@ #include #endif -#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS +#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS || \ + SANITIZER_OHOS #include extern "C" void* _DYNAMIC; #elif SANITIZER_NETBSD @@ -121,7 +122,7 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS // FIXME: should we do anything for Android? void AsanCheckDynamicRTPrereqs() {} void AsanCheckIncompatibleRT() {} @@ -214,7 +215,7 @@ void AsanCheckIncompatibleRT() { } #endif // SANITIZER_ANDROID -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS void ReadContextStack(void *context, uptr *stack, uptr *ssize) { ucontext_t *ucp = (ucontext_t*)context; *stack = (uptr)ucp->uc_stack.ss_sp; diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index c0b79bba48ff..25f5b5a44416 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -1322,7 +1322,9 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) { memcpy(Ident(&c), Ident(&b), sizeof(long double)); } -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(__OHOS__) +// On OHOS/Musl sched_param is not int. +// See __interceptor_pthread_getschedparam TEST(AddressSanitizer, pthread_getschedparam) { int policy; struct sched_param param; diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 73b6bead8424..6088cce8f8dd 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -693,6 +693,7 @@ else () foreach (arch ${BUILTIN_SUPPORTED_ARCH}) if (CAN_TARGET_${arch}) + set(BUILTIN_CFLAGS_${arch} ${BUILTIN_CFLAGS}) # For ARM archs, exclude any VFP builtins if VFP is not supported if (${arch} MATCHES "^(arm|armhf|armv7|armv7s|armv7k|armv7m|armv7em)$") string(REPLACE ";" " " _TARGET_${arch}_CFLAGS "${TARGET_${arch}_CFLAGS}") @@ -717,13 +718,13 @@ else () # Needed for clear_cache on debug mode, due to r7's usage in inline asm. # Release mode already sets it via -O2/3, Debug mode doesn't. if (${arch} STREQUAL "armhf") - list(APPEND BUILTIN_CFLAGS -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET) + list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET) endif() # For RISCV32, we must force enable int128 for compiling long # double routines. if("${arch}" STREQUAL "riscv32") - list(APPEND BUILTIN_CFLAGS -fforce-enable-int128) + list(APPEND BUILTIN_CFLAGS_${arch} -fforce-enable-int128) endif() add_compiler_rt_runtime(clang_rt.builtins @@ -731,7 +732,7 @@ else () ARCHS ${arch} SOURCES ${${arch}_SOURCES} DEFS ${BUILTIN_DEFS} - CFLAGS ${BUILTIN_CFLAGS} + CFLAGS ${BUILTIN_CFLAGS_${arch}} PARENT_TARGET builtins) endif () endforeach () diff --git a/compiler-rt/lib/builtins/divtf3.c b/compiler-rt/lib/builtins/divtf3.c index 5bcc9a8e4aa1..809c5a4f4adb 100644 --- a/compiler-rt/lib/builtins/divtf3.c +++ b/compiler-rt/lib/builtins/divtf3.c @@ -16,7 +16,7 @@ #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) -#define NUMBER_OF_HALF_ITERATIONS 4 +#define NUMBER_OF_HALF_ITERATIONS 5 #define NUMBER_OF_FULL_ITERATIONS 1 #include "fp_div_impl.inc" diff --git a/compiler-rt/lib/builtins/fp_div_impl.inc b/compiler-rt/lib/builtins/fp_div_impl.inc index 29bcd1920edf..b49a6fd2bd73 100644 --- a/compiler-rt/lib/builtins/fp_div_impl.inc +++ b/compiler-rt/lib/builtins/fp_div_impl.inc @@ -325,7 +325,7 @@ static __inline fp_t __divXf3__(fp_t a, fp_t b) { #define RECIPROCAL_PRECISION REP_C(10) #elif defined(DOUBLE_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 3 && NUMBER_OF_FULL_ITERATIONS == 1 #define RECIPROCAL_PRECISION REP_C(220) -#elif defined(QUAD_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 4 && NUMBER_OF_FULL_ITERATIONS == 1 +#elif defined(QUAD_PRECISION) && NUMBER_OF_HALF_ITERATIONS == 5 && NUMBER_OF_FULL_ITERATIONS == 1 #define RECIPROCAL_PRECISION REP_C(13922) #else #error Invalid number of iterations diff --git a/compiler-rt/lib/builtins/int_util.h b/compiler-rt/lib/builtins/int_util.h index c372c2edc637..c95c728598fb 100644 --- a/compiler-rt/lib/builtins/int_util.h +++ b/compiler-rt/lib/builtins/int_util.h @@ -40,6 +40,10 @@ NORETURN void __compilerrt_abort_impl(const char *file, int line, #define REPEAT_4_TIMES(code_to_repeat) \ REPEAT_3_TIMES(code_to_repeat) \ code_to_repeat +#define REPEAT_5_TIMES(code_to_repeat) \ + REPEAT_4_TIMES(code_to_repeat) \ + code_to_repeat + #define REPEAT_N_TIMES_(N, code_to_repeat) REPEAT_##N##_TIMES(code_to_repeat) #define REPEAT_N_TIMES(N, code_to_repeat) REPEAT_N_TIMES_(N, code_to_repeat) diff --git a/compiler-rt/lib/cfi/CMakeLists.txt b/compiler-rt/lib/cfi/CMakeLists.txt index 9a641d33ac48..1cc0b3cb6087 100644 --- a/compiler-rt/lib/cfi/CMakeLists.txt +++ b/compiler-rt/lib/cfi/CMakeLists.txt @@ -1,6 +1,6 @@ add_compiler_rt_component(cfi) -if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD") +if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD" OR OS_NAME MATCHES "OHOS") set(CFI_SOURCES cfi.cpp ) diff --git a/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp b/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp index b87798603fda..cb2d1e5843f9 100644 --- a/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp @@ -25,6 +25,7 @@ } #include +#include #include #include // for dlsym() diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index c5322110cb66..5d301bb90ae4 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -76,7 +76,7 @@ static void InitializeFlags() { cf.intercept_tls_get_addr = true; cf.exitcode = 99; // 8 shadow pages ~512kB, small enough to cover common stack sizes. - cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8); + cf.clear_shadow_mmap_threshold = 4096 * ((SANITIZER_ANDROID) ? 2 : 8); // Sigtrap is used in error reporting. cf.handle_sigtrap = kHandleSignalExclusive; diff --git a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp index 12730b29bae3..d99ff482eed1 100644 --- a/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp +++ b/compiler-rt/lib/hwasan/hwasan_dynamic_shadow.cpp @@ -24,7 +24,7 @@ // The code in this file needs to run in an unrelocated binary. It should not // access any external symbol, including its own non-hidden globals. -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS extern "C" { INTERFACE_ATTRIBUTE void __hwasan_shadow(); diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index cb0b5284ed26..9536a3d52ce4 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -16,8 +16,8 @@ #include "sanitizer_common/sanitizer_internal_defs.h" -#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ - !SANITIZER_NETBSD && !SANITIZER_WINDOWS && \ +#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ + !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_OHOS && \ !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS # error "Interception doesn't work on this operating system." #endif diff --git a/compiler-rt/lib/interception/interception_type_test.cpp b/compiler-rt/lib/interception/interception_type_test.cpp index a611604a700c..37f54a79b165 100644 --- a/compiler-rt/lib/interception/interception_type_test.cpp +++ b/compiler-rt/lib/interception/interception_type_test.cpp @@ -31,8 +31,8 @@ COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ - _FILE_OFFSET_BITS != 64 +#if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ + _FILE_OFFSET_BITS != 64 || SANITIZER_OHOS COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); # endif diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index b0ae6f020b63..3c65d9df225e 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -31,7 +31,7 @@ // the new architecture inside the sanitizer library. // Exclude leak-detection on arm32 for Android because `__aeabi_read_tp` // is missing. This caused a link error. -#if SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__)) +#if (SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))) #define CAN_SANITIZE_LEAKS 0 #elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp index 3157b35ffaf8..b5b14b921824 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cpp @@ -26,7 +26,7 @@ const char *SecondaryAllocatorName = "LargeMmapAllocator"; // ThreadSanitizer for Go uses libc malloc/free. #if defined(SANITIZER_USE_MALLOC) -# if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern "C" void *__libc_malloc(uptr size); # if !SANITIZER_GO extern "C" void *__libc_memalign(uptr alignment, uptr size); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index d4b9ea5f7f06..37d5dfbc8d89 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2180,11 +2180,13 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { } namespace __sanitizer { extern "C" { +#if !SANITIZER_OHOS int real_clock_gettime(u32 clk_id, void *tp) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_clock_gettime(clk_id, tp); return REAL(clock_gettime)(clk_id, tp); } +#endif } // extern "C" } // namespace __sanitizer INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { @@ -2451,7 +2453,7 @@ INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { } return res; } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); @@ -3750,7 +3752,7 @@ INTERCEPTOR(char *, strerror, int errnum) { // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ - SANITIZER_FREEBSD + SANITIZER_FREEBSD || SANITIZER_OHOS // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index b7da65987557..a546a45293a9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -98,7 +98,7 @@ static void ioctl_table_fill() { _(SIOCSIFNETMASK, READ, struct_ifreq_sz); #endif -#if (SANITIZER_LINUX && !SANITIZER_ANDROID) +#if (SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS) _(SIOCGETSGCNT, WRITE, struct_sioc_sg_req_sz); _(SIOCGETVIFCNT, WRITE, struct_sioc_vif_req_sz); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc index 1b89d6e17684..e5f7af4d107a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2294,7 +2294,7 @@ PRE_SYSCALL(ni_syscall)() {} POST_SYSCALL(ni_syscall)(long res) {} PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ +#if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) @@ -2316,7 +2316,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) { } POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) { -#if !SANITIZER_ANDROID && \ +#if !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \ SANITIZER_RISCV64) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index 94f16b6e8735..efcc9820bd59 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -23,8 +23,7 @@ #if SANITIZER_FREEBSD || SANITIZER_MAC # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD || \ - SANITIZER_RTEMS +#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_RTEMS # define __errno_location __errno #elif SANITIZER_SOLARIS # define __errno_location ___errno diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index cfb5822645f1..32827da14f1b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -60,7 +60,8 @@ COMMON_FLAG( "Mention name of executable when reporting error and " "append executable name to logs (as in \"log_path.exe_name.pid\").") COMMON_FLAG( - bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, + bool, log_to_syslog, + (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC || (bool)SANITIZER_OHOS, "Write all sanitizer output to syslog in addition to other means of " "logging.") COMMON_FLAG( @@ -230,13 +231,15 @@ COMMON_FLAG(bool, intercept_stat, true, COMMON_FLAG(bool, intercept_send, true, "If set, uses custom wrappers for send* functions " "to find more errors.") -COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID, +COMMON_FLAG(bool, decorate_proc_maps, + (bool)SANITIZER_ANDROID || (bool)SANITIZER_OHOS, "If set, decorate sanitizer mappings in /proc/self/maps with " "user-readable names") COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( - bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, + bool, abort_on_error, + (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC || (bool)SANITIZER_OHOS, "If set, the tool calls abort() instead of _exit() after printing the " "error report.") COMMON_FLAG(bool, suppress_equal_pcs, true, diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index d8f0540037d2..16345fb954fa 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -168,8 +168,8 @@ typedef long pid_t; typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ + SANITIZER_OHOS || \ (SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \ (SANITIZER_LINUX && defined(__x86_64__)) typedef u64 OFF_T; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 379f6d9e294b..bef7eb5d7f52 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -49,7 +49,6 @@ #include #undef stat #endif - #include #include #include @@ -74,7 +73,7 @@ #include #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS #include #endif @@ -489,7 +488,7 @@ int TgKill(pid_t pid, tid_t tid, int sig) { } #endif -#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD +#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_OHOS u64 NanoTime() { #if SANITIZER_FREEBSD timeval tv; @@ -501,10 +500,19 @@ u64 NanoTime() { return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; } +#elif SANITIZER_OHOS +u64 NanoTime() { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec; +} +#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD + +#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_OHOS uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { return internal_syscall(SYSCALL(clock_gettime), clk_id, tp); } -#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD +#endif // Like getenv, but reads env directly from /proc (on Linux) or parses the // 'environ' array (on some others) and does not use libc. This function @@ -822,7 +830,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { // rt_sigaction, so we need to do the same (we'll need to reimplement the // restorers; for x86_64 the restorer address can be obtained from // oldact->sa_restorer upon a call to sigaction(xxx, NULL, oldact). -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 k_act.sa_restorer = u_act->sa_restorer; #endif } @@ -838,7 +846,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { internal_memcpy(&u_oldact->sa_mask, &k_oldact.sa_mask, sizeof(__sanitizer_kernel_sigset_t)); u_oldact->sa_flags = k_oldact.sa_flags; -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 +#if (!SANITIZER_ANDROID && !SANITIZER_OHOS) || !SANITIZER_MIPS32 u_oldact->sa_restorer = k_oldact.sa_restorer; #endif } @@ -1004,7 +1012,7 @@ static uptr GetKernelAreaSize() { if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0; } -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS // Even if nothing is mapped, top Gb may still be accessible // if we are running on 64-bit kernel. // Uname may report misleading results if personality type @@ -1765,7 +1773,7 @@ void *internal_start_thread(void *(*func)(void *arg), void *arg) { // Start the thread with signals blocked, otherwise it can steal user signals. __sanitizer_sigset_t set, old; internal_sigfillset(&set); -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS // Glibc uses SIGSETXID signal during setuid call. If this signal is blocked // on any thread, setuid call hangs (see test/tsan/setuid.c). internal_sigdelset(&set, 33); @@ -1795,7 +1803,7 @@ struct __sanitizer_esr_context { static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) { static const u32 kEsrMagic = 0x45535201; - u8 *aux = ucontext->uc_mcontext.__reserved; + u8 *aux = (u8 *)ucontext->uc_mcontext.__reserved; while (true) { _aarch64_ctx *ctx = (_aarch64_ctx *)aux; if (ctx->size == 0) break; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 24902d1b6bce..4aefab43b13c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -116,7 +116,7 @@ inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { ReleaseMemoryPagesToOS(beg, end); } -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #if defined(__aarch64__) # define __get_tls() \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index f20b9001c2c2..fe9d80e0e465 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -75,7 +75,7 @@ struct __sanitizer::linux_dirent { #endif #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS #include #include #endif @@ -803,7 +803,7 @@ void LogMessageOnPrintf(const char *str) { #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_GO +#if SANITIZER_LINUX && !SANITIZER_GO && !SANITIZER_OHOS // glibc crashes when using clock_gettime from a preinit_array function as the // vDSO function pointers haven't been initialized yet. __progname is // initialized after the vDSO function pointers, so if it exists, is not null @@ -839,7 +839,11 @@ u64 MonotonicNanoTime() { // Non-Linux & Go always use the syscall. u64 MonotonicNanoTime() { timespec ts; +#if SANITIZER_OHOS + clock_gettime(CLOCK_MONOTONIC, &ts); +#else internal_clock_gettime(CLOCK_MONOTONIC, &ts); +#endif return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; } #endif // SANITIZER_LINUX && !SANITIZER_GO diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 96c01bad870d..8f5f59b34366 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -13,9 +13,9 @@ #define SANITIZER_PLATFORM_H #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ - !defined(__APPLE__) && !defined(_WIN32) && \ - !defined(__Fuchsia__) && !defined(__rtems__) && \ - !(defined(__sun__) && defined(__svr4__)) + !defined(__APPLE__) && !defined(_WIN32) && !defined(__OHOS_FAMILY__) && \ + !defined(__Fuchsia__) && !defined(__rtems__) && \ + !(defined(__sun__) && defined(__svr4__)) # error "This operating system is not supported" #endif @@ -105,6 +105,12 @@ # define SANITIZER_ANDROID 0 #endif +#if defined(__OHOS__) +#define SANITIZER_OHOS 1 +#else +#define SANITIZER_OHOS 0 +#endif + #if defined(__Fuchsia__) # define SANITIZER_FUCHSIA 1 #else @@ -238,7 +244,8 @@ // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. #ifndef SANITIZER_CAN_USE_ALLOCATOR64 -# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA +#if ((SANITIZER_ANDROID || SANITIZER_OHOS) && defined(__aarch64__)) || \ + SANITIZER_FUCHSIA # define SANITIZER_CAN_USE_ALLOCATOR64 1 # elif defined(__mips64) || defined(__aarch64__) # define SANITIZER_CAN_USE_ALLOCATOR64 0 diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 068fc9829e57..70e8a2c197fa 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -58,6 +58,12 @@ #define SI_ANDROID 0 #endif +#if SANITIZER_OHOS +#define SI_OHOS 1 +#else +#define SI_OHOS 0 +#endif + #if SANITIZER_FREEBSD #define SI_FREEBSD 1 #else @@ -271,7 +277,7 @@ #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX #define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 -#if SI_LINUX_NOT_ANDROID && \ +#if SI_LINUX_NOT_ANDROID && !SI_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -341,8 +347,9 @@ #define SANITIZER_INTERCEPT_ETHER_HOST \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SHMCTL \ - (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \ +#define SANITIZER_INTERCEPT_SHMCTL \ + (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && !SI_OHOS && \ + SANITIZER_WORDSIZE == 64) || \ SI_NETBSD || SI_SOLARIS) // NOLINT #define SANITIZER_INTERCEPT_RANDOM_R SI_GLIBC #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX @@ -464,7 +471,7 @@ #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX #define SANITIZER_INTERCEPT_STAT \ - (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS) + (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || SI_OHOS) #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX) #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID @@ -494,7 +501,7 @@ #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX #define SANITIZER_INTERCEPT_WCSDUP SI_POSIX #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID +#define SANITIZER_INTERCEPT_BSD_SIGNAL (SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD @@ -505,7 +512,7 @@ #define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD #define SANITIZER_INTERCEPT_STRLCPY \ - (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID) + (SI_NETBSD || SI_FREEBSD || SI_MAC || SI_ANDROID || SI_OHOS) #define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index c51327e1269e..470f6ebf8d38 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -59,7 +59,7 @@ using namespace __sanitizer; namespace __sanitizer { #if !SANITIZER_ANDROID - unsigned struct_statfs64_sz = sizeof(struct statfs64); +unsigned struct_statfs64_sz = sizeof(struct statfs64); #endif } // namespace __sanitizer @@ -81,7 +81,7 @@ CHECK_SIZE_AND_OFFSET(io_event, obj); CHECK_SIZE_AND_OFFSET(io_event, res); CHECK_SIZE_AND_OFFSET(io_event, res2); -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(sizeof(struct __sanitizer_perf_event_attr) <= sizeof(struct perf_event_attr)); CHECK_SIZE_AND_OFFSET(perf_event_attr, type); @@ -90,7 +90,7 @@ CHECK_SIZE_AND_OFFSET(perf_event_attr, size); COMPILER_CHECK(iocb_cmd_pread == IOCB_CMD_PREAD); COMPILER_CHECK(iocb_cmd_pwrite == IOCB_CMD_PWRITE); -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS COMPILER_CHECK(iocb_cmd_preadv == IOCB_CMD_PREADV); COMPILER_CHECK(iocb_cmd_pwritev == IOCB_CMD_PWRITEV); #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 7abaeb880bf3..c4a1b2807a84 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -69,7 +69,9 @@ #include #include #include +#if !SANITIZER_OHOS #include +#endif #include #include #include @@ -91,8 +93,17 @@ #if SANITIZER_LINUX # include # include + +#if SANITIZER_OHOS +// Do not include asm/sigcontext.h on behalf of asm/ptrace.h +// to avoid multiple definiton errors. +#define __ASM_SIGCONTEXT_H 1 +#include +#endif + #if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ SANITIZER_RISCV64 + # include # ifdef __arm__ typedef struct user_fpregs elf_fpregset_t; @@ -131,6 +142,13 @@ typedef struct user_fpregs elf_fpregset_t; #if SANITIZER_ANDROID #include +#elif SANITIZER_OHOS +#include +#include +#include +#include +#include +#include #else #include #include @@ -251,7 +269,7 @@ namespace __sanitizer { unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); unsigned struct_crypt_data_sz = sizeof(struct crypt_data); -#endif // SANITIZER_LINUX && !SANITIZER_ANDROID +#endif // SANITIZER_LINUX && !SANITIZER_ANDROID #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); @@ -269,7 +287,6 @@ namespace __sanitizer { int e_tabsz = (int)E_TABSZ; #endif - #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_shminfo_sz = sizeof(struct shminfo); unsigned struct_shm_info_sz = sizeof(struct shm_info); @@ -483,7 +500,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_MAC +#if !SANITIZER_ANDROID && !SANITIZER_MAC && !SANITIZER_OHOS unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -536,7 +553,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; unsigned IOCTL_TIOCSTI = TIOCSTI; unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; #endif @@ -820,7 +837,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_EQL_EMANCIPATE = EQL_EMANCIPATE; unsigned IOCTL_EQL_ENSLAVE = EQL_ENSLAVE; unsigned IOCTL_EQL_GETMASTRCFG = EQL_GETMASTRCFG; @@ -904,7 +921,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP; unsigned IOCTL_KDDISABIO = KDDISABIO; unsigned IOCTL_KDENABIO = KDENABIO; @@ -1072,7 +1089,8 @@ CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); // didn't exist. CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); #endif -#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) +#if SANITIZER_LINUX && (!SANITIZER_ANDROID || !SANITIZER_MIPS32) && \ + !SANITIZER_OHOS CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer); #endif @@ -1166,7 +1184,7 @@ CHECK_TYPE_SIZE(clock_t); CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_OHOS CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 8a156b7fcb80..f4294a74f8e2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -188,13 +188,15 @@ struct __sanitizer_struct_mallinfo { #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID -struct __sanitizer_struct_mallinfo { - int v[10]; -}; - extern unsigned struct_ustat_sz; extern unsigned struct_rlimit64_sz; extern unsigned struct_statvfs64_sz; +#endif + +#if SANITIZER_LINUX && !SANITIZER_ANDROID +struct __sanitizer_struct_mallinfo { + int v[10]; +}; struct __sanitizer_ipc_perm { int __key; @@ -367,7 +369,7 @@ struct __sanitizer_group { char **gr_mem; }; -#if defined(__x86_64__) && !defined(_LP64) +#if SANITIZER_OHOS || (defined(__x86_64__) && !defined(_LP64)) typedef long long __sanitizer_time_t; #else typedef long __sanitizer_time_t; @@ -475,7 +477,7 @@ struct __sanitizer_dirent { unsigned short d_reclen; // more fields that we don't care about }; -#elif SANITIZER_ANDROID || defined(__x86_64__) +#elif SANITIZER_ANDROID || defined(__x86_64__) || SANITIZER_OHOS struct __sanitizer_dirent { unsigned long long d_ino; unsigned long long d_off; @@ -601,7 +603,7 @@ struct __sanitizer_sigaction { uptr sa_flags; void (*sa_restorer)(); }; -#else // !SANITIZER_ANDROID +#else // !SANITIZER_ANDROID struct __sanitizer_sigaction { #if defined(__mips__) && !SANITIZER_FREEBSD unsigned int sa_flags; @@ -779,7 +781,7 @@ struct __sanitizer_wordexp_t { uptr we_offs; }; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS struct __sanitizer_FILE { int _flags; char *_IO_read_ptr; @@ -803,7 +805,7 @@ typedef void __sanitizer_FILE; # define SANITIZER_HAS_STRUCT_FILE 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ defined(__s390__) || SANITIZER_RISCV64) @@ -981,7 +983,7 @@ extern unsigned struct_synth_info_sz; extern unsigned struct_vt_mode_sz; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned struct_ax25_parms_struct_sz; extern unsigned struct_input_keymap_entry_sz; extern unsigned struct_ipx_config_data_sz; @@ -1002,12 +1004,12 @@ extern unsigned struct_unimapinit_sz; extern const unsigned long __sanitizer_bufsiz; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned struct_audio_buf_info_sz; extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID -#if !SANITIZER_ANDROID && !SANITIZER_MAC +#if !SANITIZER_ANDROID && !SANITIZER_MAC && !SANITIZER_OHOS extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; #endif @@ -1062,7 +1064,7 @@ extern unsigned IOCTL_TIOCSETD; extern unsigned IOCTL_TIOCSPGRP; extern unsigned IOCTL_TIOCSTI; extern unsigned IOCTL_TIOCSWINSZ; -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS extern unsigned IOCTL_SIOCGETSGCNT; extern unsigned IOCTL_SIOCGETVIFCNT; #endif @@ -1326,7 +1328,16 @@ extern unsigned IOCTL_VT_SETMODE; extern unsigned IOCTL_VT_WAITACTIVE; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS +extern unsigned IOCTL_CYGETDEFTHRESH; +extern unsigned IOCTL_CYGETDEFTIMEOUT; +extern unsigned IOCTL_CYGETMON; +extern unsigned IOCTL_CYGETTHRESH; +extern unsigned IOCTL_CYGETTIMEOUT; +extern unsigned IOCTL_CYSETDEFTHRESH; +extern unsigned IOCTL_CYSETDEFTIMEOUT; +extern unsigned IOCTL_CYSETTHRESH; +extern unsigned IOCTL_CYSETTIMEOUT; extern unsigned IOCTL_EQL_EMANCIPATE; extern unsigned IOCTL_EQL_ENSLAVE; extern unsigned IOCTL_EQL_GETMASTRCFG; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index 2e080098283f..01860a9c1704 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -341,7 +341,7 @@ bool ShouldMockFailureToOpen(const char *path) { internal_strncmp(path, "/proc/", 6) == 0; } -#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO && !SANITIZER_OHOS int GetNamedMappingFd(const char *name, uptr size, int *flags) { if (!common_flags()->decorate_proc_maps || !name) return -1; @@ -373,7 +373,7 @@ int GetNamedMappingFd(const char *name, uptr size, int *flags) { } #endif -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #define PR_SET_VMA 0x53564d41 #define PR_SET_VMA_ANON_NAME 0 void DecorateMapping(uptr addr, uptr size, const char *name) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 12603da1750d..a5e3b4d76e2d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -177,7 +177,8 @@ void SetAlternateSignalStack() { CHECK_EQ(0, sigaltstack(nullptr, &oldstack)); // If the alternate stack is already in place, do nothing. // Android always sets an alternate stack, but it's too small for us. - if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return; + if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) + return; // TODO(glider): the mapped stack should have the MAP_STACK flag in the // future. It is not required by man 2 sigaltstack now (they're using // malloc()). diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp index 44a95214e38b..38af2748c9ba 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -26,7 +26,8 @@ struct StackDepotNode { u32 tag; uptr stack[1]; // [size] - static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20; + static const u32 kTabSizeLog = + (SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20; // Lower kTabSizeLog bits are equal for all items in one bucket. // We use these bits to store the per-stack use counter. static const u32 kUseCountBits = kTabSizeLog; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h index 0e26c1fc37c4..3e6c0b9d4691 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stackdepot.h @@ -31,7 +31,8 @@ struct StackDepotHandle { void inc_use_count_unsafe(); }; -const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20); +const int kStackDepotMaxUseCount = + 1U << ((SANITIZER_ANDROID || SANITIZER_OHOS) ? 16 : 20); StackDepotStats *StackDepotGetStats(); u32 StackDepotPut(StackTrace stack); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 53cfddcfbe0b..0735b93c9a23 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -33,6 +33,11 @@ #include // for NT_PRSTATUS #if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID // GLIBC 2.20+ sys/user does not include asm/ptrace.h +#if SANITIZER_OHOS +// Do not include asm/sigcontext.h on behalf of asm/ptrace.h +// to avoid multiple definiton errors. +#define __ASM_SIGCONTEXT_H 1 +#endif # include #endif #include // for user_regs_struct diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index c99a6ceaa562..ff72a823b960 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -89,7 +89,7 @@ void ReportErrorSummary(const char *error_type, const StackTrace *stack, } void ReportMmapWriteExec(int prot) { -#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) +#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) && !SANITIZER_OHOS if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC)) return; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index b2628dcc4dc1..18178cd69eb5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -16,7 +16,7 @@ #include "sanitizer_common.h" #include "sanitizer_stacktrace.h" -#if SANITIZER_ANDROID +#if SANITIZER_ANDROID || SANITIZER_OHOS #include // for dlopen() #endif diff --git a/compiler-rt/lib/scudo/scudo_flags.inc b/compiler-rt/lib/scudo/scudo_flags.inc index c124738c1f3a..ce4d641b811a 100644 --- a/compiler-rt/lib/scudo/scudo_flags.inc +++ b/compiler-rt/lib/scudo/scudo_flags.inc @@ -39,7 +39,7 @@ SCUDO_FLAG(int, QuarantineChunksUpToSize, -1, // Disable the deallocation type check by default on Android, it causes too many // issues with third party libraries. SCUDO_FLAG(bool, DeallocationTypeMismatch, !SANITIZER_ANDROID, - "Report errors on malloc/delete, new/free, new/delete[], etc.") + "Report errors on malloc/delete, new/free, new/delete[], etc.") SCUDO_FLAG(bool, DeleteSizeMismatch, true, "Report errors on mismatch between size of new and delete.") diff --git a/compiler-rt/lib/scudo/scudo_platform.h b/compiler-rt/lib/scudo/scudo_platform.h index 07d4b70fc8e9..c2414ec60237 100644 --- a/compiler-rt/lib/scudo/scudo_platform.h +++ b/compiler-rt/lib/scudo/scudo_platform.h @@ -24,10 +24,10 @@ #ifndef SCUDO_TSD_EXCLUSIVE // SCUDO_TSD_EXCLUSIVE wasn't defined, use a default TSD model for the platform. -# if SANITIZER_ANDROID || SANITIZER_FUCHSIA +#if SANITIZER_ANDROID || SANITIZER_FUCHSIA // Android and Fuchsia use a pool of TSDs shared between threads. # define SCUDO_TSD_EXCLUSIVE 0 -# elif SANITIZER_LINUX && !SANITIZER_ANDROID +#elif SANITIZER_LINUX && !SANITIZER_ANDROID // Non-Android Linux use an exclusive TSD per thread. # define SCUDO_TSD_EXCLUSIVE 1 # else @@ -42,7 +42,7 @@ // Maximum number of TSDs that can be created for the Shared model. #ifndef SCUDO_SHARED_TSD_POOL_SIZE -# if SANITIZER_ANDROID +#if SANITIZER_ANDROID # define SCUDO_SHARED_TSD_POOL_SIZE 2U # else # define SCUDO_SHARED_TSD_POOL_SIZE 32U @@ -67,7 +67,7 @@ namespace __scudo { #if SANITIZER_CAN_USE_ALLOCATOR64 -# if defined(__aarch64__) && SANITIZER_ANDROID +#if defined(__aarch64__) && SANITIZER_ANDROID const uptr AllocatorSize = 0x4000000000ULL; // 256G. # elif defined(__aarch64__) const uptr AllocatorSize = 0x10000000000ULL; // 1T. diff --git a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp index 2c91db8ca397..002e87038cfb 100644 --- a/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp +++ b/compiler-rt/lib/ubsan/ubsan_signals_standalone.cpp @@ -26,7 +26,7 @@ // debuggerd handler, but before the ART handler. // * Interceptors don't work at all when ubsan runtime is loaded late, ex. when // it is part of an APK that does not use wrap.sh method. -#if SANITIZER_FUCHSIA || SANITIZER_ANDROID +#if SANITIZER_FUCHSIA || SANITIZER_ANDROID || SANITIZER_OHOS namespace __ubsan { void InitializeDeadlySignals() {} diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt index 855fac4f039f..c8b2152b373c 100644 --- a/compiler-rt/test/asan/CMakeLists.txt +++ b/compiler-rt/test/asan/CMakeLists.txt @@ -132,7 +132,7 @@ if(COMPILER_RT_INCLUDE_TESTS) ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py) endif() # FIXME: support unit test in the android test runner - if (NOT ANDROID) + if (NOT ANDROID AND NOT OHOS_FAMILY) list(APPEND ASAN_TEST_DEPS AsanUnitTests) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME) diff --git a/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py b/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py index 57271b8078a4..c2352c676cc5 100644 --- a/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py +++ b/compiler-rt/test/asan/TestCases/Linux/lit.local.cfg.py @@ -5,5 +5,5 @@ def getRoot(config): root = getRoot(config) -if root.host_os not in ['Linux']: +if root.host_os not in ['Linux', 'OHOS']: config.unsupported = True diff --git a/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c b/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c index 9929b4a67af3..f5f234028867 100644 --- a/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c +++ b/compiler-rt/test/asan/TestCases/Linux/odr_c_test.c @@ -17,7 +17,7 @@ __attribute__((aligned(8))) int x; __attribute__((aligned(1))) char y; // The gold linker puts ZZZ at the start of bss (where it is aligned) // unless we have a large alternative like Displace: -__attribute__((aligned(1))) char Displace[105]; +__attribute__((aligned(8))) char Displace[105]; __attribute__((aligned(1))) char ZZZ[100]; #elif defined(FILE2) int ZZZ = 1; diff --git a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp index e1752bc894c0..8fed52092be8 100644 --- a/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/shmctl.cpp @@ -1,5 +1,5 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// XFAIL: android +// XFAIL: android && !ohos_family // // RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 // Regression test for @@ -22,6 +22,6 @@ int main() { struct shm_info shmInfo; res = shmctl(0, SHM_INFO, (struct shmid_ds *)&shmInfo); assert(res > -1); - + return 0; } diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py index 4f56c886e92e..8be427f7ba1a 100644 --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -247,7 +247,7 @@ else: config.substitutions.append(('%pie', '-pie')) # Only run the tests on supported OSs. -if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: +if config.host_os not in ['OHOS', 'Linux', 'Darwin', 'FreeBSD', 'SunOS', 'Windows', 'NetBSD']: config.unsupported = True if not config.parallelism_group: diff --git a/compiler-rt/test/builtins/Unit/divtf3_test.c b/compiler-rt/test/builtins/Unit/divtf3_test.c index 927d0b826f8f..f8b1f20e59d2 100644 --- a/compiler-rt/test/builtins/Unit/divtf3_test.c +++ b/compiler-rt/test/builtins/Unit/divtf3_test.c @@ -185,6 +185,11 @@ int main() UINT64_C(0))) return 1; + if (test__divtf3(-1L, + -0.999999999999999999999999999999999904L, + UINT64_C(0x1), + UINT64_C(0x3fff000000000000))) + return 1; #else printf("skipped\n"); diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index 30cfdbee13e2..c28b2cea07ac 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -12,6 +12,9 @@ import json import lit.formats import lit.util +def is_ohos_family_mobile(): + return config.ohos_family and config.target_arch != 'x86_64' + # Choose between lit's internal shell pipeline runner and a real shell. If # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override. use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") @@ -117,10 +120,10 @@ if config.host_os == 'NetBSD': config.netbsd_nomprotect_prefix = ('sh ' + os.path.join(nb_commands_dir, 'run_nomprotect.sh')) - config.substitutions.append( ('%run_nomprotect', - config.netbsd_nomprotect_prefix) ) + config.substitutions.append(('%run_nomprotect', + config.netbsd_nomprotect_prefix)) else: - config.substitutions.append( ('%run_nomprotect', '%run') ) + config.substitutions.append(('%run_nomprotect', '%run')) # Copied from libcxx's config.py def get_lit_conf(name, default=None): @@ -136,13 +139,26 @@ emulator = get_lit_conf('emulator', None) # Allow tests to be executed on a simulator or remotely. if emulator: - config.substitutions.append( ('%run', emulator) ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', emulator)) + config.substitutions.append(('%env ', "env ")) # TODO: Implement `%device_rm` to perform removal of files in the emulator. # For now just make it a no-op. lit_config.warning('%device_rm is not implemented') - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" +elif is_ohos_family_mobile(): + config.available_features.add('ohos_family') + # FIXME: some tests for hos also need this now, + # probably this shouldn't be added for ohos + config.available_features.add('android') + compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "ohos_family_commands", "ohos_compile.py") + " " + config.compile_wrapper = compile_wrapper + config.substitutions.append( ('%run', "") ) + config.substitutions.append( ('%env ', "env ") ) + # TODO: Implement `%device_rm` to perform removal of files on a device. For + # now just make it a no-op. + lit_config.warning('%device_rm is not implemented') + config.substitutions.append( ('%device_rm', 'echo ') ) elif config.host_os == 'Darwin' and config.apple_platform != "osx": # Darwin tests can be targetting macOS, a device or a simulator. All devices # are declared as "ios", even for iOS derivatives (tvOS, watchOS). Similarly, @@ -203,20 +219,20 @@ elif config.android: config.available_features.add('android') compile_wrapper = os.path.join(config.compiler_rt_src_root, "test", "sanitizer_common", "android_commands", "android_compile.py") + " " config.compile_wrapper = compile_wrapper - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) else: - config.substitutions.append( ('%run', "") ) - config.substitutions.append( ('%env ', "env ") ) + config.substitutions.append(('%run', "")) + config.substitutions.append(('%env ', "env ")) # When running locally %device_rm is a no-op. - config.substitutions.append( ('%device_rm', 'echo ') ) + config.substitutions.append(('%device_rm', 'echo ')) config.compile_wrapper = "" # Define CHECK-%os to check for OS-dependent output. -config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os))) +config.substitutions.append(('CHECK-%os', ("CHECK-" + config.host_os))) # Define %arch to check for architecture-dependent output. -config.substitutions.append( ('%arch', (config.host_arch))) +config.substitutions.append(('%arch', (config.host_arch))) if config.host_os == 'Windows': # FIXME: This isn't quite right. Specifically, it will succeed if the program @@ -227,7 +243,7 @@ if config.host_os == 'Windows': else: config.expect_crash = "not --crash " -config.substitutions.append( ("%expect_crash ", config.expect_crash) ) +config.substitutions.append(("%expect_crash ", config.expect_crash)) target_arch = getattr(config, 'target_arch', None) if target_arch: @@ -329,12 +345,12 @@ if config.host_os == 'Darwin': for vers in min_macos_deployment_target_substitutions: flag = config.apple_platform_min_deployment_target_flag major, minor = get_macos_aligned_version(vers) - config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '{}={}.{}'.format(flag, major, minor)) ) + config.substitutions.append(('%%min_macos_deployment_target=%s.%s' % vers, '{}={}.{}'.format(flag, major, minor))) else: for vers in min_macos_deployment_target_substitutions: - config.substitutions.append( ('%%min_macos_deployment_target=%s.%s' % vers, '') ) + config.substitutions.append(('%%min_macos_deployment_target=%s.%s' % vers, '')) -if config.android: +if config.android or is_ohos_family_mobile(): env = os.environ.copy() if config.android_serial: env['ANDROID_SERIAL'] = config.android_serial @@ -345,21 +361,25 @@ if config.android: # These are needed for tests to upload/download temp files, such as # suppression-files, to device. config.substitutions.append( ('%device_rundir', "/data/local/tmp/Output") ) - config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%pull_from_device', "%s -s '%s' pull " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) - config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) + if not config.host_os == 'OHOS': + config.substitutions.append( ('%push_to_device', "%s -s '%s' push " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%pull_from_device', "%s -s '%s' pull " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%adb_shell ', "%s -s '%s' shell " % (adb, env['ANDROID_SERIAL']) ) ) + config.substitutions.append( ('%device_rm', "%s -s '%s' shell 'rm ' " % (adb, env['ANDROID_SERIAL']) ) ) try: - android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() - android_api_codename = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") + android_api_level_str = subprocess.check_output( + [adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip() + android_api_codename = subprocess.check_output( + [adb, "shell", "getprop", "ro.build.version.codename"], env=env).rstrip().decode("utf-8") except (subprocess.CalledProcessError, OSError): lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb) try: android_api_level = int(android_api_level_str) except ValueError: lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str)) - android_api_level = min(android_api_level, int(config.android_api_level)) + if config.android_api_level: + android_api_level = min(android_api_level, int(config.android_api_level)) for required in [26, 28, 30]: if android_api_level >= required: config.available_features.add('android-%s' % required) @@ -507,7 +527,7 @@ for postfix in ["2", "1", ""]: elif config.host_os in ('FreeBSD', 'NetBSD', 'OpenBSD'): config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) - elif config.host_os == 'Linux': + elif config.host_os in ['Linux', 'OHOS']: config.substitutions.append( ("%ld_flags_rpath_exe" + postfix, "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec" + postfix) ) config.substitutions.append( ("%ld_flags_rpath_so" + postfix, '') ) elif config.host_os == 'SunOS': @@ -546,7 +566,7 @@ if config.host_os == 'Darwin': lit_config.warning('log command found but cannot queried') else: lit_config.warning('log command not found. Some tests will be skipped.') -elif config.android: +elif config.android or is_ohos_family_mobile(): config.default_sanitizer_opts += ['abort_on_error=0'] # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index 5653bcd90caa..957226a91888 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -40,6 +40,7 @@ set_default("use_thinlto", False) set_default("use_lto", config.use_thinlto) set_default("use_newpm", False) set_default("android", @ANDROID_PYBOOL@) +set_default("ohos_family", @OHOS_FAMILY_PYBOOL@) set_default("android_api_level", "@ANDROID_API_LEVEL@") set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@") set_default("android_files_to_push", []) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py new file mode 100644 index 000000000000..e38f7a485189 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py @@ -0,0 +1,45 @@ +import os, subprocess, tempfile + +OHOS_TMPDIR = '/data/local/tmp/Output' +ADB = os.environ.get('ADB', 'adb') + +verbose = False +if os.environ.get('OHOS_RUN_VERBOSE') == '1': + verbose = True + +def host_to_device_path(path): + rel = os.path.relpath(path, "/") + dev = os.path.join(OHOS_TMPDIR, rel) + return dev + +def adb(args, attempts = 1): + if verbose: + print args + tmpname = tempfile.mktemp() + out = open(tmpname, 'w') + ret = 255 + while attempts > 0 and ret != 0: + attempts -= 1 + ret = subprocess.call([ADB] + args, stdout=out, stderr=subprocess.STDOUT) + if attempts != 0: + ret = 5 + if ret != 0: + print "adb command failed", args + print tmpname + out.close() + out = open(tmpname, 'r') + print out.read() + out.close() + os.unlink(tmpname) + return ret + +def pull_from_device(path): + tmp = tempfile.mktemp() + adb(['pull', path, tmp], 5) + text = open(tmp, 'r').read() + os.unlink(tmp) + return text + +def push_to_device(path): + dst_path = host_to_device_path(path) + adb(['push', path, dst_path], 5) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py new file mode 100644 index 000000000000..bc5cd811ebb2 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_compile.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +import os, sys, subprocess +from ohos_common import * + + +here = os.path.abspath(os.path.dirname(sys.argv[0])) +ohos_run = os.path.join(here, 'ohos_run.py') + +output = None +output_type = 'executable' + +args = sys.argv[1:] +append_args = [] +check_trgt = False +while args: + arg = args.pop(0) + if arg == '-shared': + output_type = 'shared' + elif arg == '-c': + output_type = 'object' + elif arg == '-o': + output = args.pop(0) + elif arg == '-target': + check_trgt = True + elif check_trgt or arg.startswith('--target='): + check_trgt = False + if arg.endswith('-linux-ohos'): + arg = arg.split('=')[-1] + dyld = 'unknown_ohos_dyld' + # FIXME: Handle -mfloat-abi=hard for arm + # TODO: Support x86_64 + if arg.startswith('arm'): + dyld = 'ld-musl-arm.so.1' + elif arg.startswith('aarch64'): + dyld = 'ld-musl-aarch64.so.1' + append_args += ['-Wl,--dynamic-linker=' + os.path.join(OHOS_TMPDIR, dyld)] + +if output == None: + print "No output file name!" + sys.exit(1) + +ret = subprocess.call(sys.argv[1:] + append_args) +if ret != 0: + sys.exit(ret) + +if output_type in ['executable', 'shared']: + push_to_device(output) + +if output_type == 'executable': + os.rename(output, output + '.real') + os.symlink(ohos_run, output) diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py new file mode 100644 index 000000000000..b5605e615dc3 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_run.py @@ -0,0 +1,38 @@ +#!/usr/bin/python + +import os, signal, sys, subprocess +import re +from ohos_common import * + +device_binary = host_to_device_path(sys.argv[0]) + +def build_env(): + args = [] + # HOS linker ignores RPATH. Set LD_LIBRARY_PATH to Output dir. + args.append('LD_LIBRARY_PATH=%s' % (OHOS_TMPDIR,)) + for (key, value) in os.environ.items(): + if key in ['ASAN_ACTIVATION_OPTIONS', 'SCUDO_OPTIONS'] or key.endswith('SAN_OPTIONS'): + args.append('%s="%s"' % (key, value)) + return ' '.join(args) + +device_env = build_env() +device_args = ' '.join(sys.argv[1:]) # FIXME: escape? +device_stdout = device_binary + '.stdout' +device_stderr = device_binary + '.stderr' +device_exitcode = device_binary + '.exitcode' +device_linker = '' + +ret = adb(['shell', 'cd %s && %s %s %s %s >%s 2>%s ; echo $? >%s' % + (OHOS_TMPDIR, device_env, device_linker, device_binary, device_args, + device_stdout, device_stderr, device_exitcode)]) +if ret != 0: + sys.exit(ret) + +sys.stdout.write(pull_from_device(device_stdout)) +sys.stderr.write(pull_from_device(device_stderr)) +retcode = int(pull_from_device(device_exitcode)) +# If the device process died with a signal, do abort(). +# Not exactly the same, but good enough to fool "not --crash". +if retcode > 128: + os.kill(os.getpid(), signal.SIGABRT) +sys.exit(retcode) diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index cdd5495e36ab..25ce254649a9 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -400,9 +400,17 @@ endif () #=============================================================================== if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) - set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR}) - set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + if(OHOS) + set(LIBCXX_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR}) + set(LIBCXX_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX}) + else() + set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR}) + set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR}) diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index 894f637f814f..991efe0c25d5 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -93,6 +93,8 @@ elseif(APPLE) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_RT_LIB NO) set(LIBCXX_HAS_ATOMIC_LIB NO) +elseif(OHOS) + set(LIBCXX_HAS_ATOMIC_LIB NO) elseif(FUCHSIA) set(LIBCXX_HAS_M_LIB NO) set(LIBCXX_HAS_PTHREAD_LIB NO) diff --git a/libcxx/include/__config b/libcxx/include/__config index a3838c89e8e1..384d59700132 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1132,6 +1132,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( defined(__CloudABI__) || \ defined(__sun__) || \ defined(__MVS__) || \ + defined(__OHOS_FAMILY__) || \ (defined(__MINGW32__) && __has_include()) # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) @@ -1226,7 +1227,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( # endif #endif -#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__NuttX__) || \ +#if defined(__BIONIC__) || defined(__CloudABI__) || defined(__OHOS_FAMILY__) || \ defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || \ defined(__MVS__) || defined(__OpenBSD__) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 77e5faab2676..9d6a901898e2 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -43,6 +43,9 @@ #elif defined(__wasi__) // WASI libc uses musl's locales support. # include <__support/musl/xlocale.h> +#elif defined(__LITEOS__) || defined(__OHOS__) +// LiteOS libc uses musl's locales support. +# include <__support/musl/xlocale.h> #elif defined(_LIBCPP_HAS_MUSL_LIBC) # include <__support/musl/xlocale.h> #endif diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt index 9965104cb5b2..f80c8e062526 100644 --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -178,11 +178,14 @@ if (LIBCXX_ENABLE_SHARED) add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) target_link_libraries(cxx_shared PUBLIC cxx-headers PRIVATE ${LIBCXX_LIBRARIES}) + if (NOT DEFINED LIBCXX_OUTPUT_NAME) + set (LIBCXX_OUTPUT_NAME "c++") + endif() set_target_properties(cxx_shared PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_NAME}" VERSION "${LIBCXX_ABI_VERSION}.0" SOVERSION "${LIBCXX_ABI_VERSION}" DEFINE_SYMBOL "" @@ -254,11 +257,14 @@ if (LIBCXX_ENABLE_STATIC) target_link_libraries(cxx_static PUBLIC cxx-headers PRIVATE ${LIBCXX_LIBRARIES}) set(CMAKE_STATIC_LIBRARY_PREFIX "lib") + if (NOT DEFINED LIBCXX_OUTPUT_STATIC_NAME) + set (LIBCXX_OUTPUT_STATIC_NAME "c++") + endif() set_target_properties(cxx_static PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" LINK_FLAGS "${LIBCXX_LINK_FLAGS}" - OUTPUT_NAME "c++" + OUTPUT_NAME "${LIBCXX_OUTPUT_STATIC_NAME}" ) cxx_add_common_build_flags(cxx_static) cxx_set_common_defines(cxx_static) diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index 3113f9fb5cd1..91b4de27f768 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -29,6 +29,8 @@ // No _LIBCPP_ELAST needed on Fuchsia #elif defined(__wasi__) // No _LIBCPP_ELAST needed on WASI +#elif defined(__OHOS_FAMILY__) +// No _LIBCPP_ELAST needed on LiteOS #elif defined(__linux__) || defined(_LIBCPP_HAS_MUSL_LIBC) #define _LIBCPP_ELAST 4095 #elif defined(__APPLE__) diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt index 6de2b5a2ed10..981d0c583485 100644 --- a/libcxxabi/CMakeLists.txt +++ b/libcxxabi/CMakeLists.txt @@ -179,8 +179,15 @@ set(CMAKE_MODULE_PATH ) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) - set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + if(OHOS) + set(LIBCXXABI_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBCXXABI_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/${LLVM_TARGET_MULTILIB_SUFFIX}) + else() + set(LIBCXXABI_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + set(LIBCXXABI_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXXABI_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) string(APPEND LIBCXXABI_INSTALL_LIBRARY_DIR /${LIBCXXABI_LIBDIR_SUBDIR}) @@ -464,7 +471,7 @@ if (LIBCXXABI_BAREMETAL) add_definitions(-DLIBCXXABI_BAREMETAL) endif() -if (LIBCXXABI_HAS_COMMENT_LIB_PRAGMA) +if (LIBCXXABI_HAS_COMMENT_LIB_PRAGMA AND NOT OHOS) if (LIBCXXABI_HAS_PTHREAD_LIB) add_definitions(-D_LIBCXXABI_LINK_PTHREAD_LIB) endif() diff --git a/libcxxabi/src/abort_message.cpp b/libcxxabi/src/abort_message.cpp index ad44063facb7..e2a53cc70878 100644 --- a/libcxxabi/src/abort_message.cpp +++ b/libcxxabi/src/abort_message.cpp @@ -11,7 +11,7 @@ #include #include "abort_message.h" -#ifdef __BIONIC__ +#if defined(__BIONIC__) && !defined(__OHOS__) # include # if __ANDROID_API__ >= 21 # include @@ -52,7 +52,7 @@ void abort_message(const char* format, ...) va_end(list); CRSetCrashLogMessage(buffer); -#elif defined(__BIONIC__) +#elif defined(__BIONIC__) && !defined(__OHOS__) char* buffer; va_list list; va_start(list, format); diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index 570b8db90653..a9320d965207 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -114,8 +114,15 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) - set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + if(OHOS) + set(LIBUNWIND_LIBRARY_DIR + ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + set(LIBUNWIND_INSTALL_LIBRARY_DIR + lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/${LLVM_TARGET_MULTILIB_SUFFIX}) + else() + set(LIBUNWIND_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + set(LIBUNWIND_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++) + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBUNWIND_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) string(APPEND LIBUNWIND_INSTALL_LIBRARY_DIR /${LIBUNWIND_LIBDIR_SUBDIR}) @@ -327,7 +334,7 @@ if (LIBUNWIND_HAS_COMMENT_LIB_PRAGMA) if (LIBUNWIND_HAS_DL_LIB) add_definitions(-D_LIBUNWIND_LINK_DL_LIB) endif() - if (LIBUNWIND_HAS_PTHREAD_LIB) + if (LIBUNWIND_HAS_PTHREAD_LIB AND NOT OHOS) add_definitions(-D_LIBUNWIND_LINK_PTHREAD_LIB) endif() endif() diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index c84b5f5bdfda..39b7ec18cc3f 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -263,6 +263,8 @@ struct Configuration { uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + unsigned ltos; + bool mergeFunctions; unsigned optimize; StringRef thinLTOJobs; unsigned timeTraceGranularity; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 3b2a8ba19293..a41a7d1b8dc4 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -62,6 +62,7 @@ #include "llvm/Support/raw_ostream.h" #include #include +#include using namespace llvm; using namespace llvm::ELF; @@ -925,6 +926,48 @@ static void parseClangOption(StringRef opt, const Twine &msg) { error(msg + ": " + StringRef(err).trim()); } +static std::pair parseLTOOptArg(opt::InputArgList &args, + unsigned key, + StringRef defaultValue) { + auto *a = args.getLastArg(key); + llvm::StringRef value = a ? a->getValue() : defaultValue; + + unsigned optLevel = 0; + unsigned sizeLevel = 0; + + if (value.size() != 1) { + error("invalid optimization level for LTO: " + value); + return {optLevel, sizeLevel}; + } + + char c = value[0]; + + switch (c) { + + case '0': + case '1': + case '2': + case '3': + optLevel = c - '0'; + break; + + case 's': + optLevel = 2; + sizeLevel = 1; + break; + + case 'z': + optLevel = 2; + sizeLevel = 2; + break; + + default: + error("invalid optimization level for LTO: " + value); + } + + return {optLevel, sizeLevel}; +} + // Initializes Config members by the command line options. static void readConfigs(opt::InputArgList &args) { errorHandler().verbose = args.hasArg(OPT_verbose); @@ -1002,8 +1045,9 @@ static void readConfigs(opt::InputArgList &args) { config->ltoWholeProgramVisibility = args.hasFlag(OPT_lto_whole_program_visibility, OPT_no_lto_whole_program_visibility, false); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); + std::tie(config->ltoo, config->ltos) = parseLTOOptArg(args, OPT_lto_O, "2"); + config->mergeFunctions = args.hasArg(OPT_lto_mf); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoPseudoProbeForProfiling = args.hasArg(OPT_lto_pseudo_probe_for_profiling); diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index b3d4b7dee9f8..9381509542ad 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -129,6 +129,8 @@ static lto::Config createConfig() { c.DisableVerify = config->disableVerify; c.DiagHandler = diagnosticHandler; c.OptLevel = config->ltoo; + c.SizeLevel = config->ltos; + c.MergeFunctions = config->mergeFunctions; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 65ef3e824f50..e6d77f21d027 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -538,6 +538,10 @@ def lto_newpm_passes: JJ<"lto-newpm-passes=">, HelpText<"Passes to run during LTO">; def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; +def lto_S: J<"lto-S">, MetaVarName<"">, + HelpText<"Size Optimization level for LTO, works only with -lto-O2">; +def lto_mf: F<"lto-mf">, + HelpText<"Enable Merge Functions pass for link time optimizations.">; def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, diff --git a/lld/test/ELF/lto/opt-level.ll b/lld/test/ELF/lto/opt-level.ll index 6e0cc9ac98c5..628e4ef7126c 100644 --- a/lld/test/ELF/lto/opt-level.ll +++ b/lld/test/ELF/lto/opt-level.ll @@ -19,14 +19,14 @@ ; RUN: FileCheck --check-prefix=INVALID1 %s ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=Ofoo %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALID2 %s -; INVALID2: --plugin-opt=Ofoo: number expected, but got 'foo' +; INVALID2: invalid optimization level for LTO: foo ; RUN: not ld.lld -o /dev/null -e main --lto-O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s -; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE1: invalid optimization level for LTO: -1 ; RUN: not ld.lld -o /dev/null -e main --plugin-opt=O-1 %t.o 2>&1 | \ ; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s -; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 +; INVALIDNEGATIVE2: invalid optimization level for LTO: -1 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt index b5633e21c56a..7448c99de72a 100644 --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -31,13 +31,21 @@ if (WIN32) endif() if (LLDB_ENABLE_PYTHON) - execute_process( - COMMAND ${Python3_EXECUTABLE} - -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))" - OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE) - - file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH) + if (NOT CMAKE_CROSSCOMPILING) + execute_process( + COMMAND ${Python3_EXECUTABLE} + -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))" + OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + + file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH) + else () + if ("${LLDB_PYTHON_RELATIVE_PATH}" STREQUAL "") + message(FATAL_ERROR + "Crosscompiling LLDB with Python requires manually setting + LLDB_PYTHON_RELATIVE_PATH.") + endif () + endif () set(LLDB_PYTHON_RELATIVE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} CACHE STRING "Path where Python modules are installed, relative to install prefix") endif () diff --git a/lldb/cmake/modules/FindPythonAndSwig.cmake b/lldb/cmake/modules/FindPythonAndSwig.cmake index 3535b548c45f..562d5307e8c8 100644 --- a/lldb/cmake/modules/FindPythonAndSwig.cmake +++ b/lldb/cmake/modules/FindPythonAndSwig.cmake @@ -35,6 +35,17 @@ macro(FindPython3) endif() endmacro() +#OHOS specific: copy LLVM-10 definitions if new Python3_*** are not set +if(NOT Python3_EXECUTABLE AND PYTHON_EXECUTABLE) + set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) +endif() +if(NOT Python3_LIBRARIES AND PYTHON_LIBRARIES) + set(Python3_LIBRARIES ${PYTHON_LIBRARIES}) +endif() +if(NOT Python3_INCLUDE_DIRS AND PYTHON_INCLUDE_DIRS) + set(Python3_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) +endif() + if(Python3_LIBRARIES AND Python3_INCLUDE_DIRS AND Python3_EXECUTABLE AND SWIG_EXECUTABLE) set(PYTHONANDSWIG_FOUND TRUE) else() diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 2fdf1502d055..a50f6ce7c315 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -295,7 +295,7 @@ endif() # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. -if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows") +if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows|OHOS") set(LLDB_CAN_USE_LLDB_SERVER ON) else() set(LLDB_CAN_USE_LLDB_SERVER OFF) diff --git a/lldb/include/lldb/Host/HostInfo.h b/lldb/include/lldb/Host/HostInfo.h index b7010d69d88e..fbb5bbf1e442 100644 --- a/lldb/include/lldb/Host/HostInfo.h +++ b/lldb/include/lldb/Host/HostInfo.h @@ -39,6 +39,9 @@ #if defined(__ANDROID__) #include "lldb/Host/android/HostInfoAndroid.h" #define HOST_INFO_TYPE HostInfoAndroid +#elif defined(__OHOS_FAMILY__) +#include "lldb/Host/ohos/HostInfoOHOS.h" +#define HOST_INFO_TYPE HostInfoOHOS #else #include "lldb/Host/linux/HostInfoLinux.h" #define HOST_INFO_TYPE HostInfoLinux diff --git a/lldb/include/lldb/Host/MainLoop.h b/lldb/include/lldb/Host/MainLoop.h index 9ca5040b60a8..e26b8c8cb61b 100644 --- a/lldb/include/lldb/Host/MainLoop.h +++ b/lldb/include/lldb/Host/MainLoop.h @@ -14,7 +14,8 @@ #include "llvm/ADT/DenseMap.h" #include -#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) +#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__) && \ + !defined(__OHOS_FAMILY__) #define SIGNAL_POLLING_UNSUPPORTED 1 #endif diff --git a/lldb/include/lldb/Host/ohos/HostInfoOHOS.h b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h new file mode 100644 index 000000000000..e20582820145 --- /dev/null +++ b/lldb/include/lldb/Host/ohos/HostInfoOHOS.h @@ -0,0 +1,32 @@ +//===-- HostInfoOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_ohos_HostInfoOHOS_h_ +#define lldb_Host_ohos_HostInfoOHOS_h_ + +#include "lldb/Host/linux/HostInfoLinux.h" + +namespace lldb_private { + +class HostInfoOHOS : public HostInfoLinux { + friend class HostInfoBase; + +public: + static FileSpec GetDefaultShell(); + static FileSpec ResolveLibraryPath(const std::string &path, + const ArchSpec &arch); + +protected: + static void ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64); + static bool ComputeTempFileBaseDirectory(FileSpec &file_spec); +}; + +} // end of namespace lldb_private + +#endif // #ifndef lldb_Host_ohos_HostInfoOHOS_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepRange.h b/lldb/include/lldb/Target/ThreadPlanStepRange.h index 2fe885277100..36288a0d10ae 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepRange.h @@ -44,6 +44,7 @@ protected: bool InRange(); lldb::FrameComparison CompareCurrentFrameToStartFrame(); bool InSymbol(); + bool MaybeAArch32Or64FunctionTail(); void DumpRanges(Stream *s); Disassembler *GetDisassembler(); diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index ff445fa0b926..f66cb7f1d6d0 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -641,6 +641,9 @@ def skipIfPlatform(oslist): return unittest2.skipIf(lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist))) +def skipOnHuaweiCI(func): + return unittest2.skipIf(lldbplatformutil.isHuaweiCI(), "skip on Huawei CI")(func) + def skipUnlessPlatform(oslist): """Decorate the item to skip tests unless running on one of the listed platforms.""" diff --git a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py index 94b133589dcc..d1dfcde78c44 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplatformutil.py @@ -152,6 +152,8 @@ def getPlatform(): # It still might be an unconnected remote platform. return '' +def isHuaweiCI(): + return getPlatform() == 'linux' and os.path.exists('/.dockerenv') def platformIsDarwin(): """Returns true if the OS triple for the selected platform is any valid apple OS""" diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index 958cadd3a7c8..964bcfdd1cff 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -804,11 +804,6 @@ class Base(unittest2.TestCase): for setting, value in configuration.settings: commands.append('setting set %s %s'%(setting, value)) - # Make sure that a sanitizer LLDB's environment doesn't get passed on. - if cls.platformContext and cls.platformContext.shlib_environment_var in os.environ: - commands.append('settings set target.env-vars {}='.format( - cls.platformContext.shlib_environment_var)) - # Set environment variables for the inferior. if lldbtest_config.inferior_env: commands.append('settings set target.env-vars {}'.format( diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index b87a759aadc5..f892bb3dbd9b 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -166,6 +166,18 @@ public: const Constant *constant = dyn_cast(value); if (constant) { + if (constant->getValueID() == Value::ConstantFPVal) { + if (auto *cfp = dyn_cast(constant)) { + if (cfp->getType()->isDoubleTy()) + scalar = cfp->getValueAPF().convertToDouble(); + else if (cfp->getType()->isFloatTy()) + scalar = cfp->getValueAPF().convertToFloat(); + else + return false; + return true; + } + return false; + } APInt value_apint; if (!ResolveConstantValue(value_apint, constant)) @@ -188,9 +200,18 @@ public: lldb::offset_t offset = 0; if (value_size <= 8) { - uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); - return AssignToMatchType(scalar, llvm::APInt(64, u64value), - value->getType()); + Type *ty = value->getType(); + if (ty->isDoubleTy()) { + scalar = value_extractor.GetDouble(&offset); + return true; + } else if (ty->isFloatTy()) { + scalar = value_extractor.GetFloat(&offset); + return true; + } else { + uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); + return AssignToMatchType(scalar, llvm::APInt(64, u64value), + value->getType()); + } } return false; @@ -204,11 +225,15 @@ public: return false; lldb_private::Scalar cast_scalar; - - scalar.MakeUnsigned(); - if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), - value->getType())) - return false; + Type *vty = value->getType(); + if (vty->isFloatTy() || vty->isDoubleTy()) { + cast_scalar = scalar; + } else { + scalar.MakeUnsigned(); + if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), + value->getType())) + return false; + } size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); @@ -534,16 +559,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, } break; case Instruction::GetElementPtr: break; + case Instruction::FCmp: case Instruction::ICmp: { - ICmpInst *icmp_inst = dyn_cast(&ii); + CmpInst *cmp_inst = dyn_cast(&ii); - if (!icmp_inst) { + if (!cmp_inst) { error.SetErrorToGenericError(); error.SetErrorString(interpreter_internal_error); return false; } - switch (icmp_inst->getPredicate()) { + switch (cmp_inst->getPredicate()) { default: { LLDB_LOGF(log, "Unsupported ICmp predicate: %s", PrintValue(&ii).c_str()); @@ -552,11 +578,17 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, error.SetErrorString(unsupported_opcode_error); return false; } + case CmpInst::FCMP_OEQ: case CmpInst::ICMP_EQ: + case CmpInst::FCMP_UNE: case CmpInst::ICMP_NE: + case CmpInst::FCMP_OGT: case CmpInst::ICMP_UGT: + case CmpInst::FCMP_OGE: case CmpInst::ICMP_UGE: + case CmpInst::FCMP_OLT: case CmpInst::ICMP_ULT: + case CmpInst::FCMP_OLE: case CmpInst::ICMP_ULE: case CmpInst::ICMP_SGT: case CmpInst::ICMP_SGE: @@ -586,6 +618,11 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, case Instruction::Xor: case Instruction::ZExt: break; + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + break; } for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) { @@ -701,7 +738,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, case Instruction::AShr: case Instruction::And: case Instruction::Or: - case Instruction::Xor: { + case Instruction::Xor: + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: { const BinaryOperator *bin_op = dyn_cast(inst); if (!bin_op) { @@ -740,12 +781,15 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: break; case Instruction::Add: + case Instruction::FAdd: result = L + R; break; case Instruction::Mul: + case Instruction::FMul: result = L * R; break; case Instruction::Sub: + case Instruction::FSub: result = L - R; break; case Instruction::SDiv: @@ -758,6 +802,9 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = L / R; break; + case Instruction::FDiv: + result = L / R; + break; case Instruction::SRem: L.MakeSigned(); R.MakeSigned(); @@ -1020,10 +1067,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str()); } } break; + case Instruction::FCmp: case Instruction::ICmp: { - const ICmpInst *icmp_inst = cast(inst); + const CmpInst *cmp_inst = cast(inst); - CmpInst::Predicate predicate = icmp_inst->getPredicate(); + CmpInst::Predicate predicate = cmp_inst->getPredicate(); Value *lhs = inst->getOperand(0); Value *rhs = inst->getOperand(1); @@ -1051,9 +1099,11 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, default: return false; case CmpInst::ICMP_EQ: + case CmpInst::FCMP_OEQ: result = (L == R); break; case CmpInst::ICMP_NE: + case CmpInst::FCMP_UNE: result = (L != R); break; case CmpInst::ICMP_UGT: @@ -1066,16 +1116,28 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, R.MakeUnsigned(); result = (L >= R); break; + case CmpInst::FCMP_OGE: + result = (L >= R); + break; + case CmpInst::FCMP_OGT: + result = (L > R); + break; case CmpInst::ICMP_ULT: L.MakeUnsigned(); R.MakeUnsigned(); result = (L < R); break; + case CmpInst::FCMP_OLT: + result = (L < R); + break; case CmpInst::ICMP_ULE: L.MakeUnsigned(); R.MakeUnsigned(); result = (L <= R); break; + case CmpInst::FCMP_OLE: + result = (L <= R); + break; case CmpInst::ICMP_SGT: L.MakeSigned(); R.MakeSigned(); diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index 7456cb98bfa1..1cf30c20a030 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -99,7 +99,7 @@ else() endif() - elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") + elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_host_subdirectory(linux linux/AbstractSocket.cpp linux/Host.cpp @@ -113,6 +113,11 @@ else() android/LibcGlue.cpp ) endif() + if (CMAKE_SYSTEM_NAME MATCHES "OHOS") + add_host_subdirectory(ohos + ohos/HostInfoOHOS.cpp + ) + endif() elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") add_host_subdirectory(freebsd freebsd/Host.cpp diff --git a/lldb/source/Host/common/MainLoop.cpp b/lldb/source/Host/common/MainLoop.cpp index 02cabbc93550..fc8b94309b09 100644 --- a/lldb/source/Host/common/MainLoop.cpp +++ b/lldb/source/Host/common/MainLoop.cpp @@ -86,7 +86,7 @@ private: int num_events = -1; #else -#ifdef __ANDROID__ +#if defined(__ANDROID__) fd_set read_fd_set; #else std::vector read_fds; @@ -140,7 +140,7 @@ void MainLoop::RunImpl::ProcessEvents() { } #else MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) { -#ifndef __ANDROID__ +#if !defined(__ANDROID__) read_fds.reserve(loop.m_read_fds.size()); #endif } @@ -162,7 +162,7 @@ sigset_t MainLoop::RunImpl::get_sigmask() { return sigmask; } -#ifdef __ANDROID__ +#if defined(__ANDROID__) Status MainLoop::RunImpl::Poll() { // ppoll(2) is not supported on older all android versions. Also, older // versions android (API <= 19) implemented pselect in a non-atomic way, as a @@ -218,7 +218,7 @@ Status MainLoop::RunImpl::Poll() { #endif void MainLoop::RunImpl::ProcessEvents() { -#ifdef __ANDROID__ +#if defined(__ANDROID__) // Collect first all readable file descriptors into a separate vector and // then iterate over it to invoke callbacks. Iterating directly over // loop.m_read_fds is not possible because the callbacks can modify the diff --git a/lldb/source/Host/common/Socket.cpp b/lldb/source/Host/common/Socket.cpp index 4bcf34a6b456..f4037da059e5 100644 --- a/lldb/source/Host/common/Socket.cpp +++ b/lldb/source/Host/common/Socket.cpp @@ -38,7 +38,7 @@ #include "lldb/Host/linux/AbstractSocket.h" #endif -#ifdef __ANDROID__ +#if defined(__ANDROID__) #include #include #include diff --git a/lldb/source/Host/common/TCPSocket.cpp b/lldb/source/Host/common/TCPSocket.cpp index ea7377edbd45..c9f4db5fae49 100644 --- a/lldb/source/Host/common/TCPSocket.cpp +++ b/lldb/source/Host/common/TCPSocket.cpp @@ -162,6 +162,8 @@ Status TCPSocket::Connect(llvm::StringRef name) { std::vector addresses = SocketAddress::GetAddressInfo( host_str.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + llvm::partition(addresses, + [](auto &sa) { return sa.GetFamily() == AF_INET; }); for (SocketAddress &address : addresses) { error = CreateSocket(address.GetFamily()); if (error.Fail()) diff --git a/lldb/source/Host/ohos/HostInfoOHOS.cpp b/lldb/source/Host/ohos/HostInfoOHOS.cpp new file mode 100644 index 000000000000..e47d26e3e938 --- /dev/null +++ b/lldb/source/Host/ohos/HostInfoOHOS.cpp @@ -0,0 +1,94 @@ +//===-- HostInfoOHOS.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ohos/HostInfoOHOS.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/linux/HostInfoLinux.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +using namespace lldb_private; +using namespace llvm; + +void HostInfoOHOS::ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64) { + HostInfoLinux::ComputeHostArchitectureSupport(arch_32, arch_64); + + if (arch_32.IsValid()) { + arch_32.GetTriple().setEnvironment(llvm::Triple::UnknownEnvironment); + } + if (arch_64.IsValid()) { + arch_64.GetTriple().setEnvironment(llvm::Triple::UnknownEnvironment); + } +} + +FileSpec HostInfoOHOS::GetDefaultShell() { + return FileSpec("/system/bin/sh"); +} + +FileSpec HostInfoOHOS::ResolveLibraryPath(const std::string &module_path, + const ArchSpec &arch) { + static const char *const ld_library_path_separator = ":"; + static const char *const default_lib32_path[] = {"/vendor/lib", "/system/lib", + nullptr}; + static const char *const default_lib64_path[] = {"/vendor/lib64", + "/system/lib64", nullptr}; + + if (module_path.empty() || module_path[0] == '/') { + FileSpec file_spec(module_path.c_str()); + FileSystem::Instance().Resolve(file_spec); + return file_spec; + } + + SmallVector ld_paths; + + if (const char *ld_library_path = ::getenv("LD_LIBRARY_PATH")) + StringRef(ld_library_path) + .split(ld_paths, StringRef(ld_library_path_separator), -1, false); + + const char *const *default_lib_path = nullptr; + switch (arch.GetAddressByteSize()) { + case 4: + default_lib_path = default_lib32_path; + break; + case 8: + default_lib_path = default_lib64_path; + break; + default: + assert(false && "Unknown address byte size"); + return FileSpec(); + } + + for (const char *const *it = default_lib_path; *it; ++it) + ld_paths.push_back(StringRef(*it)); + + for (const StringRef &path : ld_paths) { + FileSpec file_candidate(path.str().c_str()); + FileSystem::Instance().Resolve(file_candidate); + file_candidate.AppendPathComponent(module_path.c_str()); + + if (FileSystem::Instance().Exists(file_candidate)) + return file_candidate; + } + + return FileSpec(); +} + +bool HostInfoOHOS::ComputeTempFileBaseDirectory(FileSpec &file_spec) { + bool success = HostInfoLinux::ComputeTempFileBaseDirectory(file_spec); + + // On OHOS, there is no path which is guaranteed to be writable. If the + // user has not provided a path via an environment variable, the generic + // algorithm will deduce /tmp, which is plain wrong. In that case we have an + // invalid directory, we substitute the path with /data/local/tmp, which is + // correct at least in some cases (i.e., when running as shell user). + if (!success || !FileSystem::Instance().Exists(file_spec)) + file_spec = FileSpec("/data/local/tmp"); + + return FileSystem::Instance().Exists(file_spec); +} diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp index 5a396906fdf6..97e8d4859e14 100644 --- a/lldb/source/Host/posix/DomainSocket.cpp +++ b/lldb/source/Host/posix/DomainSocket.cpp @@ -18,7 +18,7 @@ using namespace lldb; using namespace lldb_private; -#ifdef __ANDROID__ +#if defined(__ANDROID__) // Android does not have SUN_LEN #ifndef SUN_LEN #define SUN_LEN(ptr) \ diff --git a/lldb/source/Host/posix/HostInfoPosix.cpp b/lldb/source/Host/posix/HostInfoPosix.cpp index 7e110f07d7cf..cbfdf60a0a0a 100644 --- a/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/lldb/source/Host/posix/HostInfoPosix.cpp @@ -86,7 +86,7 @@ llvm::Optional PosixUserIDResolver::DoGetUserName(id_t uid) { } llvm::Optional PosixUserIDResolver::DoGetGroupName(id_t gid) { -#ifndef __ANDROID__ +#if !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) char group_buffer[PATH_MAX]; size_t group_buffer_size = sizeof(group_buffer); struct group group_info; diff --git a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 35482341d3e6..de622473272a 100644 --- a/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -38,7 +38,7 @@ using namespace lldb; using namespace lldb_private; static void FixupEnvironment(Environment &env) { -#ifdef __ANDROID__ +#if defined(__ANDROID__) // If there is no PATH variable specified inside the environment then set the // path to /system/bin. It is required because the default path used by // execve() is wrong on android. diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 9be294750fa0..7e0da5663b37 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -519,7 +519,7 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language, // Try to create a configuration from the files. If there is no valid // configuration possible with the files, this just returns an invalid // configuration. - return CppModuleConfiguration(files); + return CppModuleConfiguration(files, target->GetArchitecture().GetTriple()); } bool ClangUserExpression::PrepareForParsing( diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp index ffab16b1682b..7148a7c236d6 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp @@ -10,6 +10,7 @@ #include "ClangHost.h" #include "lldb/Host/FileSystem.h" +#include "llvm/ADT/Triple.h" using namespace lldb_private; @@ -30,7 +31,29 @@ bool CppModuleConfiguration::SetOncePath::TrySet(llvm::StringRef path) { return false; } -bool CppModuleConfiguration::analyzeFile(const FileSpec &f) { +static std::string targetSpecificIncludePath(const llvm::Triple &triple) { + if (triple.getArchName().empty() || triple.getOSAndEnvironmentName().empty()) + return ""; + return ("/usr/include/" + triple.getArchName() + "-" + + triple.getOSAndEnvironmentName()) + .str(); +} + +static bool guessIncludePath(llvm::StringRef pathToFile, + llvm::StringRef pattern, llvm::StringRef &result) { + result = llvm::StringRef(); + if (pattern.empty()) + return false; + size_t pos = pathToFile.find(pattern); + if (pos == llvm::StringRef::npos) + return false; + + result = pathToFile.substr(0, pos + pattern.size()); + return true; +} + +bool CppModuleConfiguration::analyzeFile(const FileSpec &f, + const llvm::Triple &triple) { using namespace llvm::sys::path; // Convert to slashes to make following operations simpler. std::string dir_buffer = convert_to_slash(f.GetDirectory().GetStringRef()); @@ -46,12 +69,12 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) { return m_std_inc.TrySet(posix_dir); } - // Check for /usr/include. On Linux this might be /usr/include/bits, so - // we should remove that '/bits' suffix to get the actual include directory. - if (posix_dir.endswith("/usr/include/bits")) - posix_dir.consume_back("/bits"); - if (posix_dir.endswith("/usr/include")) - return m_c_inc.TrySet(posix_dir); + llvm::StringRef inc_path; + // Target specific path contains /usr/include, so we check it first + if (guessIncludePath(posix_dir, targetSpecificIncludePath(triple), inc_path)) + return m_c_target_inc.TrySet(inc_path); + if (guessIncludePath(posix_dir, "/usr/include", inc_path)) + return m_c_inc.TrySet(inc_path); // File wasn't interesting, continue analyzing. return true; @@ -92,11 +115,11 @@ bool CppModuleConfiguration::hasValidConfig() { } CppModuleConfiguration::CppModuleConfiguration( - const FileSpecList &support_files) { + const FileSpecList &support_files, const llvm::Triple &triple) { // Analyze all files we were given to build the configuration. bool error = !llvm::all_of(support_files, std::bind(&CppModuleConfiguration::analyzeFile, - this, std::placeholders::_1)); + this, std::placeholders::_1, triple)); // If we have a valid configuration at this point, set the // include directories and module list that should be used. if (!error && hasValidConfig()) { @@ -109,6 +132,8 @@ CppModuleConfiguration::CppModuleConfiguration( // This order matches the way Clang orders these directories. m_include_dirs = {m_std_inc.Get().str(), m_resource_inc, m_c_inc.Get().str()}; + if (m_c_target_inc.Valid()) + m_include_dirs.push_back(m_c_target_inc.Get().str()); m_imported_modules = {"std"}; } } diff --git a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h index b984db43fa6d..60199005b6ba 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -44,6 +44,9 @@ class CppModuleConfiguration { SetOncePath m_std_inc; /// If valid, the include path to the C library (e.g. /usr/include). SetOncePath m_c_inc; + /// If valid, the include path to target-specific C library files + /// (e.g. /usr/include/x86_64-linux-gnu). + SetOncePath m_c_target_inc; /// The Clang resource include path for this configuration. std::string m_resource_inc; @@ -53,11 +56,12 @@ class CppModuleConfiguration { /// Analyze a given source file to build the current configuration. /// Returns false iff there was a fatal error that makes analyzing any /// further files pointless as the configuration is now invalid. - bool analyzeFile(const FileSpec &f); + bool analyzeFile(const FileSpec &f, const llvm::Triple &triple); public: /// Creates a configuration by analyzing the given list of used source files. - explicit CppModuleConfiguration(const FileSpecList &support_files); + explicit CppModuleConfiguration(const FileSpecList &support_files, + const llvm::Triple &triple); /// Creates an empty and invalid configuration. CppModuleConfiguration() {} diff --git a/lldb/source/Plugins/Platform/CMakeLists.txt b/lldb/source/Plugins/Platform/CMakeLists.txt index 5f284e517dca..8c532955a9dd 100644 --- a/lldb/source/Plugins/Platform/CMakeLists.txt +++ b/lldb/source/Plugins/Platform/CMakeLists.txt @@ -15,3 +15,4 @@ add_subdirectory(POSIX) add_subdirectory(gdb-server) add_subdirectory(Android) +add_subdirectory(OHOS) diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 2cb671fd4dc3..9cdc9d5f434c 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -97,7 +97,7 @@ void PlatformLinux::Initialize() { PlatformPOSIX::Initialize(); if (g_initialize_count++ == 0) { -#if defined(__linux__) && !defined(__ANDROID__) +#if defined(__linux__) && !defined(__ANDROID__) && !defined(__OHOS_FAMILY__) PlatformSP default_platform_sp(new PlatformLinux(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); diff --git a/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt b/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt new file mode 100644 index 000000000000..cc71762efe2e --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/CMakeLists.txt @@ -0,0 +1,13 @@ +add_lldb_library(lldbPluginPlatformOHOS PLUGIN + HdcClient.cpp + PlatformOHOS.cpp + PlatformOHOSRemoteGDBServer.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbPluginPlatformLinux + lldbPluginPlatformGDB + LINK_COMPONENTS + Support + ) diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp new file mode 100644 index 000000000000..97fa08fb44da --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -0,0 +1,379 @@ +//===-- HdcClient.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "HdcClient.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FileUtilities.h" + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/PosixApi.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataEncoder.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timeout.h" + +#if defined(_WIN32) +#include +#else +#include +#endif + +#include + +#include +#include +#include +#include + +// On Windows, transitive dependencies pull in , which defines a +// macro that clashes with a method name. +#ifdef SendMessage +#undef SendMessage +#endif + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +namespace { + +const seconds kReadTimeout(20); +const char *kSocketNamespaceAbstract = "localabstract"; +const char *kSocketNamespaceFileSystem = "localfilesystem"; + +Status ReadAllBytes(Connection &conn, void *buffer, size_t size, + size_t *read_ptr, ConnectionStatus *status_ptr) { + + Status error; + ConnectionStatus status; + char *read_buffer = static_cast(buffer); + + auto now = steady_clock::now(); + const auto deadline = now + kReadTimeout; + size_t total_read_bytes = 0; + while (total_read_bytes < size && now < deadline) { + auto read_bytes = + conn.Read(read_buffer + total_read_bytes, size - total_read_bytes, + duration_cast(deadline - now), status, &error); + if (status_ptr) + *status_ptr = status; + if (error.Fail()) + return error; + total_read_bytes += read_bytes; + if (read_ptr) + *read_ptr = total_read_bytes; + if (status != eConnectionStatusSuccess) + break; + now = steady_clock::now(); + } + if (total_read_bytes < size) + error = Status( + "Unable to read requested number of bytes. Connection status: %d.", + status); + return error; +} + +} // namespace + +Status HdcClient::CreateByDeviceID(const std::string &device_id, + HdcClient &hdc) { + DeviceIDList connect_devices; + auto error = hdc.GetDevices(connect_devices); + if (error.Fail()) + return error; + + std::string hdc_utid; + if (!device_id.empty()) + hdc_utid = device_id; + else if (const char *env_hdc_utid = std::getenv("HDC_UTID")) + hdc_utid = env_hdc_utid; + + if (hdc_utid.empty()) { + if (connect_devices.size() != 1) + return Status("Expected a single connected device, got instead %zu - try " + "setting 'HDC_UTID'", + connect_devices.size()); + hdc.SetDeviceID(connect_devices.front()); + } else { + auto find_it = std::find(connect_devices.begin(), connect_devices.end(), + hdc_utid); + if (find_it == connect_devices.end()) + return Status( + "Device \"%s\" not found, check HDC_UTID environment variable", + hdc_utid.c_str()); + + hdc.SetDeviceID(*find_it); + } + return error; +} + +HdcClient::HdcClient() {} + +HdcClient::HdcClient(const std::string &device_id) : m_device_id(device_id) {} + +HdcClient::~HdcClient() {} + +void HdcClient::SetDeviceID(const std::string &device_id) { + m_device_id = device_id; +} + +const std::string &HdcClient::GetDeviceID() const { return m_device_id; } + +namespace { +typedef unsigned msg_len_t; +struct ChannelHandShake { + msg_len_t size; + char banner[12]; // must first index + union { + uint32_t channelId; + char connectKey[32]; + }; +} __attribute__((packed)); +} // namespace + +Status HdcClient::Connect() { + Status error; + ChannelHandShake handshake = {}; + if (m_device_id.size() > sizeof(handshake.connectKey)) + return Status("Device id is too long: %s", m_device_id.c_str()); + m_conn.reset(new ConnectionFileDescriptor); + std::string port = "8710"; + + const char *env_port = std::getenv("OHOS_HDC_SERVER_PORT"); + if ((env_port != NULL) && (atoi(env_port) > 0)) { + port = env_port; + } + + std::string uri = "connect://localhost:" + port; + m_conn->Connect(uri.c_str(), &error); + ConnectionStatus status = eConnectionStatusError; + if (error.Success()) { + error = ReadAllBytes(&handshake, sizeof(handshake)); + if (error.Success()) { + memset(handshake.connectKey, 0, sizeof(handshake.connectKey)); + memcpy(handshake.connectKey, m_device_id.c_str(), m_device_id.size()); + m_conn->Write(&handshake, sizeof(handshake), status, &error); + } + } + return error; +} + +Status HdcClient::GetDevices(DeviceIDList &device_list) { + device_list.clear(); + + auto error = SendMessage("list targets"); + if (error.Fail()) + return error; + + std::vector in_buffer; + error = ReadMessage(in_buffer); + + llvm::StringRef response(&in_buffer[0], in_buffer.size()); + llvm::SmallVector devices; + response.split(devices, "\n", -1, false); + + for (const auto device : devices) + device_list.push_back(static_cast(device.split('\t').first)); + + // Force disconnect since ADB closes connection after host:devices response + // is sent. + m_conn.reset(); + return error; +} + +Status HdcClient::SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port) { + char message[48]; + snprintf(message, sizeof(message), "fport tcp:%d tcp:%d", local_port, + remote_port); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status +HdcClient::SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace) { + char message[PATH_MAX]; + const char *sock_namespace_str = + (socket_namespace == UnixSocketNamespaceAbstract) + ? kSocketNamespaceAbstract + : kSocketNamespaceFileSystem; + snprintf(message, sizeof(message), "fport tcp:%d %s:%s", local_port, + sock_namespace_str, remote_socket_name.str().c_str()); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus("Forwardport result:OK"); +} + +Status HdcClient::DeletePortForwarding(std::pair fwd) { + char message[32]; + snprintf(message, sizeof(message), "fport rm tcp:%d tcp:%d", fwd.first, + fwd.second); + + const auto error = SendMessage(message); + if (error.Fail()) + return error; + + return ReadResponseStatus(nullptr); +} + +Status HdcClient::TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst) { + llvm::SmallVector cwd; + std::error_code ec = llvm::sys::fs::current_path(cwd); + if (ec) + return Status(ec); + + std::stringstream cmd; + cmd << "file " << direction << " -cwd "; + cmd.write(cwd.data(), cwd.size()); + cmd << " " << src.GetPath() << " " << dst.GetPath(); + Status error = SendMessage(cmd.str()); + if (error.Fail()) + return error; + + return ReadResponseStatus("FileTransfer finish"); +} + +Status HdcClient::RecvFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("recv", src, dst); +} + +Status HdcClient::SendFile(const FileSpec &src, const FileSpec &dst) { + return TransferFile("send", src, dst); +} + +Status HdcClient::SendMessage(llvm::StringRef packet, const bool reconnect) { + Status error; + if (!m_conn || reconnect) { + error = Connect(); + if (error.Fail()) + return error; + } + + unsigned msg_len = packet.size() + 1; + llvm::SmallVector message(msg_len + sizeof(msg_len_t), 0); + msg_len_t len = htonl(msg_len); + memcpy(message.data(), &len, sizeof(len)); + memcpy(message.data() + sizeof(len), packet.data(), packet.size()); + + ConnectionStatus status; + m_conn->Write(message.data(), message.size(), status, &error); + if (error.Fail()) + return error; + + return error; +} + +Status HdcClient::ReadMessage(std::vector &message) { + message.clear(); + + msg_len_t packet_len; + auto error = ReadAllBytes(&packet_len, sizeof(packet_len)); + if (error.Fail()) + return error; + + packet_len = htonl(packet_len); + message.resize(packet_len, 0); + error = ReadAllBytes(&message[0], packet_len); + if (error.Fail()) + message.clear(); + + return error; +} + +Status HdcClient::ReadMessageStream(std::vector &message, + milliseconds timeout) { + auto start = steady_clock::now(); + message.clear(); + + Status error; + lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; + char buffer[1024]; + while (error.Success() && status == lldb::eConnectionStatusSuccess) { + auto end = steady_clock::now(); + auto elapsed = end - start; + if (elapsed >= timeout) + return Status("Timed out"); + + size_t n = m_conn->Read(buffer, sizeof(buffer), + duration_cast(timeout - elapsed), + status, &error); + if (n > 0) + message.insert(message.end(), &buffer[0], &buffer[n]); + } + return error; +} + +Status HdcClient::ReadResponseStatus(const char *expected) { + msg_len_t len; + ConnectionStatus conn_status; + size_t read; + + auto error = ::ReadAllBytes(*m_conn, &len, sizeof(len), &read, &conn_status); + // Special case: we expect server to close connection + if (expected == nullptr) { + if (read == 0 && conn_status == eConnectionStatusEndOfFile) + return Status(); + else if (error.Fail()) + return error; + // Something went wrong - response is not empty + // Read it and wrap to error object + } + + len = htonl(len); + llvm::SmallVector message(len + 1); + error = ReadAllBytes(message.data(), len); + if (error.Fail()) + return error; + + message[len] = 0; + if (expected == nullptr || + strncmp(message.data(), expected, strlen(expected))) + return Status("%s", message.data()); + + return error; +} + +Status HdcClient::ReadAllBytes(void *buffer, size_t size) { + return ::ReadAllBytes(*m_conn, buffer, size, nullptr, nullptr); +} + +Status HdcClient::Shell(const char *command, milliseconds timeout, + std::string *output) { + assert(command && command[0]); + std::string cmd = "shell "; + cmd += command; + Status error = SendMessage(cmd); + if (error.Fail()) + return error; + + std::vector message; + error = ReadMessageStream(message, timeout); + if (error.Fail()) + return error; + + (*output) = std::string(message.data(), message.size()); + return error; +} diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.h b/lldb/source/Plugins/Platform/OHOS/HdcClient.h new file mode 100644 index 000000000000..64a5a324325a --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h @@ -0,0 +1,90 @@ +//===-- HdcClient.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_HdcClient_h_ +#define liblldb_HdcClient_h_ + +#include "lldb/Utility/Status.h" +#include +#include +#include +#include +#include +#include + +namespace lldb_private { + +class FileSpec; + +namespace platform_ohos { + +class HdcClient { +public: + enum UnixSocketNamespace { + UnixSocketNamespaceAbstract, + UnixSocketNamespaceFileSystem, + }; + + using DeviceIDList = std::list; + + static Status CreateByDeviceID(const std::string &device_id, HdcClient &hdc); + + HdcClient(); + explicit HdcClient(const std::string &device_id); + + ~HdcClient(); + + const std::string &GetDeviceID() const; + + Status GetDevices(DeviceIDList &device_list); + + Status SetPortForwarding(const uint16_t local_port, + const uint16_t remote_port); + + Status SetPortForwarding(const uint16_t local_port, + llvm::StringRef remote_socket_name, + const UnixSocketNamespace socket_namespace); + + Status DeletePortForwarding(std::pair fwd); + + Status RecvFile(const FileSpec &src, const FileSpec &dst); + + Status SendFile(const FileSpec &src, const FileSpec &dst); + + Status Shell(const char *command, std::chrono::milliseconds timeout, + std::string *output); + +private: + Status Connect(); + + Status TransferFile(const char *direction, const FileSpec &src, + const FileSpec &dst); + + void SetDeviceID(const std::string &device_id); + + Status SendMessage(llvm::StringRef packet, const bool reconnect = true); + + Status SendDeviceMessage(const std::string &packet); + + Status ReadMessage(std::vector &message); + + Status ReadMessageStream(std::vector &message, + std::chrono::milliseconds timeout); + + Status ReadResponseStatus(const char *expected); + + Status ReadAllBytes(void *buffer, size_t size); + + std::string m_device_id; + std::unique_ptr m_conn; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_HdcClient_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp new file mode 100644 index 000000000000..f76e016bb6aa --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -0,0 +1,266 @@ +//===-- PlatformOHOS.cpp -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Host/StringConvert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/UriParser.h" + +#include "HdcClient.h" +#include "PlatformOHOS.h" +#include "PlatformOHOSRemoteGDBServer.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::platform_ohos; +using namespace std::chrono; + +static uint32_t g_initialize_count = 0; +static const unsigned int g_ohos_default_cache_size = + 2048; // Fits inside 4k adb packet. + +LLDB_PLUGIN_DEFINE(PlatformOHOS); + +void PlatformOHOS::Initialize() { + PlatformLinux::Initialize(); + + if (g_initialize_count++ == 0) { +#if defined(__OHOS_FAMILY__) + PlatformSP default_platform_sp(new PlatformOHOS(true)); + default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(default_platform_sp); +#endif + PluginManager::RegisterPlugin( + PlatformOHOS::GetPluginNameStatic(false), + PlatformOHOS::GetPluginDescriptionStatic(false), + PlatformOHOS::CreateInstance); + } +} + +void PlatformOHOS::Terminate() { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { + PluginManager::UnregisterPlugin(PlatformOHOS::CreateInstance); + } + } + + PlatformLinux::Terminate(); +} + +PlatformSP PlatformOHOS::CreateInstance(bool force, const ArchSpec *arch) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) { + const char *arch_name; + if (arch && arch->GetArchitectureName()) + arch_name = arch->GetArchitectureName(); + else + arch_name = ""; + + const char *triple_cstr = + arch ? arch->GetTriple().getTriple().c_str() : ""; + + log->Printf("PlatformOHOS::%s(force=%s, arch={%s,%s})", __FUNCTION__, + force ? "true" : "false", arch_name, triple_cstr); + } + + bool create = force; + if (!create && arch && arch->IsValid()) { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) { + case llvm::Triple::PC: + create = true; + break; + default: + break; + } + + if (create) { + switch (triple.getEnvironment()) { + case llvm::Triple::OpenHOS: + break; + default: + create = false; + break; + } + } + } + + if (create) { + if (log) + log->Printf("PlatformOHOS::%s() creating remote-ohos platform", + __FUNCTION__); + + return PlatformSP(new PlatformOHOS(false)); + } + + if (log) + log->Printf( + "PlatformOHOS::%s() aborting creation of remote-ohos platform", + __FUNCTION__); + + return PlatformSP(); +} + +PlatformOHOS::PlatformOHOS(bool is_host) : PlatformLinux(is_host) {} + +PlatformOHOS::~PlatformOHOS() {} + +ConstString PlatformOHOS::GetPluginNameStatic(bool is_host) { + if (is_host) { + static ConstString g_host_name(Platform::GetHostPlatformName()); + return g_host_name; + } else { + static ConstString g_remote_name("remote-ohos"); + return g_remote_name; + } +} + +const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) { + if (is_host) + return "Local OpenHarmony OS user platform plug-in."; + else + return "Remote OpenHarmony OS user platform plug-in."; +} + +ConstString PlatformOHOS::GetPluginName() { + return GetPluginNameStatic(IsHost()); +} + +Status PlatformOHOS::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (IsHost()) { + return Status("can't connect to the host platform '%s', always connected", + GetPluginName().GetCString()); + } + + if (!m_remote_platform_sp) + m_remote_platform_sp = PlatformSP(new PlatformOHOSRemoteGDBServer()); + + int port; + llvm::StringRef scheme, host, path; + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + if (!UriParser::Parse(url, scheme, host, port, path)) + return Status("Invalid URL: %s", url); + if (host != "localhost") + m_device_id = static_cast(host); + + auto error = PlatformLinux::ConnectRemote(args); + if (error.Success()) { + HdcClient adb; + error = HdcClient::CreateByDeviceID(m_device_id, adb); + if (error.Fail()) + return error; + + m_device_id = adb.GetDeviceID(); + } + return error; +} + +Status PlatformOHOS::GetFile(const FileSpec &source, + const FileSpec &destination) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::GetFile(source, destination); + + FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix); + if (source_spec.IsRelative()) + source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + source_spec.GetCString(false)); + + HdcClient hdc(m_device_id); + Status error = hdc.RecvFile(source, destination); + return error; +} + +Status PlatformOHOS::PutFile(const FileSpec &source, + const FileSpec &destination, uint32_t uid, + uint32_t gid) { + if (IsHost() || !m_remote_platform_sp) + return PlatformLinux::PutFile(source, destination, uid, gid); + + FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix); + if (destination_spec.IsRelative()) + destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent( + destination_spec.GetCString(false)); + + // TODO: Set correct uid and gid on remote file. + HdcClient hdc(m_device_id); + Status error = hdc.SendFile(source, destination_spec); + return error; +} + +const char *PlatformOHOS::GetCacheHostname() { return m_device_id.c_str(); } + +Status PlatformOHOS::DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, + const uint64_t src_size, + const FileSpec &dst_file_spec) { + if (src_offset != 0) + return Status("Invalid offset - %" PRIu64, src_offset); + + return GetFile(src_file_spec, dst_file_spec); +} + +Status PlatformOHOS::DisconnectRemote() { + Status error = PlatformLinux::DisconnectRemote(); + if (error.Success()) + m_device_id.clear(); + return error; +} + +uint32_t PlatformOHOS::GetDefaultMemoryCacheLineSize() { + return g_ohos_default_cache_size; +} + +uint32_t PlatformOHOS::GetSdkVersion() { + if (!IsConnected()) + return 0; + + // TBD + return 1; +} + +bool PlatformOHOS::GetRemoteOSVersion() { + m_os_version = llvm::VersionTuple(GetSdkVersion()); + return !m_os_version.empty(); +} + +llvm::StringRef +PlatformOHOS::GetLibdlFunctionDeclarations(lldb_private::Process *process) { + SymbolContextList matching_symbols; + std::vector dl_open_names = { "__dl_dlopen", "dlopen" }; + const char *dl_open_name = nullptr; + Target &target = process->GetTarget(); + for (auto name: dl_open_names) { + target.GetImages().FindFunctionSymbols(ConstString(name), + eFunctionNameTypeFull, + matching_symbols); + if (matching_symbols.GetSize()) { + dl_open_name = name; + break; + } + } + // Older platform versions have the dl function symbols mangled + if (dl_open_name == dl_open_names[0]) + return R"( + extern "C" void* dlopen(const char*, int) asm("__dl_dlopen"); + extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym"); + extern "C" int dlclose(void*) asm("__dl_dlclose"); + extern "C" char* dlerror(void) asm("__dl_dlerror"); + )"; + + return PlatformPOSIX::GetLibdlFunctionDeclarations(process); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h new file mode 100644 index 000000000000..643b7ae3f75f --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h @@ -0,0 +1,80 @@ +//===-- PlatformOHOS.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOS_h_ +#define liblldb_PlatformOHOS_h_ + +#include +#include + +#include "Plugins/Platform/Linux/PlatformLinux.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOS : public platform_linux::PlatformLinux { +public: + PlatformOHOS(bool is_host); + + ~PlatformOHOS() override; + + static void Initialize(); + + static void Terminate(); + + // lldb_private::PluginInterface functions + static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); + + static ConstString GetPluginNameStatic(bool is_host); + + static const char *GetPluginDescriptionStatic(bool is_host); + + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override { return 1; } + + // lldb_private::Platform functions + + Status ConnectRemote(Args &args) override; + + Status GetFile(const FileSpec &source, const FileSpec &destination) override; + + Status PutFile(const FileSpec &source, const FileSpec &destination, + uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override; + + uint32_t GetSdkVersion(); + + bool GetRemoteOSVersion() override; + + Status DisconnectRemote() override; + + uint32_t GetDefaultMemoryCacheLineSize() override; + +protected: + const char *GetCacheHostname() override; + + Status DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, const uint64_t src_size, + const FileSpec &dst_file_spec) override; + + llvm::StringRef + GetLibdlFunctionDeclarations(lldb_private::Process *process) override; + +private: + std::string m_device_id; + + PlatformOHOS(const PlatformOHOS &other) = delete; + PlatformOHOS& operator=(const PlatformOHOS &other) = delete; +}; + +} // namespace platofor_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOS_h_ diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp new file mode 100644 index 000000000000..62dc0639afef --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -0,0 +1,247 @@ +//===-- PlatformOHOSRemoteGDBServer.cpp ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/UriParser.h" + +#include "PlatformOHOSRemoteGDBServer.h" + +#include + +using namespace lldb; +using namespace lldb_private; +using namespace platform_ohos; + +static const lldb::pid_t g_remote_platform_pid = + 0; // Alias for the process id of lldb-platform + +static uint16_t g_hdc_forward_port_offset = 0; + +static Status ForwardPortWithHdc( + const uint16_t local_port, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + const llvm::Optional &socket_namespace, + std::string &device_id) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + + HdcClient hdc; + auto error = HdcClient::CreateByDeviceID(device_id, hdc); + if (error.Fail()) + return error; + + device_id = hdc.GetDeviceID(); + if (log) + log->Printf("Connected to OHOS device \"%s\"", device_id.c_str()); + + if (remote_port != 0) { + if (log) + log->Printf("Forwarding remote TCP port %d to local TCP port %d", + remote_port, local_port); + return hdc.SetPortForwarding(local_port, remote_port); + } + + if (log) + log->Printf("Forwarding remote socket \"%s\" to local TCP port %d", + remote_socket_name.str().c_str(), local_port); + + if (!socket_namespace) + return Status("Invalid socket namespace"); + + return hdc.SetPortForwarding(local_port, remote_socket_name, + *socket_namespace); +} + +static Status DeleteForwardPortWithHdc(std::pair ports, + const std::string &device_id) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) + log->Printf("Delete port forwarding %d -> %d, device=%s", ports.first, + ports.second, device_id.c_str()); + + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(ports); +} + +static Status FindUnusedPort(uint16_t &port) { + Status error; + + if (const char *env_port = std::getenv("HDC_FORWARD_PORT_BASE_FOR_LLDB")) { + port = std::atoi(env_port) + g_hdc_forward_port_offset; + g_hdc_forward_port_offset++; + return error; + } + + std::unique_ptr tcp_socket(new TCPSocket(true, false)); + if (error.Fail()) + return error; + + error = tcp_socket->Listen("127.0.0.1:0", 1); + if (error.Success()) + port = tcp_socket->GetLocalPortNumber(); + + return error; +} + +PlatformOHOSRemoteGDBServer::PlatformOHOSRemoteGDBServer() {} + +PlatformOHOSRemoteGDBServer::~PlatformOHOSRemoteGDBServer() { + for (const auto &it : m_port_forwards) + DeleteForwardPortWithHdc(it.second, m_device_id); +} + +bool PlatformOHOSRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, + std::string &connect_url) { + uint16_t remote_port = 0; + std::string socket_name; + if (!m_gdb_client.LaunchGDBServer("127.0.0.1", pid, remote_port, socket_name)) + return false; + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + + auto error = + MakeConnectURL(pid, remote_port, socket_name.c_str(), connect_url); + if (error.Success() && log) + log->Printf("gdbserver connect URL: %s", connect_url.c_str()); + + return error.Success(); +} + +bool PlatformOHOSRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) { + DeleteForwardPort(pid); + return m_gdb_client.KillSpawnedProcess(pid); +} + +Status PlatformOHOSRemoteGDBServer::ConnectRemote(Args &args) { + m_device_id.clear(); + + if (args.GetArgumentCount() != 1) + return Status( + "\"platform connect\" takes a single argument: "); + + int remote_port; + llvm::StringRef scheme, host, path; + const char *url = args.GetArgumentAtIndex(0); + if (!url) + return Status("URL is null."); + if (!UriParser::Parse(url, scheme, host, remote_port, path)) + return Status("Invalid URL: %s", url); + if (host != "localhost") + m_device_id = static_cast(host); + + m_socket_namespace.reset(); + if (scheme == ConnectionFileDescriptor::UNIX_CONNECT_SCHEME) + m_socket_namespace = HdcClient::UnixSocketNamespaceFileSystem; + else if (scheme == ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME) + m_socket_namespace = HdcClient::UnixSocketNamespaceAbstract; + + std::string connect_url; + auto error = + MakeConnectURL(g_remote_platform_pid, (remote_port < 0) ? 0 : remote_port, + path, connect_url); + + if (error.Fail()) + return error; + + args.ReplaceArgumentAtIndex(0, connect_url); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + if (log) + log->Printf("Rewritten platform connect URL: %s", connect_url.c_str()); + + error = PlatformRemoteGDBServer::ConnectRemote(args); + if (error.Fail()) + DeleteForwardPort(g_remote_platform_pid); + + return error; +} + +Status PlatformOHOSRemoteGDBServer::DisconnectRemote() { + DeleteForwardPort(g_remote_platform_pid); + g_hdc_forward_port_offset = 0; + return PlatformRemoteGDBServer::DisconnectRemote(); +} + +void PlatformOHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + + auto it = m_port_forwards.find(pid); + if (it == m_port_forwards.end()) + return; + + const auto port = it->second; + const auto error = DeleteForwardPortWithHdc(port, m_device_id); + if (error.Fail()) { + if (log) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", fwd=(%d -> %d), device=%s): %s", + pid, port.first, port.second, m_device_id.c_str(), + error.AsCString()); + } + m_port_forwards.erase(it); +} + +Status PlatformOHOSRemoteGDBServer::MakeConnectURL( + const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, std::string &connect_url) { + static const int kAttempsNum = 5; + + Status error; + // There is a race possibility that somebody will occupy a port while we're + // in between FindUnusedPort and ForwardPortWithHdc - adding the loop to + // mitigate such problem. + for (auto i = 0; i < kAttempsNum; ++i) { + uint16_t local_port = 0; + error = FindUnusedPort(local_port); + if (error.Fail()) + return error; + + error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, + m_socket_namespace, m_device_id); + if (error.Success()) { + m_port_forwards[pid] = {local_port, remote_port}; + std::ostringstream url_str; + url_str << "connect://localhost:" << local_port; + connect_url = url_str.str(); + break; + } + } + + return error; +} + +lldb::ProcessSP PlatformOHOSRemoteGDBServer::ConnectProcess( + llvm::StringRef connect_url, llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, lldb_private::Target *target, + lldb_private::Status &error) { + // We don't have the pid of the remote gdbserver when it isn't started by us + // but we still want to store the list of port forwards we set up in our port + // forward map. Generate a fake pid for these cases what won't collide with + // any other valid pid on ohos. + static lldb::pid_t s_remote_gdbserver_fake_pid = 0xffffffffffffffffULL; + + int remote_port; + llvm::StringRef scheme, host, path; + if (!UriParser::Parse(connect_url, scheme, host, remote_port, path)) { + error.SetErrorStringWithFormat("Invalid URL: %s", + connect_url.str().c_str()); + return nullptr; + } + + std::string new_connect_url; + error = MakeConnectURL(s_remote_gdbserver_fake_pid--, + (remote_port < 0) ? 0 : remote_port, path, + new_connect_url); + if (error.Fail()) + return nullptr; + + return PlatformRemoteGDBServer::ConnectProcess(new_connect_url, plugin_name, + debugger, target, error); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h new file mode 100644 index 000000000000..f9818589275d --- /dev/null +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -0,0 +1,64 @@ +//===-- PlatformOHOSRemoteGDBServer.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PlatformOHOSRemoteGDBServer_h_ +#define liblldb_PlatformOHOSRemoteGDBServer_h_ + +#include +#include + +#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" + +#include "llvm/ADT/Optional.h" + +#include "HdcClient.h" + +namespace lldb_private { +namespace platform_ohos { + +class PlatformOHOSRemoteGDBServer + : public platform_gdb_server::PlatformRemoteGDBServer { +public: + PlatformOHOSRemoteGDBServer(); + + ~PlatformOHOSRemoteGDBServer() override; + + Status ConnectRemote(Args &args) override; + + Status DisconnectRemote() override; + + lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + lldb_private::Debugger &debugger, + lldb_private::Target *target, + lldb_private::Status &error) override; + +protected: + std::string m_device_id; + std::map> m_port_forwards; + llvm::Optional m_socket_namespace; + + bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; + + bool KillSpawnedProcess(lldb::pid_t pid) override; + + void DeleteForwardPort(lldb::pid_t pid); + + Status MakeConnectURL(const lldb::pid_t pid, const uint16_t remote_port, + llvm::StringRef remote_socket_name, + std::string &connect_url); + +private: + PlatformOHOSRemoteGDBServer(const PlatformOHOSRemoteGDBServer &other) = delete; + PlatformOHOSRemoteGDBServer& operator=(const PlatformOHOSRemoteGDBServer &other) = delete; +}; + +} // namespace platform_ohos +} // namespace lldb_private + +#endif // liblldb_PlatformOHOSRemoteGDBServer_h_ diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt index 91f20ec22ac5..36800455ab82 100644 --- a/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt @@ -1,4 +1,4 @@ -if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") add_subdirectory(Linux) add_subdirectory(POSIX) elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h index 344eae247e91..758d08db5ade 100644 --- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -14,6 +14,11 @@ #include "Plugins/Process/Linux/NativeRegisterContextLinux.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" +#if __OHOS__ +// Do not include to avoid conflicting definitions for +// aarch64-linux-ohos target +#define __ASM_SIGCONTEXT_H 1 +#endif #include namespace lldb_private { diff --git a/lldb/source/Plugins/Process/Linux/Procfs.h b/lldb/source/Plugins/Process/Linux/Procfs.h index 59dd76a2584c..3830842dae12 100644 --- a/lldb/source/Plugins/Process/Linux/Procfs.h +++ b/lldb/source/Plugins/Process/Linux/Procfs.h @@ -11,7 +11,7 @@ #include -#ifdef __ANDROID__ +#if defined(__ANDROID__) #if defined(__arm64__) || defined(__aarch64__) typedef unsigned long elf_greg_t; typedef elf_greg_t diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 1ca0290eda13..c13203e2b961 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -44,12 +44,15 @@ #include "lldb/Host/android/HostInfoAndroid.h" #endif +#if defined(__OHOS_FAMILY__) +#include "lldb/Host/ohos/HostInfoOHOS.h" +#endif using namespace lldb; using namespace lldb_private::process_gdb_remote; using namespace lldb_private; -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__OHOS_FAMILY__) const static uint32_t g_default_packet_timeout_sec = 20; // seconds #else const static uint32_t g_default_packet_timeout_sec = 0; // not specified @@ -183,7 +186,6 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( StreamString response; // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 - ArchSpec host_arch(HostInfo::GetArchitecture()); const llvm::Triple &host_triple = host_arch.GetTriple(); response.PutCString("triple:"); @@ -1277,10 +1279,12 @@ void GDBRemoteCommunicationServerCommon:: } } -FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( +FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile ( const std::string &module_path, const ArchSpec &arch) { #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); +#elif defined(__OHOS_FAMILY__) + return HostInfoOHOS::ResolveLibraryPath(module_path, arch); #else FileSpec file_spec(module_path); FileSystem::Instance().Resolve(file_spec); @@ -1289,10 +1293,9 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( } ModuleSpec -GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, +GDBRemoteCommunicationServerCommon::GetModuleInfo (llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - FileSpec req_module_path_spec(module_path); FileSystem::Instance().Resolve(req_module_path_spec); @@ -1308,6 +1311,5 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return ModuleSpec(); - return matched_module_spec; } diff --git a/lldb/source/Target/PathMappingList.cpp b/lldb/source/Target/PathMappingList.cpp index 0342130a58a0..01ee7ef707b4 100644 --- a/lldb/source/Target/PathMappingList.cpp +++ b/lldb/source/Target/PathMappingList.cpp @@ -136,7 +136,7 @@ void PathMappingList::Dump(Stream *s, int pair_index) { } } -void PathMappingList::Clear(bool notify) { +void PathMappingList::Clear (bool notify) { if (!m_pairs.empty()) ++m_mod_id; m_pairs.clear(); @@ -196,7 +196,7 @@ PathMappingList::RemapPath(llvm::StringRef path) const { return {}; } -bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { +bool PathMappingList::ReverseRemapPath (const FileSpec &file, FileSpec &fixed) const { std::string path = file.GetPath(); llvm::StringRef path_ref(path); for (const auto &it : m_pairs) { @@ -214,7 +214,8 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co llvm::Optional PathMappingList::FindFile(const FileSpec &orig_spec) const { - if (auto remapped = RemapPath(orig_spec.GetPath())) + std::string normalized_path = FileSpec(orig_spec.GetPath()).GetPath(); + if (auto remapped = RemapPath(normalized_path)) if (FileSystem::Instance().Exists(*remapped)) return remapped; diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index a03bd93ac638..84b92fdab1d1 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -124,7 +124,7 @@ void ThreadPlanStepInRange::GetDescription(Stream *s, s->PutChar('.'); } -bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { +bool ThreadPlanStepInRange::ShouldStop (Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log) { @@ -166,6 +166,16 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { Thread &thread = GetThread(); if (frame_order == eFrameCompareOlder || frame_order == eFrameCompareSameParent) { + // Here we make a nasty hack to avoid double stepping on enclosing brace + // on ARM platforms. The problem is that before 'bx lr' we typically have + // some instruction modifying the stack pointer register. This confuses + // lldb and makes it think that we're already in a different frame where + // we should stop. + // TODO: Litmit this to OHOS targets + if (MaybeAArch32Or64FunctionTail()) { + SetNextBranchBreakpoint(); + return false; + } // If we're in an older frame then we should stop. // // A caveat to this is if we think the frame is older but we're actually diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 3c42cd750dad..53953b5c33e6 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -205,6 +205,13 @@ bool ThreadPlanStepRange::InSymbol() { return false; } +// TODO: Limit this function scope to OHOS targets +bool ThreadPlanStepRange::MaybeAArch32Or64FunctionTail() { + const llvm::Triple &triple = GetTarget().GetArchitecture().GetTriple(); + const bool isArm32or64 = triple.isAArch64() || triple.isARM(); + return isArm32or64 && InSymbol() && InRange(); +} + // FIXME: This should also handle inlining if we aren't going to do inlining in // the // main stack. diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index c13e2389cfed..36ebeac81262 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -935,7 +935,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const { return IsEqualTo(rhs, false); } -static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, +static bool IsCompatibleEnvironment (llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) { if (lhs == rhs) return true; @@ -957,6 +957,8 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, // that they are using the Android ABI. if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) || + (lhs == llvm::Triple::OpenHOS && rhs == llvm::Triple::EABI) || + (rhs == llvm::Triple::OpenHOS && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) || (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) || (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) || diff --git a/lldb/source/Utility/TildeExpressionResolver.cpp b/lldb/source/Utility/TildeExpressionResolver.cpp index 75d9c47e656d..bcae7b1a006c 100644 --- a/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/lldb/source/Utility/TildeExpressionResolver.cpp @@ -39,7 +39,7 @@ bool StandardTildeExpressionResolver::ResolveExact( return !fs::real_path(Expr, Output, true); } -bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr, +bool StandardTildeExpressionResolver::ResolvePartial (StringRef Expr, StringSet<> &Output) { // We expect the tilde expression to be ONLY the expression itself, and // contain no separators. @@ -47,7 +47,7 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr, assert(Expr.empty() || Expr[0] == '~'); Output.clear(); -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(__OHOS_FAMILY__) return false; #else if (Expr.empty()) diff --git a/lldb/test/API/api/command-return-object/Makefile b/lldb/test/API/api/command-return-object/Makefile index 99998b20bcb0..680e1abfbef5 100644 --- a/lldb/test/API/api/command-return-object/Makefile +++ b/lldb/test/API/api/command-return-object/Makefile @@ -1,3 +1,4 @@ CXX_SOURCES := main.cpp +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile index c825977b1a5d..4f8e551348d9 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile @@ -1,6 +1,6 @@ CXX_SOURCES := main.cpp CFLAGS_EXTRAS := -O0 -USE_LIBSTDCPP := 1 +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py index 861b24b3a08b..0a6dfdcee7c1 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py @@ -10,7 +10,7 @@ from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil -class StdMapDataFormatterTestCase(TestBase): +class StdMapDataFormatterTestCase (TestBase): mydir = TestBase.compute_mydir(__file__) @@ -21,6 +21,7 @@ class StdMapDataFormatterTestCase(TestBase): self.line = line_number('main.cpp', '// Set break point at this line.') @add_test_categories(["libstdcxx"]) + @skipIfLinux # Not working on OHOS, because we use libc++ def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() diff --git a/lldb/test/API/functionalities/plugins/command_plugin/Makefile b/lldb/test/API/functionalities/plugins/command_plugin/Makefile index 3119c3707841..b792c8d50d98 100644 --- a/lldb/test/API/functionalities/plugins/command_plugin/Makefile +++ b/lldb/test/API/functionalities/plugins/command_plugin/Makefile @@ -2,5 +2,6 @@ DYLIB_CXX_SOURCES := plugin.cpp DYLIB_NAME := plugin DYLIB_ONLY := YES MAKE_DSYM := NO +USE_LIBCPP := 1 include Makefile.rules diff --git a/lldb/test/API/lang/c/fpeval/Makefile b/lldb/test/API/lang/c/fpeval/Makefile new file mode 100644 index 000000000000..10495940055b --- /dev/null +++ b/lldb/test/API/lang/c/fpeval/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/lang/c/fpeval/TestFPEval.py b/lldb/test/API/lang/c/fpeval/TestFPEval.py new file mode 100644 index 000000000000..fa8a4a211994 --- /dev/null +++ b/lldb/test/API/lang/c/fpeval/TestFPEval.py @@ -0,0 +1,34 @@ +"""Show bitfields and check that they display correctly.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class FPEvalTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test_and_run_command(self): + """Test 'frame variable ...' on a variable with bitfields.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + self.expect("expr --allow-jit false -- a + b", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['double', '52']) + diff --git a/lldb/test/API/lang/c/fpeval/main.c b/lldb/test/API/lang/c/fpeval/main.c new file mode 100644 index 000000000000..1f5519401e32 --- /dev/null +++ b/lldb/test/API/lang/c/fpeval/main.c @@ -0,0 +1,10 @@ +#include +#include +#include + +int main (int argc, char const *argv[]) +{ + double a = 42.0; + double b = 10.0; + return (long)(a + b); //// Set break point at this line. +} diff --git a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py index 0644e6c2e1ec..0dfa74ef010e 100644 --- a/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py +++ b/lldb/test/API/tools/lldb-server/memory-allocation/TestGdbRemoteMemoryAllocation.py @@ -73,6 +73,7 @@ class TestGdbRemoteMemoryAllocation(gdbremote_testcase.GdbRemoteTestCaseBase): True) self.expect_gdbremote_sequence() + @skipOnHuaweiCI # investigate CI test failures def test_bad_packet(self): """Make sure we get a proper error for malformed packets.""" diff --git a/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py b/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py index 74b5f2e16eeb..ec960c962769 100644 --- a/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py +++ b/lldb/test/API/tools/lldb-server/platform-process-connect/TestPlatformProcessConnect.py @@ -12,7 +12,7 @@ class TestPlatformProcessConnect(gdbremote_testcase.GdbRemoteTestCaseBase): @expectedFailureAll(hostoslist=["windows"], triple='.*-android') @skipIfWindows # lldb-server does not terminate correctly @skipIfDarwin # lldb-server not found correctly - @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) # Fails randomly + @skipIfLinux def test_platform_process_connect(self): self.build() diff --git a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py index 8d4f464b8dee..4c502b10ae69 100644 --- a/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py +++ b/lldb/test/API/tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py @@ -61,6 +61,7 @@ class TestGdbRemote_QPassSignals(gdbremote_testcase.GdbRemoteTestCaseBase): self.expect_exit_code(len(signals_to_ignore)) @skipUnlessPlatform(["linux", "android"]) + @skipOnHuaweiCI #investigate CI timeouts def test_change_signals_at_runtime(self): self.build() self.set_inferior_startup_launch() diff --git a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py index 469e5e5fedf2..abec2ade1eec 100644 --- a/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py +++ b/lldb/test/API/tools/lldb-server/thread-name/TestGdbRemoteThreadName.py @@ -27,6 +27,7 @@ class TestGdbRemoteThreadName(gdbremote_testcase.GdbRemoteTestCaseBase): self.assertEqual(expected_name, kv_dict.get("name")) @skipIfWindows # the test is not updated for Windows. + @skipOnHuaweiCI # investigate CI timeouts def test(self): """ Make sure lldb-server can retrieve inferior thread name""" self.build() diff --git a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py index aa7a3ae17cb0..8518efc541bd 100644 --- a/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py +++ b/lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py @@ -44,6 +44,7 @@ class TestVSCode_attach(lldbvscode_testcase.VSCodeTestCaseBase): self.continue_to_exit() @skipIfWindows + @skipIfLinux @skipIfNetBSD # Hangs on NetBSD as well @skipIfRemote def test_by_pid(self): diff --git a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py index 047cc317596f..6bb2965a1fe9 100644 --- a/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py +++ b/lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py @@ -48,6 +48,7 @@ class TestVSCode_runInTerminal(lldbvscode_testcase.VSCodeTestCaseBase): return False @skipIfWindows + @skipIfLinux @skipIfRemote @skipIf(archs=no_match(['x86_64'])) def test_runInTerminal(self): diff --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt index 930c327cf072..ae3c1069c64d 100644 --- a/lldb/tools/lldb-server/CMakeLists.txt +++ b/lldb/tools/lldb-server/CMakeLists.txt @@ -5,7 +5,7 @@ set_target_properties(LLGSOptionsTableGen PROPERTIES FOLDER "lldb misc") set(LLDB_PLUGINS) -if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") +if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|OHOS") list(APPEND LLDB_PLUGINS lldbPluginProcessLinux) endif() diff --git a/lldb/unittests/Expression/CppModuleConfigurationTest.cpp b/lldb/unittests/Expression/CppModuleConfigurationTest.cpp index c1d0d00dcbac..daffce0d8e6d 100644 --- a/lldb/unittests/Expression/CppModuleConfigurationTest.cpp +++ b/lldb/unittests/Expression/CppModuleConfigurationTest.cpp @@ -69,12 +69,30 @@ TEST_F(CppModuleConfigurationTest, Linux) { // C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre(libcpp, ResourceInc(), usr)); } +TEST_F(CppModuleConfigurationTest, LinuxWithTargetSpecificPaths) { + // Test multiarch Linux configuration. + + std::string usr = "/usr/include"; + std::string usr_x64 = "/usr/include/x86_64-linux-gnu"; + std::string libcpp = "/usr/include/c++/v1"; + std::vector files = {// C library + usr + "/stdio.h", usr_x64 + "/endian.h", + // C++ library + libcpp + "/vector", + libcpp + "/module.modulemap"}; + CppModuleConfiguration config(makeFiles(files), + llvm::Triple("x86_64-unknown-linux-gnu")); + EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); + EXPECT_THAT(config.GetIncludeDirs(), + testing::ElementsAre(libcpp, ResourceInc(), usr, usr_x64)); +} + TEST_F(CppModuleConfigurationTest, Sysroot) { // Test that having a sysroot for the whole system works fine. @@ -85,7 +103,7 @@ TEST_F(CppModuleConfigurationTest, Sysroot) { // C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre(libcpp, ResourceInc(), usr)); @@ -101,7 +119,7 @@ TEST_F(CppModuleConfigurationTest, LinuxLocalLibCpp) { // C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre(libcpp, ResourceInc(), usr)); @@ -119,7 +137,7 @@ TEST_F(CppModuleConfigurationTest, UnrelatedLibrary) { // C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre(libcpp, ResourceInc(), usr)); @@ -139,7 +157,7 @@ TEST_F(CppModuleConfigurationTest, Xcode) { libcpp + "/vector", libcpp + "/module.modulemap", }; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre(libcpp, ResourceInc(), usr)); @@ -154,7 +172,7 @@ TEST_F(CppModuleConfigurationTest, LibCppV2) { // C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre("/usr/include/c++/v2", ResourceInc(), @@ -172,7 +190,7 @@ TEST_F(CppModuleConfigurationTest, UnknownLibCppFile) { libcpp + "/non_existing_file", libcpp + "/module.modulemap", libcpp + "/vector"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre("std")); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre("/usr/include/c++/v1", ResourceInc(), @@ -186,7 +204,7 @@ TEST_F(CppModuleConfigurationTest, MissingUsrInclude) { std::vector files = {// C++ library libcpp + "/vector", libcpp + "/module.modulemap"}; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); } @@ -199,7 +217,7 @@ TEST_F(CppModuleConfigurationTest, MissingLibCpp) { // C library usr + "/stdio.h", }; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); } @@ -214,7 +232,7 @@ TEST_F(CppModuleConfigurationTest, IgnoreLibStdCpp) { // C++ library usr + "/c++/8.0.1/vector", }; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); } @@ -235,7 +253,7 @@ TEST_F(CppModuleConfigurationTest, AmbiguousCLib) { libcpp + "/vector", libcpp + "/module.modulemap", }; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); } @@ -257,7 +275,7 @@ TEST_F(CppModuleConfigurationTest, AmbiguousLibCpp) { libcpp2 + "/vector", libcpp2 + "/module.modulemap", }; - CppModuleConfiguration config(makeFiles(files)); + CppModuleConfiguration config(makeFiles(files), llvm::Triple()); EXPECT_THAT(config.GetImportedModules(), testing::ElementsAre()); EXPECT_THAT(config.GetIncludeDirs(), testing::ElementsAre()); } diff --git a/lldb/unittests/Target/CMakeLists.txt b/lldb/unittests/Target/CMakeLists.txt index 2c3ba699b0eb..d0afeb3d0047 100644 --- a/lldb/unittests/Target/CMakeLists.txt +++ b/lldb/unittests/Target/CMakeLists.txt @@ -6,6 +6,7 @@ add_lldb_unittest(TargetTests PathMappingListTest.cpp RemoteAwarePlatformTest.cpp StackFrameRecognizerTest.cpp + FindFileTest.cpp LINK_LIBS lldbCore diff --git a/lldb/unittests/Target/FindFileTest.cpp b/lldb/unittests/Target/FindFileTest.cpp new file mode 100644 index 000000000000..198c0f62cb47 --- /dev/null +++ b/lldb/unittests/Target/FindFileTest.cpp @@ -0,0 +1,97 @@ +//===-- FindFileTest.cpp -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TestingSupport/TestUtilities.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/PathMappingList.h" +#include "lldb/Utility/FileSpec.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" +#include "gtest/gtest.h" +#include + +using namespace llvm; +using namespace llvm::sys::fs; +using namespace lldb_private; + +namespace { +struct Matches { + FileSpec original; + llvm::StringRef remapped; + Matches(const char *o, const char *r) : original(o), remapped(r) {} + Matches(const char *o, llvm::sys::path::Style style, const char *r) + : original(o, style), remapped(r) {} +}; + +class FindFileTest : public testing::Test { +public: + void SetUp() override { + FileSystem::Initialize(); + HostInfo::Initialize(); + } + void TearDown() override { + HostInfo::Terminate(); + FileSystem::Terminate(); + } +}; +} // namespace + +static void TestFileFindings(const PathMappingList &map, + llvm::ArrayRef matches, + llvm::ArrayRef fails) { + for (const auto &fail : fails) { + SCOPED_TRACE(fail.GetCString()); + EXPECT_FALSE(map.FindFile(fail)); + } + + for (const auto &match : matches) { + SCOPED_TRACE(match.original.GetPath() + " -> " + match.remapped); + llvm::Optional remapped; + + EXPECT_TRUE(bool(remapped = map.FindFile(match.original))); + EXPECT_TRUE(FileSpec(remapped.getValue()).GetPath() == + ConstString(match.remapped).GetStringRef()); + } +} + +TEST_F(FindFileTest, FindFileTests) { + const auto *Info = testing::UnitTest::GetInstance()->current_test_info(); + llvm::SmallString<128> DirName, FileName; + int fd; + + ASSERT_NO_ERROR(createUniqueDirectory(Info->name(), DirName)); + + sys::path::append(FileName, Twine(DirName), Twine("test")); + ASSERT_NO_ERROR(openFile(FileName, fd, CD_CreateAlways, FA_Read, OF_None)); + + llvm::FileRemover dir_remover(DirName); + llvm::FileRemover file_remover(FileName); + PathMappingList map; + + map.Append(ConstString("/old"), ConstString(DirName.str()), false); + map.Append(ConstString(R"(C:\foo)"), ConstString(DirName.str()), false); + + Matches matches[] = { + {"/old", llvm::sys::path::Style::posix, DirName.c_str()}, + {"/old/test", llvm::sys::path::Style::posix, FileName.c_str()}, + {R"(C:\foo)", llvm::sys::path::Style::windows, DirName.c_str()}, + {R"(C:\foo\test)", llvm::sys::path::Style::windows, FileName.c_str()}}; + + std::vector fails{ + // path not mapped + FileSpec("/foo", llvm::sys::path::Style::posix), + FileSpec("/new", llvm::sys::path::Style::posix), + FileSpec(R"(C:\new)", llvm::sys::path::Style::windows), + // path mapped, but file not exist + FileSpec("/old/test1", llvm::sys::path::Style::posix), + FileSpec(R"(C:\foo\test2)", llvm::sys::path::Style::windows)}; + + TestFileFindings(map, matches, fails); +} diff --git a/llvm-build/build.py b/llvm-build/build.py old mode 100644 new mode 100755 index c2dff3deffac..f6f079f025b9 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -195,7 +195,7 @@ class BuildUtils(object): self.CMAKE_BIN_DIR = os.path.abspath( os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.use_platform()[:-3], 'bin')) - def open_hos_triple(self, arch): + def open_ohos_triple(self, arch): return arch + self.build_config.OPENHOS_SFX def liteos_triple(self, arch): @@ -815,13 +815,13 @@ class LlvmLibs(BuildUtils): ('arm', self.liteos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), - ('arm', self.open_hos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), - ('arm', self.open_hos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), - ('arm', self.open_hos_triple('arm'), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mfloat-abi=soft', ''), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft', 'a7_soft'), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), - ('arm', self.open_hos_triple('arm'), + ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), - ('aarch64', self.open_hos_triple('aarch64'), '', ''), ] + ('aarch64', self.open_ohos_triple('aarch64'), '', ''), ] cc = os.path.join(llvm_install, 'bin', 'clang') cxx = os.path.join(llvm_install, 'bin', 'clang++') @@ -840,7 +840,7 @@ class LlvmLibs(BuildUtils): self.build_libs_defines(llvm_triple, defines, cc, cxx, llvm_config, ldflags, cflags, extra_flags) llvm_path = self.merge_out_path('llvm_make') - arch_list = [self.liteos_triple('arm'), self.open_hos_triple('arm'), self.open_hos_triple('aarch64')] + arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), self.open_ohos_triple('aarch64')] if precompilation: self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) continue @@ -1951,10 +1951,10 @@ def main(): configs = [] if not build_config.no_build_arm: configs.append(('arm', build_utils.liteos_triple('arm'))) - configs.append(('arm', build_utils.open_hos_triple('arm'))) + configs.append(('arm', build_utils.open_ohos_triple('arm'))) if not build_config.no_build_aarch64: - configs.append(('arm64', build_utils.open_hos_triple('aarch64'))) + configs.append(('arm64', build_utils.open_ohos_triple('aarch64'))) if build_config.do_build and need_host: llvm_core.llvm_compile( diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh index 962777b33850..0cc61592e361 100755 --- a/llvm-build/env_prepare.sh +++ b/llvm-build/env_prepare.sh @@ -9,10 +9,10 @@ mkdir -p $cmake_dir wget https://mirrors.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz wget https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/linux/cmake-linux-x86-3.16.5.tar.gz -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +#wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz tar -xvf llvm.tar.gz tar -xvf cmake-linux-x86-3.16.5.tar.gz tar -xvf clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz mv $llvm_name $llvm_dir/llvm mv $cmake_name $cmake_dir/linux-x86 -mv $clang_name $llvm_dir/clang-10.0.1 \ No newline at end of file +mv $clang_name $llvm_dir/clang-10.0.1 diff --git a/llvm-build/mingw.py b/llvm-build/mingw.py old mode 100644 new mode 100755 diff --git a/llvm-build/windres.sh b/llvm-build/windres.sh old mode 100644 new mode 100755 diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index eed315c929ad..183ac3787fdc 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -172,7 +172,7 @@ public: IOS, KFreeBSD, Linux, - Lv2, // PS3 + Lv2, // PS3 MacOSX, NetBSD, OpenBSD, @@ -182,15 +182,15 @@ public: Haiku, Minix, RTEMS, - NaCl, // Native Client + NaCl, // Native Client AIX, - CUDA, // NVIDIA CUDA - NVCL, // NVIDIA OpenCL - AMDHSA, // AMD HSA Runtime + CUDA, // NVIDIA CUDA + NVCL, // NVIDIA OpenCL + AMDHSA, // AMD HSA Runtime PS4, ELFIAMCU, - TvOS, // Apple tvOS - WatchOS, // Apple watchOS + TvOS, // Apple tvOS + WatchOS, // Apple watchOS Mesa3D, Contiki, AMDPAL, // AMD PAL Runtime @@ -198,7 +198,8 @@ public: Hurd, // GNU/Hurd WASI, // Experimental WebAssembly OS Emscripten, - LastOSType = Emscripten + LiteOS, + LastOSType = LiteOS }; enum EnvironmentType { UnknownEnvironment, @@ -223,8 +224,9 @@ public: Cygnus, CoreCLR, Simulator, // Simulator variants of other systems, e.g., Apple's iOS - MacABI, // Mac Catalyst variant of Apple's iOS deployment target. - LastEnvironmentType = MacABI + MacABI, // Mac Catalyst variant of Apple's iOS deployment target. + OpenHOS, + LastEnvironmentType = OpenHOS }; enum ObjectFormatType { UnknownObjectFormat, @@ -687,9 +689,19 @@ public: bool isMusl() const { return getEnvironment() == Triple::Musl || getEnvironment() == Triple::MuslEABI || - getEnvironment() == Triple::MuslEABIHF; + getEnvironment() == Triple::MuslEABIHF || + getEnvironment() == Triple::OpenHOS || + isOSLiteOS(); } + /// Tests whether the target is OHOS + /// LiteOS default enviroment is also OHOS, but omited on triple. + bool isOHOSFamily() const { return isOpenHOS() || isOSLiteOS(); } + + bool isOpenHOS() const { return getEnvironment() == Triple::OpenHOS; } + + bool isOSLiteOS() const { return getOS() == Triple::LiteOS; } + /// Tests whether the target is SPIR (32- or 64-bit). bool isSPIR() const { return getArch() == Triple::spir || getArch() == Triple::spir64; diff --git a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def index 543305feea77..c03a4f8fd9ea 100644 --- a/llvm/include/llvm/BinaryFormat/MinidumpConstants.def +++ b/llvm/include/llvm/BinaryFormat/MinidumpConstants.def @@ -115,6 +115,7 @@ HANDLE_MDMP_PLATFORM(0x8202, Solaris) // Solaris HANDLE_MDMP_PLATFORM(0x8203, Android) // Android HANDLE_MDMP_PLATFORM(0x8204, PS3) // PS3 HANDLE_MDMP_PLATFORM(0x8205, NaCl) // Native Client (NaCl) +HANDLE_MDMP_PLATFORM(0x8207, OpenHOS) HANDLE_MDMP_PROTECT(0x01, NoAccess, PAGE_NO_ACCESS) HANDLE_MDMP_PROTECT(0x02, ReadOnly, PAGE_READ_ONLY) diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h index 88c1452e5aa9..0f88c06d0fd4 100644 --- a/llvm/include/llvm/LTO/Config.h +++ b/llvm/include/llvm/LTO/Config.h @@ -51,6 +51,9 @@ struct Config { CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + unsigned SizeLevel = 0; + bool MergeFunctions = false; + bool DisableVerify = false; /// Use the new pass manager diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp index 78f2c642f96a..9cc8dcc00fdc 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -448,7 +448,6 @@ private: case SpillLocKind: { // Spills are indirect DBG_VALUEs, with a base register and offset. // Use the original DBG_VALUEs expression to build the spilt location - // on top of. FIXME: spill locations created before this pass runs // are not recognized, and not handled here. auto *TRI = MF.getSubtarget().getRegisterInfo(); auto Deref = Indirect ? DIExpression::DerefAfter : 0; diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 9103d11059e0..da8d5606865e 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -129,6 +129,8 @@ void llvm::computeLTOCacheKey( AddUnsigned(Conf.CGOptLevel); AddUnsigned(Conf.CGFileType); AddUnsigned(Conf.OptLevel); + AddUnsigned(Conf.SizeLevel); + AddUnsigned(Conf.MergeFunctions); AddUnsigned(Conf.UseNewPM); AddUnsigned(Conf.Freestanding); AddString(Conf.OptPipeline); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 1796d6ba60cc..b25191b16bd1 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -361,6 +361,9 @@ static void runOldPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, PMB.OptLevel = Conf.OptLevel; PMB.PGOSampleUse = Conf.SampleProfile; PMB.EnablePGOCSInstrGen = Conf.RunCSIRInstr; + PMB.MergeFunctions = Conf.MergeFunctions; + PMB.SizeLevel = Conf.SizeLevel; + if (!Conf.RunCSIRInstr && !Conf.CSIRProfile.empty()) { PMB.EnablePGOCSInstrUse = true; PMB.PGOInstrUse = Conf.CSIRProfile; diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp index 503a7bd49d15..1f07ee0e1a73 100644 --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -193,7 +193,7 @@ void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { bool AArch64::isX18ReservedByDefault(const Triple &TT) { return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() || - TT.isOSWindows(); + TT.isOSWindows() || TT.isOHOSFamily(); } // Allows partial match, ex. "v8a" matches "armv8a". diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp index eb425cbb1d25..cf7027cdd467 100644 --- a/llvm/lib/Support/ARMTargetParser.cpp +++ b/llvm/lib/Support/ARMTargetParser.cpp @@ -624,7 +624,7 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { default: if (TT.isOSNetBSD()) return "apcs-gnu"; - if (TT.isOSOpenBSD()) + if (TT.isOSOpenBSD() || TT.isOHOSFamily()) return "aapcs-linux"; return "aapcs"; } diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index 4f483c965282..c520d96db9fd 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -220,6 +220,8 @@ StringRef Triple::getOSTypeName(OSType Kind) { case WatchOS: return "watchos"; case Win32: return "windows"; case ZOS: return "zos"; + case LiteOS: + return "liteos"; } llvm_unreachable("Invalid OSType"); @@ -248,6 +250,8 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case MuslEABI: return "musleabi"; case MuslEABIHF: return "musleabihf"; case Simulator: return "simulator"; + case OpenHOS: + return "ohos"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -495,43 +499,44 @@ static Triple::VendorType parseVendor(StringRef VendorName) { static Triple::OSType parseOS(StringRef OSName) { return StringSwitch(OSName) - .StartsWith("ananas", Triple::Ananas) - .StartsWith("cloudabi", Triple::CloudABI) - .StartsWith("darwin", Triple::Darwin) - .StartsWith("dragonfly", Triple::DragonFly) - .StartsWith("freebsd", Triple::FreeBSD) - .StartsWith("fuchsia", Triple::Fuchsia) - .StartsWith("ios", Triple::IOS) - .StartsWith("kfreebsd", Triple::KFreeBSD) - .StartsWith("linux", Triple::Linux) - .StartsWith("lv2", Triple::Lv2) - .StartsWith("macos", Triple::MacOSX) - .StartsWith("netbsd", Triple::NetBSD) - .StartsWith("openbsd", Triple::OpenBSD) - .StartsWith("solaris", Triple::Solaris) - .StartsWith("win32", Triple::Win32) - .StartsWith("windows", Triple::Win32) - .StartsWith("zos", Triple::ZOS) - .StartsWith("haiku", Triple::Haiku) - .StartsWith("minix", Triple::Minix) - .StartsWith("rtems", Triple::RTEMS) - .StartsWith("nacl", Triple::NaCl) - .StartsWith("aix", Triple::AIX) - .StartsWith("cuda", Triple::CUDA) - .StartsWith("nvcl", Triple::NVCL) - .StartsWith("amdhsa", Triple::AMDHSA) - .StartsWith("ps4", Triple::PS4) - .StartsWith("elfiamcu", Triple::ELFIAMCU) - .StartsWith("tvos", Triple::TvOS) - .StartsWith("watchos", Triple::WatchOS) - .StartsWith("mesa3d", Triple::Mesa3D) - .StartsWith("contiki", Triple::Contiki) - .StartsWith("amdpal", Triple::AMDPAL) - .StartsWith("hermit", Triple::HermitCore) - .StartsWith("hurd", Triple::Hurd) - .StartsWith("wasi", Triple::WASI) - .StartsWith("emscripten", Triple::Emscripten) - .Default(Triple::UnknownOS); + .StartsWith("ananas", Triple::Ananas) + .StartsWith("cloudabi", Triple::CloudABI) + .StartsWith("darwin", Triple::Darwin) + .StartsWith("dragonfly", Triple::DragonFly) + .StartsWith("freebsd", Triple::FreeBSD) + .StartsWith("fuchsia", Triple::Fuchsia) + .StartsWith("ios", Triple::IOS) + .StartsWith("kfreebsd", Triple::KFreeBSD) + .StartsWith("linux", Triple::Linux) + .StartsWith("lv2", Triple::Lv2) + .StartsWith("macos", Triple::MacOSX) + .StartsWith("netbsd", Triple::NetBSD) + .StartsWith("openbsd", Triple::OpenBSD) + .StartsWith("solaris", Triple::Solaris) + .StartsWith("win32", Triple::Win32) + .StartsWith("windows", Triple::Win32) + .StartsWith("zos", Triple::ZOS) + .StartsWith("haiku", Triple::Haiku) + .StartsWith("minix", Triple::Minix) + .StartsWith("rtems", Triple::RTEMS) + .StartsWith("nacl", Triple::NaCl) + .StartsWith("aix", Triple::AIX) + .StartsWith("cuda", Triple::CUDA) + .StartsWith("nvcl", Triple::NVCL) + .StartsWith("amdhsa", Triple::AMDHSA) + .StartsWith("ps4", Triple::PS4) + .StartsWith("elfiamcu", Triple::ELFIAMCU) + .StartsWith("tvos", Triple::TvOS) + .StartsWith("watchos", Triple::WatchOS) + .StartsWith("mesa3d", Triple::Mesa3D) + .StartsWith("contiki", Triple::Contiki) + .StartsWith("amdpal", Triple::AMDPAL) + .StartsWith("hermit", Triple::HermitCore) + .StartsWith("hurd", Triple::Hurd) + .StartsWith("wasi", Triple::WASI) + .StartsWith("emscripten", Triple::Emscripten) + .StartsWith("liteos", Triple::LiteOS) + .Default(Triple::UnknownOS); } static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { @@ -556,6 +561,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("coreclr", Triple::CoreCLR) .StartsWith("simulator", Triple::Simulator) .StartsWith("macabi", Triple::MacABI) + .StartsWith("ohos", Triple::OpenHOS) .Default(Triple::UnknownEnvironment); } diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp index b7dd757a8af3..9b616ae6f232 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.cpp @@ -526,8 +526,8 @@ static const char *getRegisterName(unsigned RegNum) { {0x2e09, "COMPUTE_NUM_THREAD_Z"}, {0xa2db, "VGT_TF_PARAM"}, {0xa2d6, "VGT_LS_HS_CONFIG"}, - {0xa287, "VGT_HOS_MIN_TESS_LEVEL"}, - {0xa286, "VGT_HOS_MAX_TESS_LEVEL"}, + {0xa287, "VGT_OHOS_MIN_TESS_LEVEL"}, + {0xa286, "VGT_OHOS_MAX_TESS_LEVEL"}, {0xa2f8, "PA_SC_AA_CONFIG"}, {0xa310, "PA_SC_SHADER_CONTROL"}, {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"}, diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index fd9b94fdaa23..e124cfe2373a 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -762,7 +762,8 @@ public: } bool isTargetMuslAEABI() const { return (TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && !isTargetDarwin() && !isTargetWindows(); } @@ -775,13 +776,14 @@ public: TargetTriple.getEnvironment() == Triple::EABIHF || TargetTriple.getEnvironment() == Triple::GNUEABIHF || TargetTriple.getEnvironment() == Triple::MuslEABIHF || - isTargetAndroid()) && + isTargetAndroid() || isTargetOHOSFamily()) && !isTargetDarwin() && !isTargetWindows(); } bool isTargetHardFloat() const; bool isTargetAndroid() const { return TargetTriple.isAndroid(); } + bool isTargetOHOSFamily() const { return TargetTriple.isOHOSFamily(); } bool isXRaySupported() const override; diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 237ef54c8339..e6b085dd4571 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -234,7 +234,8 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT, if ((TargetTriple.getEnvironment() == Triple::GNUEABI || TargetTriple.getEnvironment() == Triple::GNUEABIHF || TargetTriple.getEnvironment() == Triple::MuslEABI || - TargetTriple.getEnvironment() == Triple::MuslEABIHF) && + TargetTriple.getEnvironment() == Triple::MuslEABIHF || + TargetTriple.getEnvironment() == Triple::OpenHOS) && !(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin())) this->Options.EABIVersion = EABI::GNU; else diff --git a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll index 89fc6457482f..0ea2e20cfa52 100644 --- a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll +++ b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll @@ -2,6 +2,7 @@ ; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-android -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-linux-ohos -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi.ll b/llvm/test/Transforms/SafeStack/AArch64/abi.ll index bd6710d160c5..45961b767180 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi.ll @@ -1,8 +1,10 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOS define void @foo() nounwind uwtable safestack { entry: +; OHOS-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll index c78b20aaa01a..9069ea50a4d5 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/abi_ssp.ll @@ -1,4 +1,5 @@ ; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefixes=TLS,ANDROID %s +; RUN: opt -safe-stack -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck --check-prefix=OHOS %s ; RUN: opt -safe-stack -S -mtriple=aarch64-unknown-fuchsia < %s -o - | FileCheck --check-prefixes=TLS,FUCHSIA %s define void @foo() nounwind uwtable safestack sspreq { @@ -6,6 +7,7 @@ entry: ; The first @llvm.thread.pointer is for the unsafe stack pointer, skip it. ; TLS: call i8* @llvm.thread.pointer() +; OHOS-NOT: call i8* @llvm.thread.pointer() ; TLS: %[[TP2:.*]] = call i8* @llvm.thread.pointer() ; ANDROID: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40 ; FUCHSIA: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 -16 diff --git a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll index 53ed690ebb09..7009fce7a4a4 100644 --- a/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll +++ b/llvm/test/Transforms/SafeStack/AArch64/unreachable.ll @@ -1,7 +1,9 @@ ; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-android < %s -o - | FileCheck %s +; RUN: opt -safe-stack -safe-stack-coloring -S -mtriple=aarch64-linux-ohos < %s -o - | FileCheck %s --check-prefix=OHOSMUSL define void @foo() nounwind uwtable safestack { entry: +; OHOSMUSL-NOT: call i8* @llvm.thread.pointer() ; CHECK: %[[TP:.*]] = call i8* @llvm.thread.pointer() ; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72 ; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8** diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 949c5e694db7..d96b5de5027b 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -11,7 +11,7 @@ from lit.llvm.subst import ToolSubst lit_path_displayed = False -class LLVMConfig(object): +class LLVMConfig (object): def __init__(self, lit_config, config): self.lit_config = lit_config @@ -62,6 +62,8 @@ class LLVMConfig(object): features.add('system-windows') elif platform.system() == 'Linux': features.add('system-linux') + if os.path.exists('/.dockerenv'): + features.add('ohos-ci') elif platform.system() in ['FreeBSD']: features.add('system-freebsd') elif platform.system() == 'NetBSD': diff --git a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h index f1319c7f2e29..bcd18572cf3d 100644 --- a/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h +++ b/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h @@ -74,6 +74,9 @@ # if defined __ANDROID__ # define GTEST_OS_LINUX_ANDROID 1 # endif +# if defined __OHOS_FAMILY__ +# define GTEST_OS_LINUX_OHOS_FAMILY 1 +# endif #elif defined __MVS__ # define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) diff --git a/llvm/utils/unittest/googletest/src/gtest-port.cc b/llvm/utils/unittest/googletest/src/gtest-port.cc index 6aeef4957cf5..6135ffdcb486 100644 --- a/llvm/utils/unittest/googletest/src/gtest-port.cc +++ b/llvm/utils/unittest/googletest/src/gtest-port.cc @@ -954,7 +954,7 @@ class CapturedStream { // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. -# if GTEST_OS_LINUX_ANDROID +# if GTEST_OS_LINUX_ANDROID || GTEST_OS_LINUX_OHOS_FAMILY // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index 87e91a0f8d10..a9256cf3da6a 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -54,9 +54,8 @@ #define KMP_CANCEL_THREADS #define KMP_THREAD_ATTR -// Android does not have pthread_cancel. Undefine KMP_CANCEL_THREADS if being // built on Android -#if defined(__ANDROID__) +#if defined(__ANDROID__) || defined(__OHOS__) #undef KMP_CANCEL_THREADS #endif diff --git a/openmp/runtime/src/kmp_i18n.cpp b/openmp/runtime/src/kmp_i18n.cpp index d2651cfabdf3..507d1a19955d 100644 --- a/openmp/runtime/src/kmp_i18n.cpp +++ b/openmp/runtime/src/kmp_i18n.cpp @@ -709,7 +709,8 @@ static char *sys_error(int err) { #if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || \ (defined(__BIONIC__) && defined(_GNU_SOURCE) && \ - __ANDROID_API__ >= __ANDROID_API_M__) + __ANDROID_API__ >= __ANDROID_API_M__) || \ + (defined(__OHOS__) && defined(_GNU_SOURCE)) // GNU version of strerror_r. char buffer[2048]; diff --git a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp index 3eb28607e462..cae7e885bb42 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/depend.cpp @@ -1,7 +1,7 @@ // RUN: %libomp-cxx-compile-and-run +// UNSUPPORTED: ohos-ci -/* - * This test aims to check whether hidden helper task can work with regular task +/* This test aims to check whether hidden helper task can work with regular task * in terms of dependences. It is equivalent to the following code: * * #pragma omp parallel diff --git a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp index d5af89553caf..6819db432463 100644 --- a/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp +++ b/openmp/runtime/test/tasking/hidden_helper_task/gtid.cpp @@ -41,7 +41,9 @@ struct anon { }; } -kmp_int32 __kmp_hidden_helper_threads_num; +// OHOS specific: we use static libomp and get link error on this symbol +// probably push this to mainline +__attribute__((weak)) kmp_int32 __kmp_hidden_helper_threads_num; kmp_int32 omp_task_entry(kmp_int32 gtid, kmp_task_t_with_privates *task) { auto shareds = reinterpret_cast(task->task.shareds); -- Gitee From c4dcef655120dd5714cd19494ae30744819347b4 Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Sun, 3 Jul 2022 16:40:20 +0800 Subject: [PATCH 14/19] Add cpython-mingw prebuilts building script to support lldb-mi Signed-off-by: liwentao Change-Id: I418c8faf8b7253761020e37980f89dae1704f80d --- llvm-build/build_cpython-mingw.sh | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 llvm-build/build_cpython-mingw.sh diff --git a/llvm-build/build_cpython-mingw.sh b/llvm-build/build_cpython-mingw.sh new file mode 100755 index 000000000000..570741b720bc --- /dev/null +++ b/llvm-build/build_cpython-mingw.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +PROJECT_ROOT=$(pwd) +CPYTHON_MINGW_SRC=${PROJECT_ROOT}/third_party/python +MINGW_W64_SRC=${PROJECT_ROOT}/third_party/mingw-w64 + +# prepare SYSROOT for cpython-mingw build +CLANG_MINGW_BUILD=${PROJECT_ROOT}/out/clang_mingw +python3 ${PROJECT_ROOT}/toolchain/llvm-build/mingw.py + +# refreash cpython-mingw config +cd ${CPYTHON_MINGW_SRC} +cat ./patchs/cpython_mingw_v3.10.2.patch | patch -d ./ -p1 -E +rm -rf ${CPYTHON_MINGW_SRC}/configure +autoconf ${CPYTHON_MINGW_SRC}/configure.ac > ${CPYTHON_MINGW_SRC}/configure +chmod 777 ${CPYTHON_MINGW_SRC}/configure +./configure + +# # prepare build config and build libpython for cpython-mingw +CPYTHON_MINGW_BUILD=${PROJECT_ROOT}/out/cpython-mingw-build +mkdir -p ${CPYTHON_MINGW_BUILD} +cd ${CPYTHON_MINGW_BUILD} +MINGW_PREFIX=${CPYTHON_MINGW_BUILD}/mingw64 +MINGW_CHOST=x86_64-w64-mingw32 +MINGW_BUILD=x86_64-unknown-linux-gnu +TOOLCHAIN_ROOT=${CLANG_MINGW_BUILD}/clang-10.0.1/bin +SYSROOT=${CLANG_MINGW_BUILD}/clang-10.0.1/x86_64-w64-mingw32 +mkdir $MINGW_BUILD + +export CC=$TOOLCHAIN_ROOT/clang +export CXX=$TOOLCHAIN_ROOT/clang++ +export CFLAGS="-target ${MINGW_CHOST} --sysroot=$SYSROOT" +export LDFLAGS="--sysroot=$SYSROOT -rtlib=compiler-rt -target ${MINGW_CHOST} -lucrt -lucrtbase -fuse-ld=lld" + +${CPYTHON_MINGW_SRC}/configure \ + --prefix=${MINGW_PREFIX} \ + --host=${MINGW_CHOST} \ + --build=${MINGW_BUILD} \ + --enable-shared \ + --enable-static \ + --without-ensurepip \ + --without-c-locale-coercion \ + --enable-loadable-sqlite-extensions + +make -j4 + +# copy build result to mingw-w64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll.a ${MINGW_W64_SRC}/mingw-w64-crt/lib64 +cp ${CPYTHON_MINGW_BUILD}/libpython3.10.dll ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cd ../.. + +# example steps to install autoconf 2.71 +# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz +# export PATH=/mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/bin:$PATH +# sudo cp -r /mnt/disk2/liwentao/workspace/tools/autoconf/autoconf-2.71/lib /usr/local/share/autoconf + +# refreash configure and Makefile for mingw-w64 +# you need autoconf (2.69 for Ubuntu 20.04 LTS apt install, to support mingw-w64 9.x and later version, please install autoconf 2.71 http://ftp.gnu.org/gnu/autoconf/) +# and automake (1.16.1 for Ubuntu 20.04 LTS apt install) +cd ${MINGW_W64_SRC}/mingw-w64-crt +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +cd ${MINGW_W64_SRC}/mingw-w64-headers +rm -rf configure +autoconf configure.ac > configure +chmod 777 configure + +aclocal +automake + +# move cpython-mingw build result and python header file to mingw-w64 +cp -r ${CPYTHON_MINGW_SRC}/Include ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +cp ${CPYTHON_MINGW_SRC}/pyconfig.h ${MINGW_W64_SRC}/mingw-w64-headers/include/python3.10 +mkdir -p ${MINGW_W64_SRC}/mingw-w64-python/3.10 +cp -r ${CPYTHON_MINGW_SRC}/Lib ${MINGW_W64_SRC}/mingw-w64-python/3.10/lib \ No newline at end of file -- Gitee From a7c9aeb166fa293095eda228abe3ae24ba9ca293 Mon Sep 17 00:00:00 2001 From: liuyaning6 Date: Mon, 11 Jul 2022 15:55:53 +0800 Subject: [PATCH 15/19] add llvm-build for openharmony in README.md Signed-off-by: liuyaning6 Change-Id: If28e22d232f9dede040fcfb4a698304d3178dd61 --- README.md | 2 ++ README_zh.md | 7 ++++++- llvm-build/README.md | 4 ++-- llvm-build/toolchain_readme.md | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6e02ee378eb3..21370584c1c7 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,5 @@ Consult the page for detailed information on configuring and compiling LLVM. You can visit [Directory Layout](https://llvm.org/docs/GettingStarted.html#directory-layout) to learn about the layout of the source code tree. + +For the llvm construction of openharmony, please refer to [llvm-build](https://gitee.com/openharmony-sig/third_party_llvm-project/tree/llvmorg-12.0.1-dev/llvm-build). \ No newline at end of file diff --git a/README_zh.md b/README_zh.md index f58d9cd8a031..c5e7574ec922 100644 --- a/README_zh.md +++ b/README_zh.md @@ -20,6 +20,8 @@ LLVM项目有多个组件。该项目的核心本身被称为“LLVM”。这包 ### 获取源代码并构建LLVM +在OpenHarmony中,我们建议您基于[llvm-build](https://gitee.com/openharmony-sig/third_party_llvm-project/blob/master/llvm-build/README.md)的指导获取源码并进行构建。 + LLVM入门文档可能已过期。[Clang入门](https://clang.llvm.org/get_started.html) 页面可能有更准确的信息。 这是获取和构建LLVM源的示例工作流和配置: @@ -67,4 +69,7 @@ LLVM入门文档可能已过期。[Clang入门](https://clang.llvm.org/get_start - 有关详细信息,请参阅 [CMake](https://llvm.org/docs/CMake.html) -请参阅 [LLVM入门](https://llvm.org/docs/GettingStarted.html#getting-started-with-llvm) 页面,了解有关配置和编译LLVM的详细信息。您可以访问 [目录布局](https://llvm.org/docs/GettingStarted.html#directory-layout) 以了解源代码树的布局。 \ No newline at end of file +请参阅 [LLVM入门](https://llvm.org/docs/GettingStarted.html#getting-started-with-llvm) 页面,了解有关配置和编译LLVM的详细信息。您可以访问 [目录布局](https://llvm.org/docs/GettingStarted.html#directory-layout) 以了解源代码树的布局。 + +有关Openharmony的llvm构建请参考[llvm-build](https://gitee.com/openharmony-sig/third_party_llvm-project/tree/llvmorg-12.0.1-dev/llvm-build)。 + diff --git a/llvm-build/README.md b/llvm-build/README.md index ded1748c725c..e12de6c793fa 100644 --- a/llvm-build/README.md +++ b/llvm-build/README.md @@ -32,7 +32,7 @@ Here is an example of starting build process on Linux or MacOS: # update prebuilts, no need to run each time ./toolchain/llvm-project/llvm-build/env_prepare.sh # build -python3 ./toolchain/llvm-project/llvm-build/build.py +python3 ./toolchain/llvm-build/build.py ``` 1. env_prepare (one time only) @@ -108,7 +108,7 @@ License: Apache License v2.0 with LLVM Exceptions ### Functionality -The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 10.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html).
    ### Specifically Included Triplets diff --git a/llvm-build/toolchain_readme.md b/llvm-build/toolchain_readme.md index 441305ead76d..eb042745aa11 100644 --- a/llvm-build/toolchain_readme.md +++ b/llvm-build/toolchain_readme.md @@ -4,7 +4,8 @@ This readme briefly describes the functionality of our LLVM toolchain and what w ## Functionality -The LLVM toolchain is built based on LLVM 10.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 10.0.1, please refer to [LLVM 10.0.1](https://lists.llvm.org/pipermail/llvm-announce/2020-August/000088.html). +The LLVM toolchain is built based on LLVM 12.0.1. It is used to provide capability of building ohos image. For detailed information about LLVM 12.0.1, please refer to [LLVM 12.0.1](https://lists.llvm.org/pipermail/llvm-announce/2021-July/000093.html). +
    ## Specifically Included Triplets -- Gitee From bd2e36753d71e5306ca5748a206d7d8eb9d37c4b Mon Sep 17 00:00:00 2001 From: xwx1135370 Date: Tue, 5 Jul 2022 12:46:55 +0800 Subject: [PATCH 16/19] Fport rm message sent by lldb to hdc does not match fport Signed-off-by: xwx1135370 Change-Id: If76cf7bea7d702330497984572c9355691ee036c --- .../Plugins/Platform/OHOS/HdcClient.cpp | 22 ++++++- lldb/source/Plugins/Platform/OHOS/HdcClient.h | 3 + .../OHOS/PlatformOHOSRemoteGDBServer.cpp | 65 +++++++++++++++---- .../OHOS/PlatformOHOSRemoteGDBServer.h | 1 + 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp index 97fa08fb44da..6807d24cf317 100644 --- a/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.cpp @@ -235,7 +235,27 @@ Status HdcClient::DeletePortForwarding(std::pair fwd) { if (error.Fail()) return error; - return ReadResponseStatus(nullptr); + return ReadResponseStatus("Remove forward ruler success"); +} + +Status HdcClient::DeletePortForwarding(const uint16_t local_port, + const std::string remote_socket_name, + const UnixSocketNamespace socket_namespace) { + const char *sock_namespace_str = + (socket_namespace == UnixSocketNamespaceAbstract) + ? kSocketNamespaceAbstract + : kSocketNamespaceFileSystem; + char message[PATH_MAX] = ""; + + snprintf(message, sizeof(message), "fport rm tcp:%d %s:%s", local_port, + sock_namespace_str, remote_socket_name.c_str()); + + const auto error = SendMessage(message); + if (error.Fail()){ + return error; + } + + return ReadResponseStatus("Remove forward ruler success"); } Status HdcClient::TransferFile(const char *direction, const FileSpec &src, diff --git a/lldb/source/Plugins/Platform/OHOS/HdcClient.h b/lldb/source/Plugins/Platform/OHOS/HdcClient.h index 64a5a324325a..39b6569b447a 100644 --- a/lldb/source/Plugins/Platform/OHOS/HdcClient.h +++ b/lldb/source/Plugins/Platform/OHOS/HdcClient.h @@ -51,6 +51,9 @@ public: const UnixSocketNamespace socket_namespace); Status DeletePortForwarding(std::pair fwd); + + Status DeletePortForwarding(const uint16_t local_port, const std::string remote_socket_name, + const UnixSocketNamespace socket_namespace); Status RecvFile(const FileSpec &src, const FileSpec &dst); diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp index 62dc0639afef..b4e9f40407c1 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.cpp @@ -70,6 +70,23 @@ static Status DeleteForwardPortWithHdc(std::pair ports, return hdc.DeletePortForwarding(ports); } +static Status DeleteForwardPortWithHdc(std::pair remote_socket, + const llvm::Optional &socket_namespace, + const std::string &device_id) { + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); + uint16_t local_port = remote_socket.first; + std::string remote_socket_name = remote_socket.second; + if (log) + log->Printf("Delete port forwarding %d -> %s, device=%s", local_port, + remote_socket_name.c_str(), device_id.c_str()); + if (!socket_namespace) + return Status("Invalid socket namespace"); + + HdcClient hdc(device_id); + return hdc.DeletePortForwarding(local_port, remote_socket_name, *socket_namespace); +} + static Status FindUnusedPort(uint16_t &port) { Status error; @@ -93,8 +110,12 @@ static Status FindUnusedPort(uint16_t &port) { PlatformOHOSRemoteGDBServer::PlatformOHOSRemoteGDBServer() {} PlatformOHOSRemoteGDBServer::~PlatformOHOSRemoteGDBServer() { - for (const auto &it : m_port_forwards) + for (const auto &it : m_port_forwards) { DeleteForwardPortWithHdc(it.second, m_device_id); + } + for (const auto &it_socket : m_remote_socket_name) { + DeleteForwardPortWithHdc(it_socket.second, m_socket_namespace, m_device_id); + } } bool PlatformOHOSRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid, @@ -173,19 +194,30 @@ void PlatformOHOSRemoteGDBServer::DeleteForwardPort(lldb::pid_t pid) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); auto it = m_port_forwards.find(pid); - if (it == m_port_forwards.end()) - return; - - const auto port = it->second; - const auto error = DeleteForwardPortWithHdc(port, m_device_id); - if (error.Fail()) { - if (log) - log->Printf("Failed to delete port forwarding (pid=%" PRIu64 - ", fwd=(%d -> %d), device=%s): %s", - pid, port.first, port.second, m_device_id.c_str(), - error.AsCString()); + auto it_socket = m_remote_socket_name.find(pid); + if (it != m_port_forwards.end() && it->second.second != 0) { + const auto error = DeleteForwardPortWithHdc(it->second, m_device_id); + if (error.Fail()) { + if (log) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", fwd=(%d -> %d), device=%s): %s", + pid, it->second.first, it->second.second, m_device_id.c_str(), + error.AsCString()); + } + m_port_forwards.erase(it); + } + + if(it_socket != m_remote_socket_name.end()) { + const auto error_Socket = DeleteForwardPortWithHdc(it_socket->second, m_socket_namespace, m_device_id); + if (error_Socket.Fail()) { + if (log) + log->Printf("Failed to delete port forwarding (pid=%" PRIu64 + ", fwd=(%d->%s)device=%s): %s", pid, it_socket->second.first, it_socket->second.second.c_str(), m_device_id.c_str(),error_Socket.AsCString()); + } + m_remote_socket_name.erase(it_socket); } - m_port_forwards.erase(it); + + return; } Status PlatformOHOSRemoteGDBServer::MakeConnectURL( @@ -206,7 +238,12 @@ Status PlatformOHOSRemoteGDBServer::MakeConnectURL( error = ForwardPortWithHdc(local_port, remote_port, remote_socket_name, m_socket_namespace, m_device_id); if (error.Success()) { - m_port_forwards[pid] = {local_port, remote_port}; + if (remote_port != 0){ + m_port_forwards[pid] = {local_port, remote_port}; + } + else{ + m_remote_socket_name[pid] ={local_port, remote_socket_name.str()}; + } std::ostringstream url_str; url_str << "connect://localhost:" << local_port; connect_url = url_str.str(); diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h index f9818589275d..680ddc1e733c 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOSRemoteGDBServer.h @@ -41,6 +41,7 @@ public: protected: std::string m_device_id; std::map> m_port_forwards; + std::map> m_remote_socket_name; llvm::Optional m_socket_namespace; bool LaunchGDBServer(lldb::pid_t &pid, std::string &connect_url) override; -- Gitee From 90d8f82a9f5342fbaa7feb8b380faa4decc5cbad Mon Sep 17 00:00:00 2001 From: liwentao_uiw Date: Sun, 10 Jul 2022 21:45:59 +0800 Subject: [PATCH 17/19] [BUILD] Refactor env prepare script for downloading (refer prebuilts_download.sh for OpenHarmony) Signed-off-by: liwentao Change-Id: If175c0f449689f232624804d1957a380cfc52726 --- llvm-build/env_prepare.sh | 142 +++++++++++++++++++++++++++++++++----- 1 file changed, 124 insertions(+), 18 deletions(-) diff --git a/llvm-build/env_prepare.sh b/llvm-build/env_prepare.sh index 0cc61592e361..527c69a51fd9 100755 --- a/llvm-build/env_prepare.sh +++ b/llvm-build/env_prepare.sh @@ -1,18 +1,124 @@ -llvm_name=llvm -cmake_name=linux-x86 -clang_name=clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04 -llvm_dir=clang/ohos/linux-x86_64 -cmake_dir=cmake -cd prebuilts -mkdir -p $llvm_dir -mkdir -p $cmake_dir - -wget https://mirrors.huaweicloud.com/harmonyos/compiler/clang/10.0.1-62608/linux/llvm.tar.gz -wget https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/linux/cmake-linux-x86-3.16.5.tar.gz -#wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz -tar -xvf llvm.tar.gz -tar -xvf cmake-linux-x86-3.16.5.tar.gz -tar -xvf clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz -mv $llvm_name $llvm_dir/llvm -mv $cmake_name $cmake_dir/linux-x86 -mv $clang_name $llvm_dir/clang-10.0.1 +case $(uname -s) in + Linux) + + host_platform=linux + ;; + Darwin) + host_platform=darwin + ;; + *) + echo "Unsupported host platform: $(uname -s)" + exit 1 +esac + +case $(uname -m) in + arm64) + + host_cpu=arm64 + ;; + *) + host_cpu=x86_64 +esac + +# sync code directory +code_dir=$(pwd) + +# downloaded files will be automatically unzipped under this path +bin_dir=${code_dir}/download_packages + +# download and initialize prebuild files +if [ ! -d "${bin_dir}" ];then + mkdir -p "${bin_dir}" +fi + + +function download_and_archive() { + archive_dir=$1 + download_source_url=$2 + bin_file=$(basename ${download_source_url}) + #wget -t3 -T10 -O "${bin_dir}/${bin_file}" "${download_source_url}" + if [ ! -d "${code_dir}/${archive_dir}" ];then + mkdir -p "${code_dir}/${archive_dir}" + fi + if [ "X${bin_file:0-3}" = "Xzip" ];then + unzip -o "${bin_dir}/${bin_file}" -d "${code_dir}/${archive_dir}/" + elif [ "X${bin_file:0-6}" = "Xtar.gz" ];then + tar -xvzf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + else + tar -xvf "${bin_dir}/${bin_file}" -C "${code_dir}/${archive_dir}" + fi +} + + +copy_config=""" +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://mirrors.huaweicloud.com/openharmony/compiler/clang/12.0.1-530132/${host_platform}/clang-530132-${host_platform}-x86_64.tar.bz2 +""" + +copy_config_linux_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +""" + +copy_config_darwin_x86_64=""" +prebuilts/cmake,https://mirrors.huaweicloud.com/harmonyos/compiler/cmake/3.16.5/${host_platform}/cmake-${host_platform}-x86-3.16.5.tar.gz +prebuilts/clang/ohos/${host_platform}-${host_cpu},https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.1/clang+llvm-10.0.1-x86_64-apple-darwin.tar.xz +""" + +# +if [[ "${host_platform}" == "linux" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_linux_x86_64} + echo "add ubuntu here" + else + echo "unknwon host_cpu - ${host_cpu} for linux" + fi +elif [[ "${host_platform}" == "darwin" ]]; then + if [[ "${host_cpu}" == "x86_64" ]]; then + copy_config+=${copy_config_darwin_x86_64} + echo "add x86-64 mac here" + elif [[ "${host_cpu}" == "arm64" ]]; then + echo "add m1 config here" + else + echo "unknwon host_cpu - ${host_cpu} for darwin" + fi +else + echo "unknown ${host_platform}" +fi + + + +for i in $(echo ${copy_config}) +do + unzip_dir=$(echo $i|awk -F ',' '{print $1}') + remote_url=$(echo $i|awk -F ',' '{print $2}') + download_and_archive "${unzip_dir}" "${remote_url}" +done + + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-530132" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-530132" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm" + ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/linux-x86_64/llvm/lib/clang/current" +fi + +if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-${host_cpu}/clang-530132" ];then + if [[ "${host_cpu}" == "arm64" ]]; then + rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm" + mv "${code_dir}/prebuilts/clang/ohos/darwin-arm64/clang-530132" "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm" + ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/darwin-arm64/llvm/lib/clang/current" + else + rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm" + mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-530132" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm" + ln -snf 12.0.1 "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/llvm/lib/clang/current" + fi +fi + +if [ -d "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-gnu-ubuntu-16.04.tar.xz" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang+llvm-10.0.1-x86_64-gnu-ubuntu-16.04" "${code_dir}/prebuilts/clang/ohos/linux-x86_64/clang-10.0.1" +fi + +if [ -d "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-10.0.1-x86_64-apple-darwin" ];then + rm -rf "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" + mv "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang+llvm-10.0.1-x86_64-apple-darwin" "${code_dir}/prebuilts/clang/ohos/darwin-x86_64/clang-10.0.1" +fi -- Gitee From a4ac5794e1cb96f600dbfd63c3528ebcb467b660 Mon Sep 17 00:00:00 2001 From: liwentao Date: Mon, 25 Jul 2022 02:39:46 +0000 Subject: [PATCH 18/19] !22 Add support for x86_64-linux-ohos target and m1 build, add some lldb bugfixs Author: @Anton @Pavel @Leviant @Nikolai Signed-off-by: liwentao Change-Id: I905afefabce1553349bd84ce3a5280d400ae4fe1 --- clang/lib/Driver/ToolChains/Gnu.cpp | 3 +- clang/test/Driver/ohos.c | 2 + clang/test/Preprocessor/ohos.c | 2 + compiler-rt/lib/asan/asan_malloc_linux.cpp | 4 +- .../sanitizer_platform_limits_posix.cpp | 2 +- lldb/include/lldb/Target/Platform.h | 2 + .../Plugins/Platform/OHOS/PlatformOHOS.cpp | 43 +++++++++--- .../Plugins/Platform/OHOS/PlatformOHOS.h | 7 +- .../Process/Utility/InferiorCallPOSIX.cpp | 5 +- lldb/source/Target/Platform.cpp | 4 ++ llvm-build/Makefile | 10 ++- llvm-build/build.py | 67 ++++++++++++------- llvm-build/build_musl.sh | 7 +- 13 files changed, 113 insertions(+), 45 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 4106cd9cfa68..cbd64e597976 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -2105,7 +2105,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "x86_64-redhat-linux", "x86_64-suse-linux", "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", "x86_64-unknown-linux", - "x86_64-amazon-linux", "x86_64-linux-android"}; + "x86_64-amazon-linux", "x86_64-linux-android", + "x86_64-linux-ohos"}; static const char *const X32LibDirs[] = {"/libx32"}; static const char *const X86LibDirs[] = {"/lib32", "/lib"}; static const char *const X86Triples[] = { diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c index 170c0da0ce06..e20d6bfd2177 100644 --- a/clang/test/Driver/ohos.c +++ b/clang/test/Driver/ohos.c @@ -56,6 +56,8 @@ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // RUN: %clang %s -### --target=aarch64-linux-ohos -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME +// RUN: %clang %s -### --target=x86_64-linux-ohos -fuse-ld=lld 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-RUNTIME // CHECK-RUNTIME: "{{.*}}/libclang_rt.builtins.a" // CHECK-RUNTIME: "-l:libunwind.a" // CHECK-LIBM: "-lm" diff --git a/clang/test/Preprocessor/ohos.c b/clang/test/Preprocessor/ohos.c index bd1060133c4e..9c3a81bbceed 100644 --- a/clang/test/Preprocessor/ohos.c +++ b/clang/test/Preprocessor/ohos.c @@ -1,11 +1,13 @@ // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM-OHOS-CXX // RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=aarch64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=ARM64-OHOS-CXX +// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=x86_64-linux-ohos < /dev/null | FileCheck %s -match-full-lines -check-prefix=X86_64-OHOS-CXX // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-linux-ohos < /dev/null | FileCheck %s -check-prefix=OHOS-DEFS // ARM-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U // ARM-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U // ARM64-HOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // ARM64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// X86_64-OHOS-CXX: #define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // OHOS-DEFS: __OHOS_FAMILY__ // OHOS-DEFS: __OHOS__ // OHOS-DEFS-NOT: __OHOS__ diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp index 9c3f0a5338ee..ca45b86e1aa1 100644 --- a/compiler-rt/lib/asan/asan_malloc_linux.cpp +++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp @@ -243,7 +243,7 @@ INTERCEPTOR(void, malloc_stats, void) { __asan_print_accumulated_stats(); } -#if SANITIZER_ANDROID +#if SANITIZER_BIONIC // Format of __libc_malloc_dispatch has changed in Android L. // While we are moving towards a solution that does not depend on bionic // internals, here is something to support both K* and L releases. @@ -295,7 +295,7 @@ void ReplaceSystemMalloc() { } } // namespace __asan -#else // SANITIZER_ANDROID +#else // SANITIZER_BIONIC namespace __asan { void ReplaceSystemMalloc() { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index c4a1b2807a84..a31947c08016 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -98,7 +98,6 @@ // Do not include asm/sigcontext.h on behalf of asm/ptrace.h // to avoid multiple definiton errors. #define __ASM_SIGCONTEXT_H 1 -#include #endif #if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ @@ -143,6 +142,7 @@ typedef struct user_fpregs elf_fpregset_t; #if SANITIZER_ANDROID #include #elif SANITIZER_OHOS +#include #include #include #include diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index df46466655c3..d83f54ca62bc 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -580,6 +580,8 @@ public: virtual Status Unlink(const FileSpec &file_spec); + virtual ConstString GetMmapSymbolName(const ArchSpec &arch); + virtual MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, lldb::addr_t length, diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp index f76e016bb6aa..249cd5e9d801 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.cpp @@ -1,4 +1,4 @@ -//===-- PlatformOHOS.cpp -------------------------------------*- C++ -*-===// +//===-- PlatformOHOS.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Config/config.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" @@ -30,13 +31,13 @@ static uint32_t g_initialize_count = 0; static const unsigned int g_ohos_default_cache_size = 2048; // Fits inside 4k adb packet. -LLDB_PLUGIN_DEFINE(PlatformOHOS); +LLDB_PLUGIN_DEFINE(PlatformOHOS) void PlatformOHOS::Initialize() { PlatformLinux::Initialize(); if (g_initialize_count++ == 0) { -#if defined(__OHOS_FAMILY__) +#if defined(__OHOS__) PlatformSP default_platform_sp(new PlatformOHOS(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); Platform::SetHostPlatform(default_platform_sp); @@ -112,7 +113,8 @@ PlatformSP PlatformOHOS::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -PlatformOHOS::PlatformOHOS(bool is_host) : PlatformLinux(is_host) {} +PlatformOHOS::PlatformOHOS(bool is_host) + : PlatformLinux(is_host), m_sdk_version(0) {} PlatformOHOS::~PlatformOHOS() {} @@ -128,9 +130,9 @@ ConstString PlatformOHOS::GetPluginNameStatic(bool is_host) { const char *PlatformOHOS::GetPluginDescriptionStatic(bool is_host) { if (is_host) - return "Local OpenHarmony OS user platform plug-in."; + return "Local Open HarmonyOS user platform plug-in."; else - return "Remote OpenHarmony OS user platform plug-in."; + return "Remote Open HarmonyOS user platform plug-in."; } ConstString PlatformOHOS::GetPluginName() { @@ -216,8 +218,10 @@ Status PlatformOHOS::DownloadModuleSlice(const FileSpec &src_file_spec, Status PlatformOHOS::DisconnectRemote() { Status error = PlatformLinux::DisconnectRemote(); - if (error.Success()) + if (error.Success()) { m_device_id.clear(); + m_sdk_version = 0; + } return error; } @@ -229,8 +233,25 @@ uint32_t PlatformOHOS::GetSdkVersion() { if (!IsConnected()) return 0; - // TBD - return 1; + if (m_sdk_version != 0) + return m_sdk_version; + + std::string version_string; + HdcClient hdc(m_device_id); + Status error = + hdc.Shell("getprop ro.build.version.sdk", seconds(5), &version_string); + version_string = llvm::StringRef(version_string).trim().str(); + + if (error.Fail() || version_string.empty()) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); + if (log) + log->Printf("Get SDK version failed. (error: %s, output: %s)", + error.AsCString(), version_string.c_str()); + return 0; + } + + m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); + return m_sdk_version; } bool PlatformOHOS::GetRemoteOSVersion() { @@ -264,3 +285,7 @@ PlatformOHOS::GetLibdlFunctionDeclarations(lldb_private::Process *process) { return PlatformPOSIX::GetLibdlFunctionDeclarations(process); } + +ConstString PlatformOHOS::GetMmapSymbolName(const ArchSpec &arch) { + return arch.GetTriple().isArch32Bit() ? ConstString("__lldb_mmap") : PlatformLinux::GetMmapSymbolName(arch); +} diff --git a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h index 643b7ae3f75f..886ca74ed84b 100644 --- a/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h +++ b/lldb/source/Plugins/Platform/OHOS/PlatformOHOS.h @@ -1,4 +1,4 @@ -//===-- PlatformOHOS.h ---------------------------------------*- C++ -*-===// +//===-- PlatformOHOS.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -57,6 +57,8 @@ public: uint32_t GetDefaultMemoryCacheLineSize() override; + ConstString GetMmapSymbolName(const ArchSpec &arch) override; + protected: const char *GetCacheHostname() override; @@ -69,12 +71,13 @@ protected: private: std::string m_device_id; + uint32_t m_sdk_version; PlatformOHOS(const PlatformOHOS &other) = delete; PlatformOHOS& operator=(const PlatformOHOS &other) = delete; }; -} // namespace platofor_ohos +} // namespace platform_ohos } // namespace lldb_private #endif // liblldb_PlatformOHOS_h_ diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 0f331933f2ea..c59e79306a4b 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -41,11 +41,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, if (thread == nullptr) return false; + const ArchSpec arch = process->GetTarget().GetArchitecture(); + auto mmap_name = process->GetTarget().GetPlatform()->GetMmapSymbolName(arch); const bool include_symbols = true; const bool include_inlines = false; SymbolContextList sc_list; process->GetTarget().GetImages().FindFunctions( - ConstString("mmap"), eFunctionNameTypeFull, include_symbols, + mmap_name, eFunctionNameTypeFull, include_symbols, include_inlines, sc_list); const uint32_t count = sc_list.GetSize(); if (count > 0) { @@ -89,7 +91,6 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, CompilerType void_ptr_type = type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid) .GetPointerType(); - const ArchSpec arch = process->GetTarget().GetArchitecture(); MmapArgList args = process->GetTarget().GetPlatform()->GetMmapArgumentList( arch, addr, length, prot_arg, flags, fd, offset); diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index a77ecddfbab6..8c3c2c013454 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1301,6 +1301,10 @@ Status Platform::Unlink(const FileSpec &path) { return error; } +ConstString Platform::GetMmapSymbolName(const ArchSpec &) { + return ConstString("mmap"); +} + MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, addr_t length, unsigned prot, unsigned flags, addr_t fd, diff --git a/llvm-build/Makefile b/llvm-build/Makefile index 5a8c15452bf1..d6e8933dc328 100644 --- a/llvm-build/Makefile +++ b/llvm-build/Makefile @@ -73,16 +73,24 @@ else ifeq ($(ARCH),aarch64) ARCH_CFLAGS = else +ifeq ($(ARCH),x86_64) +ARCH_CFLAGS = +else $(warning *** warning: ARCH $(ARCH) has not been tested yet, use with cautions!) ARCH_CFLAGS = endif endif +endif ifeq ($(ARCH),aarch64) CFLAGS = -march=armv8 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack else +ifeq ($(ARCH),x86_64) +CFLAGS = -march=x86-64 -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack +else CFLAGS = -march=armv7-a -O2 -Wall -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wl,-z,relro,-z,now,-z,noexecstack endif +endif .PHONY: $(TARGETS:%=musl_copy_for_%) .PHONY: $(TARGETS:%=musl_patch_for_%) @@ -201,4 +209,4 @@ clean: $(HIDE) rm -rf musl_copy_for_* linux_header_install_for_* distclean: clean - $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr \ No newline at end of file + $(HIDE) rm -rf $(SYSROOTDIR)/lib $(SYSROOTDIR)/usr diff --git a/llvm-build/build.py b/llvm-build/build.py index f6f079f025b9..a200c11b05c4 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -193,7 +193,7 @@ class BuildUtils(object): self.build_config = build_config self.CMAKE_BIN_DIR = os.path.abspath( - os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.use_platform()[:-3], 'bin')) + os.path.join(self.build_config.REPOROOT_DIR, 'prebuilts/cmake', self.platform_prefix(), 'bin')) def open_ohos_triple(self, arch): return arch + self.build_config.OPENHOS_SFX @@ -293,17 +293,21 @@ class BuildUtils(object): @staticmethod def use_platform(): - sysstr = platform.system() - if (sysstr == "Linux"): - return 'linux-x86_64' - else: - return 'darwin-x86_64' + sysstr = platform.system().lower() + arch = platform.machine() + return "%s-%s" % (sysstr, arch) + + def platform_prefix(self): + prefix = self.use_platform() + if (prefix.endswith('x86_64')): + return prefix[:-3] + return prefix def host_is_linux(self): - return self.use_platform() == 'linux-x86_64' + return self.use_platform().startswith('linux-') def host_is_darwin(self): - return self.use_platform() == 'darwin-x86_64' + return self.use_platform().startswith('darwin-') def rm_cmake_cache(self, cache_dir): for dirpath, dirs, files in os.walk(cache_dir): @@ -694,7 +698,7 @@ class SysrootComposer(BuildUtils): # but it didn't contain these two lines, so we still need OHOS.cmake. ohos_cmake = 'OHOS.cmake' dst_dir = self.merge_out_path( - '../prebuilts/cmake/linux-x86/share/cmake-3.16/Modules/Platform') + '../prebuilts/cmake/%s/share/cmake-3.16/Modules/Platform' % self.platform_prefix()) src_file = '%s/%s' % (self.build_config.CURRENT_DIR, ohos_cmake) if os.path.exists(os.path.join(dst_dir, ohos_cmake)): os.remove(os.path.join(dst_dir, ohos_cmake)) @@ -711,13 +715,14 @@ class SysrootComposer(BuildUtils): os.chdir(cur_dir) def install_linux_headers(self, arch, target): + dir_sufix = 'x86' if arch == 'x86_64' else arch linux_kernel_dir = os.path.join('kernel_linux_patches', 'linux-5.10') linux_kernel_path = os.path.join(self.build_config.OUT_PATH, '..', linux_kernel_dir) ohosmusl_sysroot_dst = self.merge_out_path('sysroot', target, 'usr') headers_tmp_dir = os.path.join(linux_kernel_path, 'prebuilts', 'usr', 'include') self.check_copy_tree(os.path.join(headers_tmp_dir, 'linux'), os.path.join(ohosmusl_sysroot_dst, 'include/linux')) - self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % arch, 'asm'), + self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-%s' % dir_sufix,'asm'), os.path.join(ohosmusl_sysroot_dst, 'include', 'asm')) self.check_copy_tree(os.path.join(headers_tmp_dir, 'asm-generic'), os.path.join(ohosmusl_sysroot_dst, 'include/asm-generic')) @@ -765,6 +770,7 @@ class LlvmLibs(BuildUtils): defines, cc, cxx, + ar, llvm_config, ldflags, cflags, @@ -774,6 +780,7 @@ class LlvmLibs(BuildUtils): defines['CMAKE_C_COMPILER'] = cc defines['CMAKE_CXX_COMPILER'] = cxx + defines['CMAKE_AR'] = ar defines['LLVM_CONFIG_PATH'] = llvm_config defines['CMAKE_SYSROOT'] = sysroot defines['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE'] = 'ONLY' @@ -821,10 +828,12 @@ class LlvmLibs(BuildUtils): '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4', 'a7_softfp_neon-vfpv4'), ('arm', self.open_ohos_triple('arm'), '-march=armv7-a -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4', 'a7_hard_neon-vfpv4'), - ('aarch64', self.open_ohos_triple('aarch64'), '', ''), ] + ('aarch64', self.open_ohos_triple('aarch64'), '', ''), + ('x86_64', self.open_ohos_triple('x86_64'), '', ''),] cc = os.path.join(llvm_install, 'bin', 'clang') cxx = os.path.join(llvm_install, 'bin', 'clang++') + ar = os.path.join(llvm_install, 'bin', 'llvm-ar') llvm_config = os.path.join(llvm_install, 'bin', 'llvm-config') seen_arch_list = [self.liteos_triple('arm')] @@ -837,10 +846,11 @@ class LlvmLibs(BuildUtils): ldflags = [] cflags = [] self.logger().info('Build libs for %s', llvm_triple) - self.build_libs_defines(llvm_triple, defines, cc, cxx, llvm_config, ldflags, cflags, extra_flags) + self.build_libs_defines(llvm_triple, defines, cc, cxx, ar, llvm_config, ldflags, cflags, extra_flags) llvm_path = self.merge_out_path('llvm_make') - arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), self.open_ohos_triple('aarch64')] + arch_list = [self.liteos_triple('arm'), self.open_ohos_triple('arm'), self.open_ohos_triple('aarch64'), + self.open_ohos_triple('x86_64')] if precompilation: self.build_crts(llvm_install, arch, llvm_triple, cflags, ldflags, multilib_suffix, defines) continue @@ -1063,7 +1073,7 @@ class LlvmLibs(BuildUtils): else: libcxx_defines['LIBCXX_ABI_NAMESPACE'] = '__n1' libcxx_defines['CMAKE_INSTALL_PREFIX'] = libcxx_ndk_install - libcxx_defines['LIBCXX_INSTALL_HEADER_PREFIX'] = libcxx_ndk_install + '/' + libcxx_defines['LIBCXX_INSTALL_HEADER_PREFIX'] = os.path.join(libcxx_ndk_install, 'include', 'libcxx-ohos', '') libcxx_defines['LIBCXX_OUTPUT_NAME'] = 'c++_shared' libcxx_defines['LIBCXX_OUTPUT_STATIC_NAME'] = 'c++_static' @@ -1404,18 +1414,21 @@ class LldbMi(BuildUtils): if self.host_is_darwin(): cflags = [] + cxxflags =[] ldflags = ['-Wl,-rpath,%s' % '@loader_path/../lib'] else: cflags = [] + cxxflags =[] ldflags = ['-fuse-ld=lld', '-Wl,-rpath,%s' % '\$ORIGIN/../lib'] ldflags.append('-L%s' % os.path.join(llvm_path, 'lib')) + cxxflags.append('-std=c++14') lldb_mi_defines = {} lldb_mi_defines['CMAKE_C_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang') lldb_mi_defines['CMAKE_CXX_COMPILER'] = os.path.join(llvm_path, 'bin', 'clang++') lldb_mi_defines['CMAKE_C_FLAGS'] = ' '.join(cflags) - lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cflags) + lldb_mi_defines['CMAKE_CXX_FLAGS'] = ' '.join(cxxflags) lldb_mi_defines['CMAKE_EXE_LINKER_FLAGS'] = ' '.join(ldflags) lldb_mi_defines['CMAKE_SHARED_LINKER_FLAGS'] = ' '.join(ldflags) lldb_mi_defines['CMAKE_MODULE_LINKER_FLAGS'] = ' '.join(ldflags) @@ -1573,8 +1586,8 @@ class LlvmPackage(BuildUtils): def package_libcxx(self): libcxx_ndk_install=self.merge_out_path('libcxx-ndk') - libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'c++', 'v1') - hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64'] + libcxx_ndk_install_include=self.merge_out_path(libcxx_ndk_install, 'include', 'libcxx-ohos', 'include', 'c++', 'v1') + hosts_list=['linux-x86_64', 'darwin-x86_64', 'windows-x86_64', 'darwin-arm64'] if os.path.exists(libcxx_ndk_install): for headerfile in os.listdir(libcxx_ndk_install_include): @@ -1650,7 +1663,7 @@ class LlvmPackage(BuildUtils): def strip_lldb_server(self, host, install_dir): clang_version_bin_dir = os.path.join(install_dir, 'lib', 'clang', '10.0.1', 'bin') - if not host == 'linux-x86_64' or not os.path.exists(clang_version_bin_dir): + if not host.startswith('linux') or not os.path.exists(clang_version_bin_dir): return llvm_strip = os.path.join(install_dir, 'bin', 'llvm-strip') for llvm_triple_dir in os.listdir(clang_version_bin_dir): @@ -1680,7 +1693,7 @@ class LlvmPackage(BuildUtils): with open(zlib_license_file) as notice_file: notices.append(notice_file.read()) - if host == 'windows-x86_64': + if host.startswith('windows'): mingw_license_file = os.path.abspath(os.path.join(self.build_config.REPOROOT_DIR, 'third_party/mingw-w64/COPYING')) with open(mingw_license_file) as notice_file: @@ -1692,7 +1705,7 @@ class LlvmPackage(BuildUtils): def tar_windows_mingw(self, host): - if host == 'windows-x86_64': + if host.startswith('windows'): windows64_install = self.merge_out_path('windows-x86_64-install') clang_mingw_dir = self.merge_out_path('clang_mingw') clang_mingw_sysroot_dir = os.path.join(clang_mingw_dir, 'clang-10.0.1', 'x86_64-w64-mingw32') @@ -1820,7 +1833,7 @@ class LlvmPackage(BuildUtils): lib_files = [] if os.path.isdir(lib_dir): lib_files = os.listdir(lib_dir) - if host == 'windows-x86_64': + if host.startswith('windows'): vers_major = int(self.build_config.VERSION.split('.')[0]) # Redefining necessary bin files for Windows. windows_forbidden_list_bin_files = ['clang-%s%s' % (vers_major, ext), 'scan-build%s' % ext, @@ -1847,7 +1860,7 @@ class LlvmPackage(BuildUtils): package_path = '%s%s' % (self.merge_out_path(tarball_name), '.tar.bz2') self.logger().info('Packaging %s', package_path) args = ['tar', '-cjC', install_host_dir, '-f', package_path, package_name] - if host == 'windows-x86_64': + if host.startswith('windows'): # windows do not support symlinks, # replace them with file copies args.insert(1, '--dereference') @@ -1855,7 +1868,7 @@ class LlvmPackage(BuildUtils): self.check_call(args) # Package ohos NDK - if host == 'linux-x86_64' and os.path.exists(self.merge_out_path('sysroot')): + if os.path.exists(self.merge_out_path('sysroot')): tarball_ndk_name = 'ohos-sysroot-%s' % self.build_config.build_name package_ndk_path = '%s%s' % (self.merge_out_path(tarball_ndk_name), '.tar.bz2') self.logger().info('Packaging %s', package_ndk_path) @@ -1870,10 +1883,10 @@ class LlvmPackage(BuildUtils): package_name = 'clang-%s' % self.build_config.build_name self.set_clang_version(build_dir) - if host == 'windows-x86_64': + if host.startswith('windows'): ext = '.exe' shlib_ext = '.dll' - elif host == 'linux-x86_64': + elif host.startswith('linux'): ext = '' shlib_ext = '.so' else: @@ -1956,6 +1969,10 @@ def main(): if not build_config.no_build_aarch64: configs.append(('arm64', build_utils.open_ohos_triple('aarch64'))) + if not build_config.no_build_x86_64: + configs.append(('x86_64', build_utils.open_ohos_triple('x86_64'))) + + if build_config.do_build and need_host: llvm_core.llvm_compile( build_config.build_name, diff --git a/llvm-build/build_musl.sh b/llvm-build/build_musl.sh index 2d67800641e6..a05b87229d3c 100755 --- a/llvm-build/build_musl.sh +++ b/llvm-build/build_musl.sh @@ -72,6 +72,9 @@ if [ $TARGET_TRIPLE == "arm-liteos-ohos" ]; then elif [ $TARGET_TRIPLE == "arm-linux-ohos" ]; then TARGET_USER="linux_user" TARGETS_PREFIX="arm" +elif [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then + TARGET_USER="linux_user" + TARGETS_PREFIX="x86_64" else TARGET_USER="linux_user" TARGETS_PREFIX="aarch64" @@ -91,7 +94,7 @@ make musl_header_install_for_${TARGET_USER} CLANG="${CLANG_BIN_ROOT}/clang" TOPD # build musl_libs if ((make_libs == 1)); then - if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ]; then + if [ $TARGET_TRIPLE == "aarch64-linux-ohos" ] || [ $TARGET_TRIPLE == "x86_64-linux-ohos" ]; then make CLANG="${CLANG_BIN_ROOT}/clang" TOPDIR=${PWD}/../../ SYSROOTDIR=${OUT}/sysroot TARGETS=${TARGET_USER}\ TARGET=${TARGET_TRIPLE} ARCH=${TARGETS_PREFIX} -f Makefile else @@ -102,4 +105,4 @@ if ((make_libs == 1)); then done fi fi -make distclean -f Makefile \ No newline at end of file +make distclean -f Makefile -- Gitee From 44c508ef2c654ce746e1d8a593282330486a8e25 Mon Sep 17 00:00:00 2001 From: hhj Date: Tue, 9 Aug 2022 11:48:06 +0800 Subject: [PATCH 19/19] Use emulated-tls for ohos build For ie/le compatibility reasons, use the emulated-tls as the default TLS implementation for ohos target. If want to change diable emulated tls, pls use -fno-emulated-tls options. TEST: llvm CodeGen/santizer test case Signed-off-by: hhj --- compiler-rt/lib/asan/asan_fake_stack.cpp | 2 +- compiler-rt/lib/lsan/lsan_common.h | 3 ++- .../sanitizer_platform_interceptors.h | 2 +- llvm/include/llvm/ADT/Triple.h | 2 +- llvm/test/CodeGen/AArch64/emutls.ll | 4 ++++ llvm/test/CodeGen/AArch64/emutls_generic.ll | 12 ++++++++++++ llvm/test/CodeGen/ARM/emutls.ll | 4 ++++ llvm/test/CodeGen/ARM/emutls_generic.ll | 4 ++++ llvm/test/CodeGen/X86/emutls-pic.ll | 4 ++++ llvm/test/CodeGen/X86/emutls-pie.ll | 8 ++++++++ llvm/test/CodeGen/X86/emutls.ll | 4 ++++ llvm/test/CodeGen/X86/emutls_generic.ll | 12 ++++++++++++ 12 files changed, 57 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/asan/asan_fake_stack.cpp b/compiler-rt/lib/asan/asan_fake_stack.cpp index 295e6debc96c..959a61b09d60 100644 --- a/compiler-rt/lib/asan/asan_fake_stack.cpp +++ b/compiler-rt/lib/asan/asan_fake_stack.cpp @@ -170,7 +170,7 @@ void FakeStack::ForEachFakeFrame(RangeIteratorCallback callback, void *arg) { } } -#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA +#if (SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_OHOS) || SANITIZER_FUCHSIA static THREADLOCAL FakeStack *fake_stack_tls; FakeStack *GetTLSFakeStack() { diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index 3c65d9df225e..bc4ad44eb748 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -31,7 +31,8 @@ // the new architecture inside the sanitizer library. // Exclude leak-detection on arm32 for Android because `__aeabi_read_tp` // is missing. This caused a link error. -#if (SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))) +#if SANITIZER_OHOS || \ +(SANITIZER_ANDROID && (__ANDROID_API__ < 28 || defined(__arm__))) #define CAN_SANITIZE_LEAKS 0 #elif (SANITIZER_LINUX || SANITIZER_MAC) && (SANITIZER_WORDSIZE == 64) && \ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index 70e8a2c197fa..f53e9b9f27e8 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -413,7 +413,7 @@ (SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || (SI_LINUX_NOT_ANDROID && !SI_OHOS) || SI_SOLARIS) #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 183ac3787fdc..cfda6ad94281 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -821,7 +821,7 @@ public: /// Tests whether the target uses emulated TLS as default. bool hasDefaultEmulatedTLS() const { - return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); + return isOpenHOS() || isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); } /// Tests whether the target uses -data-sections as default. diff --git a/llvm/test/CodeGen/AArch64/emutls.ll b/llvm/test/CodeGen/AArch64/emutls.ll index 25be391bbfaa..918eb75bc7bd 100644 --- a/llvm/test/CodeGen/AArch64/emutls.ll +++ b/llvm/test/CodeGen/AArch64/emutls.ll @@ -2,6 +2,10 @@ ; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s ; RUN: llc -mtriple=aarch64-linux-android \ ; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s +; RUN: llc -emulated-tls -mtriple=aarch64-linux-ohos \ +; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s +; RUN: llc -mtriple=aarch64-linux-ohos \ +; RUN: -relocation-model=pic -frame-pointer=all < %s | FileCheck -check-prefix=ARM64 %s ; Copied from X86/emutls.ll diff --git a/llvm/test/CodeGen/AArch64/emutls_generic.ll b/llvm/test/CodeGen/AArch64/emutls_generic.ll index 840833972881..6b5819a7fc4e 100644 --- a/llvm/test/CodeGen/AArch64/emutls_generic.ll +++ b/llvm/test/CodeGen/AArch64/emutls_generic.ll @@ -8,6 +8,12 @@ ; RUN: | FileCheck -check-prefix=ARM_64 %s ; RUN: llc < %s -emulated-tls -mtriple=aarch64-apple-darwin -O3 \ ; RUN: | FileCheck -check-prefix=DARWIN %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s ; RUN: llc < %s -mtriple=aarch64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=ARM_64 %s @@ -18,6 +24,12 @@ ; aarch64-windows-gnu needs explicit -emulated-tls ; RUN: llc < %s -mtriple=aarch64-apple-darwin -O3 \ ; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-ohos -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/ARM/emutls.ll b/llvm/test/CodeGen/ARM/emutls.ll index 92b656d9ba09..29894a9efa7b 100644 --- a/llvm/test/CodeGen/ARM/emutls.ll +++ b/llvm/test/CodeGen/ARM/emutls.ll @@ -2,6 +2,10 @@ ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s ; RUN: llc -mtriple=arm-linux-android \ ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s +; RUN: llc -emulated-tls -mtriple=arm-linux-ohos \ +; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s +; RUN: llc -mtriple=arm-linux-ohos \ +; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s ; Copied from X86/emutls.ll diff --git a/llvm/test/CodeGen/ARM/emutls_generic.ll b/llvm/test/CodeGen/ARM/emutls_generic.ll index 8bf0ab301244..803462740f79 100644 --- a/llvm/test/CodeGen/ARM/emutls_generic.ll +++ b/llvm/test/CodeGen/ARM/emutls_generic.ll @@ -10,6 +10,8 @@ ; RUN: | FileCheck -check-prefix=DARWIN %s ; RUN: llc < %s -emulated-tls -mtriple=thumbv7-windows-gnu -O3 \ ; RUN: | FileCheck -check-prefix=WIN %s +; RUN: llc < %s -emulated-tls -mtriple=arm-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s ; RUN: llc < %s -mtriple=arm-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=ARM_32 %s @@ -21,6 +23,8 @@ ; RUN: | FileCheck -check-prefix=ARM_32 %s ; arm-apple-darwin must use -emulated-tls ; windows must use -emulated-tls +; RUN: llc < %s -mtriple=arm-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s ; Make sure that TLS symbols are emitted in expected order. diff --git a/llvm/test/CodeGen/X86/emutls-pic.ll b/llvm/test/CodeGen/X86/emutls-pic.ll index 66f226a8bd5a..b265bb6517c3 100644 --- a/llvm/test/CodeGen/X86/emutls-pic.ll +++ b/llvm/test/CodeGen/X86/emutls-pic.ll @@ -2,11 +2,15 @@ ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mtriple=i386-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos -relocation-model=pic | FileCheck -check-prefix=X64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/X86/emutls-pie.ll b/llvm/test/CodeGen/X86/emutls-pie.ll index 38f0c245bee6..40945a37ab57 100644 --- a/llvm/test/CodeGen/X86/emutls-pie.ll +++ b/llvm/test/CodeGen/X86/emutls-pie.ll @@ -6,6 +6,10 @@ ; RUN: | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=NoEMU %s @@ -15,6 +19,10 @@ ; RUN: | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s ; NoEMU-NOT: __emutls diff --git a/llvm/test/CodeGen/X86/emutls.ll b/llvm/test/CodeGen/X86/emutls.ll index 7e567d287c61..7105f595221e 100644 --- a/llvm/test/CodeGen/X86/emutls.ll +++ b/llvm/test/CodeGen/X86/emutls.ll @@ -2,11 +2,15 @@ ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -emulated-tls -mtriple=i386-linux-ohos | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=NoEMU %s ; RUN: llc < %s -mtriple=i386-linux-android | FileCheck -check-prefix=X86 %s ; RUN: llc < %s -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-ohos | FileCheck -check-prefix=X86 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos | FileCheck -check-prefix=X64 %s ; Copied from tls.ll; emulated TLS model is not implemented ; for *-pc-win32 and *-pc-windows targets yet. diff --git a/llvm/test/CodeGen/X86/emutls_generic.ll b/llvm/test/CodeGen/X86/emutls_generic.ll index 7fc6089b9077..9e61bc5924cf 100644 --- a/llvm/test/CodeGen/X86/emutls_generic.ll +++ b/llvm/test/CodeGen/X86/emutls_generic.ll @@ -6,6 +6,12 @@ ; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck %s +; RUN: llc < %s -emulated-tls -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -emulated-tls -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X86_32 %s @@ -15,6 +21,12 @@ ; RUN: | FileCheck -check-prefix=X86_64 %s ; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=i686-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=x86_64-linux-ohos -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_64 %s ; NoEMU-NOT: __emutls -- Gitee