Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ pr_check_commits_task:
x_check_task:
skip: $CIRRUS_PR == ""
name: (PR) Run ./x check
depends_on: (PR) Check commits structure
# TODO(xdoardo): Figure out when it makes sense to have this dependency, or
# how that dependency should actually work. Having this dependency would
# pretty much mean making every PR that merges changes on `beta` to `master`
# to have failing CI, which would be the reason why we want to make PRs and
# not direct pushes in the first place.
# depends_on: (PR) Check commits structure
timeout_in: 240m
gce_instance: &arm_vm
image_project: ubuntu-os-cloud
Expand All @@ -54,6 +59,8 @@ x_check_task:
- export CCACHE_REMOTE_STORAGE="http://${CIRRUS_HTTP_CACHE_HOST}/${CIRRUS_OS}/"
- export CCACHE_REMOTE_ONLY=1
- env
test_script: CC="clang" CXX="clang++" ./x check
pull_master_script: git fetch origin master
tidy_script: CC="clang" CXX="clang++" ./x test tidy
check_script: CC="clang" CXX="clang++" ./x check

# -- End PR tasks
2 changes: 1 addition & 1 deletion cheri/gen_bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ change-id = 140732
ccache = true

[rust]
#channel = "nightly"
channel = "beta"
#codegen-backends = ["llvm"]
#debug = true
#debuginfo-level = 2
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout, WrappingRange};
use rustc_apfloat::{Float, Round, Status, ieee};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::common::{
AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind,
AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, PreserveCheriTags,
};
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
Expand Down Expand Up @@ -1369,6 +1369,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
_src_align: Align,
size: RValue<'gcc>,
flags: MemFlags,
_preserve_cheri_tags: PreserveCheriTags,
) {
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memcpy not supported");
let size = self.intcast(size, self.type_size_t(), false);
Expand All @@ -1391,6 +1392,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
_src_align: Align,
size: RValue<'gcc>,
flags: MemFlags,
_preserve_cheri_flags: PreserveCheriTags,
) {
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memmove not supported");
let size = self.intcast(size, self.type_size_t(), false);
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_abi::ExternAbi;
use rustc_abi::{BackendRepr, HasDataLayout};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::common::IntPredicate;
use rustc_codegen_ssa::common::{IntPredicate, PreserveCheriTags};
use rustc_codegen_ssa::errors::InvalidMonomorphization;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
Expand Down Expand Up @@ -771,6 +771,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
scratch_align,
bx.const_usize(self.layout.size.bytes()),
MemFlags::empty(),
PreserveCheriTags::Unknown,
);

bx.lifetime_end(scratch, scratch_size);
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_abi::{
X86Call,
};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::common::PreserveCheriTags;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
use rustc_codegen_ssa::traits::*;
Expand Down Expand Up @@ -238,6 +239,8 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
scratch_align,
bx.const_usize(copy_bytes),
MemFlags::empty(),
// Handling of CHERI capabilities could probably be more efficient.
PreserveCheriTags::Unknown,
);
bx.lifetime_end(llscratch, scratch_size);
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::attributes;
use crate::common::Funclet;
use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
use crate::llvm::{
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True,
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True, PreserveCheriTags
};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
Expand Down Expand Up @@ -1106,9 +1106,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
src_align: Align,
size: &'ll Value,
flags: MemFlags,
preserve_tags: rustc_codegen_ssa::common::PreserveCheriTags,
) {
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memcpy not supported");
let size = self.intcast(size, self.type_isize(), false);
let preserve_tags = PreserveCheriTags::from_generic(preserve_tags);
let is_volatile = flags.contains(MemFlags::VOLATILE);
unsafe {
llvm::LLVMRustBuildMemCpy(
Expand All @@ -1118,6 +1120,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
src,
src_align.bytes() as c_uint,
size,
preserve_tags,
is_volatile,
);
}
Expand All @@ -1131,9 +1134,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
src_align: Align,
size: &'ll Value,
flags: MemFlags,
preserve_tags: rustc_codegen_ssa::common::PreserveCheriTags,
) {
assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memmove not supported");
let size = self.intcast(size, self.type_isize(), false);
let preserve_tags = PreserveCheriTags::from_generic(preserve_tags);
let is_volatile = flags.contains(MemFlags::VOLATILE);
unsafe {
llvm::LLVMRustBuildMemMove(
Expand All @@ -1143,6 +1148,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
src,
src_align.bytes() as c_uint,
size,
preserve_tags,
is_volatile,
);
}
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,25 @@ pub(crate) enum Opcode {
CatchSwitch = 65,
}

/// LLVMPreserveCheriTags
#[derive(Copy, Clone)]
#[repr(C)]
pub(crate) enum PreserveCheriTags {
Unknown,
Required,
Unnecessary,
}

impl PreserveCheriTags {
pub(crate) fn from_generic(value: rustc_codegen_ssa::common::PreserveCheriTags) -> Self {
match value {
rustc_codegen_ssa::common::PreserveCheriTags::Unknown => PreserveCheriTags::Unknown,
rustc_codegen_ssa::common::PreserveCheriTags::Required => PreserveCheriTags::Required,
rustc_codegen_ssa::common::PreserveCheriTags::Unnecessary => PreserveCheriTags::Unnecessary,
}
}
}

unsafe extern "C" {
type Opaque;
}
Expand Down Expand Up @@ -1933,6 +1952,7 @@ unsafe extern "C" {
Src: &'a Value,
SrcAlign: c_uint,
Size: &'a Value,
PreserveTags: PreserveCheriTags,
IsVolatile: bool,
) -> &'a Value;
pub(crate) fn LLVMRustBuildMemMove<'a>(
Expand All @@ -1942,6 +1962,7 @@ unsafe extern "C" {
Src: &'a Value,
SrcAlign: c_uint,
Size: &'a Value,
PreserveTags: PreserveCheriTags,
IsVolatile: bool,
) -> &'a Value;
pub(crate) fn LLVMRustBuildMemSet<'a>(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/va_arg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_abi::{Align, BackendRepr, Endian, HasDataLayout, Primitive, Size, TyAndLayout};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::common::IntPredicate;
use rustc_codegen_ssa::common::{IntPredicate, PreserveCheriTags};
use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, LayoutTypeCodegenMethods,
Expand Down Expand Up @@ -735,6 +735,7 @@ fn copy_to_temporary_if_more_aligned<'ll, 'tcx>(
src_align,
bx.const_u32(layout.layout.size().bytes() as u32),
MemFlags::empty(),
PreserveCheriTags::Unknown,
);
tmp
} else {
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ pub enum AtomicRmwBinOp {
AtomicUMin,
}

#[derive(Copy, Clone, Debug)]
pub enum PreserveCheriTags {
Unknown,
Required,
Unnecessary,
}

#[derive(Copy, Clone, Debug)]
pub enum SynchronizationScope {
SingleThread,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::operand::OperandValue::{Immediate, Pair, Ref, ZeroSized};
use super::place::{PlaceRef, PlaceValue};
use super::{CachedLlbb, FunctionCx, LocalRef};
use crate::base::{self, is_call_from_compiler_builtins_to_upstream_monomorphization};
use crate::common::{self, IntPredicate};
use crate::common::{self, IntPredicate, PreserveCheriTags};
use crate::errors::CompilerBuiltinsCannotCall;
use crate::traits::*;
use crate::{MemFlags, meth};
Expand Down Expand Up @@ -1601,6 +1601,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
align,
bx.const_usize(copy_bytes),
MemFlags::empty(),
PreserveCheriTags::Unknown,
);
// ...and then load it with the ABI type.
llval = load_cast(bx, cast, llscratch, scratch_align);
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_span::sym;
use super::FunctionCx;
use super::operand::OperandRef;
use super::place::PlaceRef;
use crate::common::{AtomicRmwBinOp, SynchronizationScope};
use crate::common::{AtomicRmwBinOp, SynchronizationScope, PreserveCheriTags};
use crate::errors::InvalidMonomorphization;
use crate::traits::*;
use crate::{MemFlags, meth, size_of_val};
Expand All @@ -27,10 +27,12 @@ fn copy_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let align = layout.align.abi;
let size = bx.mul(bx.const_usize(size.bytes()), count);
let flags = if volatile { MemFlags::VOLATILE } else { MemFlags::empty() };
// Handling of CHERI capabilities could probably be more efficient.
let preserve_tags = PreserveCheriTags::Unknown;
if allow_overlap {
bx.memmove(dst, align, src, align, size, flags);
bx.memmove(dst, align, src, align, size, flags, preserve_tags);
} else {
bx.memcpy(dst, align, src, align, size, flags);
bx.memcpy(dst, align, src, align, size, flags, preserve_tags);
}
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use rustc_middle::span_bug;
use tracing::instrument;

use super::{FunctionCx, LocalRef};
use crate::common::PreserveCheriTags;
use crate::traits::*;

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Expand Down Expand Up @@ -90,7 +91,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let align = pointee_layout.align;
let dst = dst_val.immediate();
let src = src_val.immediate();
bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty());
// Handling of CHERI capabilities could probably be more efficient.
bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty(), PreserveCheriTags::Unknown);
}
mir::StatementKind::FakeRead(..)
| mir::StatementKind::Retag { .. }
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_ssa/src/traits/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ use super::misc::MiscCodegenMethods;
use super::type_::{ArgAbiBuilderMethods, BaseTypeCodegenMethods, LayoutTypeCodegenMethods};
use super::{CodegenMethods, StaticBuilderMethods};
use crate::MemFlags;
use crate::common::{AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind};
use crate::common::{
PreserveCheriTags, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind,
};
use crate::mir::operand::{OperandRef, OperandValue};
use crate::mir::place::{PlaceRef, PlaceValue};

Expand Down Expand Up @@ -424,6 +426,7 @@ pub trait BuilderMethods<'a, 'tcx>:
src_align: Align,
size: Self::Value,
flags: MemFlags,
preserve_tags: PreserveCheriTags,
);
fn memmove(
&mut self,
Expand All @@ -433,6 +436,7 @@ pub trait BuilderMethods<'a, 'tcx>:
src_align: Align,
size: Self::Value,
flags: MemFlags,
preserve_tags: PreserveCheriTags,
);
fn memset(
&mut self,
Expand Down Expand Up @@ -480,7 +484,8 @@ pub trait BuilderMethods<'a, 'tcx>:
temp.val.store_with_flags(self, dst.with_type(layout), flags);
} else if !layout.is_zst() {
let bytes = self.const_usize(layout.size.bytes());
self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags);
self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags,
PreserveCheriTags::Unknown);
}
}

Expand Down
54 changes: 39 additions & 15 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1564,23 +1564,47 @@ LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RustStringRef MessageOut,
return true;
}

extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst,
unsigned DstAlign, LLVMValueRef Src,
unsigned SrcAlign,
LLVMValueRef Size,
bool IsVolatile) {
return wrap(unwrap(B)->CreateMemCpy(unwrap(Dst), MaybeAlign(DstAlign),
unwrap(Src), MaybeAlign(SrcAlign),
unwrap(Size), IsVolatile));
enum class LLVMPreserveCheriTags {
Unknown,
Required,
Unnecessary,
};

static PreserveCheriTags fromRust(LLVMPreserveCheriTags PreserveTags) {
switch (PreserveTags) {
case LLVMPreserveCheriTags::Unknown:
return PreserveCheriTags::Unknown;
case LLVMPreserveCheriTags::Required:
return PreserveCheriTags::Required;
case LLVMPreserveCheriTags::Unnecessary:
return PreserveCheriTags::Unnecessary;
}

report_fatal_error("Invalid LLVMPreserveCheriTags value!");
}

extern "C" LLVMValueRef
LLVMRustBuildMemMove(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size,
bool IsVolatile) {
return wrap(unwrap(B)->CreateMemMove(unwrap(Dst), MaybeAlign(DstAlign),
unwrap(Src), MaybeAlign(SrcAlign),
unwrap(Size), IsVolatile));
extern "C" LLVMValueRef LLVMRustBuildMemCpy(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size, LLVMPreserveCheriTags PreserveTags,
bool IsVolatile) {
return wrap(unwrap(B)->CreateMemCpy(
unwrap(Dst), MaybeAlign(DstAlign),
unwrap(Src), MaybeAlign(SrcAlign),
unwrap(Size), fromRust(PreserveTags),
IsVolatile));
}

extern "C" LLVMValueRef LLVMRustBuildMemMove(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size, LLVMPreserveCheriTags PreserveTags,
bool IsVolatile) {
return wrap(unwrap(B)->CreateMemMove(
unwrap(Dst), MaybeAlign(DstAlign),
unwrap(Src), MaybeAlign(SrcAlign),
unwrap(Size), fromRust(PreserveTags),
IsVolatile));
}

extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
Expand Down