Skip to content

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

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
pmur:murp/add-fentry
Jun 26, 2026
Merged

Add -Zinstrument-mcount=fentry to -Zinstrument-mcount#158036
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
pmur:murp/add-fentry

Conversation

@pmur

@pmur pmur commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

View all comments

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

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.

If it compiles and links as I'd hope, it should print something like:

mcount: call from 0x55b6b374478a to 0x55b6b37447f9                                                                               
main() called

It's frustratingly frail when Rust also links the profiling libraries using the default options. Let me investigate, and the example probably shouldn't link default libraries anyways.

I'll also add an fentry hook example for x86.

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.

Oh, I see why the example did not work. A small typo: RUSTFLAG -> RUSTFLAGS.

And... wrapping the example in cargo shows I need a bit more cleanup.

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.

ah, right. Can you include the expected output too?

@pmur pmur force-pushed the murp/add-fentry branch 2 times, most recently from 0921fd6 to f22ba59 Compare June 25, 2026 16:42
@rust-log-analyzer

This comment has been minimized.

Comment thread src/doc/unstable-book/src/compiler-flags/instrument-mcount.md Outdated
@pmur pmur force-pushed the murp/add-fentry branch from f22ba59 to 87514a3 Compare June 25, 2026 17:55
@folkertdev

Copy link
Copy Markdown
Contributor

Looks good!

@bors r+

@rust-bors

rust-bors Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 87514a3 has been approved by folkertdev

It is now in the queue for this repository.

🌲 The tree is currently closed for pull requests below priority 4. This pull request will be tested once the tree is reopened.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 25, 2026
rust-bors Bot pushed a commit that referenced this pull request Jun 25, 2026
Rollup of 10 pull requests

Successful merges:

 - #158410 (Update LLVM for Mach-O __LINKEDIT alignment fix.)
 - #157397 (cmse: clear padding when crossing the secure boundary)
 - #158036 (Add -Zinstrument-mcount=fentry to -Zinstrument-mcount)
 - #158330 (llvm: use intrinsics for f16, f32 minimum/maximum)
 - #158359 (fix(tests): allow either branch direction in ilog_known_base)
 - #158067 (LLVM 23: Adapt codegen test to moved assume)
 - #158261 (Move part of the target checking for `#[may_dangle]` to the parser)
 - #158358 (Fix invalid E0609 raw pointer deref suggestion inside macros)
 - #158392 (delegation: add tests for defaults and infers in generics)
 - #158394 (Generate synthetic generic args only for delegation's child segment)
@rust-bors rust-bors Bot merged commit a82172d into rust-lang:main Jun 26, 2026
13 checks passed
@rustbot rustbot added this to the 1.98.0 milestone Jun 26, 2026
rust-timer added a commit that referenced this pull request Jun 26, 2026
Rollup merge of #158036 - pmur:murp/add-fentry, r=folkertdev

Add -Zinstrument-mcount=fentry to -Zinstrument-mcount

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.
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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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