@@ -2570,20 +2570,6 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2570
2570
unsafe {
2571
2571
let mut declared = HashSet :: new ( ) ;
2572
2572
2573
- let iter_globals = |llmod| {
2574
- ValueIter {
2575
- cur : llvm:: LLVMGetFirstGlobal ( llmod) ,
2576
- step : llvm:: LLVMGetNextGlobal ,
2577
- }
2578
- } ;
2579
-
2580
- let iter_functions = |llmod| {
2581
- ValueIter {
2582
- cur : llvm:: LLVMGetFirstFunction ( llmod) ,
2583
- step : llvm:: LLVMGetNextFunction ,
2584
- }
2585
- } ;
2586
-
2587
2573
// Collect all external declarations in all compilation units.
2588
2574
for ccx in cx. iter ( ) {
2589
2575
for val in iter_globals ( ccx. llmod ( ) ) . chain ( iter_functions ( ccx. llmod ( ) ) ) {
@@ -2623,28 +2609,83 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2623
2609
}
2624
2610
}
2625
2611
}
2612
+ }
2613
+
2614
+ // Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
2615
+ // This is required to satisfy `dllimport` references to static data in .rlibs
2616
+ // when using MSVC linker. We do this only for data, as linker can fix up
2617
+ // code references on its own.
2618
+ // See #26591, #27438
2619
+ fn create_imps ( cx : & SharedCrateContext ) {
2620
+ // The x86 ABI seems to require that leading underscores are added to symbol
2621
+ // names, so we need an extra underscore on 32-bit. There's also a leading
2622
+ // '\x01' here which disables LLVM's symbol mangling (e.g. no extra
2623
+ // underscores added in front).
2624
+ let prefix = if cx. sess ( ) . target . target . target_pointer_width == "32" {
2625
+ "\x01 __imp__"
2626
+ } else {
2627
+ "\x01 __imp_"
2628
+ } ;
2629
+ unsafe {
2630
+ for ccx in cx. iter ( ) {
2631
+ let exported: Vec < _ > = iter_globals ( ccx. llmod ( ) )
2632
+ . filter ( |& val| llvm:: LLVMGetLinkage ( val) == llvm:: ExternalLinkage as c_uint &&
2633
+ llvm:: LLVMIsDeclaration ( val) == 0 )
2634
+ . collect ( ) ;
2635
+
2636
+ let i8p_ty = Type :: i8p ( & ccx) ;
2637
+ for val in exported {
2638
+ let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) ) ;
2639
+ let mut imp_name = prefix. as_bytes ( ) . to_vec ( ) ;
2640
+ imp_name. extend ( name. to_bytes ( ) ) ;
2641
+ let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
2642
+ let imp = llvm:: LLVMAddGlobal ( ccx. llmod ( ) , i8p_ty. to_ref ( ) ,
2643
+ imp_name. as_ptr ( ) as * const _ ) ;
2644
+ let init = llvm:: LLVMConstBitCast ( val, i8p_ty. to_ref ( ) ) ;
2645
+ llvm:: LLVMSetInitializer ( imp, init) ;
2646
+ llvm:: SetLinkage ( imp, llvm:: ExternalLinkage ) ;
2647
+ }
2648
+ }
2649
+ }
2650
+ }
2626
2651
2652
+ struct ValueIter {
2653
+ cur : ValueRef ,
2654
+ step : unsafe extern "C" fn ( ValueRef ) -> ValueRef ,
2655
+ }
2656
+
2657
+ impl Iterator for ValueIter {
2658
+ type Item = ValueRef ;
2627
2659
2628
- struct ValueIter {
2629
- cur : ValueRef ,
2630
- step : unsafe extern "C" fn ( ValueRef ) -> ValueRef ,
2660
+ fn next ( & mut self ) -> Option < ValueRef > {
2661
+ let old = self . cur ;
2662
+ if !old. is_null ( ) {
2663
+ self . cur = unsafe {
2664
+ let step: unsafe extern "C" fn ( ValueRef ) -> ValueRef =
2665
+ mem:: transmute_copy ( & self . step ) ;
2666
+ step ( old)
2667
+ } ;
2668
+ Some ( old)
2669
+ } else {
2670
+ None
2671
+ }
2631
2672
}
2673
+ }
2632
2674
2633
- impl Iterator for ValueIter {
2634
- type Item = ValueRef ;
2675
+ fn iter_globals ( llmod : llvm:: ModuleRef ) -> ValueIter {
2676
+ unsafe {
2677
+ ValueIter {
2678
+ cur : llvm:: LLVMGetFirstGlobal ( llmod) ,
2679
+ step : llvm:: LLVMGetNextGlobal ,
2680
+ }
2681
+ }
2682
+ }
2635
2683
2636
- fn next ( & mut self ) -> Option < ValueRef > {
2637
- let old = self . cur ;
2638
- if !old. is_null ( ) {
2639
- self . cur = unsafe {
2640
- let step: unsafe extern "C" fn ( ValueRef ) -> ValueRef =
2641
- mem:: transmute_copy ( & self . step ) ;
2642
- step ( old)
2643
- } ;
2644
- Some ( old)
2645
- } else {
2646
- None
2647
- }
2684
+ fn iter_functions ( llmod : llvm:: ModuleRef ) -> ValueIter {
2685
+ unsafe {
2686
+ ValueIter {
2687
+ cur : llvm:: LLVMGetFirstFunction ( llmod) ,
2688
+ step : llvm:: LLVMGetNextFunction ,
2648
2689
}
2649
2690
}
2650
2691
}
@@ -2824,6 +2865,11 @@ pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslat
2824
2865
& reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
2825
2866
}
2826
2867
2868
+ if sess. target . target . options . is_like_msvc &&
2869
+ sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ) {
2870
+ create_imps ( & shared_ccx) ;
2871
+ }
2872
+
2827
2873
let metadata_module = ModuleTranslation {
2828
2874
llcx : shared_ccx. metadata_llcx ( ) ,
2829
2875
llmod : shared_ccx. metadata_llmod ( ) ,
0 commit comments