Skip to content

Commit 2ad1c73

Browse files
authored
Rollup merge of rust-lang#85967 - atopia:update-l4re-target, r=petrochenkov
add support for the l4-bender linker on the x86_64-unknown-l4re-uclibc tier 3 target This PR contains the work by `@humenda` to update support for the `x86_64-unknown-l4re-uclibc` tier 3 target (published at [humenda/rust](https://github.com/humenda/rust)), rebased and adapted to current rust in follow up commits by myself. The publishing of the rebased changes is authorized and preferred by the original author. As the goal was to distort the original work as little as possible, individual commits introduce changes that are incompatible to the newer code base that the changes were rebased on. These incompatibilities have been remedied in follow up commits, so that the PR as a whole should result in a clean update of the target. If you prefer another strategy to mainline these changes while preserving attribution, please let me know.
2 parents ecf7299 + 29d6235 commit 2ad1c73

File tree

7 files changed

+178
-17
lines changed

7 files changed

+178
-17
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
11591159
LinkerFlavor::Lld(_) => "lld",
11601160
LinkerFlavor::PtxLinker => "rust-ptx-linker",
11611161
LinkerFlavor::BpfLinker => "bpf-linker",
1162+
LinkerFlavor::L4Bender => "l4-bender",
11621163
}),
11631164
flavor,
11641165
)),

compiler/rustc_codegen_ssa/src/back/linker.rs

+153-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ pub fn get_linker<'a>(
126126
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
127127
// to the linker args construction.
128128
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
129-
130129
match flavor {
131130
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
132131
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
@@ -149,6 +148,8 @@ pub fn get_linker<'a>(
149148
LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
150149

151150
LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
151+
152+
LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>,
152153
}
153154
}
154155

@@ -1355,6 +1356,157 @@ impl<'a> Linker for WasmLd<'a> {
13551356
}
13561357
}
13571358

1359+
/// Linker shepherd script for L4Re (Fiasco)
1360+
pub struct L4Bender<'a> {
1361+
cmd: Command,
1362+
sess: &'a Session,
1363+
hinted_static: bool,
1364+
}
1365+
1366+
impl<'a> Linker for L4Bender<'a> {
1367+
fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
1368+
bug!("dylibs are not supported on L4Re");
1369+
}
1370+
fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) {
1371+
self.hint_static();
1372+
self.cmd.arg(format!("-PC{}", lib));
1373+
}
1374+
fn link_rlib(&mut self, lib: &Path) {
1375+
self.hint_static();
1376+
self.cmd.arg(lib);
1377+
}
1378+
fn include_path(&mut self, path: &Path) {
1379+
self.cmd.arg("-L").arg(path);
1380+
}
1381+
fn framework_path(&mut self, _: &Path) {
1382+
bug!("frameworks are not supported on L4Re");
1383+
}
1384+
fn output_filename(&mut self, path: &Path) {
1385+
self.cmd.arg("-o").arg(path);
1386+
}
1387+
1388+
fn add_object(&mut self, path: &Path) {
1389+
self.cmd.arg(path);
1390+
}
1391+
1392+
fn full_relro(&mut self) {
1393+
self.cmd.arg("-zrelro");
1394+
self.cmd.arg("-znow");
1395+
}
1396+
1397+
fn partial_relro(&mut self) {
1398+
self.cmd.arg("-zrelro");
1399+
}
1400+
1401+
fn no_relro(&mut self) {
1402+
self.cmd.arg("-znorelro");
1403+
}
1404+
1405+
fn cmd(&mut self) -> &mut Command {
1406+
&mut self.cmd
1407+
}
1408+
1409+
fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}
1410+
1411+
fn link_rust_dylib(&mut self, _: Symbol, _: &Path) {
1412+
panic!("Rust dylibs not supported");
1413+
}
1414+
1415+
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
1416+
bug!("frameworks not supported on L4Re");
1417+
}
1418+
1419+
fn link_whole_staticlib(&mut self, lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) {
1420+
self.hint_static();
1421+
self.cmd.arg("--whole-archive").arg(format!("-l{}", lib));
1422+
self.cmd.arg("--no-whole-archive");
1423+
}
1424+
1425+
fn link_whole_rlib(&mut self, lib: &Path) {
1426+
self.hint_static();
1427+
self.cmd.arg("--whole-archive").arg(lib).arg("--no-whole-archive");
1428+
}
1429+
1430+
fn gc_sections(&mut self, keep_metadata: bool) {
1431+
if !keep_metadata {
1432+
self.cmd.arg("--gc-sections");
1433+
}
1434+
}
1435+
1436+
fn no_gc_sections(&mut self) {
1437+
self.cmd.arg("--no-gc-sections");
1438+
}
1439+
1440+
fn optimize(&mut self) {
1441+
// GNU-style linkers support optimization with -O. GNU ld doesn't
1442+
// need a numeric argument, but other linkers do.
1443+
if self.sess.opts.optimize == config::OptLevel::Default
1444+
|| self.sess.opts.optimize == config::OptLevel::Aggressive
1445+
{
1446+
self.cmd.arg("-O1");
1447+
}
1448+
}
1449+
1450+
fn pgo_gen(&mut self) {}
1451+
1452+
fn debuginfo(&mut self, strip: Strip) {
1453+
match strip {
1454+
Strip::None => {}
1455+
Strip::Debuginfo => {
1456+
self.cmd().arg("--strip-debug");
1457+
}
1458+
Strip::Symbols => {
1459+
self.cmd().arg("--strip-all");
1460+
}
1461+
}
1462+
}
1463+
1464+
fn no_default_libraries(&mut self) {
1465+
self.cmd.arg("-nostdlib");
1466+
}
1467+
1468+
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
1469+
// ToDo, not implemented, copy from GCC
1470+
self.sess.warn("exporting symbols not implemented yet for L4Bender");
1471+
return;
1472+
}
1473+
1474+
fn subsystem(&mut self, subsystem: &str) {
1475+
self.cmd.arg(&format!("--subsystem {}", subsystem));
1476+
}
1477+
1478+
fn reset_per_library_state(&mut self) {
1479+
self.hint_static(); // Reset to default before returning the composed command line.
1480+
}
1481+
1482+
fn group_start(&mut self) {
1483+
self.cmd.arg("--start-group");
1484+
}
1485+
1486+
fn group_end(&mut self) {
1487+
self.cmd.arg("--end-group");
1488+
}
1489+
1490+
fn linker_plugin_lto(&mut self) {}
1491+
1492+
fn control_flow_guard(&mut self) {}
1493+
1494+
fn no_crt_objects(&mut self) {}
1495+
}
1496+
1497+
impl<'a> L4Bender<'a> {
1498+
pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
1499+
L4Bender { cmd: cmd, sess: sess, hinted_static: false }
1500+
}
1501+
1502+
fn hint_static(&mut self) {
1503+
if !self.hinted_static {
1504+
self.cmd.arg("-static");
1505+
self.hinted_static = true;
1506+
}
1507+
}
1508+
}
1509+
13581510
pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
13591511
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
13601512
return exports.clone();

compiler/rustc_session/src/config.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashSet;
1212
use rustc_data_structures::impl_stable_hash_via_hash;
1313

1414
use rustc_target::abi::{Align, TargetDataLayout};
15-
use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple, TargetWarnings};
15+
use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
1616

1717
use rustc_serialize::json;
1818

@@ -2237,6 +2237,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
22372237
}
22382238
}
22392239

2240+
if cg.linker_flavor == Some(LinkerFlavor::L4Bender)
2241+
&& !nightly_options::is_unstable_enabled(matches)
2242+
{
2243+
early_error(
2244+
error_format,
2245+
"`l4-bender` linker flavor is unstable, `-Z unstable-options` \
2246+
flag must also be passed to explicitly use it",
2247+
);
2248+
}
2249+
22402250
let prints = collect_print_requests(&mut cg, &mut debugging_opts, matches, error_format);
22412251

22422252
let cg = cg;

compiler/rustc_target/src/spec/l4re_base.rs

+3-14
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
11
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-
//}
2+
use std::default::Default;
143

154
pub fn opts() -> TargetOptions {
165
TargetOptions {
176
os: "l4re".to_string(),
187
env: "uclibc".to_string(),
19-
linker_flavor: LinkerFlavor::Ld,
8+
linker_flavor: LinkerFlavor::L4Bender,
209
executables: true,
2110
panic_strategy: PanicStrategy::Abort,
22-
linker: Some("ld".to_string()),
11+
linker: Some("l4-bender".to_string()),
2312
linker_is_gnu: false,
2413
families: vec!["unix".to_string()],
2514
..Default::default()

compiler/rustc_target/src/spec/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ mod windows_uwp_msvc_base;
9090
pub enum LinkerFlavor {
9191
Em,
9292
Gcc,
93+
L4Bender,
9394
Ld,
9495
Msvc,
9596
Lld(LldFlavor),
@@ -160,6 +161,7 @@ macro_rules! flavor_mappings {
160161
flavor_mappings! {
161162
((LinkerFlavor::Em), "em"),
162163
((LinkerFlavor::Gcc), "gcc"),
164+
((LinkerFlavor::L4Bender), "l4-bender"),
163165
((LinkerFlavor::Ld), "ld"),
164166
((LinkerFlavor::Msvc), "msvc"),
165167
((LinkerFlavor::PtxLinker), "ptx-linker"),

compiler/rustc_target/src/spec/x86_64_unknown_l4re_uclibc.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
use crate::spec::Target;
1+
use crate::spec::{PanicStrategy, Target};
22

33
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_allows_dylibs = false;
8+
base.dynamic_linking = false;
9+
base.panic_strategy = PanicStrategy::Abort;
710

811
Target {
912
llvm_target: "x86_64-unknown-l4re-uclibc".to_string(),

library/panic_unwind/src/lib.rs

+4
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;

0 commit comments

Comments
 (0)