From b8ad99e435974b2bbfd63d5b01b94d188e898768 Mon Sep 17 00:00:00 2001 From: Afonso Bordado Date: Tue, 22 Jun 2021 20:18:26 +0100 Subject: [PATCH] aarch64: Implement TLS ELF GD Relocations Implement the `TlsValue` opcode in the aarch64 backend for ELF_GD. This is a little bit unusual as the default TLS mechanism for aarch64 is TLS Descriptors in other compilers. However currently we only recognize elf_gd so lets start with that as a TLS implementation. --- cranelift/codegen/src/binemit/mod.rs | 12 ++++++++ .../codegen/src/isa/aarch64/inst/emit.rs | 28 +++++++++++++++++- cranelift/codegen/src/isa/aarch64/inst/mod.rs | 18 ++++++++++++ .../codegen/src/isa/aarch64/lower_inst.rs | 21 ++++++++++++-- .../filetests/isa/aarch64/tls-elf-gd.clif | 29 +++++++++++++++++++ cranelift/object/src/backend.rs | 24 +++++++++++++++ 6 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 cranelift/filetests/filetests/isa/aarch64/tls-elf-gd.clif diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index aa3102797e..62602d5a88 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -68,6 +68,16 @@ pub enum Reloc { /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. MachOX86_64Tlv, + + /// AArch64 TLS GD + /// Set an ADRP immediate field to the top 21 bits of the final address. Checks for overflow. + /// This is equivalent to `R_AARCH64_TLSGD_ADR_PAGE21` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage) + Aarch64TlsGdAdrPage21, + + /// AArch64 TLS GD + /// Set the add immediate field to the low 12 bits of the final address. Does not check for overflow. + /// This is equivalent to `R_AARCH64_TLSGD_ADD_LO12_NC` in the [aaelf64](https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aaelf64/aaelf64.rst#relocations-for-thread-local-storage) + Aarch64TlsGdAddLo12Nc, } impl fmt::Display for Reloc { @@ -87,6 +97,8 @@ impl fmt::Display for Reloc { Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), + Self::Aarch64TlsGdAdrPage21 => write!(f, "Aarch64TlsGdAdrPage21"), + Self::Aarch64TlsGdAddLo12Nc => write!(f, "Aarch64TlsGdAddLo12Nc"), } } } diff --git a/cranelift/codegen/src/isa/aarch64/inst/emit.rs b/cranelift/codegen/src/isa/aarch64/inst/emit.rs index 0e622b2b54..c2b4deda36 100644 --- a/cranelift/codegen/src/isa/aarch64/inst/emit.rs +++ b/cranelift/codegen/src/isa/aarch64/inst/emit.rs @@ -3,7 +3,7 @@ use crate::binemit::{CodeOffset, Reloc, StackMap}; use crate::ir::constant::ConstantData; use crate::ir::types::*; -use crate::ir::{MemFlags, TrapCode}; +use crate::ir::{LibCall, MemFlags, TrapCode}; use crate::isa::aarch64::inst::*; use crate::machinst::ty_bits; @@ -2563,6 +2563,32 @@ impl MachInstEmit for Inst { sink.bind_label(jump_around_label); } } + + &Inst::ElfTlsGetAddr { ref symbol } => { + // This is the instruction sequence that GCC emits for ELF GD TLS Relocations in aarch64 + // See: https://gcc.godbolt.org/z/KhMh5Gvra + + // adrp x0,