mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
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:
commit
ffd199d768
@ -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,
|
||||
)),
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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"),
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user