Change linker for x86_64-fortanix-unknown-sgx to rust-lld
For SGX, the relocation using the relocation table is done by the code in rust/src/libstd/sys/sgx/abi/reloc.rs and this code should not require relocation. Setting RelaxELFRelocations flag if allows this to happen, hence adding a Target Option for it.
This commit is contained in:
parent
4af3ee8ee2
commit
54b206034f
6 changed files with 40 additions and 31 deletions
|
@ -167,7 +167,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
|
||||||
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
|
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
|
||||||
|
|
||||||
let asm_comments = sess.asm_comments();
|
let asm_comments = sess.asm_comments();
|
||||||
|
let relax_elf_relocations = sess.target.target.options.relax_elf_relocations;
|
||||||
Arc::new(move || {
|
Arc::new(move || {
|
||||||
let tm = unsafe {
|
let tm = unsafe {
|
||||||
llvm::LLVMRustCreateTargetMachine(
|
llvm::LLVMRustCreateTargetMachine(
|
||||||
|
@ -183,6 +183,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
|
||||||
singlethread,
|
singlethread,
|
||||||
asm_comments,
|
asm_comments,
|
||||||
emit_stack_size_section,
|
emit_stack_size_section,
|
||||||
|
relax_elf_relocations,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1702,7 +1702,8 @@ extern "C" {
|
||||||
TrapUnreachable: bool,
|
TrapUnreachable: bool,
|
||||||
Singlethread: bool,
|
Singlethread: bool,
|
||||||
AsmComments: bool,
|
AsmComments: bool,
|
||||||
EmitStackSizeSection: bool)
|
EmitStackSizeSection: bool,
|
||||||
|
RelaxELFRelocations: bool)
|
||||||
-> Option<&'static mut TargetMachine>;
|
-> Option<&'static mut TargetMachine>;
|
||||||
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
|
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
|
||||||
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,
|
pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder,
|
||||||
|
|
|
@ -398,7 +398,8 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
|
|
||||||
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
|
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
|
||||||
// Symbol visibility in object files typically takes care of this.
|
// Symbol visibility in object files typically takes care of this.
|
||||||
if crate_type == CrateType::Executable {
|
if crate_type == CrateType::Executable &&
|
||||||
|
self.sess.target.target.options.override_export_symbols.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -803,6 +803,9 @@ pub struct TargetOptions {
|
||||||
|
|
||||||
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
|
/// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
|
||||||
pub llvm_abiname: String,
|
pub llvm_abiname: String,
|
||||||
|
|
||||||
|
/// Whether or not RelaxElfRelocation flag will be passed to the linker
|
||||||
|
pub relax_elf_relocations: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TargetOptions {
|
impl Default for TargetOptions {
|
||||||
|
@ -890,6 +893,7 @@ impl Default for TargetOptions {
|
||||||
merge_functions: MergeFunctions::Aliases,
|
merge_functions: MergeFunctions::Aliases,
|
||||||
target_mcount: "mcount".to_string(),
|
target_mcount: "mcount".to_string(),
|
||||||
llvm_abiname: "".to_string(),
|
llvm_abiname: "".to_string(),
|
||||||
|
relax_elf_relocations: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1207,6 +1211,7 @@ impl Target {
|
||||||
key!(merge_functions, MergeFunctions)?;
|
key!(merge_functions, MergeFunctions)?;
|
||||||
key!(target_mcount);
|
key!(target_mcount);
|
||||||
key!(llvm_abiname);
|
key!(llvm_abiname);
|
||||||
|
key!(relax_elf_relocations, bool);
|
||||||
|
|
||||||
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
|
||||||
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
for name in array.iter().filter_map(|abi| abi.as_string()) {
|
||||||
|
@ -1426,6 +1431,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(merge_functions);
|
target_option_val!(merge_functions);
|
||||||
target_option_val!(target_mcount);
|
target_option_val!(target_mcount);
|
||||||
target_option_val!(llvm_abiname);
|
target_option_val!(llvm_abiname);
|
||||||
|
target_option_val!(relax_elf_relocations);
|
||||||
|
|
||||||
if default.abi_blacklist != self.options.abi_blacklist {
|
if default.abi_blacklist != self.options.abi_blacklist {
|
||||||
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
|
||||||
|
|
|
@ -1,35 +1,31 @@
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
|
||||||
|
|
||||||
pub fn target() -> Result<Target, String> {
|
pub fn target() -> Result<Target, String> {
|
||||||
const PRE_LINK_ARGS: &[&str] = &[
|
const PRE_LINK_ARGS: &[&str] = &[
|
||||||
"-Wl,--as-needed",
|
"--as-needed",
|
||||||
"-Wl,-z,noexecstack",
|
"--eh-frame-hdr",
|
||||||
"-m64",
|
"-z" , "noexecstack",
|
||||||
"-fuse-ld=gold",
|
"-e","sgx_entry",
|
||||||
"-nostdlib",
|
"-Bstatic",
|
||||||
"-shared",
|
"--gc-sections",
|
||||||
"-Wl,-e,sgx_entry",
|
"-z","text",
|
||||||
"-Wl,-Bstatic",
|
"-z","norelro",
|
||||||
"-Wl,--gc-sections",
|
"--no-undefined",
|
||||||
"-Wl,-z,text",
|
"--error-unresolved-symbols",
|
||||||
"-Wl,-z,norelro",
|
"--no-undefined-version",
|
||||||
"-Wl,--rosegment",
|
"-Bsymbolic",
|
||||||
"-Wl,--no-undefined",
|
"--export-dynamic",
|
||||||
"-Wl,--error-unresolved-symbols",
|
|
||||||
"-Wl,--no-undefined-version",
|
|
||||||
"-Wl,-Bsymbolic",
|
|
||||||
"-Wl,--export-dynamic",
|
|
||||||
// The following symbols are needed by libunwind, which is linked after
|
// The following symbols are needed by libunwind, which is linked after
|
||||||
// libstd. Make sure they're included in the link.
|
// libstd. Make sure they're included in the link.
|
||||||
"-Wl,-u,__rust_abort",
|
"-u","__rust_abort",
|
||||||
"-Wl,-u,__rust_c_alloc",
|
"-u","__rust_c_alloc",
|
||||||
"-Wl,-u,__rust_c_dealloc",
|
"-u","__rust_c_dealloc",
|
||||||
"-Wl,-u,__rust_print_err",
|
"-u","__rust_print_err",
|
||||||
"-Wl,-u,__rust_rwlock_rdlock",
|
"-u","__rust_rwlock_rdlock",
|
||||||
"-Wl,-u,__rust_rwlock_unlock",
|
"-u","__rust_rwlock_unlock",
|
||||||
"-Wl,-u,__rust_rwlock_wrlock",
|
"-u","__rust_rwlock_wrlock"
|
||||||
];
|
];
|
||||||
|
|
||||||
const EXPORT_SYMBOLS: &[&str] = &[
|
const EXPORT_SYMBOLS: &[&str] = &[
|
||||||
|
@ -50,18 +46,20 @@ pub fn target() -> Result<Target, String> {
|
||||||
dynamic_linking: false,
|
dynamic_linking: false,
|
||||||
executables: true,
|
executables: true,
|
||||||
linker_is_gnu: true,
|
linker_is_gnu: true,
|
||||||
|
linker: Some("rust-lld".to_owned()),
|
||||||
max_atomic_width: Some(64),
|
max_atomic_width: Some(64),
|
||||||
panic_strategy: PanicStrategy::Unwind,
|
panic_strategy: PanicStrategy::Unwind,
|
||||||
cpu: "x86-64".into(),
|
cpu: "x86-64".into(),
|
||||||
features: "+rdrnd,+rdseed".into(),
|
features: "+rdrnd,+rdseed".into(),
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
pre_link_args: iter::once((
|
pre_link_args: iter::once((
|
||||||
LinkerFlavor::Gcc,
|
LinkerFlavor::Lld(LldFlavor::Ld),
|
||||||
PRE_LINK_ARGS.iter().cloned().map(String::from).collect(),
|
PRE_LINK_ARGS.iter().cloned().map(String::from).collect(),
|
||||||
))
|
))
|
||||||
.collect(),
|
.collect(),
|
||||||
post_link_objects: vec!["libunwind.a".into()],
|
post_link_objects: vec!["libunwind.a".into()],
|
||||||
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()),
|
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()),
|
||||||
|
relax_elf_relocations: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
Ok(Target {
|
Ok(Target {
|
||||||
|
@ -74,7 +72,7 @@ pub fn target() -> Result<Target, String> {
|
||||||
target_vendor: "fortanix".into(),
|
target_vendor: "fortanix".into(),
|
||||||
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(),
|
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(),
|
||||||
arch: "x86_64".into(),
|
arch: "x86_64".into(),
|
||||||
linker_flavor: LinkerFlavor::Gcc,
|
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
|
||||||
options: opts,
|
options: opts,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,7 +393,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||||
bool TrapUnreachable,
|
bool TrapUnreachable,
|
||||||
bool Singlethread,
|
bool Singlethread,
|
||||||
bool AsmComments,
|
bool AsmComments,
|
||||||
bool EmitStackSizeSection) {
|
bool EmitStackSizeSection,
|
||||||
|
bool RelaxELFRelocations) {
|
||||||
|
|
||||||
auto OptLevel = fromRust(RustOptLevel);
|
auto OptLevel = fromRust(RustOptLevel);
|
||||||
auto RM = fromRust(RustReloc);
|
auto RM = fromRust(RustReloc);
|
||||||
|
@ -418,6 +419,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
|
||||||
Options.MCOptions.AsmVerbose = AsmComments;
|
Options.MCOptions.AsmVerbose = AsmComments;
|
||||||
Options.MCOptions.PreserveAsmComments = AsmComments;
|
Options.MCOptions.PreserveAsmComments = AsmComments;
|
||||||
Options.MCOptions.ABIName = ABIStr;
|
Options.MCOptions.ABIName = ABIStr;
|
||||||
|
Options.RelaxELFRelocations = RelaxELFRelocations;
|
||||||
|
|
||||||
if (TrapUnreachable) {
|
if (TrapUnreachable) {
|
||||||
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.
|
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue