'How can I call a rust function in rust inline asm module
I try to call my function just like the example code:
use std::arch::asm;
extern "C" fn foo(arg: i32) -> i32 {
println!("arg = {}", arg);
arg * 2
}
fn call_foo(arg: i32) -> i32 {
unsafe {
let result;
asm!(
"call *{}",
// Function pointer to call
in(reg) foo,
// 1st argument in rdi
in("rdi") arg,
// Return value in rax
out("rax") result,
// Mark all registers which are not preserved by the "C" calling
// convention as clobbered.
clobber_abi("C"),
);
result
}
} //this is the example code
My code :
use core::arch::global_asm;
fn main() {
println!("Hello, world!");
unsafe{
myfunc();
}
}
fn pt() {
println!("This func is called by inline asm");
}
extern "C" {
fn myfunc();
}
global_asm!(
"
.global myfunc
myfunc:
call *{}
ret",
in(reg) pt,
);
it raise error when compiling
Compiling asm_test v0.1.0 (/home/zhou/codes/rust/practice/asm_test)
error: expected expression, found keyword `in`
--> src/main.rs:26:1
|
26 | in(reg) pt,
| ^^ expected expression
error: could not compile `asm_test` due to previous error
if I try to just call pt
,like this
use core::arch::global_asm;
fn main() {
println!("Hello, world!");
unsafe{
myfunc();
}
}
fn pt() {
println!("This func is called by inline asm");
}
extern "C" {
fn myfunc();
}
global_asm!(
"
.global myfunc
myfunc:
call pt
ret",
);
It raise a link-time error:
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.0.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.1.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.2.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.3.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.4.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.5.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.6.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.7.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.4utlkaaskc2kqzwc.rcgu.o" "-Wl,--as-needed" "-L" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps" "-L" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-a46a068050a12a4b.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-1df56095db9453cb.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-9062de483386e50b.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-b988ab269ff13602.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-1bc822d886d4f7bd.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-963eca8df4c224a6.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-d805b480c9102e58.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-06dfdbc22b935051.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-d7523a4d118e6572.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-5d7898c7fac3a07d.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-8c2bdbab4845bf3d.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-d578639df0547b30.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-58bbb7b1efa3a5e2.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-4c9b082d197c16f8.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-70f9ed6d8e7a5ce6.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-8c0a241d0360fa53.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-bad7ed93fdd31371.rlib" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-98b4d121af2b7335.rlib" "-Wl,--end-group" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-1d9f7e5920635d15.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/zhou/.rustup/toolchains/1.59.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
= note: /usr/bin/ld: /home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-cefff555edfd8301.asm_test.debf28cc-cgu.6.rcgu.o: in function `myfunc':
asm_test.debf28cc-cgu.6:(.text+0x1): undefined reference to `pt'
collect2: error: ld returned 1 exit status
= help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the `-l` flag to specify native libraries to link
= note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
warning: `asm_test` (bin "asm_test") generated 1 warning
error: could not compile `asm_test` due to previous error; 1 warning emitted
My rustc version is rustc 1.59.0 (9d1b2106e 2022-02-23)
Now I'm wondering how can I call my rust function in the inline asm? Thanks for answering.
ps:
Even if I marked extern "C"
to the pt()
function, it will raise the same error.
call by function pointer:
use core::arch::global_asm;
fn main() {
println!("Hello, world!");
unsafe{
myfunc();
}
}
extern "C" fn pt() {
println!("This func is called by inline asm");
}
extern "C" {
fn myfunc();
}
global_asm!(
"
.global myfunc
myfunc:
call *{}
ret",
in(reg) pt,
);
outputs:
Compiling asm_test v0.1.0 (/home/zhou/codes/rust/practice/asm_test)
error: expected expression, found keyword `in`
--> src/main.rs:25:1
|
25 | in(reg) pt,
| ^^ expected expression
error: could not compile `asm_test` due to previous error
call directly by function name:
use core::arch::global_asm;
fn main() {
println!("Hello, world!");
unsafe{
myfunc();
}
}
extern "C" fn pt() {
println!("This func is called by inline asm");
}
extern "C" {
fn myfunc();
}
global_asm!(
"
.global myfunc
myfunc:
call pt
ret
"
);
outputs
Compiling asm_test v0.1.0 (/home/zhou/codes/rust/practice/asm_test)
warning: function is never used: `pt`
--> src/main.rs:11:15
|
11 | extern "C" fn pt() {
| ^^
|
= note: `#[warn(dead_code)]` on by default
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.11cntnpkwkcxlijf.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.1265vrgnblsvk7p4.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.1t6teuukd293c2fa.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.2dq4ncsizye722cr.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.3wcrpa0pe60imxoq.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.472oc353m17m7nk9.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.4jq8ds1i0f9k3y80.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.qpnijj966uqfsk9.rcgu.o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.4jqwi4eladczupq3.rcgu.o" "-Wl,--as-needed" "-L" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps" "-L" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8d61b92a0a02f53a.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-fc45202bb435016b.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-f2400674c7513725.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-605c3a7d1a5d300d.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-3d4fb4efa907e4e8.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-65207f030ab23308.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-76ca199cb0186109.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-1e3e01ed4f561dc1.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-dd8dddcba7c13fee.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-00b13d31c3420656.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-e4c8460b81557bd5.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-600d46e5f0005455.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-e4a08a2585b62d37.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-fbc21ec567cb9dc7.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-10b3fa8e49bd978f.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-64625b73694ffce7.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-fb6b78ac543a58ee.rlib" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-1d1f2d1bec6f51b8.rlib" "-Wl,--end-group" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-acf5ff6e9595d982.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/zhou/.rustup/toolchains/1.60.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
= note: /usr/bin/ld: /home/zhou/codes/rust/practice/asm_test/target/debug/deps/asm_test-0ec3f71f4270eb6c.2dq4ncsizye722cr.rcgu.o: in function `myfunc':
2dq4ncsizye722cr:(.text+0x1): undefined reference to `pt'
collect2: error: ld returned 1 exit status
= help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the `-l` flag to specify native libraries to link
= note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
warning: `asm_test` (bin "asm_test") generated 1 warning
error: could not compile `asm_test` due to previous error; 1 warning emitted
Solution 1:[1]
By default, Rust mangles the function names. A function named pt
in Rust will be named something like _ZN7example2pt17hfba60a8558e697b1E
, to account for crate name, module hierarchy, traits, and generic parameters - to prevent name collisions. Thus the linker cannot find it.
You can order Rust to stop mangle a specific function by using the #[no_mangle]
attribute on it. Beware this attribute is unsafe: it can cause name collisions and that is undefined behavior. Also, to call the function from assembly, you will need a defined calling convention, e.g. extern "C"
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Chayim Friedman |