Skip to content

Commit 0b326b2

Browse files
committed
[PAC][CodeGen][ELF][AArch64] Support signed TLSDESC
Support the following relocations and assembly operators: - `R_AARCH64_AUTH_TLSDESC_ADR_PAGE21` (`:tlsdesc_auth:` for `adrp`) - `R_AARCH64_AUTH_TLSDESC_LD64_LO12` (`:tlsdesc_auth_lo12:` for `ldr`) - `R_AARCH64_AUTH_TLSDESC_ADD_LO12` (`:tlsdesc_auth_lo12:` for `add`) `TLSDESC_AUTH_CALLSEQ` pseudo-instruction is introduced which is later expanded to actual instruction sequence like the following. ``` adrp x0, :tlsdesc_auth:var ldr x16, [x0, #:tlsdesc_auth_lo12:var] add x0, x0, #:tlsdesc_auth_lo12:var .tlsdesccall var blraa x16, x0 (TPIDR_EL0 offset now in x0) ``` Only SelectionDAG ISel is supported. Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.
1 parent eeadd01 commit 0b326b2

12 files changed

+409
-141
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,65 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
27192719
EmitToStreamer(*OutStreamer, TmpInstSB);
27202720
return;
27212721
}
2722+
case AArch64::TLSDESC_AUTH_CALLSEQ: {
2723+
/// lower this to:
2724+
/// adrp x0, :tlsdesc_auth:var
2725+
/// ldr x16, [x0, #:tlsdesc_auth_lo12:var]
2726+
/// add x0, x0, #:tlsdesc_auth_lo12:var
2727+
/// .tlsdesccall var
2728+
/// blraa x16, x0
2729+
/// (TPIDR_EL0 offset now in x0)
2730+
const MachineOperand &MO_Sym = MI->getOperand(0);
2731+
MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
2732+
MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
2733+
MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
2734+
MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
2735+
MCInstLowering.lowerOperand(MO_Sym, Sym);
2736+
MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
2737+
MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
2738+
2739+
MCInst Adrp;
2740+
Adrp.setOpcode(AArch64::ADRP);
2741+
Adrp.addOperand(MCOperand::createReg(AArch64::X0));
2742+
Adrp.addOperand(SymTLSDesc);
2743+
EmitToStreamer(*OutStreamer, Adrp);
2744+
2745+
MCInst Ldr;
2746+
Ldr.setOpcode(AArch64::LDRXui);
2747+
Ldr.addOperand(MCOperand::createReg(AArch64::X16));
2748+
Ldr.addOperand(MCOperand::createReg(AArch64::X0));
2749+
Ldr.addOperand(SymTLSDescLo12);
2750+
Ldr.addOperand(MCOperand::createImm(0));
2751+
EmitToStreamer(*OutStreamer, Ldr);
2752+
2753+
MCInst Add;
2754+
Add.setOpcode(AArch64::ADDXri);
2755+
Add.addOperand(MCOperand::createReg(AArch64::X0));
2756+
Add.addOperand(MCOperand::createReg(AArch64::X0));
2757+
Add.addOperand(SymTLSDescLo12);
2758+
Add.addOperand(MCOperand::createImm(AArch64_AM::getShiftValue(0)));
2759+
EmitToStreamer(*OutStreamer, Add);
2760+
2761+
// Emit a relocation-annotation. This expands to no code, but requests
2762+
// the following instruction gets an R_AARCH64_TLSDESC_CALL.
2763+
// TODO: we probably don't need that for AUTH TLSDESC. Emit as for now for
2764+
// consistency with non-AUTH case.
2765+
MCInst TLSDescCall;
2766+
TLSDescCall.setOpcode(AArch64::TLSDESCCALL);
2767+
TLSDescCall.addOperand(Sym);
2768+
EmitToStreamer(*OutStreamer, TLSDescCall);
2769+
#ifndef NDEBUG
2770+
--InstsEmitted; // no code emitted
2771+
#endif
2772+
2773+
MCInst Blraa;
2774+
Blraa.setOpcode(AArch64::BLRAA);
2775+
Blraa.addOperand(MCOperand::createReg(AArch64::X16));
2776+
Blraa.addOperand(MCOperand::createReg(AArch64::X0));
2777+
EmitToStreamer(*OutStreamer, Blraa);
2778+
2779+
return;
2780+
}
27222781
case AArch64::TLSDESC_CALLSEQ: {
27232782
/// lower this to:
27242783
/// adrp x0, :tlsdesc:var

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,6 +2655,7 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
26552655
MAKE_CASE(AArch64ISD::CSINC)
26562656
MAKE_CASE(AArch64ISD::THREAD_POINTER)
26572657
MAKE_CASE(AArch64ISD::TLSDESC_CALLSEQ)
2658+
MAKE_CASE(AArch64ISD::TLSDESC_AUTH_CALLSEQ)
26582659
MAKE_CASE(AArch64ISD::PROBED_ALLOCA)
26592660
MAKE_CASE(AArch64ISD::ABDS_PRED)
26602661
MAKE_CASE(AArch64ISD::ABDU_PRED)
@@ -9911,8 +9912,11 @@ SDValue AArch64TargetLowering::LowerELFTLSDescCallSeq(SDValue SymAddr,
99119912
SDValue Chain = DAG.getEntryNode();
99129913
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
99139914

9914-
Chain =
9915-
DAG.getNode(AArch64ISD::TLSDESC_CALLSEQ, DL, NodeTys, {Chain, SymAddr});
9915+
unsigned Opcode =
9916+
DAG.getMachineFunction().getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
9917+
? AArch64ISD::TLSDESC_AUTH_CALLSEQ
9918+
: AArch64ISD::TLSDESC_CALLSEQ;
9919+
Chain = DAG.getNode(Opcode, DL, NodeTys, {Chain, SymAddr});
99169920
SDValue Glue = Chain.getValue(1);
99179921

99189922
return DAG.getCopyFromReg(Chain, DL, AArch64::X0, PtrVT, Glue);
@@ -9925,7 +9929,13 @@ AArch64TargetLowering::LowerELFGlobalTLSAddress(SDValue Op,
99259929

99269930
const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
99279931

9928-
TLSModel::Model Model = getTargetMachine().getTLSModel(GA->getGlobal());
9932+
TLSModel::Model Model;
9933+
if (DAG.getMachineFunction()
9934+
.getInfo<AArch64FunctionInfo>()
9935+
->hasELFSignedGOT())
9936+
Model = TLSModel::GeneralDynamic;
9937+
else
9938+
Model = getTargetMachine().getTLSModel(GA->getGlobal());
99299939

99309940
if (!EnableAArch64ELFLocalDynamicTLSGeneration) {
99319941
if (Model == TLSModel::LocalDynamic)

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum NodeType : unsigned {
8383
// Produces the full sequence of instructions for getting the thread pointer
8484
// offset of a variable into X0, using the TLSDesc model.
8585
TLSDESC_CALLSEQ,
86+
TLSDESC_AUTH_CALLSEQ,
8687
ADRP, // Page address of a TargetGlobalAddress operand.
8788
ADR, // ADR
8889
ADDlow, // Add the low 12 bits of a TargetGlobalAddress operand.

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ def SDT_AArch64stnp : SDTypeProfile<0, 3, [SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1
501501
// number of operands (the variable)
502502
def SDT_AArch64TLSDescCallSeq : SDTypeProfile<0,1,
503503
[SDTCisPtrTy<0>]>;
504+
def SDT_AArch64TLSDescAuthCallSeq : SDTypeProfile<0,1,
505+
[SDTCisPtrTy<0>]>;
504506

505507
def SDT_AArch64WrapperLarge : SDTypeProfile<1, 4,
506508
[SDTCisVT<0, i64>, SDTCisVT<1, i32>,
@@ -886,6 +888,10 @@ def AArch64tlsdesc_callseq : SDNode<"AArch64ISD::TLSDESC_CALLSEQ",
886888
SDT_AArch64TLSDescCallSeq,
887889
[SDNPOutGlue, SDNPHasChain, SDNPVariadic]>;
888890

891+
def AArch64tlsdesc_auth_callseq : SDNode<"AArch64ISD::TLSDESC_AUTH_CALLSEQ",
892+
SDT_AArch64TLSDescAuthCallSeq,
893+
[SDNPInGlue, SDNPOutGlue, SDNPHasChain,
894+
SDNPVariadic]>;
889895

890896
def AArch64WrapperLarge : SDNode<"AArch64ISD::WrapperLarge",
891897
SDT_AArch64WrapperLarge>;
@@ -3315,8 +3321,16 @@ def TLSDESC_CALLSEQ
33153321
: Pseudo<(outs), (ins i64imm:$sym),
33163322
[(AArch64tlsdesc_callseq tglobaltlsaddr:$sym)]>,
33173323
Sched<[WriteI, WriteLD, WriteI, WriteBrReg]>;
3324+
let isCall = 1, Defs = [NZCV, LR, X0, X16], hasSideEffects = 1, Size = 16,
3325+
isCodeGenOnly = 1 in
3326+
def TLSDESC_AUTH_CALLSEQ
3327+
: Pseudo<(outs), (ins i64imm:$sym),
3328+
[(AArch64tlsdesc_auth_callseq tglobaltlsaddr:$sym)]>,
3329+
Sched<[WriteI, WriteLD, WriteI, WriteBrReg]>;
33183330
def : Pat<(AArch64tlsdesc_callseq texternalsym:$sym),
33193331
(TLSDESC_CALLSEQ texternalsym:$sym)>;
3332+
def : Pat<(AArch64tlsdesc_auth_callseq texternalsym:$sym),
3333+
(TLSDESC_AUTH_CALLSEQ texternalsym:$sym)>;
33203334

33213335
//===----------------------------------------------------------------------===//
33223336
// Conditional branch (immediate) instruction.

llvm/lib/Target/AArch64/AArch64MCInstLower.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,16 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
194194
} else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
195195
TLSModel::Model Model;
196196
if (MO.isGlobal()) {
197-
const GlobalValue *GV = MO.getGlobal();
198-
Model = Printer.TM.getTLSModel(GV);
199-
if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
200-
Model == TLSModel::LocalDynamic)
197+
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
198+
if (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()) {
201199
Model = TLSModel::GeneralDynamic;
202-
200+
} else {
201+
const GlobalValue *GV = MO.getGlobal();
202+
Model = Printer.TM.getTLSModel(GV);
203+
if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
204+
Model == TLSModel::LocalDynamic)
205+
Model = TLSModel::GeneralDynamic;
206+
}
203207
} else {
204208
assert(MO.isSymbol() &&
205209
StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
@@ -218,10 +222,18 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
218222
case TLSModel::LocalDynamic:
219223
RefFlags |= AArch64MCExpr::VK_DTPREL;
220224
break;
221-
case TLSModel::GeneralDynamic:
222-
RefFlags |= AArch64MCExpr::VK_TLSDESC;
225+
case TLSModel::GeneralDynamic: {
226+
// TODO: it's probably better to introduce MO_TLS_AUTH or smth and avoid
227+
// running hasELFSignedGOT() every time, but existing flags already
228+
// cover all 12 bits of SubReg_TargetFlags field in MachineOperand, and
229+
// making the field wider breaks static assertions.
230+
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
231+
RefFlags |= MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
232+
? AArch64MCExpr::VK_TLSDESC_AUTH
233+
: AArch64MCExpr::VK_TLSDESC;
223234
break;
224235
}
236+
}
225237
} else if (MO.getTargetFlags() & AArch64II::MO_PREL) {
226238
RefFlags |= AArch64MCExpr::VK_PREL;
227239
} else {

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ class AArch64Operand : public MCParsedAsmOperand {
904904
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
905905
ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
906906
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
907+
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
907908
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
908909
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
909910
ELFRefKind == AArch64MCExpr::VK_GOT_PAGE_LO15) {
@@ -1021,6 +1022,7 @@ class AArch64Operand : public MCParsedAsmOperand {
10211022
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
10221023
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
10231024
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
1025+
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
10241026
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
10251027
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
10261028
}
@@ -3314,7 +3316,8 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
33143316
ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
33153317
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
33163318
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
3317-
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
3319+
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE &&
3320+
ELFRefKind != AArch64MCExpr::VK_TLSDESC_AUTH_PAGE) {
33183321
// The operand must be an @page or @gotpage qualified symbolref.
33193322
return Error(S, "page or gotpage label reference expected");
33203323
}
@@ -4392,56 +4395,59 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
43924395
return TokError("expect relocation specifier in operand after ':'");
43934396

43944397
std::string LowerCase = getTok().getIdentifier().lower();
4395-
RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
4396-
.Case("lo12", AArch64MCExpr::VK_LO12)
4397-
.Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
4398-
.Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
4399-
.Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
4400-
.Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
4401-
.Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
4402-
.Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
4403-
.Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
4404-
.Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
4405-
.Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
4406-
.Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
4407-
.Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
4408-
.Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
4409-
.Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
4410-
.Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
4411-
.Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
4412-
.Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
4413-
.Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
4414-
.Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
4415-
.Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
4416-
.Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
4417-
.Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
4418-
.Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
4419-
.Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
4420-
.Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
4421-
.Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
4422-
.Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
4423-
.Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
4424-
.Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
4425-
.Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
4426-
.Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
4427-
.Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
4428-
.Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
4429-
.Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
4430-
.Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
4431-
.Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
4432-
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
4433-
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
4434-
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
4435-
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
4436-
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
4437-
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
4438-
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
4439-
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
4440-
.Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
4441-
.Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
4442-
.Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
4443-
.Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
4444-
.Default(AArch64MCExpr::VK_INVALID);
4398+
RefKind =
4399+
StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
4400+
.Case("lo12", AArch64MCExpr::VK_LO12)
4401+
.Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
4402+
.Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
4403+
.Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
4404+
.Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
4405+
.Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
4406+
.Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
4407+
.Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
4408+
.Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
4409+
.Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
4410+
.Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
4411+
.Case("prel_g3", AArch64MCExpr::VK_PREL_G3)
4412+
.Case("prel_g2", AArch64MCExpr::VK_PREL_G2)
4413+
.Case("prel_g2_nc", AArch64MCExpr::VK_PREL_G2_NC)
4414+
.Case("prel_g1", AArch64MCExpr::VK_PREL_G1)
4415+
.Case("prel_g1_nc", AArch64MCExpr::VK_PREL_G1_NC)
4416+
.Case("prel_g0", AArch64MCExpr::VK_PREL_G0)
4417+
.Case("prel_g0_nc", AArch64MCExpr::VK_PREL_G0_NC)
4418+
.Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
4419+
.Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
4420+
.Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
4421+
.Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
4422+
.Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
4423+
.Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
4424+
.Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
4425+
.Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
4426+
.Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
4427+
.Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
4428+
.Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
4429+
.Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
4430+
.Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
4431+
.Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
4432+
.Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
4433+
.Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
4434+
.Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
4435+
.Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
4436+
.Case("tlsdesc_auth_lo12", AArch64MCExpr::VK_TLSDESC_AUTH_LO12)
4437+
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
4438+
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
4439+
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
4440+
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
4441+
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
4442+
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
4443+
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
4444+
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
4445+
.Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
4446+
.Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
4447+
.Case("tlsdesc_auth", AArch64MCExpr::VK_TLSDESC_AUTH_PAGE)
4448+
.Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
4449+
.Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
4450+
.Default(AArch64MCExpr::VK_INVALID);
44454451

44464452
if (RefKind == AArch64MCExpr::VK_INVALID)
44474453
return TokError("expect relocation specifier in operand after ':'");
@@ -5815,6 +5821,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
58155821
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
58165822
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
58175823
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
5824+
ELFRefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12 ||
58185825
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
58195826
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) &&
58205827
(Inst.getOpcode() == AArch64::ADDXri ||

llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
178178
return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
179179
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
180180
return R_CLS(TLSDESC_ADR_PAGE21);
181+
if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH && !IsNC) {
182+
if (IsILP32) {
183+
Ctx.reportError(Fixup.getLoc(),
184+
"ILP32 ADRP AUTH relocation not supported "
185+
"(LP64 eqv: AUTH_TLSDESC_ADR_PAGE21)");
186+
return ELF::R_AARCH64_NONE;
187+
}
188+
return ELF::R_AARCH64_AUTH_TLSDESC_ADR_PAGE21;
189+
}
181190
Ctx.reportError(Fixup.getLoc(),
182191
"invalid symbol kind for ADRP relocation");
183192
return ELF::R_AARCH64_NONE;
@@ -249,6 +258,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
249258
return R_CLS(TLSLE_ADD_TPREL_LO12);
250259
if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
251260
return R_CLS(TLSDESC_ADD_LO12);
261+
if (RefKind == AArch64MCExpr::VK_TLSDESC_AUTH_LO12) {
262+
if (IsILP32) {
263+
Ctx.reportError(Fixup.getLoc(),
264+
"ILP32 ADD AUTH relocation not supported "
265+
"(LP64 eqv: AUTH_TLSDESC_ADD_LO12)");
266+
return ELF::R_AARCH64_NONE;
267+
}
268+
return ELF::R_AARCH64_AUTH_TLSDESC_ADD_LO12;
269+
}
252270
if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
253271
if (IsILP32) {
254272
Ctx.reportError(Fixup.getLoc(),
@@ -393,6 +411,14 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
393411
"TLSDESC_LD64_LO12)");
394412
return ELF::R_AARCH64_NONE;
395413
}
414+
if (SymLoc == AArch64MCExpr::VK_TLSDESC_AUTH) {
415+
if (!IsILP32)
416+
return ELF::R_AARCH64_AUTH_TLSDESC_LD64_LO12;
417+
Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store AUTH "
418+
"relocation not supported (LP64 eqv: "
419+
"AUTH_TLSDESC_LD64_LO12)");
420+
return ELF::R_AARCH64_NONE;
421+
}
396422
Ctx.reportError(Fixup.getLoc(),
397423
"invalid fixup for 64-bit load/store instruction");
398424
return ELF::R_AARCH64_NONE;

0 commit comments

Comments
 (0)