@@ -71,9 +71,13 @@ pub struct CodegenCx<'ll, 'tcx> {
7171 /// to constants.)
7272 pub statics_to_rauw : RefCell < Vec < ( & ' ll Value , & ' ll Value ) > > ,
7373
74+ /// Statics that will be placed in the llvm.used variable
75+ /// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
76+ pub used_statics : RefCell < Vec < & ' ll Value > > ,
77+
7478 /// Statics that will be placed in the llvm.compiler.used variable
7579 /// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
76- pub used_statics : RefCell < Vec < & ' ll Value > > ,
80+ pub compiler_used_statics : RefCell < Vec < & ' ll Value > > ,
7781
7882 /// Mapping of non-scalar types to llvm types and field remapping if needed.
7983 pub type_lowering : RefCell < FxHashMap < ( Ty < ' tcx > , Option < VariantIdx > ) , TypeLowering < ' ll > > > ,
@@ -325,6 +329,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
325329 const_globals : Default :: default ( ) ,
326330 statics_to_rauw : RefCell :: new ( Vec :: new ( ) ) ,
327331 used_statics : RefCell :: new ( Vec :: new ( ) ) ,
332+ compiler_used_statics : RefCell :: new ( Vec :: new ( ) ) ,
328333 type_lowering : Default :: default ( ) ,
329334 scalar_lltypes : Default :: default ( ) ,
330335 pointee_infos : Default :: default ( ) ,
@@ -347,6 +352,18 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
347352 pub fn coverage_context ( & ' a self ) -> Option < & ' a coverageinfo:: CrateCoverageContext < ' ll , ' tcx > > {
348353 self . coverage_cx . as_ref ( )
349354 }
355+
356+ fn create_used_variable_impl ( & self , name : & ' static CStr , values : & [ & ' ll Value ] ) {
357+ let section = cstr ! ( "llvm.metadata" ) ;
358+ let array = self . const_array ( & self . type_ptr_to ( self . type_i8 ( ) ) , values) ;
359+
360+ unsafe {
361+ let g = llvm:: LLVMAddGlobal ( self . llmod , self . val_ty ( array) , name. as_ptr ( ) ) ;
362+ llvm:: LLVMSetInitializer ( g, array) ;
363+ llvm:: LLVMRustSetLinkage ( g, llvm:: Linkage :: AppendingLinkage ) ;
364+ llvm:: LLVMSetSection ( g, section. as_ptr ( ) ) ;
365+ }
366+ }
350367}
351368
352369impl MiscMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
@@ -437,6 +454,10 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
437454 & self . used_statics
438455 }
439456
457+ fn compiler_used_statics ( & self ) -> & RefCell < Vec < & ' ll Value > > {
458+ & self . compiler_used_statics
459+ }
460+
440461 fn set_frame_pointer_type ( & self , llfn : & ' ll Value ) {
441462 attributes:: set_frame_pointer_type ( self , llfn)
442463 }
@@ -447,23 +468,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
447468 }
448469
449470 fn create_used_variable ( & self ) {
450- // The semantics of #[used] in Rust only require the symbol to make it into the object
451- // file. It is explicitly allowed for the linker to strip the symbol if it is dead.
452- // As such, use llvm.compiler.used instead of llvm.used.
453- // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
454- // sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs in
455- // some versions of the gold linker.
456- let name = cstr ! ( "llvm.compiler.used" ) ;
457- let section = cstr ! ( "llvm.metadata" ) ;
458- let array =
459- self . const_array ( & self . type_ptr_to ( self . type_i8 ( ) ) , & * self . used_statics . borrow ( ) ) ;
471+ self . create_used_variable_impl ( cstr ! ( "llvm.used" ) , & * self . used_statics . borrow ( ) ) ;
472+ }
460473
461- unsafe {
462- let g = llvm:: LLVMAddGlobal ( self . llmod , self . val_ty ( array) , name. as_ptr ( ) ) ;
463- llvm:: LLVMSetInitializer ( g, array) ;
464- llvm:: LLVMRustSetLinkage ( g, llvm:: Linkage :: AppendingLinkage ) ;
465- llvm:: LLVMSetSection ( g, section. as_ptr ( ) ) ;
466- }
474+ fn create_compiler_used_variable ( & self ) {
475+ self . create_used_variable_impl (
476+ cstr ! ( "llvm.compiler.used" ) ,
477+ & * self . compiler_used_statics . borrow ( ) ,
478+ ) ;
467479 }
468480
469481 fn declare_c_main ( & self , fn_type : Self :: Type ) -> Option < Self :: Function > {
0 commit comments