diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index d95f6fa97cf4..31d428d26683 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -12,21 +12,71 @@ use PanicStrategy; use LinkerFlavor; use target::{LinkArgs, TargetOptions}; use std::default::Default; +use std::env; +use std::process::Command; -pub fn opts() -> TargetOptions { +// Use GCC to locate code for crt* libraries from the host, not from L4Re. Note +// that a few files also come from L4Re, for these, the function shouldn't be +// used. This uses GCC for the location of the file, but GCC is required for L4Re anyway. +fn get_path_or(filename: &str) -> String { + let child = Command::new("gcc") + .arg(format!("-print-file-name={}", filename)).output() + .expect("Failed to execute GCC"); + String::from_utf8(child.stdout) + .expect("Couldn't read path from GCC").trim().into() +} + +pub fn opts() -> Result { + let l4re_lib_path = env::var_os("L4RE_LIBDIR").ok_or("Unable to find L4Re \ + library directory: L4RE_LIBDIR not set.")?.into_string().unwrap(); let mut pre_link_args = LinkArgs::new(); pre_link_args.insert(LinkerFlavor::Ld, vec![ - "-nostdlib".to_string(), + format!("-T{}/main_stat.ld", l4re_lib_path), + "--defsym=__executable_start=0x01000000".to_string(), + "--defsym=__L4_KIP_ADDR__=0x6ffff000".to_string(), + format!("{}/crt1.o", l4re_lib_path), + format!("{}/crti.o", l4re_lib_path), + get_path_or("crtbeginT.o"), + ]); + let mut post_link_args = LinkArgs::new(); + post_link_args.insert(LinkerFlavor::Ld, vec![ + format!("{}/l4f/libpthread.a", l4re_lib_path), + format!("{}/l4f/libc_be_sig.a", l4re_lib_path), + format!("{}/l4f/libc_be_sig_noop.a", l4re_lib_path), + format!("{}/l4f/libc_be_socket_noop.a", l4re_lib_path), + format!("{}/l4f/libc_be_fs_noop.a", l4re_lib_path), + format!("{}/l4f/libc_be_sem_noop.a", l4re_lib_path), + format!("{}/l4f/libl4re-vfs.o.a", l4re_lib_path), + format!("{}/l4f/lib4re.a", l4re_lib_path), + format!("{}/l4f/lib4re-util.a", l4re_lib_path), + format!("{}/l4f/libc_support_misc.a", l4re_lib_path), + format!("{}/l4f/libsupc++.a", l4re_lib_path), + format!("{}/l4f/lib4shmc.a", l4re_lib_path), + format!("{}/l4f/lib4re-c.a", l4re_lib_path), + format!("{}/l4f/lib4re-c-util.a", l4re_lib_path), + get_path_or("libgcc_eh.a"), + format!("{}/l4f/libdl.a", l4re_lib_path), + "--start-group".to_string(), + format!("{}/l4f/libl4util.a", l4re_lib_path), + format!("{}/l4f/libc_be_l4re.a", l4re_lib_path), + format!("{}/l4f/libuc_c.a", l4re_lib_path), + format!("{}/l4f/libc_be_l4refile.a", l4re_lib_path), + "--end-group".to_string(), + format!("{}/l4f/libl4sys.a", l4re_lib_path), + "-gc-sections".to_string(), + get_path_or("crtend.o"), + format!("{}/crtn.o", l4re_lib_path), ]); - TargetOptions { + Ok(TargetOptions { executables: true, has_elf_tls: false, - exe_allocation_crate: Some("alloc_system".to_string()), + exe_allocation_crate: None, panic_strategy: PanicStrategy::Abort, linker: "ld".to_string(), pre_link_args, + post_link_args, target_family: Some("unix".to_string()), .. Default::default() - } + }) } diff --git a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs b/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs index b447f8a989db..99d3171e1c0e 100644 --- a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs +++ b/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs @@ -12,7 +12,7 @@ use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::l4re_base::opts(); + let mut base = super::l4re_base::opts()?; base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64);