File tree Expand file tree Collapse file tree 3 files changed +75
-0
lines changed
tests/run-make/rust-lld-encapsulation-symbol Expand file tree Collapse file tree 3 files changed +75
-0
lines changed Original file line number Diff line number Diff line change 1+ #![ crate_type = "rlib" ]
2+
3+ // This file contains a very minimalistic reproduction of what the
4+ // linkme (https://github.com/dtolnay/linkme) crate does.
5+ // This linker behavior fails with LLD without -znostart-stop-gc.
6+
7+ type Item = fn ( u32 ) ;
8+
9+ pub struct DistributedSlice {
10+ section_start : * const Item ,
11+ section_stop : * const Item ,
12+ }
13+
14+ unsafe impl Sync for DistributedSlice { }
15+
16+ impl DistributedSlice {
17+ pub fn get_slice ( & self ) -> & ' static [ Item ] {
18+ let stride = std:: mem:: size_of :: < Item > ( ) ;
19+ let start = self . section_start ;
20+ let stop = self . section_stop ;
21+ let byte_offset = stop as usize - start as usize ;
22+ let len = byte_offset / stride;
23+ unsafe { std:: slice:: from_raw_parts ( start, len) }
24+ }
25+ }
26+
27+ pub static EXTERN_FNS : DistributedSlice = {
28+ unsafe extern "Rust" {
29+ // The __start_ and __stop_ section names are magical for the linker,
30+ // It will put link sections named EXTERNFNS in-between them.
31+ #[ link_name = "__start_EXTERNFNS" ]
32+ static SECTION_START : Item ;
33+ #[ link_name = "__stop_EXTERNFNS" ]
34+ static SECTION_STOP : Item ;
35+ }
36+ DistributedSlice {
37+ section_start : & raw const SECTION_START ,
38+ section_stop : & raw const SECTION_STOP
39+ }
40+ } ;
Original file line number Diff line number Diff line change 1+ extern crate dep;
2+
3+ use dep:: EXTERN_FNS ;
4+
5+ // Add a function to the distributed slice contained in
6+ // the EXTERNFNS link section.
7+ #[ used]
8+ #[ unsafe( link_section = "EXTERNFNS" ) ]
9+ pub static EXTERN_FN_LOCAL : fn ( u32 ) = extern_fn;
10+
11+ fn extern_fn ( x : u32 ) {
12+ println ! ( "{x}" ) ;
13+ }
14+
15+ fn main ( ) {
16+ for func in EXTERN_FNS . get_slice ( ) {
17+ func ( 42 ) ;
18+ }
19+ }
Original file line number Diff line number Diff line change 1+ // This test checks that when certain link sections are not garbage
2+ // collected by LLD. The compiler needs to use the -znostart-stop-gc flag for LLD,
3+ // otherwise this test will fail.
4+ // The test replicates the behavior of the linkme crate.
5+ //
6+ //@ needs-rust-lld
7+ //@ only-x86_64-unknown-linux-gnu
8+
9+ use run_make_support:: { cmd, rustc} ;
10+
11+ fn main ( ) {
12+ rustc ( ) . input ( "dep.rs" ) . run ( ) ;
13+ rustc ( ) . input ( "foo.rs" ) . run ( ) ;
14+
15+ cmd ( "./foo" ) . run ( ) . assert_stdout_equals ( "42\n " ) ;
16+ }
You can’t perform that action at this time.
0 commit comments