unsafe {
let mut declared = HashSet::new();
- let iter_globals = |llmod| {
- ValueIter {
- cur: llvm::LLVMGetFirstGlobal(llmod),
- step: llvm::LLVMGetNextGlobal,
- }
- };
-
- let iter_functions = |llmod| {
- ValueIter {
- cur: llvm::LLVMGetFirstFunction(llmod),
- step: llvm::LLVMGetNextFunction,
- }
- };
-
// Collect all external declarations in all compilation units.
for ccx in cx.iter() {
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
}
}
}
+}
+// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
+// This is required to satisfy `dllimport` references to static data in .rlibs
+// when using MSVC linker. We do this only for data, as linker can fix up
+// code references on its own.
+// See #26591, #27438
+fn create_imps(cx: &SharedCrateContext, _reachable: &HashSet<&str>) {
+ unsafe {
- struct ValueIter {
- cur: ValueRef,
- step: unsafe extern "C" fn(ValueRef) -> ValueRef,
+ for ccx in cx.iter() {
+ let exported: Vec<_> = iter_globals(ccx.llmod())
+ .filter(|&val| llvm::LLVMGetLinkage(val) == llvm::ExternalLinkage as c_uint &&
+ llvm::LLVMIsDeclaration(val) == 0)
+ .collect();
+
+ let i8p_ty = Type::i8p(&ccx);
+ for val in exported {
+ let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
+ let imp_name = String::from("__imp_") +
+ str::from_utf8(name.to_bytes()).unwrap();
+ let imp_name = CString::new(imp_name).unwrap();
+ let imp = llvm::LLVMAddGlobal(ccx.llmod(), i8p_ty.to_ref(),
+ imp_name.as_ptr() as *const _);
+ llvm::LLVMSetInitializer(imp, llvm::LLVMConstBitCast(val, i8p_ty.to_ref()));
+ llvm::SetLinkage(imp, llvm::ExternalLinkage);
+ }
+ }
}
+}
- impl Iterator for ValueIter {
- type Item = ValueRef;
+struct ValueIter {
+ cur: ValueRef,
+ step: unsafe extern "C" fn(ValueRef) -> ValueRef,
+}
- fn next(&mut self) -> Option<ValueRef> {
- let old = self.cur;
- if !old.is_null() {
- self.cur = unsafe {
- let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
- mem::transmute_copy(&self.step);
- step(old)
- };
- Some(old)
- } else {
- None
- }
+impl Iterator for ValueIter {
+ type Item = ValueRef;
+
+ fn next(&mut self) -> Option<ValueRef> {
+ let old = self.cur;
+ if !old.is_null() {
+ self.cur = unsafe {
+ let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
+ mem::transmute_copy(&self.step);
+ step(old)
+ };
+ Some(old)
+ } else {
+ None
+ }
+ }
+}
+
+fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter {
+ unsafe {
+ ValueIter {
+ cur: llvm::LLVMGetFirstGlobal(llmod),
+ step: llvm::LLVMGetNextGlobal,
+ }
+ }
+}
+
+fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
+ unsafe {
+ ValueIter {
+ cur: llvm::LLVMGetFirstFunction(llmod),
+ step: llvm::LLVMGetNextFunction,
}
}
}
&reachable_symbols.iter().map(|x| &x[..]).collect());
}
+ if sess.target.target.options.is_like_msvc &&
+ sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateTypeRlib ||
+ *ct == config::CrateTypeStaticlib) {
+ create_imps(&shared_ccx, &reachable_symbols.iter().map(|x| &x[..]).collect());
+ }
+
let metadata_module = ModuleTranslation {
llcx: shared_ccx.metadata_llcx(),
llmod: shared_ccx.metadata_llmod(),
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo;
+
+fn main() {
+ println!("The answer is {} !", foo::FOO);
+}
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+
+pub static FOO: i32 = 42;