Merge pull request #3026 from afonso360/aarch64-elf-tls

aarch64: Implement TLS ELF GD Relocations
This commit is contained in:
Chris Fallin
2021-06-24 11:54:34 -07:00
committed by GitHub
6 changed files with 129 additions and 3 deletions

View File

@@ -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, <label>
sink.add_reloc(state.cur_srcloc(), Reloc::Aarch64TlsGdAdrPage21, symbol, 0);
sink.put4(0x90000000);
// add x0, x0, <label>
sink.add_reloc(state.cur_srcloc(), Reloc::Aarch64TlsGdAddLo12Nc, symbol, 0);
sink.put4(0x91000000);
// bl __tls_get_addr
sink.add_reloc(
state.cur_srcloc(),
Reloc::Arm64Call,
&ExternalName::LibCall(LibCall::ElfTlsGetAddr),
0,
);
sink.put4(0x94000000);
// nop
sink.put4(0xd503201f);
}
&Inst::ValueLabelMarker { .. } => {
// Nothing; this is only used to compute debug info.
}

View File

@@ -30,6 +30,8 @@ pub mod args;
pub use self::args::*;
pub mod emit;
pub use self::emit::*;
use crate::isa::aarch64::abi::AArch64MachineDeps;
pub mod unwind;
#[cfg(test)]
@@ -1276,6 +1278,11 @@ pub enum Inst {
needed_space: CodeOffset,
},
/// A call to the `ElfTlsGetAddr` libcall. Returns address of TLS symbol in x0.
ElfTlsGetAddr {
symbol: ExternalName,
},
/// A definition of a value label.
ValueLabelMarker {
reg: Reg,
@@ -2150,6 +2157,12 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
&Inst::ValueLabelMarker { reg, .. } => {
collector.add_use(reg);
}
&Inst::ElfTlsGetAddr { .. } => {
for reg in AArch64MachineDeps::get_regs_clobbered_by_call(CallConv::SystemV) {
collector.add_def(reg);
}
}
&Inst::Unwind { .. } => {}
&Inst::EmitIsland { .. } => {}
}
@@ -2959,6 +2972,7 @@ fn aarch64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
}
&mut Inst::VirtualSPOffsetAdj { .. } => {}
&mut Inst::EmitIsland { .. } => {}
&mut Inst::ElfTlsGetAddr { .. } => {}
&mut Inst::ValueLabelMarker { ref mut reg, .. } => {
map_use(mapper, reg);
}
@@ -4333,6 +4347,10 @@ impl Inst {
}
&Inst::EmitIsland { needed_space } => format!("emit_island {}", needed_space),
&Inst::ElfTlsGetAddr { ref symbol } => {
format!("elf_tls_get_addr {}", symbol)
}
&Inst::ValueLabelMarker { label, reg } => {
format!("value_label {:?}, {}", label, reg.show_rru(mb_rru))
}

View File

@@ -8,7 +8,7 @@ use crate::ir::{InstructionData, Opcode, TrapCode};
use crate::isa::aarch64::settings as aarch64_settings;
use crate::machinst::lower::*;
use crate::machinst::*;
use crate::settings::Flags;
use crate::settings::{Flags, TlsModel};
use crate::{CodegenError, CodegenResult};
use crate::isa::aarch64::abi::*;
@@ -3506,7 +3506,24 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
});
}
Opcode::TlsValue => unimplemented!("tls_value"),
Opcode::TlsValue => match flags.tls_model() {
TlsModel::ElfGd => {
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
let (name, _, _) = ctx.symbol_value(insn).unwrap();
let symbol = name.clone();
ctx.emit(Inst::ElfTlsGetAddr { symbol });
let x0 = xreg(0);
ctx.emit(Inst::gen_move(dst, x0, I64));
}
_ => {
todo!(
"Unimplemented TLS model in AArch64 backend: {:?}",
flags.tls_model()
);
}
},
Opcode::FcvtLowFromSint => unimplemented!("FcvtLowFromSint"),
Opcode::FvpromoteLow => unimplemented!("FvpromoteLow"),
Opcode::Fvdemote => unimplemented!("Fvdemote"),