gz/rust-lkl

Linking issues with a hello world example

Opened this issue · 2 comments

Hey @gz, thanks for the library, this looks like a fun project to work on. I was trying to build a hello-world example with something like

fn main() {
    unsafe {
        lkl::lkl_start_kernel(std::ptr::null_mut(), std::ptr::null());
    }
}

and it's failing with linker errors I cannot debug. This is the full CC output:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.1xpdat2d0wy30xki.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.2czisjfef98d21j3.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.2h7evc9vz2gt72zg.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.2l4veanthxf8gzvz.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.2s1abyz7t0u3k2t3.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.2uygunk01ayeb05d.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.31s5g22vo29043mh.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.32wq4m6wgzpkwamv.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.35zpug9e648d5hsh.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4ku75uzh0wr7yapp.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4oubp8sg3tqm7psu.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4rv74hsii8n8qyo3.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4wnjby8xg82n56x1.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4zjrj5ulx8mjcoql.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.507x0k4w7kq5xgo2.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.52vj39kp1tq2i3e9.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.592u5dpcpfk6vkre.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.5dy9qr1e8s2id6z9.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.pwwmu4hckcogtzm.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.qhlurdgc324duxw.rcgu.o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.w82zzpcoj6vtg69.rcgu.o" "-o" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42" "/home/j/src/netlink/target/debug/deps/app-bcf37244f7bf2c42.4dgnyxyazfuvvnxj.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/home/j/src/netlink/target/debug/deps" "-L" "/home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out" "-L" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "-llinux" "-Wl,--no-whole-archive" "/home/j/src/netlink/target/debug/deps/liblkl-8a22c2235901a326.rlib" "-Wl,--start-group" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-5880c0f0bfd74f3b.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-80318e9a073232dc.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-32bb59042e6ce4f7.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-9b38c0948c2d27e2.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-7a3d82bf6cf61acc.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-a66835881023c910.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-21e51998beafe269.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-ff91d811cb2cc06b.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-1a3ebd51865a27a7.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-42821e074cc8ca7e.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-3820a32f8f6914a6.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-f50813bc0da88bf6.rlib" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-a2554e6c88c3fd7a.rlib" "-Wl,--end-group" "/home/j/.rustup/toolchains/nightly-2020-04-07-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-cc0b971ba3542be2.rlib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `thread_sched_jb':
          /home/j/src/lkl/./arch/lkl/include/asm/sched.h:15: undefined reference to `lkl_bug'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `threads_init':
          /home/j/src/lkl/arch/lkl/kernel/threads.c:207: undefined reference to `lkl_printf'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `thread_sched_jb':
          /home/j/src/lkl/./arch/lkl/include/asm/sched.h:15: undefined reference to `lkl_bug'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `lkl_cpu_change_owner':
          /home/j/src/lkl/arch/lkl/kernel/cpu.c:90: undefined reference to `lkl_bug'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `lkl_cpu_put':
          /home/j/src/lkl/arch/lkl/kernel/cpu.c:119: undefined reference to `lkl_bug'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `thread_sched_jb':
          /home/j/src/lkl/./arch/lkl/include/asm/sched.h:15: undefined reference to `lkl_bug'
          /usr/bin/ld: /home/j/src/netlink/target/debug/build/lkl-fc2e2e3b997ff1f0/out/liblinux.a(lkl.o): in function `lkl_cpu_put':
          /home/j/src/lkl/arch/lkl/kernel/cpu.c:131: undefined reference to `lkl_bug'
          collect2: error: ld returned 1 exit status

Its failing to find lkl_bug and lkl_print and both these functions seems to be missing from the object file as well. Is that expected?

$ nm ~/src/lkl/liblinux.a | grep ' U '
                 U _GLOBAL_OFFSET_TABLE_
                 U lkl_bug
                 U lkl_printf

Do you have a sample rust program that compiles that you could share or add to the tests?

I haven't been able to find anything related online so far, so filing a bug here to start a discussion.

gz commented

Hi @jaseemabid,

You'll need to provide those symbols among with a bunch of others (for thread management, etc.) yourself in order to get the necessary runtime support to boot/start LKL.

e.g. something like this might get you started:

pub fn main() {
    use cstr_core::CStr;

    extern "C" {
        // int __init lkl_start_kernel(struct lkl_host_operations *ops, const char *fmt, ...)
        fn lkl_start_kernel(ops: *const lkl::lkl_host_operations, fmt: *const i8) -> i32;
        fn lkl_sys_halt();
    }

    let up = lineup::DEFAULT_UPCALLS;

    let mut scheduler = lineup::Scheduler::new(up);
    scheduler.spawn(
        32 * 4096,
        |_yielder| unsafe {
            let linux_ops = linuxrt::get_host_ops();
            let boot_arg = CStr::from_bytes_with_nul(b"mem=16M loglevel=8\0");
            let r = lkl_start_kernel(&linux_ops, boot_arg.unwrap().as_ptr());
            info!("lkl_start_kernel {}", r);

            arch::debug::shutdown(ExitReason::Ok);
        },
        core::ptr::null_mut(),
    );

    loop {
        scheduler.run();
    }
}

#[no_mangle]
pub unsafe extern "C" fn lkl_bug(fmt: *const i8) {
    info!("lkl_bug");
}

#[no_mangle]
pub unsafe extern "C" fn lkl_printf(fmt: *const i8) {
    info!("lkl_printf");
}

Sorry I don't have any public code for this at the moment, but hopefully sooner than later -- stay tuned ;). In essence, anything that shows up as undefined you're probably going to have to implement yourself.

Also note that in your project you'll probably have to add something like this to your build.rs file to link against liblinux.a:

println!("cargo:rustc-link-lib=static=linux");

And I'd be glad to accept any kind of documentation/examples as pull request that document this crate better.