Skip to content

Commit d3b02f3

Browse files
humendapetrochenkov
authored andcommitted
L4Re WIP
1 parent 4e880f8 commit d3b02f3

File tree

7 files changed

+107
-34
lines changed

7 files changed

+107
-34
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,13 @@ pub fn get_linker<'a>(
134134
}
135135
LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
136136
LinkerFlavor::Gcc => {
137-
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
138-
as Box<dyn Linker>
137+
Box::new(GccLinker::new(cmd, sess, target_cpu, false)) as Box<dyn Linker>
139138
}
140139

141140
LinkerFlavor::Lld(LldFlavor::Ld)
142141
| LinkerFlavor::Lld(LldFlavor::Ld64)
143142
| LinkerFlavor::Ld => {
144-
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
145-
as Box<dyn Linker>
143+
Box::new(GccLinker::new(cmd, sess, target_cpu, true)) as Box<dyn Linker>
146144
}
147145

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

222220
impl<'a> GccLinker<'a> {
221+
fn new(mut cmd: Command, sess: &'a Session, target_cpu: &'a str, is_ld: bool) -> GccLinker<'a> {
222+
if sess.target.os == "l4re" {
223+
// FIXME: Why is this a rustc's job at all?
224+
// Why can't l4-bender read the `L4_BENDER_ARGS` variable instead?
225+
// If this needs to be done with rustc, then why it cannot be done with existing
226+
// generic tools like `-Clink-arg` or `-Zpre-link-arg`
227+
add_l4bender_args(&mut cmd);
228+
}
229+
GccLinker { cmd, sess, target_cpu, is_ld, hinted_static: false }
230+
}
231+
223232
/// Argument that must be passed *directly* to the linker
224233
///
225234
/// These arguments need to be prepended with `-Wl`, when a GCC-style linker is used.
@@ -339,6 +348,10 @@ impl<'a> Linker for GccLinker<'a> {
339348
}
340349

341350
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
351+
if self.sess.target.os == "l4re" {
352+
// FIXME: Should be unnecessary if the targets correctly specify not supporting dylibs and cdylibs.
353+
return;
354+
}
342355
match output_kind {
343356
LinkOutputKind::DynamicNoPicExe => {
344357
if !self.is_ld && self.sess.target.linker_is_gnu {
@@ -433,7 +446,12 @@ impl<'a> Linker for GccLinker<'a> {
433446
}
434447
fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) {
435448
self.hint_static();
436-
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
449+
if self.sess.target.os == "l4re" {
450+
// FIXME: Why is this deliberate difference from gcc necessary?
451+
self.cmd.arg(format!("-PC{}", lib));
452+
} else {
453+
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
454+
}
437455
}
438456
fn link_rlib(&mut self, lib: &Path) {
439457
self.hint_static();
@@ -452,14 +470,33 @@ impl<'a> Linker for GccLinker<'a> {
452470
self.cmd.arg(path);
453471
}
454472
fn full_relro(&mut self) {
455-
self.linker_arg("-zrelro");
456-
self.linker_arg("-znow");
473+
if self.sess.target.os == "l4re" {
474+
// FIXME: Why a comma between `-z` and `relro`?
475+
// FIXME: Why a comma between `-z,relro and -z,now`?
476+
// FIXME: Will `-zrelro` without space or comma work?
477+
self.cmd.arg("-z,relro,-z,now");
478+
} else {
479+
self.linker_arg("-zrelro");
480+
self.linker_arg("-znow");
481+
}
457482
}
458483
fn partial_relro(&mut self) {
459-
self.linker_arg("-zrelro");
484+
if self.sess.target.os == "l4re" {
485+
// FIXME: Why a comma between `-z` and `relro`?
486+
// FIXME: Will `-zrelro` without space or comma work?
487+
self.cmd.arg("-z,relro");
488+
} else {
489+
self.linker_arg("-zrelro");
490+
}
460491
}
461492
fn no_relro(&mut self) {
462-
self.linker_arg("-znorelro");
493+
if self.sess.target.os == "l4re" {
494+
// FIXME: Why a comma between `-z` and `norelro`?
495+
// FIXME: Will `-znorelro` without space or comma work?
496+
self.cmd.arg("-z,norelro");
497+
} else {
498+
self.linker_arg("-znorelro");
499+
}
463500
}
464501

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

555594
fn optimize(&mut self) {
556-
if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm {
595+
if self.sess.target.os == "l4re" {
596+
// FIXME: Why the difference with the GNU case below?
597+
self.cmd.arg("-O2");
598+
return;
599+
} else if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm {
557600
return;
558601
}
559602

@@ -713,8 +756,13 @@ impl<'a> Linker for GccLinker<'a> {
713756
}
714757

715758
fn subsystem(&mut self, subsystem: &str) {
716-
self.linker_arg("--subsystem");
717-
self.linker_arg(&subsystem);
759+
if self.sess.target.os == "l4re" {
760+
// FIXME: Why the comma between --subsystem and its name?
761+
self.cmd.arg(&format!("--subsystem,{}", subsystem));
762+
} else {
763+
self.linker_arg("--subsystem");
764+
self.linker_arg(&subsystem);
765+
}
718766
}
719767

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

15981646
fn linker_plugin_lto(&mut self) {}
15991647
}
1648+
1649+
fn add_l4bender_args(cmd: &mut Command) {
1650+
if let Ok(l4bender_args) = env::var("L4_BENDER_ARGS") {
1651+
// This parses a shell-escaped string and unquotes the arguments. It doesn't attempt to
1652+
// completely understand shell, but should instead allow passing arguments like
1653+
// `-Dlinker="ld -m x86_64"`, and a copy without quotes, but spaces preserved, is added
1654+
// as an argument to the given Command. This means that constructs as \" are not
1655+
// understood, so quote wisely.
1656+
let mut arg = String::new();
1657+
let mut quoted = false;
1658+
for character in l4bender_args.chars() {
1659+
match character {
1660+
' ' if !quoted => {
1661+
cmd.arg(&arg);
1662+
arg.clear();
1663+
}
1664+
'"' | '\'' => quoted = !quoted,
1665+
_ => arg.push(character),
1666+
};
1667+
}
1668+
if arg.len() > 0 {
1669+
cmd.arg(&arg);
1670+
arg.clear();
1671+
}
1672+
}
1673+
1674+
cmd.arg("--"); // separate direct l4-bender args from linker args
1675+
}
Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,15 @@
1-
use crate::spec::{LinkerFlavor, PanicStrategy, TargetOptions};
2-
//use std::process::Command;
3-
4-
// Use GCC to locate code for crt* libraries from the host, not from L4Re. Note
5-
// that a few files also come from L4Re, for these, the function shouldn't be
6-
// used. This uses GCC for the location of the file, but GCC is required for L4Re anyway.
7-
//fn get_path_or(filename: &str) -> String {
8-
// let child = Command::new("gcc")
9-
// .arg(format!("-print-file-name={}", filename)).output()
10-
// .expect("Failed to execute GCC");
11-
// String::from_utf8(child.stdout)
12-
// .expect("Couldn't read path from GCC").trim().into()
13-
//}
1+
use crate::spec::{PanicStrategy, TargetOptions};
142

153
pub fn opts() -> TargetOptions {
164
TargetOptions {
175
os: "l4re".to_string(),
186
env: "uclibc".to_string(),
19-
linker_flavor: LinkerFlavor::Ld,
207
executables: true,
218
panic_strategy: PanicStrategy::Abort,
22-
linker: Some("ld".to_string()),
9+
linker: Some("l4-bender".to_string()),
2310
linker_is_gnu: false,
2411
families: vec!["unix".to_string()],
12+
limit_rdylib_exports: false,
2513
..Default::default()
2614
}
2715
}

compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub fn target() -> Target {
44
let mut base = super::l4re_base::opts();
55
base.cpu = "x86-64".to_string();
66
base.max_atomic_width = Some(64);
7+
base.crt_static_default = true;
78

89
Target {
910
llvm_target: "x86_64-unknown-l4re-uclibc".to_string(),

library/panic_unwind/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ cfg_if::cfg_if! {
3939
} else if #[cfg(target_os = "hermit")] {
4040
#[path = "hermit.rs"]
4141
mod real_imp;
42+
} else if #[cfg(target_os = "l4re")] {
43+
// L4Re is unix family but does not yet support unwinding.
44+
#[path = "dummy.rs"]
45+
mod real_imp;
4246
} else if #[cfg(target_env = "msvc")] {
4347
#[path = "seh.rs"]
4448
mod real_imp;

library/std/src/sys/unix/l4re.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub mod net {
5959
}
6060

6161
pub fn is_read_vectored(&self) -> bool {
62-
unimpl!();
62+
false
6363
}
6464

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

8585
pub fn is_write_vectored(&self) -> bool {
86-
unimpl!();
86+
false
8787
}
8888

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

193193
pub fn is_read_vectored(&self) -> bool {
194-
unimpl!();
194+
false
195195
}
196196

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

205205
pub fn is_write_vectored(&self) -> bool {
206-
unimpl!();
206+
false
207207
}
208208

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

498498
impl LookupHost {
499499
pub fn port(&self) -> u16 {
500-
unimpl!();
500+
0 // unimplemented
501501
}
502502
}
503503

library/std/src/sys/unix/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
8080
target_os = "macos",
8181
target_os = "ios",
8282
target_os = "redox",
83+
target_os = "l4re",
8384
)))] {
8485
use crate::sys::os::errno;
8586
let pfds: &mut [_] = &mut [

library/std/src/sys/unix/process/process_unix.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ use crate::sys::weak::weak;
2626
#[cfg(target_os = "vxworks")]
2727
use libc::RTP_ID as pid_t;
2828

29-
#[cfg(not(target_os = "vxworks"))]
29+
#[cfg(target_os = "l4re")]
30+
use libc::{c_int, pid_t};
31+
32+
#[cfg(not(any(target_os = "vxworks", target_os = "l4re")))]
3033
use libc::{c_int, gid_t, pid_t, uid_t};
3134

3235
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)