Skip to content

Commit

Permalink
[CHERI] Consistently treat anything that's not a compartment call as …
Browse files Browse the repository at this point in the history
…a libcall for linking.

This fixes an issue where taking the address of a local function would cause a linker
error, because we were sometimes treating it as a compartment export and sometimes as
a libcall. With this change, we now consistently treat it as a libcall with forced-local
visibility.
  • Loading branch information
resistor committed Dec 23, 2024
1 parent 178dee2 commit 45ce3ba
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 16 deletions.
7 changes: 5 additions & 2 deletions llvm/lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,15 @@ InstructionSelector *createRISCVInstructionSelector(const RISCVTargetMachine &,
RISCVRegisterBankInfo &);
void initializeRISCVDAGToDAGISelPass(PassRegistry &);

inline bool isCheriCompartmentCall(int CC) {
return (CC == CallingConv::CHERI_CCall) || (CC == CallingConv::CHERI_CCallee);
}

/// Returns the symbol name for either an import or export table entry.
inline std::string getImportExportTableName(StringRef Compartment,
StringRef FnName, int CC,
bool IsImport) {
bool IsCCall =
(CC == CallingConv::CHERI_CCall) || (CC == CallingConv::CHERI_CCallee);
bool IsCCall = isCheriCompartmentCall(CC);
Twine TargetPrefix = !IsCCall ? "__library" : "_";
Twine KindPrefix = TargetPrefix + (IsImport ? "_import_" : "_export_");
return (KindPrefix + Compartment + "_" + FnName).str();
Expand Down
11 changes: 4 additions & 7 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,13 @@ bool RISCVAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
{std::string(Fn.getFnAttribute("cheri-compartment").getValueAsString()),
Fn, OutStreamer->getContext().getOrCreateSymbol(MF.getName()),
countUsedArgRegisters(MF) + interruptFlag, false, stackSize});
} else if (Fn.getCallingConv() == CallingConv::CHERI_LibCall)
} else {
CompartmentEntries.push_back(
{"libcalls", Fn,
OutStreamer->getContext().getOrCreateSymbol(MF.getName()),
countUsedArgRegisters(MF) + interruptFlag});
else if (interruptFlag != 0)
CompartmentEntries.push_back(
{std::string(Fn.getFnAttribute("cheri-compartment").getValueAsString()),
Fn, OutStreamer->getContext().getOrCreateSymbol(MF.getName()),
countUsedArgRegisters(MF) + interruptFlag, true});
countUsedArgRegisters(MF) + interruptFlag,
/*forceLocal*/ Fn.getCallingConv() != CallingConv::CHERI_LibCall});
}

return false;
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ MachineBasicBlock *RISCVExpandPseudo::insertLoadOfImportTable(
const StringRef ImportName = Fn->getName();
// We can hit this code path if we need to do a library-style import
// for a local exported function.
const bool IsLibrary = Fn->getCallingConv() == CallingConv::CHERI_LibCall;
const bool IsLibrary = !isCheriCompartmentCall(Fn->getCallingConv());
const StringRef CompartmentName =
IsLibrary ? "libcalls"
: Fn->getFnAttribute("cheri-compartment").getValueAsString();
Expand Down
44 changes: 44 additions & 0 deletions llvm/test/CodeGen/RISCV/cheri/cheri-local-libcall.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
; RUN: llc --filetype=asm --mcpu=cheriot --mtriple=riscv32-unknown-unknown -target-abi cheriot -mattr=+xcheri,+cap-mode < %s | FileCheck %s
target datalayout = "e-m:e-pf200:64:64:64:32-p:32:32-i64:64-n32-S128-A200-P200-G200"
target triple = "riscv32cheriot-unknown-cheriotrtos"

@f = dso_local local_unnamed_addr addrspace(200) global ptr addrspace(200) null, align 8

define dso_local void @_Z11id_functionv() addrspace(200) #0 {
entry:
ret void
}

define dso_local chericcallcce void @_Z9say_hellov() local_unnamed_addr addrspace(200) #1 {
entry:
store ptr addrspace(200) @_Z11id_functionv, ptr addrspace(200) @f, align 8
ret void
}

attributes #0 = { minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none) "cheri-compartment"="hello" "interrupt-state"="disabled" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cheriot" "target-features"="+32bit,+c,+cap-mode,+e,+m,+relax,+xcheri,-a,-d,-experimental-smaia,-experimental-ssaia,-experimental-zacas,-experimental-zfa,-experimental-zfbfmin,-experimental-zicond,-experimental-zihintntl,-experimental-ztso,-experimental-zvbb,-experimental-zvbc,-experimental-zvfbfmin,-experimental-zvfbfwma,-experimental-zvkg,-experimental-zvkn,-experimental-zvknc,-experimental-zvkned,-experimental-zvkng,-experimental-zvknha,-experimental-zvknhb,-experimental-zvks,-experimental-zvksc,-experimental-zvksed,-experimental-zvksg,-experimental-zvksh,-experimental-zvkt,-f,-h,-save-restore,-svinval,-svnapot,-svpbmt,-v,-xcvbitmanip,-xcvmac,-xsfcie,-xsfvcp,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zicbom,-zicbop,-zicboz,-zicntr,-zicsr,-zifencei,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }
attributes #1 = { minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(write, argmem: none, inaccessiblemem: none) "cheri-compartment"="hello" "interrupt-state"="enabled" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cheriot" "target-features"="+32bit,+c,+cap-mode,+e,+m,+relax,+xcheri,-a,-d,-experimental-smaia,-experimental-ssaia,-experimental-zacas,-experimental-zfa,-experimental-zfbfmin,-experimental-zicond,-experimental-zihintntl,-experimental-ztso,-experimental-zvbb,-experimental-zvbc,-experimental-zvfbfmin,-experimental-zvfbfwma,-experimental-zvkg,-experimental-zvkn,-experimental-zvknc,-experimental-zvkned,-experimental-zvkng,-experimental-zvknha,-experimental-zvknhb,-experimental-zvks,-experimental-zvksc,-experimental-zvksed,-experimental-zvksg,-experimental-zvksh,-experimental-zvkt,-f,-h,-save-restore,-svinval,-svnapot,-svpbmt,-v,-xcvbitmanip,-xcvmac,-xsfcie,-xsfvcp,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmp,-zcmt,-zdinx,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zicbom,-zicbop,-zicboz,-zicntr,-zicsr,-zifencei,-zihintpause,-zihpm,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-zmmul,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfh,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b" }

; CHECK: .section .compartment_exports,"aR",@progbits
; CHECK-NEXT: .type __library_export_libcalls__Z11id_functionv,@object
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: __library_export_libcalls__Z11id_functionv:
; CHECK-NEXT: .half _Z11id_functionv-__compartment_pcc_start
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 16
; CHECK-NEXT: .size __library_export_libcalls__Z11id_functionv, 4
; CHECK-NEXT: .type __export_hello__Z9say_hellov,@object
; CHECK-NEXT: .globl __export_hello__Z9say_hellov
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT:__export_hello__Z9say_hellov:
; CHECK-NEXT: .half _Z9say_hellov-__compartment_pcc_start
; CHECK-NEXT: .byte 0
; CHECK-NEXT: .byte 8
; CHECK-NEXT: .size __export_hello__Z9say_hellov, 4
; CHECK-NEXT: .section .compartment_imports,"aG",@progbits,__library_import_libcalls__Z11id_functionv,comdat
; CHECK-NEXT: .type __library_import_libcalls__Z11id_functionv,@object
; CHECK-NEXT: .weak __library_import_libcalls__Z11id_functionv
; CHECK-NEXT: .p2align 3, 0x0
; CHECK-NEXT:__library_import_libcalls__Z11id_functionv:
; CHECK-NEXT: .word __library_export_libcalls__Z11id_functionv+1
; CHECK-NEXT: .word 0
; CHECK-NEXT: .size __library_import_libcalls__Z11id_functionv, 8
12 changes: 6 additions & 6 deletions llvm/test/CodeGen/RISCV/cheri/cheri-mcu-interrupt-attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ define dso_local i32 @outer_disabled_e() local_unnamed_addr addrspace(200) #4 {
entry:
; Different state, should call via import table
; CHECK-LABEL: outer_disabled_e
; CHECK: %cheriot_compartment_hi(__library_import__inner_enabled)
; CHECK: %cheriot_compartment_hi(__library_import_libcalls_inner_enabled)
; CHECK: cjalr
%call = call i32 @inner_enabled()
%add = add nsw i32 %call, 12
Expand All @@ -70,7 +70,7 @@ define dso_local i32 @outer_enabled_d() local_unnamed_addr addrspace(200) #5 {
entry:
; Different state, should call via import table
; CHECK-LABEL: outer_enabled_d
; CHECK: %cheriot_compartment_hi(__library_import__inner_disabled)
; CHECK: %cheriot_compartment_hi(__library_import_libcalls_inner_disabled)
; CHECK: cjalr
%call = call i32 @inner_disabled()
%add = add nsw i32 %call, 12
Expand Down Expand Up @@ -104,7 +104,7 @@ define dso_local i32 @outer_inherit_d() local_unnamed_addr addrspace(200) #6 {
entry:
; Different state, should call via import table
; CHECK-LABEL: outer_inherit_d
; CHECK: %cheriot_compartment_hi(__library_import__inner_disabled)
; CHECK: %cheriot_compartment_hi(__library_import_libcalls_inner_disabled)
; CHECK: cjalr
%call = call i32 @inner_disabled()
%add = add nsw i32 %call, 12
Expand All @@ -116,7 +116,7 @@ define dso_local i32 @outer_inherit_e() local_unnamed_addr addrspace(200) #6 {
entry:
; Different state, should call via import table
; CHECK-LABEL: outer_inherit_e
; CHECK: %cheriot_compartment_hi(__library_import__inner_enabled)
; CHECK: %cheriot_compartment_hi(__library_import_libcalls_inner_enabled)
; CHECK: cjalr
%call = call i32 @inner_enabled()
%add = add nsw i32 %call, 12
Expand Down Expand Up @@ -152,12 +152,12 @@ attributes #7 = { nounwind }
!3 = !{!"clang version 13.0.0 ([email protected]:v3/Portmeirion/CHERI-MCU/LLVM 83ddcec972c6a81bda278ebdb3791041fc8ce47c)"}

; CHECK-NOT: .globl __library_export__inner_enabled
; CHECK: __library_export__inner_disabled:
; CHECK: __library_export_libcalls_inner_disabled:
; CHECK-NEXT: .half inner_disabled-__compartment_pcc_start
; CHECK-NEXT: .byte 0
; Check that this has the correct bit set to indicate interrupts are disabled
; CHECK-NEXT: .byte 16
; CHECK: __library_export__inner_enabled:
; CHECK: __library_export_libcalls_inner_enabled:
; CHECK-NEXT: .half inner_enabled-__compartment_pcc_start
; CHECK-NEXT: .byte 0
; Check that this has the correct bit set to indicate interrupts are enabled
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/RISCV/idiv_large.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ define i128 @udiv_i128(i128 %x, i128 %y) nounwind {
define i129 @udiv_i129(i129 %x, i129 %y) nounwind {
; CHECK-LABEL: udiv_i129:
; CHECK-NOT: call{{.*}}div
; CHECK: ret
%res = udiv i129 %x, %y
ret i129 %res
}

0 comments on commit 45ce3ba

Please sign in to comment.