about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-01 06:18:59 +0000
committerbors <bors@rust-lang.org>2015-10-01 06:18:59 +0000
commite5ba127734f7754a326d3197229e94c8a5a3be23 (patch)
tree6f53049bbb05a66945adb46bf68bf583c2fbe6dd
parent587be42d0bd318d6c2f41fe4716e040366dc8951 (diff)
parent25354de928f56924b7cbc28a2132e6110262cb57 (diff)
downloadrust-e5ba127734f7754a326d3197229e94c8a5a3be23.tar.gz
rust-e5ba127734f7754a326d3197229e94c8a5a3be23.zip
Auto merge of #28741 - alexcrichton:fix-msvc-32, r=vadimcn
Turns out the symbol names are slightly different on 32-bit than on 64, so the
prefix needs to be tweaked just a bit!
-rw-r--r--src/librustc_trans/trans/base.rs16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 9dab5c2f514..528b8f9e532 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2617,6 +2617,15 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
 // code references on its own.
 // See #26591, #27438
 fn create_imps(cx: &SharedCrateContext) {
+    // The x86 ABI seems to require that leading underscores are added to symbol
+    // names, so we need an extra underscore on 32-bit. There's also a leading
+    // '\x01' here which disables LLVM's symbol mangling (e.g. no extra
+    // underscores added in front).
+    let prefix = if cx.sess().target.target.target_pointer_width == "32" {
+        "\x01__imp__"
+    } else {
+        "\x01__imp_"
+    };
     unsafe {
         for ccx in cx.iter() {
             let exported: Vec<_> = iter_globals(ccx.llmod())
@@ -2627,12 +2636,13 @@ fn create_imps(cx: &SharedCrateContext) {
             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 mut imp_name = prefix.as_bytes().to_vec();
+                imp_name.extend(name.to_bytes());
                 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()));
+                let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
+                llvm::LLVMSetInitializer(imp, init);
                 llvm::SetLinkage(imp, llvm::ExternalLinkage);
             }
         }