Rollup merge of #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.
This commit is contained in:
Matthias Krüger 2022-01-22 15:32:48 +01:00 committed by GitHub
commit ffd199d768
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 178 additions and 17 deletions

View File

@ -1159,6 +1159,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
LinkerFlavor::Lld(_) => "lld",
LinkerFlavor::PtxLinker => "rust-ptx-linker",
LinkerFlavor::BpfLinker => "bpf-linker",
LinkerFlavor::L4Bender => "l4-bender",
}),
flavor,
)),

View File

@ -126,7 +126,6 @@ pub fn get_linker<'a>(
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
// to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor {
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
@ -149,6 +148,8 @@ pub fn get_linker<'a>(
LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>,
}
}
@ -1355,6 +1356,157 @@ impl<'a> Linker for WasmLd<'a> {
}
}
/// Linker shepherd script for L4Re (Fiasco)
pub struct L4Bender<'a> {
cmd: Command,
sess: &'a Session,
hinted_static: bool,
}
impl<'a> Linker for L4Bender<'a> {
fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
bug!("dylibs are not supported on L4Re");
}
fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) {
self.hint_static();
self.cmd.arg(format!("-PC{}", lib));
}
fn link_rlib(&mut self, lib: &Path) {
self.hint_static();
self.cmd.arg(lib);
}
fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
}
fn framework_path(&mut self, _: &Path) {
bug!("frameworks are not supported on L4Re");
}
fn output_filename(&mut self, path: &Path) {
self.cmd.arg("-o").arg(path);
}
fn add_object(&mut self, path: &Path) {
self.cmd.arg(path);
}
fn full_relro(&mut self) {
self.cmd.arg("-zrelro");
self.cmd.arg("-znow");
}
fn partial_relro(&mut self) {
self.cmd.arg("-zrelro");
}
fn no_relro(&mut self) {
self.cmd.arg("-znorelro");
}
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}
fn link_rust_dylib(&mut self, _: Symbol, _: &Path) {
panic!("Rust dylibs not supported");
}
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
bug!("frameworks not supported on L4Re");
}
fn link_whole_staticlib(&mut self, lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) {
self.hint_static();
self.cmd.arg("--whole-archive").arg(format!("-l{}", lib));
self.cmd.arg("--no-whole-archive");
}
fn link_whole_rlib(&mut self, lib: &Path) {
self.hint_static();
self.cmd.arg("--whole-archive").arg(lib).arg("--no-whole-archive");
}
fn gc_sections(&mut self, keep_metadata: bool) {
if !keep_metadata {
self.cmd.arg("--gc-sections");
}
}
fn no_gc_sections(&mut self) {
self.cmd.arg("--no-gc-sections");
}
fn optimize(&mut self) {
// GNU-style linkers support optimization with -O. GNU ld doesn't
// need a numeric argument, but other linkers do.
if self.sess.opts.optimize == config::OptLevel::Default
|| self.sess.opts.optimize == config::OptLevel::Aggressive
{
self.cmd.arg("-O1");
}
}
fn pgo_gen(&mut self) {}
fn debuginfo(&mut self, strip: Strip) {
match strip {
Strip::None => {}
Strip::Debuginfo => {
self.cmd().arg("--strip-debug");
}
Strip::Symbols => {
self.cmd().arg("--strip-all");
}
}
}
fn no_default_libraries(&mut self) {
self.cmd.arg("-nostdlib");
}
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
// ToDo, not implemented, copy from GCC
self.sess.warn("exporting symbols not implemented yet for L4Bender");
return;
}
fn subsystem(&mut self, subsystem: &str) {
self.cmd.arg(&format!("--subsystem {}", subsystem));
}
fn reset_per_library_state(&mut self) {
self.hint_static(); // Reset to default before returning the composed command line.
}
fn group_start(&mut self) {
self.cmd.arg("--start-group");
}
fn group_end(&mut self) {
self.cmd.arg("--end-group");
}
fn linker_plugin_lto(&mut self) {}
fn control_flow_guard(&mut self) {}
fn no_crt_objects(&mut self) {}
}
impl<'a> L4Bender<'a> {
pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
L4Bender { cmd: cmd, sess: sess, hinted_static: false }
}
fn hint_static(&mut self) {
if !self.hinted_static {
self.cmd.arg("-static");
self.hinted_static = true;
}
}
}
pub(crate) fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
if let Some(ref exports) = tcx.sess.target.override_export_symbols {
return exports.clone();

View File

@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::impl_stable_hash_via_hash;
use rustc_target::abi::{Align, TargetDataLayout};
use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple, TargetWarnings};
use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
use rustc_serialize::json;
@ -2237,6 +2237,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
}
if cg.linker_flavor == Some(LinkerFlavor::L4Bender)
&& !nightly_options::is_unstable_enabled(matches)
{
early_error(
error_format,
"`l4-bender` linker flavor is unstable, `-Z unstable-options` \
flag must also be passed to explicitly use it",
);
}
let prints = collect_print_requests(&mut cg, &mut debugging_opts, matches, error_format);
let cg = cg;

View File

@ -1,25 +1,14 @@
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 std::default::Default;
pub fn opts() -> TargetOptions {
TargetOptions {
os: "l4re".to_string(),
env: "uclibc".to_string(),
linker_flavor: LinkerFlavor::Ld,
linker_flavor: LinkerFlavor::L4Bender,
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()],
..Default::default()

View File

@ -90,6 +90,7 @@ mod windows_uwp_msvc_base;
pub enum LinkerFlavor {
Em,
Gcc,
L4Bender,
Ld,
Msvc,
Lld(LldFlavor),
@ -160,6 +161,7 @@ macro_rules! flavor_mappings {
flavor_mappings! {
((LinkerFlavor::Em), "em"),
((LinkerFlavor::Gcc), "gcc"),
((LinkerFlavor::L4Bender), "l4-bender"),
((LinkerFlavor::Ld), "ld"),
((LinkerFlavor::Msvc), "msvc"),
((LinkerFlavor::PtxLinker), "ptx-linker"),

View File

@ -1,9 +1,12 @@
use crate::spec::Target;
use crate::spec::{PanicStrategy, Target};
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_allows_dylibs = false;
base.dynamic_linking = false;
base.panic_strategy = PanicStrategy::Abort;
Target {
llvm_target: "x86_64-unknown-l4re-uclibc".to_string(),

View File

@ -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;