Skip to content

Commit 3be74a5

Browse files
committed
Add -Zinstrument-fentry
The behavior is very similar to `-Zinstrument-mcount`, except this option has no frame-pointer requirements, and is called before the call frame is set up. This only works on x86, x86-64, and s390x targets.
1 parent 62b33fc commit 3be74a5

16 files changed

Lines changed: 78 additions & 5 deletions

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,14 @@ fn instrument_function_attr<'ll>(
204204
instrument_fn: &Option<bool>,
205205
) -> SmallVec<[&'ll Attribute; 4]> {
206206
let mut attrs = SmallVec::new();
207-
if sess.opts.unstable_opts.instrument_mcount {
207+
if sess.opts.unstable_opts.instrument_mcount || sess.opts.unstable_opts.instrument_fentry {
208208
// Similar to `clang -pg` behavior. Handled by the
209209
// `post-inline-ee-instrument` LLVM pass.
210210

211211
// #[instrument_fn], the default is on.
212212
let instrument_entry = instrument_fn.unwrap_or_else(|| true);
213213

214-
if instrument_entry {
214+
if instrument_entry && sess.opts.unstable_opts.instrument_mcount {
215215
// The function name varies on platforms.
216216
// See test/CodeGen/mcount.c in clang.
217217
let mcount_name = match &sess.target.llvm_mcount_intrinsic {
@@ -225,6 +225,10 @@ fn instrument_function_attr<'ll>(
225225
mcount_name,
226226
));
227227
}
228+
229+
if instrument_entry && sess.opts.unstable_opts.instrument_fentry {
230+
attrs.push(llvm::CreateAttrStringValue(cx.llcx, "fentry-call", "true"));
231+
}
228232
}
229233
if let Some(options) = &sess.opts.unstable_opts.instrument_xray {
230234
// XRay instrumentation is similar to __cyg_profile_func_{enter,exit}.

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,8 @@ options! {
23922392
"a default MIR inlining threshold (default: 50)"),
23932393
input_stats: bool = (false, parse_bool, [UNTRACKED],
23942394
"print some statistics about AST and HIR (default: no)"),
2395+
instrument_fentry: bool = (false, parse_bool, [TRACKED],
2396+
"insert function instrument code for fentry-based tracing (default: no)"),
23952397
instrument_mcount: bool = (false, parse_bool, [TRACKED],
23962398
"insert function instrument code for mcount-based tracing (default: no)"),
23972399
instrument_xray: Option<InstrumentXRay> = (None, parse_instrument_xray, [TRACKED],

compiler/rustc_session/src/session.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,10 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
13251325
}
13261326
}
13271327

1328+
if sess.opts.unstable_opts.instrument_fentry && !sess.target.options.supports_fentry {
1329+
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "fentry".to_string() });
1330+
}
1331+
13281332
if sess.opts.unstable_opts.instrument_xray.is_some() && !sess.target.options.supports_xray {
13291333
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
13301334
}

compiler/rustc_target/src/spec/json.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ impl Target {
223223
forward!(supports_stack_protector);
224224
forward!(small_data_threshold_support);
225225
forward!(entry_name);
226+
forward!(supports_fentry);
226227
forward!(supports_xray);
227228

228229
// we're going to run `update_from_cli`, but that won't change the target's AbiMap
@@ -407,6 +408,7 @@ impl ToJson for Target {
407408
target_option_val!(small_data_threshold_support);
408409
target_option_val!(entry_name);
409410
target_option_val!(entry_abi);
411+
target_option_val!(supports_fentry);
410412
target_option_val!(supports_xray);
411413

412414
// Serializing `-Clink-self-contained` needs a dynamic key to support the
@@ -628,6 +630,7 @@ struct TargetSpecJson {
628630
supports_stack_protector: Option<bool>,
629631
small_data_threshold_support: Option<SmallDataThresholdSupport>,
630632
entry_name: Option<StaticCow<str>>,
633+
supports_fentry: Option<bool>,
631634
supports_xray: Option<bool>,
632635
entry_abi: Option<ExternAbiWrapper>,
633636
}

compiler/rustc_target/src/spec/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,6 +2702,9 @@ pub struct TargetOptions {
27022702
/// Default value is `CanonAbi::C`
27032703
pub entry_abi: CanonAbi,
27042704

2705+
/// Whether the target supports fentry instrumentation.
2706+
pub supports_fentry: bool,
2707+
27052708
/// Whether the target supports XRay instrumentation.
27062709
pub supports_xray: bool,
27072710

@@ -2944,6 +2947,7 @@ impl Default for TargetOptions {
29442947
supports_stack_protector: true,
29452948
entry_name: "main".into(),
29462949
entry_abi: CanonAbi::C,
2950+
supports_fentry: false,
29472951
supports_xray: false,
29482952
default_address_space: rustc_abi::AddressSpace::ZERO,
29492953
small_data_threshold_support: SmallDataThresholdSupport::DefaultForArch,

compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub(crate) fn target() -> Target {
2222
base.supported_sanitizers = SanitizerSet::ADDRESS;
2323
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
2424
base.stack_probes = StackProbeType::Inline;
25+
base.supports_fentry = true;
2526

2627
Target {
2728
llvm_target: "i686-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub(crate) fn target() -> Target {
1212
base.max_atomic_width = Some(64);
1313
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]);
1414
base.stack_probes = StackProbeType::Inline;
15+
base.supports_fentry = true;
1516
// FIXME(compiler-team#422): musl targets should be dynamically linked by default.
1617
base.crt_static_default = true;
1718

compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub(crate) fn target() -> Target {
1212
base.stack_probes = StackProbeType::Inline;
1313
base.supported_sanitizers =
1414
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
15+
base.supports_fentry = true;
1516

1617
Target {
1718
llvm_target: "s390x-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub(crate) fn target() -> Target {
1313
base.stack_probes = StackProbeType::Inline;
1414
base.supported_sanitizers =
1515
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
16+
base.supports_fentry = true;
1617

1718
Target {
1819
llvm_target: "s390x-unknown-linux-musl".into(),

compiler/rustc_target/src/spec/targets/s390x_unknown_none_softfloat.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub(crate) fn target() -> Target {
2020
rustc_abi: Some(RustcAbi::Softfloat),
2121
stack_probes: StackProbeType::Inline,
2222
supported_sanitizers: SanitizerSet::KERNELADDRESS,
23+
supports_fentry: true,
2324
..Default::default()
2425
};
2526

0 commit comments

Comments
 (0)