rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.97k stars 12.68k forks source link

Add SVH based symbol to dylibs #73917

Open bjorn3 opened 4 years ago

bjorn3 commented 4 years ago

Any upstream dylib and executable can then require that symbol to be present to prevent mixing up different versions of a dylib at runtime. This symbol only needs to exist for dylibs, not cdylibs or rlibs.

See https://internals.rust-lang.org/t/stability-of-dylibs-per-compiler-release/12648/10 for the discussion about this.

@rustbot modify labels: +C-enhancement +T-compiler

mzabaluev commented 4 years ago

All regular dynamic symbols created by the Rust compiler already embed some form of a hash, though as I understood from the discussion linked above, the source data for that are not sufficient to guarantee against ABI breakage.

gilescope commented 4 years ago

Will try and attempt this as part of #75594

gilescope commented 4 years ago

In compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs fn save_map_to_mod, they do llvm::add_global. Is that a good way to add a symbol?

bjorn3 commented 4 years ago

You could do it similar to the dylib metadata writing: https://github.com/rust-lang/rust/blob/85fbf49ce0e2274d0acf798f6e703747674feec3/compiler/rustc_codegen_llvm/src/base.rs#L57-L72

gilescope commented 4 years ago

Hmm, I can't see any section for that code appearing in an OSX executable. I was expecting a section called __DATA,.rustc to be somewhere in the resulting binary, but I can't find it.

bjorn3 commented 4 years ago

You may need to set the S_ATTR_NO_DEAD_STRIP section flag for Mach-O objects through some way.

gilescope commented 4 years ago

Am close. Got it coming out for exes and am adding it in for dylibs. Just need to stop it stripping for dylib and definitely can't use the reference it from main trick with a dylib! I tried .section __DATA,.rust_svh_hash,no_dead_strip but got:

error: mach-o section specifier uses an unknown section type

So there must be some cunning way to flick that on...

gilescope commented 3 years ago

Ok so this is done for dylibs now in the PR, just not for cdylibs yet.

eddyb commented 2 years ago

Duplicating/moving from my comment at https://github.com/rust-lang/rust/pull/99944#discussion_r933949542:

struct LinkGuard {
    deps: &'static [&'static LinkGuard],
}

extern "Rust" {
    // foo[b7924b40b7ed5e7f]::{shim:LINK_GUARD#0}::<0x461e83de35f0b704f7e69b4cc741ad8eu128>
    #[link_name = "_RINSCsfL95rG4I7iB_3foo10LINK_GUARDKo461e83de35f0b704f7e69b4cc741ad8e_E"] 
    static LINK_GUARD_DEP_FOO: LinkGuard;

    // bar[acb4b2d152c0bd2e]::{shim:LINK_GUARD#0}::<0xf8fc0fadc6a6e727eef4b916531abfe9u128>
    #[link_name = "_RINSCsePjaApBJGQA_3bar10LINK_GUARDKof8fc0fadc6a6e727eef4b916531abfe9_E"] 
    static LINK_GUARD_DEP_BAR: LinkGuard;
}

// my_crate[78009e3fbfa2f6af]::{shim:LINK_GUARD#0}::<0xe538955c5950b59a598304a1e701c9fbu128>
#[export_name = "_RINSCsaiLK1vfX74x_8my_crate10LINK_GUARDKoe538955c5950b59a598304a1e701c9fb_E"]
pub static LINK_GUARD: LinkGuard {
    deps: unsafe { &[
        &LINK_GUARD_DEP_FOO,
        &LINK_GUARD_DEP_BAR,
    ] }
};

The idea being that these LinkGuard statics: