From 877c469395b77058425e6b1d44a251f10543ccee Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Tue, 7 Aug 2018 16:50:36 -0700 Subject: [PATCH] Avoid increased alignment of TLS segments on Fuchsia This is a temporary workaround for Fuchsia's libc not supporting TLS segments with alignments greater than 32 bytes. It should be reverted ASAP following the fix to libc. --- src/librustc_codegen_llvm/consts.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 72ff65361cada..364131722152f 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -345,7 +345,7 @@ pub fn codegen_static<'a, 'tcx>( if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { llvm::set_thread_local_mode(g, cx.tls_model); - // Do not allow LLVM to change the alignment of a TLS on macOS. + // Do not allow LLVM to change the alignment of a TLS on macOS and Fuchsia. // // By default a global's alignment can be freely increased. // This allows LLVM to generate more performant instructions @@ -355,6 +355,10 @@ pub fn codegen_static<'a, 'tcx>( // respect any alignment given on the TLS (radar 24221680). // This will violate the alignment assumption, and causing segfault at runtime. // + // Fuchsia's libc currently does not support greater than 16-byte alignment + // of TLS segments, so this hack is also enabled temporarily for Fuchsia targets + // until libc is fixed. + // // This bug is very easy to trigger. In `println!` and `panic!`, // the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS, // which the values would be `mem::replace`d on initialization. @@ -374,7 +378,9 @@ pub fn codegen_static<'a, 'tcx>( // will use load-unaligned instructions instead, and thus avoiding the crash. // // We could remove this hack whenever we decide to drop macOS 10.10 support. - if cx.tcx.sess.target.target.options.is_like_osx { + if cx.tcx.sess.target.target.options.is_like_osx || + (cx.tcx.sess.target.target.target_os == "fuchsia") + { let sect_name = if alloc.bytes.iter().all(|b| *b == 0) { CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0") } else {