From 54b206034fe50b2234ab8ddb15214f723fe8d951 Mon Sep 17 00:00:00 2001 From: Parth Sane Date: Mon, 2 Dec 2019 17:52:45 +0530 Subject: [PATCH] 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. --- src/librustc_codegen_llvm/back/write.rs | 3 +- src/librustc_codegen_llvm/llvm/ffi.rs | 3 +- src/librustc_codegen_ssa/back/linker.rs | 3 +- src/librustc_target/spec/mod.rs | 6 +++ .../spec/x86_64_fortanix_unknown_sgx.rs | 52 +++++++++---------- src/rustllvm/PassWrapper.cpp | 4 +- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs index 07ac76cec990b..48bbc13072387 100644 --- a/src/librustc_codegen_llvm/back/write.rs +++ b/src/librustc_codegen_llvm/back/write.rs @@ -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 asm_comments = sess.asm_comments(); - + let relax_elf_relocations = sess.target.target.options.relax_elf_relocations; Arc::new(move || { let tm = unsafe { llvm::LLVMRustCreateTargetMachine( @@ -183,6 +183,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea singlethread, asm_comments, emit_stack_size_section, + relax_elf_relocations, ) }; diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index a49e863fa2185..fd31e65c9d320 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -1702,7 +1702,8 @@ extern "C" { TrapUnreachable: bool, Singlethread: bool, AsmComments: bool, - EmitStackSizeSection: bool) + EmitStackSizeSection: bool, + RelaxELFRelocations: bool) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); pub fn LLVMRustAddBuilderLibraryInfo(PMB: &'a PassManagerBuilder, diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 999cc40658503..4278852123bea 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -398,7 +398,8 @@ impl<'a> Linker for GccLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) { // 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; } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 29076254584c0..693cf75e8fd64 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -803,6 +803,9 @@ pub struct TargetOptions { /// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers pub llvm_abiname: String, + + /// Whether or not RelaxElfRelocation flag will be passed to the linker + pub relax_elf_relocations: bool, } impl Default for TargetOptions { @@ -890,6 +893,7 @@ impl Default for TargetOptions { merge_functions: MergeFunctions::Aliases, target_mcount: "mcount".to_string(), llvm_abiname: "".to_string(), + relax_elf_relocations: false, } } } @@ -1207,6 +1211,7 @@ impl Target { key!(merge_functions, MergeFunctions)?; key!(target_mcount); key!(llvm_abiname); + key!(relax_elf_relocations, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { 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!(target_mcount); target_option_val!(llvm_abiname); + target_option_val!(relax_elf_relocations); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs index 7c24c88f7aee0..dbcd77bc753e8 100644 --- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -1,35 +1,31 @@ use std::iter; -use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions}; +use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}; pub fn target() -> Result { const PRE_LINK_ARGS: &[&str] = &[ - "-Wl,--as-needed", - "-Wl,-z,noexecstack", - "-m64", - "-fuse-ld=gold", - "-nostdlib", - "-shared", - "-Wl,-e,sgx_entry", - "-Wl,-Bstatic", - "-Wl,--gc-sections", - "-Wl,-z,text", - "-Wl,-z,norelro", - "-Wl,--rosegment", - "-Wl,--no-undefined", - "-Wl,--error-unresolved-symbols", - "-Wl,--no-undefined-version", - "-Wl,-Bsymbolic", - "-Wl,--export-dynamic", + "--as-needed", + "--eh-frame-hdr", + "-z" , "noexecstack", + "-e","sgx_entry", + "-Bstatic", + "--gc-sections", + "-z","text", + "-z","norelro", + "--no-undefined", + "--error-unresolved-symbols", + "--no-undefined-version", + "-Bsymbolic", + "--export-dynamic", // The following symbols are needed by libunwind, which is linked after // libstd. Make sure they're included in the link. - "-Wl,-u,__rust_abort", - "-Wl,-u,__rust_c_alloc", - "-Wl,-u,__rust_c_dealloc", - "-Wl,-u,__rust_print_err", - "-Wl,-u,__rust_rwlock_rdlock", - "-Wl,-u,__rust_rwlock_unlock", - "-Wl,-u,__rust_rwlock_wrlock", + "-u","__rust_abort", + "-u","__rust_c_alloc", + "-u","__rust_c_dealloc", + "-u","__rust_print_err", + "-u","__rust_rwlock_rdlock", + "-u","__rust_rwlock_unlock", + "-u","__rust_rwlock_wrlock" ]; const EXPORT_SYMBOLS: &[&str] = &[ @@ -50,18 +46,20 @@ pub fn target() -> Result { dynamic_linking: false, executables: true, linker_is_gnu: true, + linker: Some("rust-lld".to_owned()), max_atomic_width: Some(64), panic_strategy: PanicStrategy::Unwind, cpu: "x86-64".into(), features: "+rdrnd,+rdseed".into(), position_independent_executables: true, pre_link_args: iter::once(( - LinkerFlavor::Gcc, + LinkerFlavor::Lld(LldFlavor::Ld), PRE_LINK_ARGS.iter().cloned().map(String::from).collect(), )) .collect(), post_link_objects: vec!["libunwind.a".into()], override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()), + relax_elf_relocations: true, ..Default::default() }; Ok(Target { @@ -74,7 +72,7 @@ pub fn target() -> Result { target_vendor: "fortanix".into(), data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(), arch: "x86_64".into(), - linker_flavor: LinkerFlavor::Gcc, + linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), options: opts, }) } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index a116ed282acd1..b7f8e83590943 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -393,7 +393,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool TrapUnreachable, bool Singlethread, bool AsmComments, - bool EmitStackSizeSection) { + bool EmitStackSizeSection, + bool RelaxELFRelocations) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -418,6 +419,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.MCOptions.AsmVerbose = AsmComments; Options.MCOptions.PreserveAsmComments = AsmComments; Options.MCOptions.ABIName = ABIStr; + Options.RelaxELFRelocations = RelaxELFRelocations; if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction.