@@ -2570,20 +2570,6 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
25702570 unsafe {
25712571 let mut declared = HashSet :: new ( ) ;
25722572
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-
25872573 // Collect all external declarations in all compilation units.
25882574 for ccx in cx. iter ( ) {
25892575 for val in iter_globals ( ccx. llmod ( ) ) . chain ( iter_functions ( ccx. llmod ( ) ) ) {
@@ -2623,28 +2609,74 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
26232609 }
26242610 }
26252611 }
2612+ }
26262613
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 {
26272621
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+ }
26312640 }
2641+ }
26322642
2633- impl Iterator for ValueIter {
2634- type Item = ValueRef ;
2643+ struct ValueIter {
2644+ cur : ValueRef ,
2645+ step : unsafe extern "C" fn ( ValueRef ) -> ValueRef ,
2646+ }
26352647
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 ,
26482680 }
26492681 }
26502682}
@@ -2824,6 +2856,12 @@ pub fn trans_crate(tcx: &ty::ctxt, analysis: ty::CrateAnalysis) -> CrateTranslat
28242856 & reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
28252857 }
28262858
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+
28272865 let metadata_module = ModuleTranslation {
28282866 llcx : shared_ccx. metadata_llcx ( ) ,
28292867 llmod : shared_ccx. metadata_llmod ( ) ,
0 commit comments