Skip to content

Add -Zinstrument-mcount=fentry to -Zinstrument-mcount#158036

Open
pmur wants to merge 2 commits into
rust-lang:mainfrom
pmur:murp/add-fentry
Open

Add -Zinstrument-mcount=fentry to -Zinstrument-mcount#158036
pmur wants to merge 2 commits into
rust-lang:mainfrom
pmur:murp/add-fentry

Conversation

@pmur

@pmur pmur commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

fentry is essentially a simpler version of mcount where the counting function is called before any other function prologue actions happen.

fentry is still used by the linux x86-64 kernel. It's unclear if or when patchable-function-entry will replace it. It is also used by clang for some x86-64 mingw toolchains.

This is only supported on some x86, x86-64, and s390x targets.

@rustbot

rustbot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

These commits modify compiler targets.
(See the Target Tier Policy.)

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 17, 2026
@rustbot

rustbot commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

r? @jackh726

rustbot has assigned @jackh726.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 20 candidates

@rust-log-analyzer

This comment has been minimized.

fentry is essentially a simpler version of mcount where the
counting function is called before any other function prologue
actions happen.

fentry is still used by the linux x86-64 kernel. It's unclear if
or when patchable-function-entry will replace it. It is also used
by clang for some x86-64 mingw toolchains.

This is only supported on some x86, x86-64, and s390x targets.
@pmur pmur force-pushed the murp/add-fentry branch from 245af6c to 6ce0650 Compare June 17, 2026 18:10
@pmur

pmur commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

@rustbot reroll

@rustbot rustbot assigned chenyukang and unassigned jackh726 Jun 22, 2026
@chenyukang

Copy link
Copy Markdown
Member

@rustbot reroll

@rustbot rustbot assigned folkertdev and unassigned chenyukang Jun 22, 2026
@folkertdev

Copy link
Copy Markdown
Contributor

What's the context/impetus for adding this? Is it for RfL?

@pmur

pmur commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

RfL. It is still used by x86, and likely not going away anytime soon.

x86 is using patchable function entries exclusively for security mitigation techniques.

Comment on lines +258 to +267
/// The different settings that the `-Z Instrument-mcount` flag can have.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum InstrumentMcount {
/// `-Z instrument-mcount=no`
Disabled,
/// `-Z instrument-mcount=yes`
Mcount,
/// `-Z instrument-mcount=fentry`
Fentry,
}

@folkertdev folkertdev Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole -Z instrument-mcount is missing an entry in the unstable book, can you add one in src/doc/unstable-book/src/compiler-flags/?

We at least try to document things from first principles, rather than just deferring to clang/LLVM.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I have been working on that. Making a simple example of a Rust mcount function has been a little a bit trickier than I'd expected. I'll add it.

Comment thread tests/assembly-llvm/fentry.rs
Comment on lines +66 to +94
// Define a custom mcount function. This may partially or fully override the glibc
// implementation depending on linker options.
#[unsafe(naked)]
#[no_mangle]
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub extern "C" fn mcount() {
core::arch::naked_asm!(
// A simplified version based on the glibc x86-64 mcount wrapper.
// Save register arguments to the stack, and call the mcount above.
"push rax",
"push rcx",
"push rdx",
"push rsi",
"push rdi",
"push r8",
"push r9",
"mov rsi, 56[rsp]",
"mov rdi, 8[rbp]",
"call __count_fn",
"pop r9",
"pop r8",
"pop rdi",
"pop rsi",
"pop rdx",
"pop rcx",
"pop rax",
"ret",
)
}

@folkertdev folkertdev Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just linking this, mcount could use extern "custom" #140829 if the ABI is truly custom.

View changes since the review

#[unsafe(naked)]
#[no_mangle]
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub extern "C" fn mcount() {

@folkertdev folkertdev Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub extern "C" fn mcount() {
unsafe extern "C" fn mcount() {

A bunch of things are pub here that really don't need to be. And if this function really has a custom ABI then it should be unsafe to call. Practically it seems fine though because all relevant registers are restored. It would help to write that down as a safety comment on the naked_asm! though.

View changes since the review


In essence, this is implementing the function `fn mcount(caller: *const std::ffi::c_void, callee: *const std::ffi::c_void)`. The calling convention for mcount follows its own ABI, which isn't usually the standard ABI for the target, but is enforced by preexisting convention.

A trivial example on x86_64-unknown-linux-gnu looks something like the following. The `#[instrument_fn]` attribute can be used to disable profiling to simplify writing counting functions, but implementors must be very careful when calling other functions (or closures which fail to inline) as they may also call mcount.

@folkertdev folkertdev Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate a bit more on what this example should do? I get

> RUSTFLAG="-Z instrument-mcount=yes" cargo +nightly run
main() called

> rustc +nightly -vV
rustc 1.98.0-nightly (4429659e4 2026-06-22)
binary: rustc
commit-hash: 4429659e4745016bd3f26a4a421843edc7fbc422
commit-date: 2026-06-22
host: x86_64-unknown-linux-gnu
release: 1.98.0-nightly
LLVM version: 22.1.7

So __count_fn is not actually called?

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants