move escape_symbol_name to cg_ssa

This commit is contained in:
usamoi 2026-02-13 20:30:23 +08:00
parent 47611e1604
commit 4796ff1bf5
3 changed files with 47 additions and 43 deletions

View file

@ -106,6 +106,7 @@ fn codegen_global_asm_inner<'tcx>(
match *piece {
InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s),
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
use rustc_codegen_ssa::back::symbol_export::escape_symbol_name;
match operands[operand_idx] {
GlobalAsmOperandRef::Const { ref string } => {
global_asm.push_str(string);
@ -121,7 +122,7 @@ fn codegen_global_asm_inner<'tcx>(
let symbol = tcx.symbol_name(instance);
// FIXME handle the case where the function was made private to the
// current codegen unit
global_asm.push_str(symbol.name);
global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span));
}
GlobalAsmOperandRef::SymStatic { def_id } => {
if cfg!(not(feature = "inline_asm_sym")) {
@ -133,7 +134,7 @@ fn codegen_global_asm_inner<'tcx>(
let instance = Instance::mono(tcx, def_id);
let symbol = tcx.symbol_name(instance);
global_asm.push_str(symbol.name);
global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span));
}
}
}

View file

@ -400,6 +400,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
match *piece {
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
use rustc_codegen_ssa::back::symbol_export::escape_symbol_name;
match operands[operand_idx] {
GlobalAsmOperandRef::Const { ref string } => {
// Const operands get injected directly into the
@ -414,7 +415,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&escape_symbol_name(self, symbol, span));
template_str.push_str(&escape_symbol_name(self.tcx, &symbol, span));
}
GlobalAsmOperandRef::SymStatic { def_id } => {
let llval = self
@ -428,7 +429,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&escape_symbol_name(self, symbol, span));
template_str.push_str(&escape_symbol_name(self.tcx, &symbol, span));
}
}
}
@ -1390,42 +1391,3 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
_ => layout.llvm_type(cx),
}
}
fn escape_symbol_name<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, symbol: String, span: Span) -> String {
use rustc_target::spec::{Arch, BinaryFormat};
if !symbol.is_empty()
&& symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.'))
{
return symbol;
}
if cx.tcx.sess.target.binary_format == BinaryFormat::Xcoff {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the binary format {}",
cx.tcx.sess.target.binary_format
),
);
}
if cx.tcx.sess.target.arch == Arch::Nvptx64 {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the architecture {}",
cx.tcx.sess.target.arch
),
);
}
let mut escaped_symbol = String::new();
escaped_symbol.push('\"');
for c in symbol.chars() {
match c {
'\n' => escaped_symbol.push_str("\\\n"),
'"' => escaped_symbol.push_str("\\\""),
'\\' => escaped_symbol.push_str("\\\\"),
c => escaped_symbol.push(c),
}
}
escaped_symbol.push('\"');
escaped_symbol
}

View file

@ -14,6 +14,7 @@ use rustc_middle::query::LocalCrate;
use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt};
use rustc_middle::util::Providers;
use rustc_session::config::CrateType;
use rustc_span::Span;
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{Arch, Os, TlsModel};
use tracing::debug;
@ -764,3 +765,43 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<String> {
ret
}
pub fn escape_symbol_name(tcx: TyCtxt<'_>, symbol: &str, span: Span) -> String {
// https://github.com/llvm/llvm-project/blob/a55fbab0cffc9b4af497b9e4f187b61143743e06/llvm/lib/MC/MCSymbol.cpp
use rustc_target::spec::{Arch, BinaryFormat};
if !symbol.is_empty()
&& symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.'))
{
return symbol.to_string();
}
if tcx.sess.target.binary_format == BinaryFormat::Xcoff {
tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the binary format {}",
tcx.sess.target.binary_format
),
);
}
if tcx.sess.target.arch == Arch::Nvptx64 {
tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the architecture {}",
tcx.sess.target.arch
),
);
}
let mut escaped_symbol = String::new();
escaped_symbol.push('\"');
for c in symbol.chars() {
match c {
'\n' => escaped_symbol.push_str("\\\n"),
'"' => escaped_symbol.push_str("\\\""),
'\\' => escaped_symbol.push_str("\\\\"),
c => escaped_symbol.push(c),
}
}
escaped_symbol.push('\"');
escaped_symbol
}