@@ -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