From ab6f8a2df3f9e65f91eae63c7d7ebcd573aaa475 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 2 Jun 2025 21:29:52 +1000 Subject: [PATCH] [CHERIoT] Generate export table entries for weak function symbols. These arise in newer libc++'s, where a library is used for explicit instantiations of some std::string methods. These become weakly exported libcall symbols from the library, and still need to be present in the export table. Since they should only ever be materialized in one translation unit, it's OK for the export table entry to be strongly exported while the symbol itself is weakly exported. --- llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 10 +++--- .../RISCV/cheri/cheriot-global-weak.ll | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/cheri/cheriot-global-weak.ll diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp index 4eb54e1396a9e..25a4188988e1b 100644 --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -742,10 +742,10 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) { /*IsImport*/ false); auto Sym = C.getOrCreateSymbol(ExportName); OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject); - // If the function isn't global, don't make its export table entry - // global either. Two different compilation units in the same - // compartment may export different static things. - if (Entry.Fn.hasExternalLinkage() && !Entry.forceLocal) + // If the function isn't global, don't make its export table entry global + // either. Two different compilation units in the same compartment may + // export different static things. + if (!Entry.Fn.isDiscardableIfUnused() && !Entry.forceLocal) OutStreamer->emitSymbolAttribute(Sym, MCSA_Global); OutStreamer->emitValueToAlignment(Align(4)); OutStreamer->emitLabel(Sym); @@ -771,7 +771,7 @@ void RISCVAsmPrinter::emitEndOfAsmFile(Module &M) { // 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) + if (!GA->isDiscardableIfUnused() && !Entry.forceLocal) OutStreamer->emitSymbolAttribute(AliasExportSym, MCSA_Global); OutStreamer->emitAssignment(AliasExportSym, MCSymbolRefExpr::create(Sym, C)); diff --git a/llvm/test/CodeGen/RISCV/cheri/cheriot-global-weak.ll b/llvm/test/CodeGen/RISCV/cheri/cheriot-global-weak.ll new file mode 100644 index 0000000000000..949935691ae9e --- /dev/null +++ b/llvm/test/CodeGen/RISCV/cheri/cheriot-global-weak.ll @@ -0,0 +1,32 @@ +; 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 weak function + +; CHECK: .section .compartment_exports,"aR",@progbits +; CHECK .type __library_export_libcalls_foo,@object +; CHECK: .p2align 2, 0x0 +; CHECK: __library_export_libcalls_foo: +; CHECK: .half foo-__compartment_pcc_start +; CHECK: .byte 0 +; CHECK: .byte 0 +; CHECK: .size __library_export_libcalls_foo, 4 + +; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +define weak dso_local cherilibcallcc noundef i32 @foo() local_unnamed_addr addrspace(200) #0 { +entry: + ret i32 42 +} + +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)"}