How to write type-parametric `naked_asm!`

I have the following code:

#[unsafe(naked)]
extern "C" fn asm_trampoline() {
    naked_asm!(
        "
            tail trampoline
        "
    )
}

#[no_mangle]
extern "C" fn trampoline() { ... }

I need to make both functions parametric, but the “obvious” Rust style doesn’t work:

#[unsafe(naked)]
extern "C" fn asm_trampoline<T>() {
    naked_asm!(
        "
            tail trampoline::<T>
        "
    )
}

#[no_mangle]
extern "C" fn trampoline<T>() { ... }

Using ::<T> syntax just gets passed to the assembler, which of course doesn’t recognize it. Unfortunately, since this is a naked function, you can’t use a local variable either:

#[unsafe(naked)]
extern "C" fn asm_trampoline<T>() {
    let trampoline = trampoline::<T>;
    naked_asm!(
        "
            tail {trampoline}
        ",
        trampoline = in(reg) trampoline,
    )
}

#[no_mangle]
extern "C" fn trampoline<T>() { ... }

naked_asm! doesn’t accept variable arguments, and naked functions can’t have any code besides a single naked_asm! block.

Any idea how I can accomplish this?

I believe you want the sym operand rather than in(reg).

That worked perfectly, thank you!

For posterity, the result looks like:

#[unsafe(naked)]
extern "C" fn asm_trampoline<T>() {
    naked_asm!(
        "
            tail {}
        ",
        sym trampoline::<T>
    )
}

// No longer needs to be `#[no_mangle]` since we're not naming it
// in the assembly
extern "C" fn trampoline<T>() { ... }

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.