Rollup merge of #113593 - rcvalle:rust-cfi-fix-90546, r=wesleywiser
CFI: Fix error compiling core with LLVM CFI enabled Fix #90546 by filtering out global value function pointer types from the type tests, and adding the LowerTypeTests pass to the rustc LTO optimization pipelines.
This commit is contained in:
commit
c097e48082
14 changed files with 90 additions and 31 deletions
|
@ -472,6 +472,8 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
Some(llvm::SanitizerOptions {
|
||||
sanitize_address: config.sanitizer.contains(SanitizerSet::ADDRESS),
|
||||
sanitize_address_recover: config.sanitizer_recover.contains(SanitizerSet::ADDRESS),
|
||||
sanitize_cfi: config.sanitizer.contains(SanitizerSet::CFI),
|
||||
sanitize_kcfi: config.sanitizer.contains(SanitizerSet::KCFI),
|
||||
sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
|
||||
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
|
||||
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
|
||||
|
@ -507,6 +509,7 @@ pub(crate) unsafe fn llvm_optimize(
|
|||
&*module.module_llvm.tm,
|
||||
to_pass_builder_opt_level(opt_level),
|
||||
opt_stage,
|
||||
cgcx.opts.cg.linker_plugin_lto.enabled(),
|
||||
config.no_prepopulate_passes,
|
||||
config.verify_llvm_ir,
|
||||
using_thin_buffers,
|
||||
|
|
|
@ -1512,9 +1512,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||
llfn: &'ll Value,
|
||||
) {
|
||||
let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
|
||||
if is_indirect_call && fn_abi.is_some() && self.tcx.sess.is_sanitizer_cfi_enabled() {
|
||||
if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::CFI) {
|
||||
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
|
||||
if self.tcx.sess.is_sanitizer_cfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
|
||||
if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1526,7 +1526,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
|
||||
}
|
||||
|
||||
let typeid = typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
|
||||
let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
|
||||
let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
|
||||
|
||||
// Test whether the function pointer is associated with the type identifier.
|
||||
|
@ -1550,25 +1550,26 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||
llfn: &'ll Value,
|
||||
) -> Option<llvm::OperandBundleDef<'ll>> {
|
||||
let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
|
||||
let kcfi_bundle = if is_indirect_call && self.tcx.sess.is_sanitizer_kcfi_enabled() {
|
||||
if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::KCFI) {
|
||||
return None;
|
||||
}
|
||||
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
|
||||
let kcfi_bundle =
|
||||
if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call {
|
||||
if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut options = TypeIdOptions::empty();
|
||||
if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
|
||||
options.insert(TypeIdOptions::GENERALIZE_POINTERS);
|
||||
}
|
||||
if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
|
||||
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
|
||||
}
|
||||
let mut options = TypeIdOptions::empty();
|
||||
if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() {
|
||||
options.insert(TypeIdOptions::GENERALIZE_POINTERS);
|
||||
}
|
||||
if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() {
|
||||
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
|
||||
}
|
||||
|
||||
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options);
|
||||
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
|
||||
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
kcfi_bundle
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,6 +475,8 @@ pub enum OptStage {
|
|||
pub struct SanitizerOptions {
|
||||
pub sanitize_address: bool,
|
||||
pub sanitize_address_recover: bool,
|
||||
pub sanitize_cfi: bool,
|
||||
pub sanitize_kcfi: bool,
|
||||
pub sanitize_memory: bool,
|
||||
pub sanitize_memory_recover: bool,
|
||||
pub sanitize_memory_track_origins: c_int,
|
||||
|
@ -894,6 +896,7 @@ extern "C" {
|
|||
pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
|
||||
pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
|
||||
pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>;
|
||||
pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
|
||||
|
||||
// Operations on constants of any type
|
||||
pub fn LLVMConstNull(Ty: &Type) -> &Value;
|
||||
|
@ -2138,6 +2141,7 @@ extern "C" {
|
|||
TM: &'a TargetMachine,
|
||||
OptLevel: PassBuilderOptLevel,
|
||||
OptStage: OptStage,
|
||||
IsLinkerPluginLTO: bool,
|
||||
NoPrepopulatePasses: bool,
|
||||
VerifyIR: bool,
|
||||
UseThinLTOBuffers: bool,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue