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:: { run, rustc} ;
10
+
11
+ fn main ( ) {
12
+ rustc ( ) . input ( "dep.rs" ) . run ( ) ;
13
+ rustc ( ) . input ( "foo.rs" ) . run ( ) ;
14
+
15
+ run ( "foo" ) . assert_stdout_equals ( "42\n " ) ;
16
+ }
0 commit comments