rustc_sanitizers/cfi/typeid/itanium_cxx_abi/
mod.rs1use rustc_abi::CanonAbi;
8use rustc_data_structures::fx::FxHashMap;
9use rustc_middle::bug;
10use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
11use rustc_target::callconv::{FnAbi, PassMode};
12use tracing::instrument;
13
14mod encode;
15mod transform;
16use crate::cfi::typeid::TypeIdOptions;
17use crate::cfi::typeid::itanium_cxx_abi::encode::{DictKey, EncodeTyOptions, encode_ty};
18use crate::cfi::typeid::itanium_cxx_abi::transform::{
19 TransformTy, TransformTyOptions, transform_instance,
20};
21
22#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("typeid_for_fnabi",
"rustc_sanitizers::cfi::typeid::itanium_cxx_abi",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs"),
::tracing_core::__macro_support::Option::Some(24u32),
::tracing_core::__macro_support::Option::Some("rustc_sanitizers::cfi::typeid::itanium_cxx_abi"),
::tracing_core::field::FieldSet::new(&["fn_abi", "options"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&fn_abi)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&options)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: String = loop {};
return __tracing_attr_fake_return;
}
{
let mut typeid = String::from("_Z");
typeid.push_str("TS");
typeid.push('F');
let mut dict: FxHashMap<DictKey<'tcx>, usize> =
FxHashMap::default();
let mut encode_ty_options =
EncodeTyOptions::from_bits(options.bits()).unwrap_or_else(||
::rustc_middle::util::bug::bug_fmt(format_args!("typeid_for_fnabi: invalid option(s) `{0:?}`",
options.bits())));
match fn_abi.conv {
CanonAbi::C => {
encode_ty_options.insert(EncodeTyOptions::GENERALIZE_REPR_C);
}
_ => {
encode_ty_options.remove(EncodeTyOptions::GENERALIZE_REPR_C);
}
}
let transform_ty_options =
TransformTyOptions::from_bits(options.bits()).unwrap_or_else(||
::rustc_middle::util::bug::bug_fmt(format_args!("typeid_for_fnabi: invalid option(s) `{0:?}`",
options.bits())));
let mut type_folder = TransformTy::new(tcx, transform_ty_options);
let ty = fn_abi.ret.layout.ty.fold_with(&mut type_folder);
typeid.push_str(&encode_ty(tcx, ty, &mut dict,
encode_ty_options));
if !fn_abi.c_variadic {
let mut pushed_arg = false;
for arg in
fn_abi.args.iter().filter(|arg|
arg.mode != PassMode::Ignore) {
pushed_arg = true;
let ty = arg.layout.ty.fold_with(&mut type_folder);
typeid.push_str(&encode_ty(tcx, ty, &mut dict,
encode_ty_options));
}
if !pushed_arg { typeid.push('v'); }
} else {
for n in 0..fn_abi.fixed_count as usize {
if fn_abi.args[n].mode == PassMode::Ignore { continue; }
let ty =
fn_abi.args[n].layout.ty.fold_with(&mut type_folder);
typeid.push_str(&encode_ty(tcx, ty, &mut dict,
encode_ty_options));
}
typeid.push('z');
}
typeid.push('E');
if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
typeid.push_str(".normalized");
}
if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) {
typeid.push_str(".generalized");
}
typeid
}
}
}#[instrument(level = "trace", skip(tcx))]
25pub fn typeid_for_fnabi<'tcx>(
26 tcx: TyCtxt<'tcx>,
27 fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
28 options: TypeIdOptions,
29) -> String {
30 let mut typeid = String::from("_Z");
33
34 typeid.push_str("TS");
38
39 typeid.push('F');
41
42 let mut dict: FxHashMap<DictKey<'tcx>, usize> = FxHashMap::default();
45
46 let mut encode_ty_options = EncodeTyOptions::from_bits(options.bits())
47 .unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
48 match fn_abi.conv {
49 CanonAbi::C => {
50 encode_ty_options.insert(EncodeTyOptions::GENERALIZE_REPR_C);
51 }
52 _ => {
53 encode_ty_options.remove(EncodeTyOptions::GENERALIZE_REPR_C);
54 }
55 }
56
57 let transform_ty_options = TransformTyOptions::from_bits(options.bits())
59 .unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
60 let mut type_folder = TransformTy::new(tcx, transform_ty_options);
61 let ty = fn_abi.ret.layout.ty.fold_with(&mut type_folder);
62 typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
63
64 if !fn_abi.c_variadic {
70 let mut pushed_arg = false;
71 for arg in fn_abi.args.iter().filter(|arg| arg.mode != PassMode::Ignore) {
72 pushed_arg = true;
73 let ty = arg.layout.ty.fold_with(&mut type_folder);
74 typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
75 }
76 if !pushed_arg {
77 typeid.push('v');
80 }
81 } else {
82 for n in 0..fn_abi.fixed_count as usize {
83 if fn_abi.args[n].mode == PassMode::Ignore {
84 continue;
85 }
86 let ty = fn_abi.args[n].layout.ty.fold_with(&mut type_folder);
87 typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
88 }
89
90 typeid.push('z');
91 }
92
93 typeid.push('E');
95
96 if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
98 typeid.push_str(".normalized");
99 }
100
101 if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) {
102 typeid.push_str(".generalized");
103 }
104
105 typeid
106}
107
108#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("typeid_for_instance",
"rustc_sanitizers::cfi::typeid::itanium_cxx_abi",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/mod.rs"),
::tracing_core::__macro_support::Option::Some(110u32),
::tracing_core::__macro_support::Option::Some("rustc_sanitizers::cfi::typeid::itanium_cxx_abi"),
::tracing_core::field::FieldSet::new(&["instance",
"options"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&instance)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&options)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: String = loop {};
return __tracing_attr_fake_return;
}
{
if !!instance.has_non_region_param() {
{
::core::panicking::panic_fmt(format_args!("{0:#?} must be fully monomorphic",
instance));
}
};
let transform_ty_options =
TransformTyOptions::from_bits(options.bits()).unwrap_or_else(||
::rustc_middle::util::bug::bug_fmt(format_args!("typeid_for_instance: invalid option(s) `{0:?}`",
options.bits())));
let instance =
transform_instance(tcx, instance, transform_ty_options);
let fn_abi =
tcx.fn_abi_of_instance(ty::TypingEnv::fully_monomorphized().as_query_input((instance,
ty::List::empty()))).unwrap_or_else(|error|
{
::rustc_middle::util::bug::bug_fmt(format_args!("typeid_for_instance: couldn\'t get fn_abi of instance {0:?}: {1:?}",
instance, error))
});
typeid_for_fnabi(tcx, fn_abi, options)
}
}
}#[instrument(level = "trace", skip(tcx))]
111pub fn typeid_for_instance<'tcx>(
112 tcx: TyCtxt<'tcx>,
113 instance: Instance<'tcx>,
114 options: TypeIdOptions,
115) -> String {
116 assert!(!instance.has_non_region_param(), "{instance:#?} must be fully monomorphic");
117 let transform_ty_options = TransformTyOptions::from_bits(options.bits())
118 .unwrap_or_else(|| bug!("typeid_for_instance: invalid option(s) `{:?}`", options.bits()));
119 let instance = transform_instance(tcx, instance, transform_ty_options);
120 let fn_abi = tcx
121 .fn_abi_of_instance(
122 ty::TypingEnv::fully_monomorphized().as_query_input((instance, ty::List::empty())),
123 )
124 .unwrap_or_else(|error| {
125 bug!("typeid_for_instance: couldn't get fn_abi of instance {instance:?}: {error:?}")
126 });
127 typeid_for_fnabi(tcx, fn_abi, options)
128}