]> git.lizzy.rs Git - rust.git/commitdiff
Fix linker error when inline asm sym operand is not exported from local CGU
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>
Sun, 5 Feb 2023 17:39:00 +0000 (17:39 +0000)
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>
Sun, 5 Feb 2023 17:39:00 +0000 (17:39 +0000)
src/common.rs
src/inline_asm.rs

index 16ae526090b7ed294725be4b38ff5a836ddbd094..a8be0d32cc8c7c4d6d2948134bf7e8abf2bcd8a7 100644 (file)
@@ -255,7 +255,7 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool {
 }
 
 pub(crate) fn create_wrapper_function(
-    module: &mut impl Module,
+    module: &mut dyn Module,
     unwind_context: &mut UnwindContext,
     sig: Signature,
     wrapper_name: &str,
index aa0b51181f40a8b81f91ac43cbac1438e7c6057e..6206fbf7dd571505c5954fff7cb55e6ee560870c 100644 (file)
@@ -6,7 +6,6 @@
 
 use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_middle::mir::InlineAsmOperand;
-use rustc_middle::ty::SymbolName;
 use rustc_span::sym;
 use rustc_target::asm::*;
 
@@ -30,7 +29,7 @@ enum CInlineAsmOperand<'tcx> {
         value: String,
     },
     Symbol {
-        symbol: SymbolName<'tcx>,
+        symbol: String,
     },
 }
 
@@ -263,7 +262,29 @@ pub(crate) fn codegen_inline_asm<'tcx>(
                         substs,
                     )
                     .unwrap();
-                    CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance) }
+                    let symbol = fx.tcx.symbol_name(instance);
+
+                    // Pass a wrapper rather than the function itself as the function itself may not
+                    // be exported from the main codegen unit and may thus be unreachable from the
+                    // object file created by an external assembler.
+                    let inline_asm_index = fx.cx.inline_asm_index.get();
+                    fx.cx.inline_asm_index.set(inline_asm_index + 1);
+                    let wrapper_name = format!(
+                        "__inline_asm_{}_wrapper_n{}",
+                        fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"),
+                        inline_asm_index
+                    );
+                    let sig =
+                        get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance);
+                    create_wrapper_function(
+                        fx.module,
+                        &mut fx.cx.unwind_context,
+                        sig,
+                        &wrapper_name,
+                        symbol.name,
+                    );
+
+                    CInlineAsmOperand::Symbol { symbol: wrapper_name }
                 } else {
                     span_bug!(span, "invalid type for asm sym (fn)");
                 }
@@ -271,7 +292,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
             InlineAsmOperand::SymStatic { def_id } => {
                 assert!(fx.tcx.is_static(def_id));
                 let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
-                CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance) }
+                CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() }
             }
         })
         .collect::<Vec<_>>();
@@ -630,7 +651,7 @@ fn generate_asm_wrapper(&self, asm_name: &str) -> String {
                         CInlineAsmOperand::Const { ref value } => {
                             generated_asm.push_str(value);
                         }
-                        CInlineAsmOperand::Symbol { symbol } => generated_asm.push_str(symbol.name),
+                        CInlineAsmOperand::Symbol { ref symbol } => generated_asm.push_str(symbol),
                     }
                 }
             }