Skip to content

Commit 25354de

Browse files
committed
trans: Fix __imp_ creation for i686 MSVC
Turns out the symbol names are slightly different on 32-bit than on 64, so the prefix needs to be tweaked just a bit!
1 parent 19fe7b6 commit 25354de

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/librustc_trans/trans/base.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -2617,6 +2617,15 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
26172617
// code references on its own.
26182618
// See #26591, #27438
26192619
fn create_imps(cx: &SharedCrateContext) {
2620+
// The x86 ABI seems to require that leading underscores are added to symbol
2621+
// names, so we need an extra underscore on 32-bit. There's also a leading
2622+
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
2623+
// underscores added in front).
2624+
let prefix = if cx.sess().target.target.target_pointer_width == "32" {
2625+
"\x01__imp__"
2626+
} else {
2627+
"\x01__imp_"
2628+
};
26202629
unsafe {
26212630
for ccx in cx.iter() {
26222631
let exported: Vec<_> = iter_globals(ccx.llmod())
@@ -2627,12 +2636,13 @@ fn create_imps(cx: &SharedCrateContext) {
26272636
let i8p_ty = Type::i8p(&ccx);
26282637
for val in exported {
26292638
let name = CStr::from_ptr(llvm::LLVMGetValueName(val));
2630-
let imp_name = String::from("__imp_") +
2631-
str::from_utf8(name.to_bytes()).unwrap();
2639+
let mut imp_name = prefix.as_bytes().to_vec();
2640+
imp_name.extend(name.to_bytes());
26322641
let imp_name = CString::new(imp_name).unwrap();
26332642
let imp = llvm::LLVMAddGlobal(ccx.llmod(), i8p_ty.to_ref(),
26342643
imp_name.as_ptr() as *const _);
2635-
llvm::LLVMSetInitializer(imp, llvm::LLVMConstBitCast(val, i8p_ty.to_ref()));
2644+
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
2645+
llvm::LLVMSetInitializer(imp, init);
26362646
llvm::SetLinkage(imp, llvm::ExternalLinkage);
26372647
}
26382648
}

0 commit comments

Comments
 (0)