Skip to content

Commit a2719a2

Browse files
committed
Fix linker error when inline asm sym operand is not exported from local CGU
1 parent 2e93be3 commit a2719a2

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool {
255255
}
256256

257257
pub(crate) fn create_wrapper_function(
258-
module: &mut impl Module,
258+
module: &mut dyn Module,
259259
unwind_context: &mut UnwindContext,
260260
sig: Signature,
261261
wrapper_name: &str,

src/inline_asm.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::fmt::Write;
66

77
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
88
use rustc_middle::mir::InlineAsmOperand;
9-
use rustc_middle::ty::SymbolName;
109
use rustc_span::sym;
1110
use rustc_target::asm::*;
1211

@@ -30,7 +29,7 @@ enum CInlineAsmOperand<'tcx> {
3029
value: String,
3130
},
3231
Symbol {
33-
symbol: SymbolName<'tcx>,
32+
symbol: String,
3433
},
3534
}
3635

@@ -263,15 +262,37 @@ pub(crate) fn codegen_inline_asm<'tcx>(
263262
substs,
264263
)
265264
.unwrap();
266-
CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance) }
265+
let symbol = fx.tcx.symbol_name(instance);
266+
267+
// Pass a wrapper rather than the function itself as the function itself may not
268+
// be exported from the main codegen unit and may thus be unreachable from the
269+
// object file created by an external assembler.
270+
let inline_asm_index = fx.cx.inline_asm_index.get();
271+
fx.cx.inline_asm_index.set(inline_asm_index + 1);
272+
let wrapper_name = format!(
273+
"__inline_asm_{}_wrapper_n{}",
274+
fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"),
275+
inline_asm_index
276+
);
277+
let sig =
278+
get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance);
279+
create_wrapper_function(
280+
fx.module,
281+
&mut fx.cx.unwind_context,
282+
sig,
283+
&wrapper_name,
284+
symbol.name,
285+
);
286+
287+
CInlineAsmOperand::Symbol { symbol: wrapper_name }
267288
} else {
268289
span_bug!(span, "invalid type for asm sym (fn)");
269290
}
270291
}
271292
InlineAsmOperand::SymStatic { def_id } => {
272293
assert!(fx.tcx.is_static(def_id));
273294
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
274-
CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance) }
295+
CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() }
275296
}
276297
})
277298
.collect::<Vec<_>>();
@@ -630,7 +651,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
630651
CInlineAsmOperand::Const { ref value } => {
631652
generated_asm.push_str(value);
632653
}
633-
CInlineAsmOperand::Symbol { symbol } => generated_asm.push_str(symbol.name),
654+
CInlineAsmOperand::Symbol { ref symbol } => generated_asm.push_str(symbol),
634655
}
635656
}
636657
}

0 commit comments

Comments
 (0)