about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarko Mijalkovic <marko.mijalkovic97@gmail.com>2020-05-10 16:06:33 -0400
committerMarko Mijalkovic <marko.mijalkovic97@gmail.com>2020-05-10 16:06:33 -0400
commit7e62240801cc5f7aa70300fb0f92f54370eabea6 (patch)
tree14a8d59f31a6924f173652f4e5232209598990a8
parent8961b083762d3660ca21110836b547e8b3f19022 (diff)
downloadrust-7e62240801cc5f7aa70300fb0f92f54370eabea6.tar.gz
rust-7e62240801cc5f7aa70300fb0f92f54370eabea6.zip
Add lld_link_script to TargetOptions
-rw-r--r--src/librustc_codegen_ssa/back/link.rs31
-rw-r--r--src/librustc_target/spec/mipsel_sony_psp.rs17
-rw-r--r--src/librustc_target/spec/mod.rs6
3 files changed, 39 insertions, 15 deletions
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 7a0e1e2c638..ab59a1c5f48 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -1179,6 +1179,34 @@ fn add_pre_link_args(
     cmd.args(&sess.opts.debugging_opts.pre_link_args);
 }
 
+/// Add an LLD link script embedded in the target, if applicable.
+fn add_lld_link_script(
+    cmd: &mut dyn Linker,
+    sess: &Session,
+    flavor: LinkerFlavor,
+    tmpdir: &Path,
+    crate_type: CrateType,
+) {
+    match (flavor, crate_type, &sess.target.target.options.lld_link_script) {
+        (
+            LinkerFlavor::Lld(LldFlavor::Ld),
+            CrateType::Cdylib | CrateType::Executable,
+            Some(script),
+        ) => {
+            let file_name = ["rustc", &sess.target.target.llvm_target, "linkfile.ld"].join("-");
+
+            let path = tmpdir.join(file_name);
+            if let Err(e) = fs::write(&path, script) {
+                sess.fatal(&format!("failed to write link script to {}: {}", path.display(), e));
+            }
+
+            cmd.arg("--script");
+            cmd.arg(path);
+        }
+        _ => {}
+    }
+}
+
 /// Add arbitrary "user defined" args defined from command line and by `#[link_args]` attributes.
 /// FIXME: Determine where exactly these args need to be inserted.
 fn add_user_defined_link_args(
@@ -1421,6 +1449,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
     // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
     add_pre_link_args(cmd, sess, flavor, crate_type);
 
+    // NO-OPT-OUT
+    add_lld_link_script(cmd, sess, flavor, tmpdir, crate_type);
+
     // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
     if sess.target.target.options.is_like_fuchsia {
         let prefix = match sess.opts.debugging_opts.sanitizer {
diff --git a/src/librustc_target/spec/mipsel_sony_psp.rs b/src/librustc_target/spec/mipsel_sony_psp.rs
index 80c253b86bb..eb38dee63b6 100644
--- a/src/librustc_target/spec/mipsel_sony_psp.rs
+++ b/src/librustc_target/spec/mipsel_sony_psp.rs
@@ -1,28 +1,14 @@
 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, RelocModel};
 use crate::spec::{Target, TargetOptions, TargetResult};
-use std::{env, fs, io, path::PathBuf};
 
 // The PSP has custom linker requirements.
 const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
 
-fn write_script() -> io::Result<PathBuf> {
-    let path = env::temp_dir().join("rustc-mipsel-sony-psp-linkfile.ld");
-    fs::write(&path, LINKER_SCRIPT)?;
-    Ok(path)
-}
-
 pub fn target() -> TargetResult {
-    let script = write_script().map_err(|e| format!("failed to write link script: {}", e))?;
-
     let mut pre_link_args = LinkArgs::new();
     pre_link_args.insert(
         LinkerFlavor::Lld(LldFlavor::Ld),
-        vec![
-            "--eh-frame-hdr".to_string(),
-            "--emit-relocs".to_string(),
-            "--script".to_string(),
-            script.display().to_string(),
-        ],
+        vec!["--eh-frame-hdr".to_string(), "--emit-relocs".to_string()],
     );
 
     Ok(Target {
@@ -49,6 +35,7 @@ pub fn target() -> TargetResult {
             // PSP does not support trap-on-condition instructions.
             llvm_args: vec!["-mno-check-zero-division".to_string()],
             pre_link_args,
+            lld_link_script: Some(LINKER_SCRIPT.to_string()),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index dab1e51e3f8..91dfa1550f6 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -668,6 +668,9 @@ pub struct TargetOptions {
     /// Linker arguments that are unconditionally passed *after* any
     /// user-defined libraries.
     pub post_link_args: LinkArgs,
+    /// Optional LLD link script applied to `dylib` and `executable` crate
+    /// types. This is a string containing the script, not a path.
+    pub lld_link_script: Option<String>,
 
     /// Environment variables to be set for the linker invocation.
     pub link_env: Vec<(String, String)>,
@@ -897,6 +900,7 @@ impl Default for TargetOptions {
             pre_link_args: LinkArgs::new(),
             pre_link_args_crt: LinkArgs::new(),
             post_link_args: LinkArgs::new(),
+            lld_link_script: None,
             asm_args: Vec::new(),
             cpu: "generic".to_string(),
             features: String::new(),
@@ -1246,6 +1250,7 @@ impl Target {
         key!(post_link_objects, list);
         key!(post_link_objects_crt, list);
         key!(post_link_args, link_args);
+        key!(lld_link_script, optional);
         key!(link_env, env);
         key!(link_env_remove, list);
         key!(asm_args, list);
@@ -1475,6 +1480,7 @@ impl ToJson for Target {
         target_option_val!(post_link_objects);
         target_option_val!(post_link_objects_crt);
         target_option_val!(link_args - post_link_args);
+        target_option_val!(lld_link_script);
         target_option_val!(env - link_env);
         target_option_val!(link_env_remove);
         target_option_val!(asm_args);