about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-08-24 12:43:13 +0000
committerbors <bors@rust-lang.org>2017-08-24 12:43:13 +0000
commitaf6298d590785088aad92f817ce07dfd6cdebdd0 (patch)
tree9fbb2c1a994beb192d5ccdb6d6c260fc69911543 /src
parenta125ec918fc228fc20da4642d17bc178a99a5d72 (diff)
parentc60fc4bd581b955287c2f9e97e1d092fbdab58f1 (diff)
downloadrust-af6298d590785088aad92f817ce07dfd6cdebdd0.tar.gz
rust-af6298d590785088aad92f817ce07dfd6cdebdd0.zip
Auto merge of #44011 - TobiasSchaffner:improved_target_spec_clean, r=alexcrichton
L4Re Target: Add the needed Libraries and locate them

Add the libraries and objects that have to be linked to a get working L4Re Binary using pre- and post-link-args. Additionaly some ld commands had to be passed.

* L4Re libraries and objects will be located by an environment variable.
* gcc libraries and objects will be located using a gcc call.

GCC is mandatory for this target, that might need documentation somewhere. As soon as something mandatory cannot be found, the compiler will panic. This is intended, because the functions involved don't allow the usage of a Result type. libgcc_eh is now passed using `-l` and crtbeginT.o and crtend.o are now located using `gcc -print-filename`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_back/target/l4re_base.rs60
-rw-r--r--src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs2
2 files changed, 56 insertions, 6 deletions
diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs
index d95f6fa97cf..31d428d2668 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<TargetOptions, String> {
+    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 b447f8a989d..99d3171e1c0 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);