diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 7a0e1e2c6388..ab59a1c5f487 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 80c253b86bbd..eb38dee63b68 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 { - 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 dab1e51e3f87..91dfa1550f62 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, /// 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);