@@ -2617,6 +2617,15 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
26172617// code references on its own.
26182618// See #26591, #27438
26192619fn 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