@@ -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,74 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2623
2609
}
2624
2610
}
2625
2611
}
2612
+ }
2626
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 , _reachable : & HashSet < & str > ) {
2620
+ unsafe {
2627
2621
2628
- struct ValueIter {
2629
- cur : ValueRef ,
2630
- step : unsafe extern "C" fn ( ValueRef ) -> ValueRef ,
2622
+ for ccx in cx. iter ( ) {
2623
+ let exported: Vec < _ > = iter_globals ( ccx. llmod ( ) )
2624
+ . filter ( |& val| llvm:: LLVMGetLinkage ( val) == llvm:: ExternalLinkage as c_uint &&
2625
+ llvm:: LLVMIsDeclaration ( val) == 0 )
2626
+ . collect ( ) ;
2627
+
2628
+ let i8p_ty = Type :: i8p ( & ccx) ;
2629
+ for val in exported {
2630
+ let name = CStr :: from_ptr ( llvm:: LLVMGetValueName ( val) ) ;
2631
+ let imp_name = String :: from ( "__imp_" ) +
2632
+ str:: from_utf8 ( name. to_bytes ( ) ) . unwrap ( ) ;
2633
+ let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
2634
+ let imp = llvm:: LLVMAddGlobal ( ccx. llmod ( ) , i8p_ty. to_ref ( ) ,
2635
+ imp_name. as_ptr ( ) as * const _ ) ;
2636
+ llvm:: LLVMSetInitializer ( imp, llvm:: LLVMConstBitCast ( val, i8p_ty. to_ref ( ) ) ) ;
2637
+ llvm:: SetLinkage ( imp, llvm:: ExternalLinkage ) ;
2638
+ }
2639
+ }
2631
2640
}
2641
+ }
2632
2642
2633
- impl Iterator for ValueIter {
2634
- type Item = ValueRef ;
2643
+ struct ValueIter {
2644
+ cur : ValueRef ,
2645
+ step : unsafe extern "C" fn ( ValueRef ) -> ValueRef ,
2646
+ }
2635
2647
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
- }
2648
+ impl Iterator for ValueIter {
2649
+ type Item = ValueRef ;
2650
+
2651
+ fn next ( & mut self ) -> Option < ValueRef > {
2652
+ let old = self . cur ;
2653
+ if !old. is_null ( ) {
2654
+ self . cur = unsafe {
2655
+ let step: unsafe extern "C" fn ( ValueRef ) -> ValueRef =
2656
+ mem:: transmute_copy ( & self . step ) ;
2657
+ step ( old)
2658
+ } ;
2659
+ Some ( old)
2660
+ } else {
2661
+ None
2662
+ }
2663
+ }
2664
+ }
2665
+
2666
+ fn iter_globals ( llmod : llvm:: ModuleRef ) -> ValueIter {
2667
+ unsafe {
2668
+ ValueIter {
2669
+ cur : llvm:: LLVMGetFirstGlobal ( llmod) ,
2670
+ step : llvm:: LLVMGetNextGlobal ,
2671
+ }
2672
+ }
2673
+ }
2674
+
2675
+ fn iter_functions ( llmod : llvm:: ModuleRef ) -> ValueIter {
2676
+ unsafe {
2677
+ ValueIter {
2678
+ cur : llvm:: LLVMGetFirstFunction ( llmod) ,
2679
+ step : llvm:: LLVMGetNextFunction ,
2648
2680
}
2649
2681
}
2650
2682
}
@@ -2824,6 +2856,12 @@ pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslat
2824
2856
& reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
2825
2857
}
2826
2858
2859
+ if sess. target . target . options . is_like_msvc &&
2860
+ sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ||
2861
+ * ct == config:: CrateTypeStaticlib ) {
2862
+ create_imps ( & shared_ccx, & reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
2863
+ }
2864
+
2827
2865
let metadata_module = ModuleTranslation {
2828
2866
llcx : shared_ccx. metadata_llcx ( ) ,
2829
2867
llmod : shared_ccx. metadata_llmod ( ) ,
0 commit comments