I am trying to use the Fortanix SGX framework to run libdvdcss in an enclave, but having problems with the linker.
I created a simple FFI wrapper around libdvdcss which works fine when executing it normally on Linux (without SGX and with libdvdcss installed globally). It does not work when I run it with the target x86_64-fortanix-unknown-sgx
as specified on the Getting started page, because the linker complains about many missing symbols, especially about malloc
etc.
From what I understand, the issue is that there is no libc in SGX, therefore I need to include rs-libc
manually, which is basically a libc to use in SGX. The rs-libc
crate contains C, ASM and also some Rust code (mostly for malloc
). Thus my Cargo.toml:
[dependencies]
rs-libc = "0.2.3"
I found out that is not sufficient and that I have to provide the following build.rs to manually tell the linker to link the libc.a
from the rs-libc
crate as well.
pub fn main() {
println!("cargo:rustc-link-search=/home/me/dev/libdvdcss/.libs"); // Will be changed later
println!("cargo:rustc-link-lib=static=dvdcss");
println!("cargo:rustc-link-lib=static=c");
}
This fixes some of the errors with strlen
etc. not being found, but not for malloc
and free
. I think the problem is that they are not compiled from a C source file, but instead in alloc.rs. I've also seen that this source file is compiled to a Rust library in target/x86_64-fortanix-unknown-sgx/debug/deps/librs_libc-04111db022dd517f.rlib
and contains the symbols:
rs_libc-04111db022dd517f.rs_libc.53f0fd72-cgu.5.rcgu.o:
0000000000000000 T calloc
0000000000000000 T free
0000000000000000 W __llvm_lvi_thunk_r11
0000000000000000 T malloc
0000000000000000 T realloc
0000000000000000 V __rustc_debug_gdb_scripts_section__
U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$12alloc_zeroed17ha722ea369ab2dac9E
U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$5alloc17h561d825df0f2dfa8E
U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$7dealloc17hbbda0b3d0a1f9d67E
U _ZN3std3sys3sgx5alloc81_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$7realloc17hf76d62802e46847bE
U _ZN4core3ptr4read17hc3470c4a404ff082E
U _ZN4core3ptr5write17ha0bb4d6cbfed535eE
U _ZN4core5alloc6layout6Layout25from_size_align_unchecked17h074422ae6f6459f7E
U _ZN4core9panicking5panic17hde9db97a7382bd28E
Unfortunately, this file does not seem to be included in the final linker command. I think this is because no usages of this library are found in my Rust application and thus it is optimized out.
Is there a way to include it nonetheless?
Adding an extern crate rs_libc;
to your crate's root should do the trick. It is mandatory that a dependency declared with extern crate
must be given to the linker. In rust 2018 and above, an appropriate declaration is implicitly added to your crate by the compiler if and only if you use one or more of that crate's symbols (rust 2015 requires the extern crate
be added explicitly). See the section in the rust reference for more information.