From b27942853efdb2fde2b6f73023c38ebfec3fcb8f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 19 Sep 2025 21:53:06 +0200 Subject: [PATCH] naked_asm: emit a label starting with `func_end` The `cargo asm` tool pattern matches on such labels to figure out where functions end: normal functions generated by LLVM always do have such a label. We don't guarantee that naked functions emit such a label, but having `cargo asm` work is convenient --- compiler/rustc_codegen_ssa/src/mir/naked_asm.rs | 6 ++++++ tests/assembly-llvm/naked-functions/wasm32.rs | 1 + 2 files changed, 7 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 31784cabf4af3..e7239ebfecf63 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -228,6 +228,9 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + // emit a label starting with `func_end` for `cargo asm` and other tooling that might + // pattern match on assembly generated by LLVM. + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { @@ -246,6 +249,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -263,6 +267,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -287,6 +292,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end).unwrap(); // .size is ignored for function symbols, so we can skip it writeln!(end, "end_function").unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); } BinaryFormat::Xcoff => { // the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the diff --git a/tests/assembly-llvm/naked-functions/wasm32.rs b/tests/assembly-llvm/naked-functions/wasm32.rs index 77547e82041fe..4bf04dd392341 100644 --- a/tests/assembly-llvm/naked-functions/wasm32.rs +++ b/tests/assembly-llvm/naked-functions/wasm32.rs @@ -21,6 +21,7 @@ use minicore::*; // CHECK: .functype nop () -> () // CHECK-NOT: .size // CHECK: end_function +// CHECK-LABEL: .Lfunc_end_nop: #[no_mangle] #[unsafe(naked)] extern "C" fn nop() {