Skip to content

unmangled symbols are not escaped in naked/global assembly #151950

@usamoi

Description

@usamoi

I tried this code:

unsafe extern "C" {
    #[link_name = "memset]; mov eax, 1; #"]
    unsafe fn inject();
}

#[unsafe(export_name = "memset]; mov eax, 1; #")]
extern "C" fn inject_() {}

#[unsafe(naked)]
extern "C" fn print_0() -> usize {
    core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject)
}

#[unsafe(naked)]
extern "C" fn print_1() -> usize {
    core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject_)
}

fn main() {
    dbg!(print_0());
    dbg!(print_1());
}

I expected to see this happen: rustc inserts escaped symbol names, and linker emits errors

Instead, this happened: interpolation works, and the binary prints 1\n1\n

I found this when trying to compile

unsafe extern "C" {
    #[link_name = "exit@GLIBC_2.2.5"]
    safe fn exit(status: i32) -> !;
}

#[unsafe(naked)]
extern "C" fn exit_(status: i32) {
    core::arch::naked_asm!("jmp {}", sym exit)
}

fn main() {
    exit_(0);
}

I expected to see it compiles but it doesn't. I have to escape it manually by

core::arch::naked_asm!("jmp \"{}\"", sym exit)

Meta

rustc --version --verbose:

rustc 1.93.0 (254b59607 2026-01-19)
binary: rustc
commit-hash: 254b59607d4417e9dffbc307138ae5c86280fe4c
commit-date: 2026-01-19
host: x86_64-unknown-linux-gnu
release: 1.93.0
LLVM version: 21.1.8

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-bugCategory: This is a bug.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions