s390x: Implement tls_value (#4616)
Implement the tls_value for s390 in the ELF general-dynamic mode. Notable differences to the x86_64 implementation are: - We use a __tls_get_offset libcall instead of __tls_get_addr. - The current thread pointer (stored in a pair of access registers) needs to be added to the result of __tls_get_offset. - __tls_get_offset has a variant ABI that requires the address of the GOT (global offset table) is passed in %r12. This means we need a new libcall entries for __tls_get_offset. In addition, we also need a way to access _GLOBAL_OFFSET_TABLE_. The latter is a "magic" symbol with a well-known name defined by the ABI and recognized by the linker. This patch introduces a new ExternalName::KnownSymbol variant to support such names (originally due to @afonso360). We also need to emit a relocation on a symbol placed in a constant pool, as well as an extra relocation on the call to __tls_get_offset required for TLS linker optimization. Needed by the cg_clif frontend.
This commit is contained in:
42
cranelift/codegen/src/ir/known_symbol.rs
Normal file
42
cranelift/codegen/src/ir/known_symbol.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use core::fmt;
|
||||
use core::str::FromStr;
|
||||
#[cfg(feature = "enable-serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A well-known symbol.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
pub enum KnownSymbol {
|
||||
/// ELF well-known linker symbol _GLOBAL_OFFSET_TABLE_
|
||||
ElfGlobalOffsetTable,
|
||||
}
|
||||
|
||||
impl fmt::Display for KnownSymbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for KnownSymbol {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"ElfGlobalOffsetTable" => Ok(Self::ElfGlobalOffsetTable),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parsing() {
|
||||
assert_eq!(
|
||||
"ElfGlobalOffsetTable".parse(),
|
||||
Ok(KnownSymbol::ElfGlobalOffsetTable)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user