Skip to content

Commit 1ac6a39

Browse files
committed
[PAC][CodeGen][ELF][AArch64] Support signed GOT
Support the following relocations and assembly operators: - `R_AARCH64_AUTH_ADR_GOT_PAGE` (`:got_auth:` for `adrp`) - `R_AARCH64_AUTH_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 ``` Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG. Tests with 'auth' in name have corresponding variants w/o it.
1 parent b9ad0b6 commit 1ac6a39

20 files changed

+389
-25
lines changed

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,40 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
12911291
MI.eraseFromParent();
12921292
return true;
12931293
}
1294+
case AArch64::LOADgotAUTH: {
1295+
Register DstReg = MI.getOperand(0).getReg();
1296+
const MachineOperand &MO1 = MI.getOperand(1);
1297+
1298+
MachineOperand GAHiOp(MO1);
1299+
MachineOperand GALoOp(MO1);
1300+
GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
1301+
GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
1302+
1303+
DebugLoc DL = MI.getDebugLoc();
1304+
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), AArch64::X16)
1305+
.add(GAHiOp);
12941306

1307+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), AArch64::X16)
1308+
.addReg(AArch64::X16)
1309+
.add(GALoOp)
1310+
.addImm(0);
1311+
1312+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui), DstReg)
1313+
.addReg(AArch64::X16)
1314+
.addImm(0);
1315+
1316+
assert(MO1.isGlobal());
1317+
assert(MO1.getGlobal()->getValueType() != nullptr);
1318+
unsigned AuthOpcode = MO1.getGlobal()->getValueType()->isFunctionTy()
1319+
? AArch64::AUTIA
1320+
: AArch64::AUTDA;
1321+
BuildMI(MBB, MBBI, DL, TII->get(AuthOpcode), DstReg)
1322+
.addReg(DstReg)
1323+
.addReg(AArch64::X16);
1324+
1325+
MI.eraseFromParent();
1326+
return true;
1327+
}
12951328
case AArch64::LOADgot: {
12961329
MachineFunction *MF = MBB.getParent();
12971330
Register DstReg = MI.getOperand(0).getReg();

llvm/lib/Target/AArch64/AArch64FastISel.cpp

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

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

457460
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
@@ -9044,6 +9044,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG,
90449044
SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
90459045
// FIXME: Once remat is capable of dealing with instructions with register
90469046
// operands, expand this into two nodes instead of using a wrapper node.
9047+
if (DAG.getMachineFunction()
9048+
.getInfo<AArch64FunctionInfo>()
9049+
->hasELFSignedGOT())
9050+
return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr),
9051+
0);
90479052
return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
90489053
}
90499054

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,10 @@ let Predicates = [HasPAuth] in {
17851785
(AUTH_TCRETURN_BTI tcGPRx16x17:$dst, imm:$FPDiff, imm:$Key,
17861786
imm:$Disc, tcGPR64:$AddrDisc)>;
17871787

1788+
def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
1789+
Sched<[WriteI, ReadI]> {
1790+
let Defs = [X16];
1791+
}
17881792
}
17891793

17901794
// 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"
@@ -184,9 +185,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
184185
MCSymbol *Sym) const {
185186
uint32_t RefFlags = 0;
186187

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

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp

Lines changed: 21 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"
@@ -82,6 +83,25 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
8283
return Key == "b_key";
8384
}
8485

86+
static bool hasELFSignedGOTHelper(const Function &F,
87+
const AArch64Subtarget *STI) {
88+
if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
89+
return false;
90+
const Module *M = F.getParent();
91+
uint64_t PAuthABIPlatform = -1;
92+
if (const auto *PAP = mdconst::extract_or_null<ConstantInt>(
93+
M->getModuleFlag("aarch64-elf-pauthabi-platform")))
94+
PAuthABIPlatform = PAP->getZExtValue();
95+
if (PAuthABIPlatform != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
96+
return false;
97+
uint64_t PAuthABIVersion = -1;
98+
if (const auto *PAV = mdconst::extract_or_null<ConstantInt>(
99+
M->getModuleFlag("aarch64-elf-pauthabi-version")))
100+
PAuthABIVersion = PAV->getZExtValue();
101+
return (PAuthABIVersion &
102+
(1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT)) != 0;
103+
}
104+
85105
AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
86106
const AArch64Subtarget *STI) {
87107
// If we already know that the function doesn't have a redzone, set
@@ -90,6 +110,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
90110
HasRedZone = false;
91111
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
92112
SignWithBKey = ShouldSignWithBKey(F, *STI);
113+
HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
93114
// TODO: skip functions that have no instrumented allocas for optimization
94115
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
95116

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
171171
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
172172
bool SignWithBKey = false;
173173

174+
/// HasELFSignedGOT is true if the target binary format is ELF and the IR
175+
/// module containing the corresponding function has the following flags:
176+
/// - aarch64-elf-pauthabi-platform flag equal to
177+
/// AARCH64_PAUTH_PLATFORM_LLVM_LINUX;
178+
/// - aarch64-elf-pauthabi-version flag with
179+
/// AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT bit set.
180+
bool HasELFSignedGOT = false;
181+
174182
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
175183
/// within the prologue, so it can be re-used for authentication in the
176184
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
@@ -482,6 +490,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
482490

483491
bool shouldSignWithBKey() const { return SignWithBKey; }
484492

493+
bool hasELFSignedGOT() const { return HasELFSignedGOT; }
494+
485495
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
486496
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
487497

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) {
@@ -4334,6 +4337,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
43344337
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
43354338
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
43364339
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
4340+
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
4341+
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
43374342
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
43384343
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
43394344
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
@@ -5708,6 +5713,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
57085713

57095714
// Only allow these with ADDXri/ADDWri
57105715
if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
5716+
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
57115717
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
57125718
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
57135719
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
@@ -2827,7 +2827,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
28272827
}
28282828

28292829
if (OpFlags & AArch64II::MO_GOT) {
2830-
I.setDesc(TII.get(AArch64::LOADgot));
2830+
I.setDesc(TII.get(MF.getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
2831+
? AArch64::LOADgotAUTH
2832+
: AArch64::LOADgot));
28312833
I.getOperand(1).setTargetFlags(OpFlags);
28322834
} else if (TM.getCodeModel() == CodeModel::Large &&
28332835
!TM.isPositionIndependent()) {

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

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
167167
}
168168
if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
169169
return R_CLS(ADR_GOT_PAGE);
170+
if (SymLoc == AArch64MCExpr::VK_GOT_AUTH && !IsNC) {
171+
if (IsILP32) {
172+
Ctx.reportError(Fixup.getLoc(),
173+
"ILP32 ADRP AUTH relocation not supported "
174+
"(LP64 eqv: AUTH_ADR_GOT_PAGE)");
175+
return ELF::R_AARCH64_NONE;
176+
}
177+
return ELF::R_AARCH64_AUTH_ADR_GOT_PAGE;
178+
}
170179
if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
171180
return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
172181
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
@@ -237,6 +246,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
237246
return R_CLS(TLSLE_ADD_TPREL_LO12);
238247
if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
239248
return R_CLS(TLSDESC_ADD_LO12);
249+
if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
250+
if (IsILP32) {
251+
Ctx.reportError(Fixup.getLoc(),
252+
"ILP32 ADD AUTH relocation not supported "
253+
"(LP64 eqv: AUTH_GOT_ADD_LO12_NC)");
254+
return ELF::R_AARCH64_NONE;
255+
}
256+
return ELF::R_AARCH64_AUTH_GOT_ADD_LO12_NC;
257+
}
240258
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
241259
return R_CLS(ADD_ABS_LO12_NC);
242260

@@ -329,17 +347,23 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
329347
case AArch64::fixup_aarch64_ldst_imm12_scale8:
330348
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
331349
return R_CLS(LDST64_ABS_LO12_NC);
332-
if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
350+
if ((SymLoc == AArch64MCExpr::VK_GOT ||
351+
SymLoc == AArch64MCExpr::VK_GOT_AUTH) &&
352+
IsNC) {
333353
AArch64MCExpr::VariantKind AddressLoc =
334354
AArch64MCExpr::getAddressFrag(RefKind);
355+
bool IsAuth = (SymLoc == AArch64MCExpr::VK_GOT_AUTH);
335356
if (!IsILP32) {
336357
if (AddressLoc == AArch64MCExpr::VK_LO15)
337358
return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
338-
return ELF::R_AARCH64_LD64_GOT_LO12_NC;
359+
return (IsAuth ? ELF::R_AARCH64_AUTH_GOT_LO12_NC
360+
: ELF::R_AARCH64_LD64_GOT_LO12_NC);
339361
}
340-
Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
341-
"relocation not supported (LP64 eqv: "
342-
"LD64_GOT_LO12_NC)");
362+
Ctx.reportError(Fixup.getLoc(),
363+
Twine("ILP32 64-bit load/store "
364+
"relocation not supported (LP64 eqv: ") +
365+
(IsAuth ? "AUTH_GOT_LO12_NC" : "LD64_GOT_LO12_NC") +
366+
Twine(')'));
343367
return ELF::R_AARCH64_NONE;
344368
}
345369
if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const AArch64MCExpr *AArch64MCExpr::create(const MCExpr *Expr, VariantKind Kind,
3030
}
3131

3232
StringRef AArch64MCExpr::getVariantKindName() const {
33+
// clang-format off
3334
switch (static_cast<uint32_t>(getKind())) {
3435
case VK_CALL: return "";
3536
case VK_LO12: return ":lo12:";
@@ -82,9 +83,13 @@ StringRef AArch64MCExpr::getVariantKindName() const {
8283
case VK_TLSDESC_PAGE: return ":tlsdesc:";
8384
case VK_SECREL_LO12: return ":secrel_lo12:";
8485
case VK_SECREL_HI12: return ":secrel_hi12:";
86+
case VK_GOT_AUTH: return ":got_auth:";
87+
case VK_GOT_AUTH_PAGE: return ":got_auth:";
88+
case VK_GOT_AUTH_LO12: return ":got_auth_lo12:";
8589
default:
8690
llvm_unreachable("Invalid ELF symbol kind");
8791
}
92+
// clang-format on
8893
}
8994

9095
void AArch64MCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {

llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace llvm {
2424
class AArch64MCExpr : public MCTargetExpr {
2525
public:
2626
enum VariantKind {
27+
// clang-format off
2728
// Symbol locations specifying (roughly speaking) what calculation should be
2829
// performed to construct the final address for the relocated
2930
// symbol. E.g. direct, via the GOT, ...
@@ -38,6 +39,7 @@ class AArch64MCExpr : public MCTargetExpr {
3839
VK_SECREL = 0x009,
3940
VK_AUTH = 0x00a,
4041
VK_AUTHADDR = 0x00b,
42+
VK_GOT_AUTH = 0x00c,
4143
VK_SymLocBits = 0x00f,
4244

4345
// Variants specifying which part of the final address calculation is
@@ -88,6 +90,8 @@ class AArch64MCExpr : public MCTargetExpr {
8890
VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC,
8991
VK_GOT_PAGE = VK_GOT | VK_PAGE,
9092
VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC,
93+
VK_GOT_AUTH_LO12 = VK_GOT_AUTH | VK_PAGEOFF | VK_NC,
94+
VK_GOT_AUTH_PAGE = VK_GOT_AUTH | VK_PAGE,
9195
VK_DTPREL_G2 = VK_DTPREL | VK_G2,
9296
VK_DTPREL_G1 = VK_DTPREL | VK_G1,
9397
VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC,
@@ -114,6 +118,7 @@ class AArch64MCExpr : public MCTargetExpr {
114118
VK_SECREL_HI12 = VK_SECREL | VK_HI12,
115119

116120
VK_INVALID = 0xfff
121+
// clang-format on
117122
};
118123

119124
private:
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=0 -verify-machineinstrs \
2+
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
3+
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=1 -verify-machineinstrs \
4+
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
5+
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=1 -verify-machineinstrs \
6+
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
7+
8+
;; Note: for FastISel, we fall back to SelectionDAG
9+
10+
@var = global i32 0
11+
12+
define i32 @get_globalvar() {
13+
; CHECK-LABEL: get_globalvar:
14+
15+
%val = load i32, ptr @var
16+
17+
; CHECK: adrp x[[GOT:[0-9]+]], :got_auth:var
18+
; CHECK: add x[[GOT]], x[[GOT]], :got_auth_lo12:var
19+
; CHECK: ldr x[[SYM:[0-9]+]], [x[[GOT]]]
20+
; CHECK: autda x[[SYM]], x[[GOT]]
21+
; CHECK: ldr w0, [x[[SYM]]]
22+
ret i32 %val
23+
}
24+
25+
define ptr @get_globalvaraddr() {
26+
; CHECK-LABEL: get_globalvaraddr:
27+
28+
%val = load i32, ptr @var
29+
30+
; CHECK: adrp x[[GOT:[0-9]+]], :got_auth:var
31+
; CHECK: add x[[GOT]], x[[GOT]], :got_auth_lo12:var
32+
; CHECK: ldr x0, [x[[GOT]]]
33+
; CHECK: autda x0, x[[GOT]]
34+
ret ptr @var
35+
}
36+
37+
!llvm.module.flags = !{!0, !1}
38+
!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
39+
!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}

0 commit comments

Comments
 (0)