// file:
// sys/cheri/cheric.h
/*
* Programmer-friendly macros for CHERI-aware C code -- requires use of
* CHERI-aware Clang/LLVM, and full capability context switching.
*/
#define cheri_getlen(x) __builtin_cheri_length_get((x))
#define cheri_getbase(x) __builtin_cheri_base_get((x))
#define cheri_getoffset(x) __builtin_cheri_offset_get((x))
#define cheri_getaddress(x) __builtin_cheri_address_get((x))
#define cheri_getperm(x) __builtin_cheri_perms_get((x))
#define cheri_getsealed(x) __builtin_cheri_sealed_get((x))
#define cheri_gettag(x) __builtin_cheri_tag_get((x))
#define cheri_gettype(x) __builtin_cheri_type_get((x))
#define cheri_andperm(x, y) __builtin_cheri_perms_and((x), (y))
#define cheri_clearperm(x, y) __builtin_cheri_perms_and((x), ~(y))
#define cheri_cleartag(x) __builtin_cheri_tag_clear((x))
#define cheri_incoffset(x, y) __builtin_cheri_offset_increment((x), (y))
#define cheri_setoffset(x, y) __builtin_cheri_offset_set((x), (y))
#define cheri_setaddress(x, y) __builtin_cheri_address_set((x), (y))
#define cheri_seal(x, y) __builtin_cheri_seal((x), (y))
#define cheri_unseal(x, y) __builtin_cheri_unseal((x), (y))
#define cheri_getcause() __builtin_mips_cheri_get_cause()
#define cheri_setcause(x) __builtin_mips_cheri_set_cause(x)
#define cheri_ccheckperm(c, p) __builtin_cheri_perms_check((c), (p))
#define cheri_cchecktype(c, t) __builtin_cheri_type_check((c), (t))
#define cheri_getdefault() __builtin_cheri_global_data_get()
#define cheri_getidc() __builtin_mips_cheri_get_invoke_data_cap()
#define cheri_getkr1c() __builtin_mips_cheri_get_kernel_cap1()
#define cheri_getkr2c() __builtin_mips_cheri_get_kernel_cap2()
#define cheri_getkcc() __builtin_mips_cheri_get_kernel_code_cap()
#define cheri_getkdc() __builtin_mips_cheri_get_kernel_data_cap()
#define cheri_getepcc() __builtin_mips_cheri_get_exception_program_counter_cap()
#define cheri_getpcc() __builtin_cheri_program_counter_get()
#define cheri_getstack() __builtin_cheri_stack_get()
#define cheri_local(c) cheri_andperm((c), ~CHERI_PERM_GLOBAL)
#define cheri_csetbounds(x, y) __builtin_cheri_bounds_set((x), (y))
#define cheri_csetboundsexact(x, y) __builtin_cheri_bounds_set_exact((x), (y))
/* XXXAR: shouldn't this be the default and we add cheri_csetbounds_untyped? */
#define cheri_csetbounds_changetype(type, x, y) \
(type)cheri_csetbounds((x), (y)))
#define cheri_csetbounds_sametype(x, y) \
((__typeof__(x))cheri_csetbounds((x), (y)))
/* Create an untagged capability from an integer */
#define cheri_fromint(x) cheri_incoffset(NULL, x)
__builtin_cheri_perms_and
// file: sys/cheri/cheric.h
#define cheri_andperm(x, y) __builtin_cheri_perms_and((x), (y))
__builtin_cheri_perms_and
is compiler built in function to emit ??? instruction:
// file:
// clang/include/clang/Basic/Builtins.def
BUILTIN(__builtin_cheri_perms_and, "v*mvC*mz", "nc")
LLM: What does this mean ???????????
// file:
// clang/lib/CodeGen/CGBuiltin.cpp: L3624 in CodeGenFunction::EmitBuiltinExpr(..)
switch (BuiltinID){
...
case Builtin::BI__builtin_cheri_perms_and:
return RValue::get(Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::cheri_cap_perms_and, SizeTy),
{EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))}));
...
}
// file:
// clang/lib/CodeGen/CGBuiltin.cpp:L12248 in *CodeGenFunction::EmitMIPSBuiltinExpr()
switch (BuiltinID) {
...
case Mips::BI__builtin_mips_cheri_and_cap_perms:
return Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::cheri_cap_perms_and, SizeTy),
{EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))});
...
}
cheri_cap_perms_and
cheri_cap_perms_and
is an llvm intrinsic defined as:
// file:
// llvm/include/llvm/IR/IntrinsicsCHERICap.td
def int_cheri_cap_perms_and :
Intrinsic<[llvm_fatptr_ty],
[llvm_fatptr_ty, llvm_anyint_ty],
[IntrNoMem]>;
// LLM: ????????????????
// file:
// llvm/lib/Target/Mips/CheriPureCapABI.cpp
// file:
// llvm/lib/Target/Mips/MipsISelLowering.cpp: LowerCall()
if (ABI.IsCheriPureCap()) {
if (FirstOffset != -1) {
SDValue PtrOff = DAG.getPointerAdd(DL, StackPtr, FirstOffset);
PtrOff = setBounds(DAG, PtrOff, LastOffset, /*CSetBoundsStatsLogged=*/true);
PtrOff = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, CapType,
DAG.getConstant(Intrinsic::cheri_cap_perms_and, DL, MVT::i64), PtrOff,
DAG.getIntPtrConstant(0xFFD7, DL));
RegsToPass.push_back(std::make_pair(Mips::C13, PtrOff));
if (cheri::ShouldCollectCSetBoundsStats) {
StringRef Name = "<unknown function>";
if (ES) {
Name = ES->getSymbol();
} else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Name = G->getGlobal()->getName();
}
cheri::CSetBoundsStats->add(
1, LastOffset, "variadic call lowering",
cheri::SetBoundsPointerSource::Stack,
StringRef("setting varargs bounds for call to ") + Name,
cheri::inferSourceLocation(DL.getDebugLoc(),
DAG.getMachineFunction().getName()));
}
} else {
// ...
}
// ...
}
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?