1
Fork 0

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:
Parth Sane 2019-12-02 17:52:45 +05:30
parent 4af3ee8ee2
commit 54b206034f
6 changed files with 40 additions and 31 deletions

View file

@ -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,
) )
}; };

View file

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

View file

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

View file

@ -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()

View file

@ -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,
}) })
} }

View file

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