From beedf4e7d88cdb803c4ba73511c871273402ebb0 Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Mon, 21 Aug 2017 09:50:13 +0200 Subject: [PATCH 1/2] 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`. Co-authored-by: TobiasSchaffner --- src/librustc_back/target/l4re_base.rs | 54 ++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index d95f6fa97cf42..b776c4bb56888 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -12,20 +12,70 @@ use PanicStrategy; use LinkerFlavor; use target::{LinkArgs, TargetOptions}; use std::default::Default; +use std::env; +use std::process::Command; + +// 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() -> TargetOptions { + let l4re_lib_path = env::var_os("L4RE_LIBDIR").expect("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 { 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() } From c60fc4bd581b955287c2f9e97e1d092fbdab58f1 Mon Sep 17 00:00:00 2001 From: Tobias Schaffner Date: Tue, 22 Aug 2017 11:11:30 +0200 Subject: [PATCH 2/2] Return L4Re TargetOptions as a Result type instead of panic If the environment variable L4RE_LIBDIR ist not set an Error will be returned wrapped in a result type instead of a panic. --- src/librustc_back/target/l4re_base.rs | 10 +++++----- src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index b776c4bb56888..31d428d266839 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -26,9 +26,9 @@ fn get_path_or(filename: &str) -> String { .expect("Couldn't read path from GCC").trim().into() } -pub fn opts() -> TargetOptions { - let l4re_lib_path = env::var_os("L4RE_LIBDIR").expect("Unable to find L4Re \ - library directory: L4RE_LIBDIR not set.").into_string().unwrap(); +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![ format!("-T{}/main_stat.ld", l4re_lib_path), @@ -68,7 +68,7 @@ pub fn opts() -> TargetOptions { format!("{}/crtn.o", l4re_lib_path), ]); - TargetOptions { + Ok(TargetOptions { executables: true, has_elf_tls: false, exe_allocation_crate: None, @@ -78,5 +78,5 @@ pub fn opts() -> TargetOptions { 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 b447f8a989db6..99d3171e1c0e0 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);