@@ -71,9 +71,13 @@ pub struct CodegenCx<'ll, 'tcx> {
71
71
/// to constants.)
72
72
pub statics_to_rauw : RefCell < Vec < ( & ' ll Value , & ' ll Value ) > > ,
73
73
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
+
74
78
/// Statics that will be placed in the llvm.compiler.used variable
75
79
/// 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 > > ,
77
81
78
82
/// Mapping of non-scalar types to llvm types and field remapping if needed.
79
83
pub type_lowering : RefCell < FxHashMap < ( Ty < ' tcx > , Option < VariantIdx > ) , TypeLowering < ' ll > > > ,
@@ -325,6 +329,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
325
329
const_globals : Default :: default ( ) ,
326
330
statics_to_rauw : RefCell :: new ( Vec :: new ( ) ) ,
327
331
used_statics : RefCell :: new ( Vec :: new ( ) ) ,
332
+ compiler_used_statics : RefCell :: new ( Vec :: new ( ) ) ,
328
333
type_lowering : Default :: default ( ) ,
329
334
scalar_lltypes : Default :: default ( ) ,
330
335
pointee_infos : Default :: default ( ) ,
@@ -347,6 +352,18 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
347
352
pub fn coverage_context ( & ' a self ) -> Option < & ' a coverageinfo:: CrateCoverageContext < ' ll , ' tcx > > {
348
353
self . coverage_cx . as_ref ( )
349
354
}
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
+ }
350
367
}
351
368
352
369
impl MiscMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
@@ -437,6 +454,10 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
437
454
& self . used_statics
438
455
}
439
456
457
+ fn compiler_used_statics ( & self ) -> & RefCell < Vec < & ' ll Value > > {
458
+ & self . compiler_used_statics
459
+ }
460
+
440
461
fn set_frame_pointer_type ( & self , llfn : & ' ll Value ) {
441
462
attributes:: set_frame_pointer_type ( self , llfn)
442
463
}
@@ -447,23 +468,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
447
468
}
448
469
449
470
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
+ }
460
473
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
+ ) ;
467
479
}
468
480
469
481
fn declare_c_main ( & self , fn_type : Self :: Type ) -> Option < Self :: Function > {
0 commit comments