replace SanitizerSet in CodegenFnAttrs by new type
This commit is contained in:
parent
642c19bfc3
commit
bc883e24b8
11 changed files with 51 additions and 37 deletions
|
|
@ -2,7 +2,7 @@
|
|||
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
|
||||
};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet};
|
||||
|
|
@ -98,10 +98,10 @@ fn patchable_function_entry_attrs<'ll>(
|
|||
pub(crate) fn sanitize_attrs<'ll, 'tcx>(
|
||||
cx: &SimpleCx<'ll>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
no_sanitize: SanitizerSet,
|
||||
sanitizer_fn_attr: SanitizerFnAttrs,
|
||||
) -> SmallVec<[&'ll Attribute; 4]> {
|
||||
let mut attrs = SmallVec::new();
|
||||
let enabled = tcx.sess.sanitizers() - no_sanitize;
|
||||
let enabled = tcx.sess.sanitizers() - sanitizer_fn_attr.disabled;
|
||||
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
|
||||
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
|
||||
}
|
||||
|
|
@ -411,7 +411,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
|||
// not used.
|
||||
} else {
|
||||
// Do not set sanitizer attributes for naked functions.
|
||||
to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.no_sanitize));
|
||||
to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.sanitizers));
|
||||
|
||||
// For non-naked functions, set branch protection attributes on aarch64.
|
||||
if let Some(BranchProtection { bti, pac_ret, gcs }) =
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_hir::attrs::Linkage;
|
||||
use rustc_middle::dep_graph;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs};
|
||||
use rustc_middle::mir::mono::Visibility;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::DebugInfo;
|
||||
|
|
@ -105,7 +105,7 @@ pub(crate) fn compile_codegen_unit(
|
|||
if let Some(entry) =
|
||||
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx, cx.codegen_unit)
|
||||
{
|
||||
let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerSet::empty());
|
||||
let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerFnAttrs::default());
|
||||
attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs);
|
||||
}
|
||||
|
||||
|
|
@ -191,10 +191,10 @@ pub(crate) fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
|
|||
}
|
||||
|
||||
pub(crate) fn set_variable_sanitizer_attrs(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||
if attrs.no_sanitize.contains(SanitizerSet::ADDRESS) {
|
||||
if attrs.sanitizers.disabled.contains(SanitizerSet::ADDRESS) {
|
||||
unsafe { llvm::LLVMRustSetNoSanitizeAddress(llval) };
|
||||
}
|
||||
if attrs.no_sanitize.contains(SanitizerSet::HWADDRESS) {
|
||||
if attrs.sanitizers.disabled.contains(SanitizerSet::HWADDRESS) {
|
||||
unsafe { llvm::LLVMRustSetNoSanitizeHWAddress(llval) };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1798,7 +1798,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
&& is_indirect_call
|
||||
{
|
||||
if let Some(fn_attrs) = fn_attrs
|
||||
&& fn_attrs.no_sanitize.contains(SanitizerSet::CFI)
|
||||
&& fn_attrs.sanitizers.disabled.contains(SanitizerSet::CFI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1856,7 +1856,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
|||
&& is_indirect_call
|
||||
{
|
||||
if let Some(fn_attrs) = fn_attrs
|
||||
&& fn_attrs.no_sanitize.contains(SanitizerSet::KCFI)
|
||||
&& fn_attrs.sanitizers.disabled.contains(SanitizerSet::KCFI)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
|
||||
};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::span_bug;
|
||||
|
|
@ -16,7 +16,6 @@ use rustc_middle::ty::{self as ty, TyCtxt};
|
|||
use rustc_session::lint;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{Ident, Span, sym};
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
|
||||
use crate::errors;
|
||||
use crate::target_features::{
|
||||
|
|
@ -351,7 +350,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
|
|||
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
|
||||
|
||||
// Compute the disabled sanitizers.
|
||||
codegen_fn_attrs.no_sanitize |= tcx.disabled_sanitizers_for(did);
|
||||
codegen_fn_attrs.sanitizers.disabled |=
|
||||
tcx.sanitizer_settings_for(did).disabled;
|
||||
// On trait methods, inherit the `#[align]` of the trait's method prototype.
|
||||
codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did));
|
||||
|
||||
|
|
@ -455,14 +455,14 @@ fn check_result(
|
|||
}
|
||||
|
||||
// warn that inline has no effect when no_sanitize is present
|
||||
if !codegen_fn_attrs.no_sanitize.is_empty()
|
||||
if codegen_fn_attrs.sanitizers != SanitizerFnAttrs::default()
|
||||
&& codegen_fn_attrs.inline.always()
|
||||
&& let (Some(no_sanitize_span), Some(inline_span)) =
|
||||
&& let (Some(sanitize_span), Some(inline_span)) =
|
||||
(interesting_spans.sanitize, interesting_spans.inline)
|
||||
{
|
||||
let hir_id = tcx.local_def_id_to_hir_id(did);
|
||||
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| {
|
||||
lint.primary_message("setting `sanitize` off will have no effect after inlining");
|
||||
tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, sanitize_span, |lint| {
|
||||
lint.primary_message("non-default `sanitize` will have no effect after inlining");
|
||||
lint.span_note(inline_span, "inlining requested here");
|
||||
})
|
||||
}
|
||||
|
|
@ -576,14 +576,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
codegen_fn_attrs
|
||||
}
|
||||
|
||||
fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
|
||||
fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs {
|
||||
// Backtrack to the crate root.
|
||||
let mut disabled = match tcx.opt_local_parent(did) {
|
||||
let mut settings = match tcx.opt_local_parent(did) {
|
||||
// Check the parent (recursively).
|
||||
Some(parent) => tcx.disabled_sanitizers_for(parent),
|
||||
Some(parent) => tcx.sanitizer_settings_for(parent),
|
||||
// We reached the crate root without seeing an attribute, so
|
||||
// there is no sanitizers to exclude.
|
||||
None => SanitizerSet::empty(),
|
||||
None => SanitizerFnAttrs::default(),
|
||||
};
|
||||
|
||||
// Check for a sanitize annotation directly on this def.
|
||||
|
|
@ -591,15 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
|
|||
{
|
||||
// the on set is the set of sanitizers explicitly enabled.
|
||||
// we mask those out since we want the set of disabled sanitizers here
|
||||
disabled &= !*on_set;
|
||||
settings.disabled &= !*on_set;
|
||||
// the off set is the set of sanitizers explicitly disabled.
|
||||
// we or those in here.
|
||||
disabled |= *off_set;
|
||||
settings.disabled |= *off_set;
|
||||
// the on set and off set are distjoint since there's a third option: unset.
|
||||
// a node may not set the sanitizer setting in which case it inherits from parents.
|
||||
// the code above in this function does this backtracking
|
||||
}
|
||||
disabled
|
||||
settings
|
||||
}
|
||||
|
||||
/// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
|
||||
|
|
@ -731,7 +731,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
codegen_fn_attrs,
|
||||
should_inherit_track_caller,
|
||||
inherited_align,
|
||||
disabled_sanitizers_for,
|
||||
sanitizer_settings_for,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#![feature(box_as_ptr)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(closure_track_caller)]
|
||||
#![feature(const_default)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(decl_macro)]
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ pub struct CodegenFnAttrs {
|
|||
/// The `#[link_section = "..."]` attribute, or what executable section this
|
||||
/// should be placed in.
|
||||
pub link_section: Option<Symbol>,
|
||||
/// The `#[sanitize(xyz = "off")]` attribute. Indicates sanitizers for which
|
||||
/// instrumentation should be disabled inside the function.
|
||||
pub no_sanitize: SanitizerSet,
|
||||
/// The `#[sanitize(xyz = "off")]` attribute. Indicates the settings for each
|
||||
/// sanitizer for this function.
|
||||
pub sanitizers: SanitizerFnAttrs,
|
||||
/// The `#[instruction_set(set)]` attribute. Indicates if the generated code should
|
||||
/// be generated against a specific instruction set. Only usable on architectures which allow
|
||||
/// switching between multiple instruction sets.
|
||||
|
|
@ -209,7 +209,7 @@ impl CodegenFnAttrs {
|
|||
linkage: None,
|
||||
import_linkage: None,
|
||||
link_section: None,
|
||||
no_sanitize: SanitizerSet::empty(),
|
||||
sanitizers: SanitizerFnAttrs::default(),
|
||||
instruction_set: None,
|
||||
alignment: None,
|
||||
patchable_function_entry: None,
|
||||
|
|
@ -241,3 +241,15 @@ impl CodegenFnAttrs {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, HashStable, TyEncodable, TyDecodable, Eq, PartialEq)]
|
||||
pub struct SanitizerFnAttrs {
|
||||
pub disabled: SanitizerSet,
|
||||
}
|
||||
|
||||
impl const Default for SanitizerFnAttrs {
|
||||
fn default() -> Self {
|
||||
Self { disabled: SanitizerSet::empty() }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@ trivial! {
|
|||
rustc_middle::ty::UnusedGenericParams,
|
||||
rustc_middle::ty::util::AlwaysRequiresDrop,
|
||||
rustc_middle::ty::Visibility<rustc_span::def_id::DefId>,
|
||||
rustc_middle::middle::codegen_fn_attrs::SanitizerFnAttrs,
|
||||
rustc_session::config::CrateType,
|
||||
rustc_session::config::EntryFnType,
|
||||
rustc_session::config::OptLevel,
|
||||
|
|
@ -365,7 +366,6 @@ trivial! {
|
|||
rustc_span::Symbol,
|
||||
rustc_span::Ident,
|
||||
rustc_target::spec::PanicStrategy,
|
||||
rustc_target::spec::SanitizerSet,
|
||||
rustc_type_ir::Variance,
|
||||
u32,
|
||||
usize,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ use rustc_session::lint::LintExpectationId;
|
|||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use rustc_target::spec::{PanicStrategy, SanitizerSet};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use {rustc_abi as abi, rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
pub use self::keys::{AsLocalKey, Key, LocalCrate};
|
||||
|
|
@ -105,7 +105,7 @@ pub use self::plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsur
|
|||
use crate::infer::canonical::{self, Canonical};
|
||||
use crate::lint::LintExpectation;
|
||||
use crate::metadata::ModChild;
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs};
|
||||
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
|
||||
use crate::middle::deduced_param_attrs::DeducedParamAttrs;
|
||||
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
|
||||
|
|
@ -2735,8 +2735,8 @@ rustc_queries! {
|
|||
/// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the
|
||||
/// crate root.
|
||||
///
|
||||
/// Returns the set of sanitizers that is explicitly disabled for this def.
|
||||
query disabled_sanitizers_for(key: LocalDefId) -> SanitizerSet {
|
||||
/// Returns the sanitizer settings for this def.
|
||||
query sanitizer_settings_for(key: LocalDefId) -> SanitizerFnAttrs {
|
||||
desc { |tcx| "checking what set of sanitizers are enabled on `{}`", tcx.def_path_str(key) }
|
||||
feedable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -818,7 +818,7 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
|
|||
}
|
||||
|
||||
let codegen_fn_attrs = tcx.codegen_fn_attrs(inliner.caller_def_id());
|
||||
if callee_attrs.no_sanitize != codegen_fn_attrs.no_sanitize {
|
||||
if callee_attrs.sanitizers != codegen_fn_attrs.sanitizers {
|
||||
return Err("incompatible sanitizer set");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#[inline(always)]
|
||||
//~^ NOTE inlining requested here
|
||||
#[sanitize(address = "off")]
|
||||
//~^ WARN setting `sanitize` off will have no effect after inlining
|
||||
//~^ WARN non-default `sanitize` will have no effect after inlining
|
||||
//~| NOTE on by default
|
||||
fn x() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
warning: setting `sanitize` off will have no effect after inlining
|
||||
warning: non-default `sanitize` will have no effect after inlining
|
||||
--> $DIR/inline-always-sanitize.rs:7:1
|
||||
|
|
||||
LL | #[sanitize(address = "off")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue