@@ -2617,6 +2617,15 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2617
2617
// code references on its own.
2618
2618
// See #26591, #27438
2619
2619
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
+ } ;
2620
2629
unsafe {
2621
2630
for ccx in cx. iter ( ) {
2622
2631
let exported: Vec < _ > = iter_globals ( ccx. llmod ( ) )
@@ -2627,12 +2636,13 @@ fn create_imps(cx: &SharedCrateContext) {
2627
2636
let i8p_ty = Type :: i8p ( & ccx) ;
2628
2637
for val in exported {
2629
2638
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 ( ) ) ;
2632
2641
let imp_name = CString :: new ( imp_name) . unwrap ( ) ;
2633
2642
let imp = llvm:: LLVMAddGlobal ( ccx. llmod ( ) , i8p_ty. to_ref ( ) ,
2634
2643
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) ;
2636
2646
llvm:: SetLinkage ( imp, llvm:: ExternalLinkage ) ;
2637
2647
}
2638
2648
}
0 commit comments