Skip to content

Commit

Permalink
Change linker for x86_64-fortanix-unknown-sgx to rust-lld
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
parthsane committed Dec 3, 2019
1 parent 4af3ee8 commit 54b2060
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 31 deletions.
3 changes: 2 additions & 1 deletion src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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,
)
};

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_codegen_ssa/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 6 additions & 0 deletions src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
}
}
}
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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()
Expand Down
52 changes: 25 additions & 27 deletions src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
use std::iter;

use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};

pub fn target() -> Result<Target, String> {
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] = &[
Expand All @@ -50,18 +46,20 @@ pub fn target() -> Result<Target, String> {
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 {
Expand All @@ -74,7 +72,7 @@ pub fn target() -> Result<Target, String> {
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,
})
}
4 changes: 3 additions & 1 deletion src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.
Expand Down

0 comments on commit 54b2060

Please sign in to comment.