1
Fork 0

LLVM Bitcode Linker: Add as a linker known to the compiler

This commit is contained in:
Kjetil Kjeka 2024-02-06 19:46:12 +01:00
parent af42d2a4b2
commit 43f2055af5
4 changed files with 142 additions and 9 deletions

View file

@ -24,6 +24,7 @@ use rustc_span::symbol::Symbol;
use rustc_target::spec::crt_objects::CrtObjects;
use rustc_target::spec::LinkSelfContainedComponents;
use rustc_target::spec::LinkSelfContainedDefault;
use rustc_target::spec::LinkerFlavorCli;
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
@ -1350,6 +1351,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
}
}
LinkerFlavor::Bpf => "bpf-linker",
LinkerFlavor::Llbc => "llvm-bitcode-linker",
LinkerFlavor::Ptx => "rust-ptx-linker",
}),
flavor,
@ -1367,8 +1369,17 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// linker and linker flavor specified via command line have precedence over what the target
// specification specifies
let linker_flavor =
sess.opts.cg.linker_flavor.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor));
let linker_flavor = match sess.opts.cg.linker_flavor {
// The linker flavors that are non-target specific can be directly translated to LinkerFlavor
Some(LinkerFlavorCli::Llbc) => Some(LinkerFlavor::Llbc),
Some(LinkerFlavorCli::Ptx) => Some(LinkerFlavor::Ptx),
// The linker flavors that corresponds to targets needs logic that keeps the base LinkerFlavor
_ => sess
.opts
.cg
.linker_flavor
.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor)),
};
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret;
}
@ -2338,8 +2349,12 @@ fn add_order_independent_options(
});
}
if flavor == LinkerFlavor::Ptx {
// Provide the linker with fallback to internal `target-cpu`.
if flavor == LinkerFlavor::Llbc {
cmd.arg("--target");
cmd.arg(sess.target.llvm_target.as_ref());
cmd.arg("--target-cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
} else if flavor == LinkerFlavor::Ptx {
cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.target_cpu);
} else if flavor == LinkerFlavor::Bpf {

View file

@ -153,6 +153,7 @@ pub fn get_linker<'a>(
LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Llbc => Box::new(LlbcLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
}
}
@ -1824,7 +1825,7 @@ impl<'a> Linker for PtxLinker<'a> {
}
Lto::No => {}
};
}
}
fn output_filename(&mut self, path: &Path) {
@ -1862,6 +1863,104 @@ impl<'a> Linker for PtxLinker<'a> {
fn linker_plugin_lto(&mut self) {}
}
/// The `self-contained` LLVM bitcode linker
pub struct LlbcLinker<'a> {
cmd: Command,
sess: &'a Session,
}
impl<'a> Linker for LlbcLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}
fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) {
panic!("external dylibs not supported")
}
fn link_staticlib_by_name(
&mut self,
_name: &str,
_verbatim: bool,
_whole_archive: bool,
_search_paths: &SearchPaths,
) {
panic!("staticlibs not supported")
}
fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) {
self.cmd.arg(path);
}
fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
}
fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
self.cmd.arg("--debug");
}
fn add_object(&mut self, path: &Path) {
self.cmd.arg(path);
}
fn optimize(&mut self) {
match self.sess.opts.optimize {
OptLevel::No => "-O0",
OptLevel::Less => "-O1",
OptLevel::Default => "-O2",
OptLevel::Aggressive => "-O3",
OptLevel::Size => "-Os",
OptLevel::SizeMin => "-Oz",
};
}
fn output_filename(&mut self, path: &Path) {
self.cmd.arg("-o").arg(path);
}
fn framework_path(&mut self, _path: &Path) {
panic!("frameworks not supported")
}
fn full_relro(&mut self) {}
fn partial_relro(&mut self) {}
fn no_relro(&mut self) {}
fn gc_sections(&mut self, _keep_metadata: bool) {}
fn no_gc_sections(&mut self) {}
fn pgo_gen(&mut self) {}
fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
fn control_flow_guard(&mut self) {}
fn ehcont_guard(&mut self) {}
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
match _crate_type {
CrateType::Cdylib => {
for sym in symbols {
self.cmd.arg("--export-symbol").arg(sym);
}
}
_ => (),
}
}
fn subsystem(&mut self, _subsystem: &str) {}
fn linker_plugin_lto(&mut self) {}
}
pub struct BpfLinker<'a> {
cmd: Command,
sess: &'a Session,