about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJethro Beekman <jethro@fortanix.com>2018-11-19 15:04:28 +0530
committerJethro Beekman <jethro@fortanix.com>2018-11-19 23:24:43 +0530
commita44e446551a7251a06c23caa97aebcfbb98c79b2 (patch)
tree18f14e0c4ad92385f2770012956f4472de2d5583
parent7e82eda000c8d4abbdaa76b3563cd77f938fc411 (diff)
downloadrust-a44e446551a7251a06c23caa97aebcfbb98c79b2.tar.gz
rust-a44e446551a7251a06c23caa97aebcfbb98c79b2.zip
Add `override_export_symbols` option to Rust target specification
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs4
-rw-r--r--src/librustc_target/spec/mod.rs15
2 files changed, 19 insertions, 0 deletions
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index da9cfbb94d1..ec5ca580104 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -1050,6 +1050,10 @@ impl<'a> Linker for WasmLd<'a> {
 }
 
 fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
+    if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols {
+        return exports.clone()
+    }
+
     let mut symbols = Vec::new();
 
     let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 16dc2a91030..57bbf6b0260 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -683,6 +683,10 @@ pub struct TargetOptions {
     /// target features. This is `true` by default, and `false` for targets like
     /// wasm32 where the whole program either has simd or not.
     pub simd_types_indirect: bool,
+
+    /// If set, have the linker export exactly these symbols, instead of using
+    /// the usual logic to figure this out from the crate itself.
+    pub override_export_symbols: Option<Vec<String>>
 }
 
 impl Default for TargetOptions {
@@ -763,6 +767,7 @@ impl Default for TargetOptions {
             emit_debug_gdb_scripts: true,
             requires_uwtable: false,
             simd_types_indirect: true,
+            override_export_symbols: None,
         }
     }
 }
@@ -898,6 +903,14 @@ impl Target {
                         )
                     );
             } );
+            ($key_name:ident, opt_list) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.find(&name[..]).map(|o| o.as_array()
+                    .map(|v| base.options.$key_name = Some(v.iter()
+                        .map(|a| a.as_string().unwrap().to_string()).collect())
+                        )
+                    );
+            } );
             ($key_name:ident, optional) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 if let Some(o) = obj.find(&name[..]) {
@@ -1044,6 +1057,7 @@ impl Target {
         key!(emit_debug_gdb_scripts, bool);
         key!(requires_uwtable, bool);
         key!(simd_types_indirect, bool);
+        key!(override_export_symbols, opt_list);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1253,6 +1267,7 @@ impl ToJson for Target {
         target_option_val!(emit_debug_gdb_scripts);
         target_option_val!(requires_uwtable);
         target_option_val!(simd_types_indirect);
+        target_option_val!(override_export_symbols);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()