Skip to content

Commit d2b7ddc

Browse files
committed
[PAC][CodeGen][ELF][AArch64] Support signed GOT
This re-applies #96164 after revert in #102434. Support the following relocations and assembly operators: - `R_AARCH64_AUTH_ADR_GOT_PAGE` (`:got_auth:` for `adrp`) - `R_AARCH64_AUTH_LD64_GOT_LO12_NC` (`:got_auth_lo12:` for `ldr`) - `R_AARCH64_AUTH_GOT_ADD_LO12_NC` (`:got_auth_lo12:` for `add`) `LOADgotAUTH` pseudo-instruction is introduced which is later expanded to actual instruction sequence like the following. ``` adrp x16, :got_auth:sym add x16, x16, :got_auth_lo12:sym ldr x0, [x16] autia x0, x16 ``` If a resign is requested, like below, `LOADgotPAC` pseudo is used, and GOT load is lowered similarly to `LOADgotAUTH`. ``` @var = global i32 0 define ptr @resign_globalvar() { ret ptr ptrauth (ptr @var, i32 3, i64 43) } ``` If FPAC bit is not set and resign is requested, a check+trap sequence similar to one used for `AUT` pseudo is emitted. Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG. Tests starting with 'ptrauth-' have corresponding variants w/o this prefix. See also specification https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#appendix-signed-got
1 parent e46f03b commit d2b7ddc

20 files changed

+586
-35
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 142 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ class AArch64AsmPrinter : public AsmPrinter {
160160
// adrp-add followed by PAC sign)
161161
void LowerMOVaddrPAC(const MachineInstr &MI);
162162

163+
// Emit the sequence for LOADgotAUTH (load+auth pointer from signed ELF GOT)
164+
void LowerLOADgotAUTH(const MachineInstr &MI);
165+
163166
/// tblgen'erated driver function for lowering simple MI->MC
164167
/// pseudo instructions.
165168
bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst);
@@ -2168,6 +2171,10 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
21682171
};
21692172

21702173
const bool IsGOTLoad = MI.getOpcode() == AArch64::LOADgotPAC;
2174+
const bool IsELFSignedGOT = MI.getParent()
2175+
->getParent()
2176+
->getInfo<AArch64FunctionInfo>()
2177+
->hasELFSignedGOT();
21712178
MachineOperand GAOp = MI.getOperand(0);
21722179
const uint64_t KeyC = MI.getOperand(1).getImm();
21732180
assert(KeyC <= AArch64PACKey::LAST &&
@@ -2184,9 +2191,17 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
21842191
// Emit:
21852192
// target materialization:
21862193
// - via GOT:
2187-
// adrp x16, :got:target
2188-
// ldr x16, [x16, :got_lo12:target]
2189-
// add offset to x16 if offset != 0
2194+
// - unsigned GOT:
2195+
// adrp x16, :got:target
2196+
// ldr x16, [x16, :got_lo12:target]
2197+
// add offset to x16 if offset != 0
2198+
// - ELF signed GOT:
2199+
// adrp x17, :got:target
2200+
// add x17, x17, :got_auth_lo12:target
2201+
// ldr x16, [x17]
2202+
// aut{i|d}a x16, x17
2203+
// check+trap sequence (if no FPAC)
2204+
// add offset to x16 if offset != 0
21902205
//
21912206
// - direct:
21922207
// adrp x16, target
@@ -2229,13 +2244,81 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
22292244
MCInstLowering.lowerOperand(GAMOLo, GAMCLo);
22302245

22312246
EmitAndIncrement(
2232-
MCInstBuilder(AArch64::ADRP).addReg(AArch64::X16).addOperand(GAMCHi));
2247+
MCInstBuilder(AArch64::ADRP)
2248+
.addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
2249+
.addOperand(GAMCHi));
22332250

22342251
if (IsGOTLoad) {
2235-
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2236-
.addReg(AArch64::X16)
2237-
.addReg(AArch64::X16)
2238-
.addOperand(GAMCLo));
2252+
if (IsELFSignedGOT) {
2253+
EmitAndIncrement(MCInstBuilder(AArch64::ADDXri)
2254+
.addReg(AArch64::X17)
2255+
.addReg(AArch64::X17)
2256+
.addOperand(GAMCLo)
2257+
.addImm(0));
2258+
2259+
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2260+
.addReg(AArch64::X16)
2261+
.addReg(AArch64::X17)
2262+
.addImm(0));
2263+
2264+
assert(GAOp.isGlobal());
2265+
assert(GAOp.getGlobal()->getValueType() != nullptr);
2266+
unsigned AuthOpcode = GAOp.getGlobal()->getValueType()->isFunctionTy()
2267+
? AArch64::AUTIA
2268+
: AArch64::AUTDA;
2269+
2270+
EmitAndIncrement(MCInstBuilder(AuthOpcode)
2271+
.addReg(AArch64::X16)
2272+
.addReg(AArch64::X16)
2273+
.addReg(AArch64::X17));
2274+
2275+
// The logic in the following if statement is partially taken from
2276+
// emitPtrauthAuthResign.
2277+
if (!STI->hasFPAC()) {
2278+
auto AuthKey = (AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA
2279+
: AArch64PACKey::DA);
2280+
unsigned XPACOpc = getXPACOpcodeForKey(AuthKey);
2281+
MCSymbol *SuccessSym = createTempSymbol("auth_success_");
2282+
2283+
// XPAC has tied src/dst: use x17 as a temporary copy.
2284+
// mov x17, x16
2285+
EmitAndIncrement(MCInstBuilder(AArch64::ORRXrs)
2286+
.addReg(AArch64::X17)
2287+
.addReg(AArch64::XZR)
2288+
.addReg(AArch64::X16)
2289+
.addImm(0));
2290+
2291+
// xpaci x17
2292+
EmitAndIncrement(
2293+
MCInstBuilder(XPACOpc).addReg(AArch64::X17).addReg(AArch64::X17));
2294+
2295+
// cmp x16, x17
2296+
EmitAndIncrement(MCInstBuilder(AArch64::SUBSXrs)
2297+
.addReg(AArch64::XZR)
2298+
.addReg(AArch64::X16)
2299+
.addReg(AArch64::X17)
2300+
.addImm(0));
2301+
2302+
// b.eq Lsuccess
2303+
EmitAndIncrement(
2304+
MCInstBuilder(AArch64::Bcc)
2305+
.addImm(AArch64CC::EQ)
2306+
.addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext)));
2307+
2308+
// Trapping sequences do a 'brk'.
2309+
// brk #<0xc470 + aut key>
2310+
EmitAndIncrement(MCInstBuilder(AArch64::BRK).addImm(0xc470 | AuthKey));
2311+
2312+
// If the auth check succeeds, we can continue.
2313+
// Lsuccess:
2314+
OutStreamer->emitLabel(SuccessSym);
2315+
}
2316+
} else {
2317+
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2318+
.addReg(AArch64::X16)
2319+
.addReg(AArch64::X16)
2320+
.addOperand(GAMCLo));
2321+
}
22392322
} else {
22402323
EmitAndIncrement(MCInstBuilder(AArch64::ADDXri)
22412324
.addReg(AArch64::X16)
@@ -2320,6 +2403,53 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
23202403
assert(STI->getInstrInfo()->getInstSizeInBytes(MI) >= InstsEmitted * 4);
23212404
}
23222405

2406+
void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
2407+
unsigned InstsEmitted = 0;
2408+
auto EmitAndIncrement = [this, &InstsEmitted](const MCInst &Inst) {
2409+
EmitToStreamer(*OutStreamer, Inst);
2410+
++InstsEmitted;
2411+
};
2412+
2413+
Register DstReg = MI.getOperand(0).getReg();
2414+
const MachineOperand &GAMO = MI.getOperand(1);
2415+
assert(GAMO.getOffset() == 0);
2416+
2417+
MachineOperand GAHiOp(GAMO);
2418+
MachineOperand GALoOp(GAMO);
2419+
GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
2420+
GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
2421+
2422+
MCOperand GAMCHi, GAMCLo;
2423+
MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
2424+
MCInstLowering.lowerOperand(GALoOp, GAMCLo);
2425+
2426+
EmitAndIncrement(
2427+
MCInstBuilder(AArch64::ADRP).addReg(AArch64::X16).addOperand(GAMCHi));
2428+
2429+
EmitAndIncrement(MCInstBuilder(AArch64::ADDXri)
2430+
.addReg(AArch64::X16)
2431+
.addReg(AArch64::X16)
2432+
.addOperand(GAMCLo)
2433+
.addImm(0));
2434+
2435+
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2436+
.addReg(DstReg)
2437+
.addReg(AArch64::X16)
2438+
.addImm(0));
2439+
2440+
assert(GAMO.isGlobal());
2441+
assert(GAMO.getGlobal()->getValueType() != nullptr);
2442+
unsigned AuthOpcode = GAMO.getGlobal()->getValueType()->isFunctionTy()
2443+
? AArch64::AUTIA
2444+
: AArch64::AUTDA;
2445+
EmitAndIncrement(MCInstBuilder(AuthOpcode)
2446+
.addReg(DstReg)
2447+
.addReg(DstReg)
2448+
.addReg(AArch64::X16));
2449+
2450+
assert(STI->getInstrInfo()->getInstSizeInBytes(MI) >= InstsEmitted * 4);
2451+
}
2452+
23232453
const MCExpr *
23242454
AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
23252455
const MCExpr *BAE = AsmPrinter::lowerBlockAddressConstant(BA);
@@ -2484,6 +2614,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
24842614
LowerMOVaddrPAC(*MI);
24852615
return;
24862616

2617+
case AArch64::LOADgotAUTH:
2618+
LowerLOADgotAUTH(*MI);
2619+
return;
2620+
24872621
case AArch64::BRA:
24882622
case AArch64::BLRA:
24892623
emitPtrauthBranch(MI);

llvm/lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,9 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) {
453453
if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO())
454454
return 0;
455455

456+
if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT())
457+
return 0;
458+
456459
unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
457460

458461
EVT DestEVT = TLI.getValueType(DL, GV->getType(), true);

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9396,6 +9396,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG,
93969396
SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
93979397
// FIXME: Once remat is capable of dealing with instructions with register
93989398
// operands, expand this into two nodes instead of using a wrapper node.
9399+
if (DAG.getMachineFunction()
9400+
.getInfo<AArch64FunctionInfo>()
9401+
->hasELFSignedGOT())
9402+
return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr),
9403+
0);
93999404
return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
94009405
}
94019406

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,8 +1885,9 @@ let Predicates = [HasPAuth] in {
18851885
Sched<[WriteI, ReadI]> {
18861886
let isReMaterializable = 1;
18871887
let isCodeGenOnly = 1;
1888-
let Size = 40; // 12 fixed + 28 variable, for pointer offset, and discriminator
1889-
let Defs = [X16,X17];
1888+
let Size = 68; // 12 fixed + 56 variable, for pointer offset, discriminator and
1889+
// ELF signed GOT signed pointer authentication (if no FPAC)
1890+
let Defs = [X16,X17,NZCV];
18901891
}
18911892

18921893
// Load a signed global address from a special $auth_ptr$ stub slot.
@@ -1924,6 +1925,12 @@ let Predicates = [HasPAuth] in {
19241925
tcGPR64:$AddrDisc),
19251926
(AUTH_TCRETURN_BTI tcGPRx16x17:$dst, imm:$FPDiff, imm:$Key,
19261927
imm:$Disc, tcGPR64:$AddrDisc)>;
1928+
1929+
def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
1930+
Sched<[WriteI, ReadI]> {
1931+
let Defs = [X16];
1932+
let Size = 16;
1933+
}
19271934
}
19281935

19291936
// v9.5-A pointer authentication extensions

llvm/lib/Target/AArch64/AArch64MCInstLower.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "AArch64MCInstLower.h"
15+
#include "AArch64MachineFunctionInfo.h"
1516
#include "MCTargetDesc/AArch64MCExpr.h"
1617
#include "Utils/AArch64BaseInfo.h"
1718
#include "llvm/CodeGen/AsmPrinter.h"
@@ -185,9 +186,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
185186
MCSymbol *Sym) const {
186187
uint32_t RefFlags = 0;
187188

188-
if (MO.getTargetFlags() & AArch64II::MO_GOT)
189-
RefFlags |= AArch64MCExpr::VK_GOT;
190-
else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
189+
if (MO.getTargetFlags() & AArch64II::MO_GOT) {
190+
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
191+
RefFlags |= (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
192+
? AArch64MCExpr::VK_GOT_AUTH
193+
: AArch64MCExpr::VK_GOT);
194+
} else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
191195
TLSModel::Model Model;
192196
if (MO.isGlobal()) {
193197
const GlobalValue *GV = MO.getGlobal();

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "AArch64MachineFunctionInfo.h"
1717
#include "AArch64InstrInfo.h"
1818
#include "AArch64Subtarget.h"
19+
#include "llvm/BinaryFormat/ELF.h"
1920
#include "llvm/IR/Constants.h"
2021
#include "llvm/IR/Metadata.h"
2122
#include "llvm/IR/Module.h"
@@ -72,6 +73,18 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
7273
return Key == "b_key";
7374
}
7475

76+
static bool HasELFSignedGOTHelper(const Function &F,
77+
const AArch64Subtarget *STI) {
78+
if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
79+
return false;
80+
const Module *M = F.getParent();
81+
const auto *Flag = mdconst::extract_or_null<ConstantInt>(
82+
M->getModuleFlag("ptrauth-elf-got"));
83+
if (Flag && Flag->getZExtValue() == 1)
84+
return true;
85+
return false;
86+
}
87+
7588
AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
7689
const AArch64Subtarget *STI) {
7790
// If we already know that the function doesn't have a redzone, set
@@ -80,6 +93,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
8093
HasRedZone = false;
8194
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
8295
SignWithBKey = ShouldSignWithBKey(F, *STI);
96+
HasELFSignedGOT = HasELFSignedGOTHelper(F, STI);
8397
// TODO: skip functions that have no instrumented allocas for optimization
8498
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
8599

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
177177
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
178178
bool SignWithBKey = false;
179179

180+
/// HasELFSignedGOT is true if the target binary format is ELF and the IR
181+
/// module containing the corresponding function has "ptrauth-elf-got" flag
182+
/// set to 1.
183+
bool HasELFSignedGOT = false;
184+
180185
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
181186
/// within the prologue, so it can be re-used for authentication in the
182187
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
@@ -509,6 +514,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
509514

510515
bool shouldSignWithBKey() const { return SignWithBKey; }
511516

517+
bool hasELFSignedGOT() const { return HasELFSignedGOT; }
518+
512519
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
513520
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
514521

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ class AArch64Operand : public MCParsedAsmOperand {
875875
if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
876876
ELFRefKind == AArch64MCExpr::VK_LO12 ||
877877
ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
878+
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
878879
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
879880
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
880881
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
@@ -986,19 +987,20 @@ class AArch64Operand : public MCParsedAsmOperand {
986987
int64_t Addend;
987988
if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
988989
DarwinRefKind, Addend)) {
989-
return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
990-
|| DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
991-
|| (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
992-
|| ELFRefKind == AArch64MCExpr::VK_LO12
993-
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
994-
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
995-
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
996-
|| ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
997-
|| ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
998-
|| ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
999-
|| ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12
1000-
|| ELFRefKind == AArch64MCExpr::VK_SECREL_HI12
1001-
|| ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
990+
return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
991+
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF ||
992+
(DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) ||
993+
ELFRefKind == AArch64MCExpr::VK_LO12 ||
994+
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
995+
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
996+
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
997+
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
998+
ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
999+
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
1000+
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
1001+
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
1002+
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
1003+
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
10021004
}
10031005

10041006
// If it's a constant, it should be a real immediate in range.
@@ -3250,6 +3252,7 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
32503252
DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
32513253
ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
32523254
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
3255+
ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
32533256
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
32543257
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
32553258
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
@@ -4335,6 +4338,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
43354338
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
43364339
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
43374340
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
4341+
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
4342+
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
43384343
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
43394344
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
43404345
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
@@ -5709,6 +5714,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
57095714

57105715
// Only allow these with ADDXri/ADDWri
57115716
if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
5717+
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
57125718
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
57135719
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
57145720
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2860,7 +2860,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
28602860
}
28612861

28622862
if (OpFlags & AArch64II::MO_GOT) {
2863-
I.setDesc(TII.get(AArch64::LOADgot));
2863+
I.setDesc(TII.get(MF.getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
2864+
? AArch64::LOADgotAUTH
2865+
: AArch64::LOADgot));
28642866
I.getOperand(1).setTargetFlags(OpFlags);
28652867
} else if (TM.getCodeModel() == CodeModel::Large &&
28662868
!TM.isPositionIndependent()) {

0 commit comments

Comments
 (0)