diff --git a/tests/Sanity/rust-x86_64-unknown-none-smoke/demo.rs b/tests/Sanity/rust-x86_64-unknown-none-smoke/demo.rs new file mode 100644 index 0000000..2fdaa75 --- /dev/null +++ b/tests/Sanity/rust-x86_64-unknown-none-smoke/demo.rs @@ -0,0 +1,62 @@ +// Credit where credit is due. This test was made following this article: +// https://vulns.xyz/2023/03/linux-executable-from-scratch-with-x86_64-unknown-none-rust/ + +// Opt-out the use of std, as x86_64-unknown-none doesn't have standard library +#![no_std] +// Inform the compiler that we don't have a main function, we'll be specifying +// the program entry point using global_asm. +#![no_main] + +use core::arch::asm; +use core::arch::global_asm; +use core::panic::PanicInfo; + +// As we don't have std library, we need to write our own panic handler +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + exit(1); +} + +// Program entry point, adjust stack pointer and call main +global_asm! { + ".global _start", + "_start:", + "mov rdi, rsp", + "call main" +} + +// exit syscall +fn exit(status: i32) -> ! { + unsafe { + asm!( + "syscall", + in("rax") 60, + in("rdi") status, + options(noreturn) + ); + } +} + +// write syscall +unsafe fn write(fd: i32, buf: *const u8, count: usize) -> isize { + let r0; + asm!( + "syscall", + inlateout("rax") 1isize => r0, + in("rdi") fd, + in("rsi") buf, + in("rdx") count, + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + r0 +} + +// Tell the compiler to not mangle the function name. We're calling main +// with this name from global_asm +#[no_mangle] +unsafe fn main(_stack_top: *const u8) -> ! { + write(1, b"Hello world\n".as_ptr(), 12); + exit(0); +} diff --git a/tests/Sanity/rust-x86_64-unknown-none-smoke/main.fmf b/tests/Sanity/rust-x86_64-unknown-none-smoke/main.fmf new file mode 100644 index 0000000..33a0f06 --- /dev/null +++ b/tests/Sanity/rust-x86_64-unknown-none-smoke/main.fmf @@ -0,0 +1,13 @@ +summary: Smoke test for the x86_64-unknown-none target +description: Compile and run a minimal example using x86_64-unknown-none target +duration: 2m +tier: 1 +# Additional requires +require+: + - rust-std-static-x86_64-unknown-none +adjust+: + - when: distro < rhel-10 or distro < fedora-38 + enabled: false + + - when: arch != x86_64 + enabled: false diff --git a/tests/Sanity/rust-x86_64-unknown-none-smoke/runtest.sh b/tests/Sanity/rust-x86_64-unknown-none-smoke/runtest.sh new file mode 100755 index 0000000..e9d2488 --- /dev/null +++ b/tests/Sanity/rust-x86_64-unknown-none-smoke/runtest.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +rlJournalStart + rlPhaseStartSetup + declare tmp + rlRun "tmp=\$(mktemp -d)" 0 "Create tmp directory" + rlRun "cp demo.rs $tmp" + rlRun "pushd $tmp" + rlRun "set -o pipefail" + rlPhaseEnd + + rlPhaseStartTest + rlRun "rustc --target x86_64-unknown-none demo.rs -o demo" + rlRun "./demo | grep 'Hello world'" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $tmp" 0 "Remove tmp directory" + rlPhaseEnd +rlJournalEnd