From 06e7fdb7820a78186b588584b5629b0175010ff1 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 29 May 2025 15:03:11 +1000 Subject: [PATCH] [CHERIoT] Add support for generating export table entries for GlobalAlias's. --- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 35 +++++++++++++++- .../RISCV/cheri/cheriot-globalalias.ll | 40 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/RISCV/cheri/cheriot-globalalias.ll diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 46cbd0d2dc691..e8393e1749abc 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -133,11 +133,14 @@ class RISCVAsmPrinter : public AsmPrinter { uint32_t stackSize = 0; }; SmallVector CompartmentEntries; + SmallDenseMap, 1> + CompartmentEntryAliases; void emitAttributes(const MCSubtargetInfo &SubtargetInfo); void emitNTLHint(const MachineInstr *MI); void emitGlobalVariable(const GlobalVariable *GV) override; + void emitGlobalAlias(const Module &M, const GlobalAlias &GV) override; // XRay Support void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr *MI); @@ -313,6 +316,17 @@ void RISCVAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { return AsmPrinter::emitGlobalVariable(GV); } +void RISCVAsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) { + AsmPrinter::emitGlobalAlias(M, GA); + + const MCSubtargetInfo &SubtargetInfo = *TM.getMCSubtargetInfo(); + if (SubtargetInfo.hasFeature(RISCV::FeatureVendorXCheriot)) { + if (auto *Fn = dyn_cast(GA.getAliasee()->stripPointerCasts())) { + CompartmentEntryAliases[Fn].push_back(&GA); + } + } +} + // If the target supports Zihintntl and the instruction has a nontemporal // MachineMemOperand, emit an NTLH hint instruction before it. void RISCVAsmPrinter::emitNTLHint(const MachineInstr *MI) { @@ -558,7 +572,6 @@ bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) { }; if (Fn.getCallingConv() == CallingConv::CHERI_CCallee) { - Function &Fn = MF.getFunction(); uint32_t stackSize; if (Fn.hasFnAttribute("minimum-stack-size")) { bool converted = @@ -712,6 +725,26 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) { OutStreamer->emitIntValue(std::min(uint32_t(255), stackSize), 1); OutStreamer->emitIntValue(Entry.LiveIns, 1); OutStreamer->emitELFSize(Sym, MCConstantExpr::create(4, C)); + + // Emit aliases for this export symbol entry. + auto I = CompartmentEntryAliases.find(&Entry.Fn); + if (I == CompartmentEntryAliases.end()) + continue; + for (const GlobalAlias *GA : I->second) { + std::string AliasExportName = getImportExportTableName( + Entry.CompartmentName, GA->getName(), Entry.Fn.getCallingConv(), + /*IsImport*/ false); + auto AliasExportSym = C.getOrCreateSymbol(AliasExportName); + + // Emit symbol alias in the export table for the alias using the same + // attributes, linkage, and size as the primary entry. + OutStreamer->emitSymbolAttribute(AliasExportSym, MCSA_ELF_TypeObject); + if (GA->hasExternalLinkage() && !Entry.forceLocal) + OutStreamer->emitSymbolAttribute(AliasExportSym, MCSA_Global); + OutStreamer->emitAssignment(AliasExportSym, + MCSymbolRefExpr::create(Sym, C)); + OutStreamer->emitELFSize(AliasExportSym, MCConstantExpr::create(4, C)); + } } } // Generate CHERIoT imports if there are any. diff --git a/llvm/test/CodeGen/RISCV/cheri/cheriot-globalalias.ll b/llvm/test/CodeGen/RISCV/cheri/cheriot-globalalias.ll new file mode 100644 index 0000000000000..b1f9a92fa5127 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/cheri/cheriot-globalalias.ll @@ -0,0 +1,40 @@ +; RUN: llc --filetype=asm --mcpu=cheriot --mtriple=riscv32cheriot-unknown-cheriotrtos -target-abi cheriot %s -mattr=+xcheri,+cap-mode,+xcheriot -o - | FileCheck %s +target datalayout = "e-m:e-p:32:32-i64:64-n32-S128-pf200:64:64:64:32-A200-P200-G200" +target triple = "riscv32cheriot-unknown-cheriotrtos" + +; Verify that we emit an export table entry for a GlobalAlias that is itself an alias to the +; export table entry for the aliasee. + +; CHECK: .section .compartment_exports,"aR",@progbits +; CHECK: .type __library_export_libcalls__Z3foov,@object +; CHECK: .globl __library_export_libcalls__Z3foov +; CHECK: .p2align 2, 0x0 +; CHECK: __library_export_libcalls__Z3foov: +; CHECK: .half _Z3foov-__compartment_pcc_start +; CHECK: .byte 0 +; CHECK: .byte 0 +; CHECK: .size __library_export_libcalls__Z3foov, 4 +; CHECK: .type __library_export_libcalls__Z3barv,@object +; CHECK: .globl __library_export_libcalls__Z3barv +; CHECK: .set __library_export_libcalls__Z3barv, __library_export_libcalls__Z3foov +; CHECK: .size __library_export_libcalls__Z3barv, 4 + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define dso_local cherilibcallcc noundef i32 @_Z3foov() local_unnamed_addr addrspace(200) #0 { +entry: + ret i32 42 +} + +@_Z3barv = alias i32(), ptr addrspace(200) @_Z3foov + +attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cheriot" "target-features"="+32bit,+c,+cap-mode,+e,+m,+relax,+xcheri,+zmmul,-a,-b,-d,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-i,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcheriot,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zacas,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" } + +!llvm.module.flags = !{!0, !1, !2, !4} +!llvm.ident = !{!5} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 1, !"target-abi", !"cheriot"} +!2 = !{i32 6, !"riscv-isa", !3} +!3 = !{!"rv32e2p0_m2p0_c2p0_zmmul1p0_xcheri0p0"} +!4 = !{i32 8, !"SmallDataLimit", i32 0} +!5 = !{!"clang version 20.1.3 (git@github.com:resistor/llvm-project-1.git b5150572190bf7926bc7c77858e6f6d49f49b0bb)"}