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:
parent
8a7b2035f8
commit
e5b76892cc
17 changed files with 71 additions and 28 deletions
|
@ -1748,7 +1748,9 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
|
|||
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
|
||||
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
|
||||
if info.level.is_below_threshold(export_threshold) {
|
||||
symbols.push(symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum));
|
||||
symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
|
||||
tcx, symbol, cnum,
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use rustc_middle::ty::{self, SymbolName, TyCtxt};
|
|||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_session::config::{CrateType, OomStrategy};
|
||||
use rustc_target::spec::SanitizerSet;
|
||||
use rustc_target::spec::{SanitizerSet, TlsModel};
|
||||
|
||||
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
|
||||
crates_export_threshold(tcx.crate_types())
|
||||
|
@ -552,6 +552,12 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
|||
|
||||
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
|
||||
|
||||
// thread local will not be a function call,
|
||||
// so it is safe to return before windows symbol decoration check.
|
||||
if let Some(name) = maybe_emutls_symbol_name(tcx, symbol, &undecorated) {
|
||||
return name;
|
||||
}
|
||||
|
||||
let target = &tcx.sess.target;
|
||||
if !target.is_like_windows {
|
||||
// Mach-O has a global "_" suffix and `object` crate will handle it.
|
||||
|
@ -612,6 +618,32 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
|
|||
format!("{prefix}{undecorated}{suffix}{args_in_bytes}")
|
||||
}
|
||||
|
||||
pub fn exporting_symbol_name_for_instance_in_crate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
cnum: CrateNum,
|
||||
) -> String {
|
||||
let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, cnum);
|
||||
maybe_emutls_symbol_name(tcx, symbol, &undecorated).unwrap_or(undecorated)
|
||||
}
|
||||
|
||||
fn maybe_emutls_symbol_name<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
symbol: ExportedSymbol<'tcx>,
|
||||
undecorated: &str,
|
||||
) -> Option<String> {
|
||||
if matches!(tcx.sess.tls_model(), TlsModel::Emulated)
|
||||
&& let ExportedSymbol::NonGeneric(def_id) = symbol
|
||||
&& tcx.is_thread_local_static(def_id)
|
||||
{
|
||||
// When using emutls, LLVM will add the `__emutls_v.` prefix to thread local symbols,
|
||||
// and exported symbol name need to match this.
|
||||
Some(format!("__emutls_v.{undecorated}"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> {
|
||||
// Build up a map from DefId to a `NativeLib` structure, where
|
||||
// `NativeLib` internally contains information about
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue