1
Fork 0

Add emulated TLS support

Currently LLVM uses emutls by default
for some targets (such as android, openbsd),
but rust does not use it, because `has_thread_local` is false.

This commit has some changes to allow users to enable emutls:

1. add `-Zhas-thread-local` flag to specify
    that std uses `#[thread_local]` instead of pthread key.
2. when using emutls, decorate symbol names
    to find thread local symbol correctly.
3. change `-Zforce-emulated-tls` to `-Ztls-model=emulated`
    to explicitly specify whether to generate emutls.
This commit is contained in:
quininer 2023-11-13 20:48:23 +08:00
parent 8a7b2035f8
commit e5b76892cc
17 changed files with 71 additions and 28 deletions

View file

@ -1,10 +1,11 @@
use crate::spec::{base, SanitizerSet, TargetOptions};
use crate::spec::{base, SanitizerSet, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions {
let mut base = base::linux::opts();
base.os = "android".into();
base.is_like_android = true;
base.default_dwarf_version = 2;
base.tls_model = TlsModel::Emulated;
base.has_thread_local = false;
base.supported_sanitizers = SanitizerSet::ADDRESS;
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867

View file

@ -1,11 +1,11 @@
use crate::spec::{base, TargetOptions};
use crate::spec::{base, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions {
let mut base = base::linux::opts();
base.env = "ohos".into();
base.crt_static_default = false;
base.force_emulated_tls = true;
base.tls_model = TlsModel::Emulated;
base.has_thread_local = false;
base

View file

@ -1,4 +1,4 @@
use crate::spec::{cvs, FramePointer, RelroLevel, TargetOptions};
use crate::spec::{cvs, FramePointer, RelroLevel, TargetOptions, TlsModel};
pub fn opts() -> TargetOptions {
TargetOptions {
@ -11,6 +11,7 @@ pub fn opts() -> TargetOptions {
frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit...
relro_level: RelroLevel::Full,
default_dwarf_version: 2,
tls_model: TlsModel::Emulated,
..Default::default()
}
}

View file

@ -929,6 +929,7 @@ pub enum TlsModel {
LocalDynamic,
InitialExec,
LocalExec,
Emulated,
}
impl FromStr for TlsModel {
@ -942,6 +943,7 @@ impl FromStr for TlsModel {
"local-dynamic" => TlsModel::LocalDynamic,
"initial-exec" => TlsModel::InitialExec,
"local-exec" => TlsModel::LocalExec,
"emulated" => TlsModel::Emulated,
_ => return Err(()),
})
}
@ -954,6 +956,7 @@ impl ToJson for TlsModel {
TlsModel::LocalDynamic => "local-dynamic",
TlsModel::InitialExec => "initial-exec",
TlsModel::LocalExec => "local-exec",
TlsModel::Emulated => "emulated",
}
.to_json()
}
@ -2190,9 +2193,6 @@ pub struct TargetOptions {
/// Whether the target supports XRay instrumentation.
pub supports_xray: bool,
/// Forces the use of emulated TLS (__emutls_get_address)
pub force_emulated_tls: bool,
}
/// Add arguments for the given flavor and also for its "twin" flavors
@ -2408,7 +2408,6 @@ impl Default for TargetOptions {
entry_name: "main".into(),
entry_abi: Conv::C,
supports_xray: false,
force_emulated_tls: false,
}
}
}
@ -3112,7 +3111,6 @@ impl Target {
key!(entry_name);
key!(entry_abi, Conv)?;
key!(supports_xray, bool);
key!(force_emulated_tls, bool);
if base.is_builtin {
// This can cause unfortunate ICEs later down the line.
@ -3368,7 +3366,6 @@ impl ToJson for Target {
target_option_val!(entry_name);
target_option_val!(entry_abi);
target_option_val!(supports_xray);
target_option_val!(force_emulated_tls);
if let Some(abi) = self.default_adjusted_cabi {
d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());