Skip to content

Add support for global constructors (i.e. life before main) #4459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 16, 2025

Conversation

ibraheemdev
Copy link
Member

This should resolve #450.

I verified that the inventory crate now works locally on my machine (Linux), but I'm not sure how this should be tested. Would adding inventory as a dependency for tests be acceptable, or should we setup the ctors manually?

@ibraheemdev ibraheemdev force-pushed the ibraheem/global-ctor branch from d12bf49 to 292d768 Compare July 10, 2025 20:13
@RalfJung
Copy link
Member

Thanks for the PR. :)

I would appreciate a test that does the setup itself, that's much easier for debugging future issues should they arise.

@ibraheemdev ibraheemdev force-pushed the ibraheem/global-ctor branch from a139568 to 92ddc4a Compare July 10, 2025 20:39
@ibraheemdev ibraheemdev force-pushed the ibraheem/global-ctor branch 5 times, most recently from ca9cba8 to 3597efd Compare July 11, 2025 00:55
#[cfg_attr(windows, link_section = ".CRT$XCU")]
#[cfg_attr(
any(target_os = "macos", target_os = "ios"),
link_section = "__DATA,__mod_init_func"
Copy link
Member

@bjorn3 bjorn3 Jul 11, 2025

Choose a reason for hiding this comment

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

Suggested change
link_section = "__DATA,__mod_init_func"
link_section = "__DATA,__mod_init_func,mod_init_funcs"

Mach-O requires the S_MOD_INIT_FUNC_POINTERS section flag (mod_init_funcs in link_section). LLVM was accidentally adding this for __DATA,__mod_init_func making it work without explicitly adding ,mod_init_funcs, but I don't know if it guarantees this. See also rust-lang/rustc_codegen_cranelift#1588

Copy link
Member Author

@ibraheemdev ibraheemdev Jul 11, 2025

Choose a reason for hiding this comment

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

From the Mach-O reference, it looks like mod_init_funcs is not strictly required for the S_MOD_INIT_FUNC_POINTERS to be set. It's possible that this is outdated and retained for backwards compatibility.

S_MOD_INIT_FUNC_POINTERS—This section contains pointers to module initialization functions.
The standard tools create __DATA,__mod_init_funcsections of this type

Copy link
Member

Choose a reason for hiding this comment

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

The docs seem to say that S_MOD_INIT_FUNC_POINTERS indicates init functions, which sounds to me like the flag is required to designate a section of init functions?

Copy link
Member Author

@ibraheemdev ibraheemdev Jul 16, 2025

Choose a reason for hiding this comment

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

I believe the flag is implied on __DATA,__mod_init_func sections, but I'm not sure. LLVM seems to implement it that way and the ecosystem relies on it, so I think it makes sense for Miri to follow.

For this specific test I don't think it matters much whether we specify the flag given that we support it either way, but I can add it if you prefer.

Copy link
Member

Choose a reason for hiding this comment

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

If it is questionable whether the version without the extra tag should work (as opposed to "happens to work due to undocumented LLVM accidents"), then at the very least we need a FIXME comment here clarifying this.

the ecosystem relies on it

Do you have a link for that?

Copy link
Member Author

Choose a reason for hiding this comment

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

The ctor and inventory crates do not set it explicitly.

I can add a comment to the code. I'm not even sure where to find the official Mach-O reference, all I can find are outdated mirrors.

Copy link
Member

@bjorn3 bjorn3 Jul 16, 2025

Choose a reason for hiding this comment

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

LLVM currently implies the flag for __DATA,__mod_init_func (https://github.com/llvm/llvm-project/blob/2e8e254d18f51b6ca898bf0b1e4d12109b5b16c7/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp#L1292-L1304), but I don't know if it actually guarantees this. The implication is because it creates a section with this name with the flag set somewhere and then merges the attributes of all definitions of the same section.

Edit: llvm/llvm-project@cb307a2 seems to have introduced this behavior as part of moving away from using the .mod_init_func assembly directive which implied this flag.

Copy link
Member

Choose a reason for hiding this comment

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

I have added a comment, that should suffice for now -- thanks for the links!

@ibraheemdev
Copy link
Member Author

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Jul 15, 2025
Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

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

Thanks! I'm onboard with the overall architecture, but have a bunch of comments. :)

@ibraheemdev ibraheemdev force-pushed the ibraheem/global-ctor branch 3 times, most recently from 579f876 to 5dc83fd Compare July 15, 2025 21:21
@ibraheemdev ibraheemdev force-pushed the ibraheem/global-ctor branch from 5dc83fd to c18f953 Compare July 15, 2025 21:24
@RalfJung
Copy link
Member

RalfJung commented Jul 16, 2025

Please avoid rebasing over new commits in master and do not force-push unless there are conflicts. Such rebases cause me a bunch of work since Github is pretty bad at dealing with force-pushes.

#[cfg_attr(windows, link_section = ".CRT$XCU")]
#[cfg_attr(
any(target_os = "macos", target_os = "ios"),
link_section = "__DATA,__mod_init_func"
Copy link
Member

Choose a reason for hiding this comment

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

The docs seem to say that S_MOD_INIT_FUNC_POINTERS indicates init functions, which sounds to me like the flag is required to designate a section of init functions?

Co-authored-by: Ralf Jung <post@ralfj.de>
@RalfJung RalfJung force-pushed the ibraheem/global-ctor branch 2 times, most recently from 4da087e to d91863d Compare July 16, 2025 10:04
@RalfJung RalfJung force-pushed the ibraheem/global-ctor branch 2 times, most recently from f2781da to 5a776d7 Compare July 16, 2025 10:31
@RalfJung RalfJung force-pushed the ibraheem/global-ctor branch from 5a776d7 to c05d20f Compare July 16, 2025 10:34
@RalfJung RalfJung enabled auto-merge July 16, 2025 10:35
@ibraheemdev
Copy link
Member Author

Thanks for pushing this forward!

@RalfJung RalfJung added this pull request to the merge queue Jul 16, 2025
Merged via the queue into rust-lang:master with commit 807129c Jul 16, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Waiting for a review to complete
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Evaluate global constructors (life before main)
5 participants