about summary refs log tree commit diff
path: root/src/librustc_back/target
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-12-10 12:21:55 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-12-21 22:05:37 -0800
commitb67b5a8d0149096712e75336f6aa32daffcaa42d (patch)
tree1e8c3ac5add64bbdad0738bf36566254b94a1fa1 /src/librustc_back/target
parentd8cc67fb26544ccd6b0292a3e3ddc730131e9256 (diff)
downloadrust-b67b5a8d0149096712e75336f6aa32daffcaa42d.tar.gz
rust-b67b5a8d0149096712e75336f6aa32daffcaa42d.zip
rustc: Add feature-gated cfg(target_thread_local)
Currently the standard library has some pretty complicated logic to detect
whether #[thread_local] should be used or whether it's supported. This is also
unfortunately not quite true for OSX where not all versions support
the #[thread_local] attribute (only 10.7+ does). Compiling code for OSX 10.6 is
typically requested via the MACOSX_DEPLOYMENT_TARGET environment variable (e.g.
the linker recognizes this), but the standard library unfortunately does not
respect this.

This commit updates the compiler to add a `target_thread_local` cfg annotation
if the platform being targeted supports the `#[thread_local]` attribute. This is
feature gated for now, and it is only true on non-aarch64 Linux and 10.7+ OSX
(e.g. what the module already does today). Logic has also been added to parse
the deployment target environment variable.
Diffstat (limited to 'src/librustc_back/target')
-rw-r--r--src/librustc_back/target/aarch64_unknown_linux_gnu.rs3
-rw-r--r--src/librustc_back/target/apple_base.rs23
-rw-r--r--src/librustc_back/target/apple_ios_base.rs1
-rw-r--r--src/librustc_back/target/arm_linux_androideabi.rs1
-rw-r--r--src/librustc_back/target/linux_base.rs1
-rw-r--r--src/librustc_back/target/mod.rs5
6 files changed, 32 insertions, 2 deletions
diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
index 51abab6609a..21bfd87e412 100644
--- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
@@ -11,7 +11,8 @@
 use target::Target;
 
 pub fn target() -> Target {
-    let base = super::linux_base::opts();
+    let mut base = super::linux_base::opts();
+    base.has_elf_tls = false;
     Target {
         llvm_target: "aarch64-unknown-linux-gnu".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/apple_base.rs b/src/librustc_back/target/apple_base.rs
index 8b75bb39414..ffcb6f971ae 100644
--- a/src/librustc_back/target/apple_base.rs
+++ b/src/librustc_back/target/apple_base.rs
@@ -8,10 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::env;
+
 use target::TargetOptions;
-use std::default::Default;
 
 pub fn opts() -> TargetOptions {
+    // ELF TLS is only available in OSX 10.7+. If you try to compile for 10.6
+    // either the linker will complain if it is used or the binary will end up
+    // segfaulting at runtime when run on 10.6. Rust by default supports OSX
+    // 10.7+, but there is a standard environment variable,
+    // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
+    // versions of OSX. For example compiling on 10.10 with
+    // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
+    // warnings about the usage of ELF TLS.
+    //
+    // Here we detect what version is being requested, defaulting to 10.7. ELF
+    // TLS is flagged as enabled if it looks to be supported.
+    let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
+    let version = deployment_target.as_ref().and_then(|s| {
+        let mut i = s.splitn(2, ".");
+        i.next().and_then(|a| i.next().map(|b| (a, b)))
+    }).and_then(|(a, b)| {
+        a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
+    }).unwrap_or((10, 7));
+
     TargetOptions {
         // OSX has -dead_strip, which doesn't rely on ffunction_sections
         function_sections: false,
@@ -25,6 +45,7 @@ pub fn opts() -> TargetOptions {
         archive_format: "bsd".to_string(),
         pre_link_args: Vec::new(),
         exe_allocation_crate: super::maybe_jemalloc(),
+        has_elf_tls: version >= (10, 7),
         .. Default::default()
     }
 }
diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs
index 77030f5d768..d182fd96056 100644
--- a/src/librustc_back/target/apple_ios_base.rs
+++ b/src/librustc_back/target/apple_ios_base.rs
@@ -88,6 +88,7 @@ pub fn opts(arch: Arch) -> TargetOptions {
         dynamic_linking: false,
         executables: true,
         pre_link_args: pre_link_args(arch),
+        has_elf_tls: false,
         .. super::apple_base::opts()
     }
 }
diff --git a/src/librustc_back/target/arm_linux_androideabi.rs b/src/librustc_back/target/arm_linux_androideabi.rs
index 732f1a353a8..7776aaacd00 100644
--- a/src/librustc_back/target/arm_linux_androideabi.rs
+++ b/src/librustc_back/target/arm_linux_androideabi.rs
@@ -13,6 +13,7 @@ use target::Target;
 pub fn target() -> Target {
     let mut base = super::android_base::opts();
     base.features = "+v7".to_string();
+    base.has_elf_tls = false;
 
     Target {
         llvm_target: "arm-linux-androideabi".to_string(),
diff --git a/src/librustc_back/target/linux_base.rs b/src/librustc_back/target/linux_base.rs
index 6492fa50159..0efcf73ee86 100644
--- a/src/librustc_back/target/linux_base.rs
+++ b/src/librustc_back/target/linux_base.rs
@@ -30,6 +30,7 @@ pub fn opts() -> TargetOptions {
         position_independent_executables: true,
         archive_format: "gnu".to_string(),
         exe_allocation_crate: super::maybe_jemalloc(),
+        has_elf_tls: true,
         .. Default::default()
     }
 }
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index f259698a220..666903b4eed 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -195,6 +195,10 @@ pub struct TargetOptions {
     /// Default crate for allocation symbols to link against
     pub lib_allocation_crate: String,
     pub exe_allocation_crate: String,
+
+    /// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
+    /// this target.
+    pub has_elf_tls: bool,
 }
 
 impl Default for TargetOptions {
@@ -240,6 +244,7 @@ impl Default for TargetOptions {
             lib_allocation_crate: "alloc_system".to_string(),
             exe_allocation_crate: "alloc_system".to_string(),
             allow_asm: true,
+            has_elf_tls: false,
         }
     }
 }