Skip to content

Commit

Permalink
L4Re WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
humenda authored and petrochenkov committed Sep 11, 2021
1 parent 4e880f8 commit d3b02f3
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 34 deletions.
102 changes: 89 additions & 13 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,13 @@ pub fn get_linker<'a>(
}
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Gcc => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
Box::new(GccLinker::new(cmd, sess, target_cpu, false)) as Box<dyn Linker>
}

LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64)
| LinkerFlavor::Ld => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
as Box<dyn Linker>
Box::new(GccLinker::new(cmd, sess, target_cpu, true)) as Box<dyn Linker>
}

LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
Expand Down Expand Up @@ -220,6 +218,17 @@ pub struct GccLinker<'a> {
}

impl<'a> GccLinker<'a> {
fn new(mut cmd: Command, sess: &'a Session, target_cpu: &'a str, is_ld: bool) -> GccLinker<'a> {
if sess.target.os == "l4re" {
// FIXME: Why is this a rustc's job at all?
// Why can't l4-bender read the `L4_BENDER_ARGS` variable instead?
// If this needs to be done with rustc, then why it cannot be done with existing
// generic tools like `-Clink-arg` or `-Zpre-link-arg`

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

-Clink-arg is not an option because l4-bender expects its options before a --, -Zpre-link-arg does not work in its current form because of the whitespace issue when passing arguments through cargo (explained in more detail in the PR).

add_l4bender_args(&mut cmd);
}
GccLinker { cmd, sess, target_cpu, is_ld, hinted_static: false }
}

/// Argument that must be passed *directly* to the linker
///
/// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used.
Expand Down Expand Up @@ -339,6 +348,10 @@ impl<'a> Linker for GccLinker<'a> {
}

fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
if self.sess.target.os == "l4re" {
// FIXME: Should be unnecessary if the targets correctly specify not supporting dylibs and cdylibs.

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

fixed

return;
}
match output_kind {
LinkOutputKind::DynamicNoPicExe => {
if !self.is_ld && self.sess.target.linker_is_gnu {
Expand Down Expand Up @@ -433,7 +446,12 @@ impl<'a> Linker for GccLinker<'a> {
}
fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) {
self.hint_static();
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
if self.sess.target.os == "l4re" {
// FIXME: Why is this deliberate difference from gcc necessary?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

Because l4-bender will interpret the argument to locate packages in the L4Re source tree, i.e. its purpose is to serve as a point of abstraction in the L4Re build system to resolve a requested library dependency (e.g. readline) to the (e.g. readline) package.

self.cmd.arg(format!("-PC{}", lib));
} else {
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
}
}
fn link_rlib(&mut self, lib: &Path) {
self.hint_static();
Expand All @@ -452,14 +470,33 @@ impl<'a> Linker for GccLinker<'a> {
self.cmd.arg(path);
}
fn full_relro(&mut self) {
self.linker_arg("-zrelro");
self.linker_arg("-znow");
if self.sess.target.os == "l4re" {
// FIXME: Why a comma between `-z` and `relro`?
// FIXME: Why a comma between `-z,relro and -z,now`?
// FIXME: Will `-zrelro` without space or comma work?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

thanks for the suggestion, fixed

self.cmd.arg("-z,relro,-z,now");
} else {
self.linker_arg("-zrelro");
self.linker_arg("-znow");
}
}
fn partial_relro(&mut self) {
self.linker_arg("-zrelro");
if self.sess.target.os == "l4re" {
// FIXME: Why a comma between `-z` and `relro`?
// FIXME: Will `-zrelro` without space or comma work?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

fixed

self.cmd.arg("-z,relro");
} else {
self.linker_arg("-zrelro");
}
}
fn no_relro(&mut self) {
self.linker_arg("-znorelro");
if self.sess.target.os == "l4re" {
// FIXME: Why a comma between `-z` and `norelro`?
// FIXME: Will `-znorelro` without space or comma work?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

fixed

self.cmd.arg("-z,norelro");
} else {
self.linker_arg("-znorelro");
}
}

fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
Expand Down Expand Up @@ -537,7 +574,9 @@ impl<'a> Linker for GccLinker<'a> {
// eliminate the metadata. If we're building an executable, however,
// --gc-sections drops the size of hello world from 1.8MB to 597K, a 67%
// reduction.
} else if (self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm)
} else if (self.sess.target.linker_is_gnu
|| self.sess.target.is_like_wasm
|| self.sess.target.os == "l4re")
&& !keep_metadata
{
self.linker_arg("--gc-sections");
Expand All @@ -553,7 +592,11 @@ impl<'a> Linker for GccLinker<'a> {
}

fn optimize(&mut self) {
if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm {
if self.sess.target.os == "l4re" {
// FIXME: Why the difference with the GNU case below?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

good point, fixed

self.cmd.arg("-O2");
return;
} else if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm {
return;
}

Expand Down Expand Up @@ -713,8 +756,13 @@ impl<'a> Linker for GccLinker<'a> {
}

fn subsystem(&mut self, subsystem: &str) {
self.linker_arg("--subsystem");
self.linker_arg(&subsystem);
if self.sess.target.os == "l4re" {
// FIXME: Why the comma between --subsystem and its name?

This comment has been minimized.

Copy link
@atopia

atopia Jan 6, 2022

fixed

self.cmd.arg(&format!("--subsystem,{}", subsystem));
} else {
self.linker_arg("--subsystem");
self.linker_arg(&subsystem);
}
}

fn reset_per_library_state(&mut self) {
Expand Down Expand Up @@ -1597,3 +1645,31 @@ impl<'a> Linker for BpfLinker<'a> {

fn linker_plugin_lto(&mut self) {}
}

fn add_l4bender_args(cmd: &mut Command) {
if let Ok(l4bender_args) = env::var("L4_BENDER_ARGS") {
// This parses a shell-escaped string and unquotes the arguments. It doesn't attempt to
// completely understand shell, but should instead allow passing arguments like
// `-Dlinker="ld -m x86_64"`, and a copy without quotes, but spaces preserved, is added
// as an argument to the given Command. This means that constructs as \" are not
// understood, so quote wisely.
let mut arg = String::new();
let mut quoted = false;
for character in l4bender_args.chars() {
match character {
' ' if !quoted => {
cmd.arg(&arg);
arg.clear();
}
'"' | '\'' => quoted = !quoted,
_ => arg.push(character),
};
}
if arg.len() > 0 {
cmd.arg(&arg);
arg.clear();
}
}

cmd.arg("--"); // separate direct l4-bender args from linker args
}
18 changes: 3 additions & 15 deletions compiler/rustc_target/src/spec/l4re_base.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
use crate::spec::{LinkerFlavor, PanicStrategy, TargetOptions};
//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()
//}
use crate::spec::{PanicStrategy, TargetOptions};

pub fn opts() -> TargetOptions {
TargetOptions {
os: "l4re".to_string(),
env: "uclibc".to_string(),
linker_flavor: LinkerFlavor::Ld,
executables: true,
panic_strategy: PanicStrategy::Abort,
linker: Some("ld".to_string()),
linker: Some("l4-bender".to_string()),
linker_is_gnu: false,
families: vec!["unix".to_string()],
limit_rdylib_exports: false,
..Default::default()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub fn target() -> Target {
let mut base = super::l4re_base::opts();
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
base.crt_static_default = true;

Target {
llvm_target: "x86_64-unknown-l4re-uclibc".to_string(),
Expand Down
4 changes: 4 additions & 0 deletions library/panic_unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "hermit")] {
#[path = "hermit.rs"]
mod real_imp;
} else if #[cfg(target_os = "l4re")] {
// L4Re is unix family but does not yet support unwinding.
#[path = "dummy.rs"]
mod real_imp;
} else if #[cfg(target_env = "msvc")] {
#[path = "seh.rs"]
mod real_imp;
Expand Down
10 changes: 5 additions & 5 deletions library/std/src/sys/unix/l4re.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub mod net {
}

pub fn is_read_vectored(&self) -> bool {
unimpl!();
false
}

pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
Expand All @@ -83,7 +83,7 @@ pub mod net {
}

pub fn is_write_vectored(&self) -> bool {
unimpl!();
false
}

pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> {
Expand Down Expand Up @@ -191,7 +191,7 @@ pub mod net {
}

pub fn is_read_vectored(&self) -> bool {
unimpl!();
false
}

pub fn write(&self, _: &[u8]) -> io::Result<usize> {
Expand All @@ -203,7 +203,7 @@ pub mod net {
}

pub fn is_write_vectored(&self) -> bool {
unimpl!();
false
}

pub fn peer_addr(&self) -> io::Result<SocketAddr> {
Expand Down Expand Up @@ -497,7 +497,7 @@ pub mod net {

impl LookupHost {
pub fn port(&self) -> u16 {
unimpl!();
0 // unimplemented
}
}

Expand Down
1 change: 1 addition & 0 deletions library/std/src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
target_os = "macos",
target_os = "ios",
target_os = "redox",
target_os = "l4re",
)))] {
use crate::sys::os::errno;
let pfds: &mut [_] = &mut [
Expand Down
5 changes: 4 additions & 1 deletion library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ use crate::sys::weak::weak;
#[cfg(target_os = "vxworks")]
use libc::RTP_ID as pid_t;

#[cfg(not(target_os = "vxworks"))]
#[cfg(target_os = "l4re")]
use libc::{c_int, pid_t};

#[cfg(not(any(target_os = "vxworks", target_os = "l4re")))]
use libc::{c_int, gid_t, pid_t, uid_t};

////////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit d3b02f3

Please sign in to comment.