Skip to content

Commit 9dae7fc

Browse files
authored
[PAC][CodeGen][ELF][AArch64] Support signed GOT (#96164)
Depends on #96158 and #96159 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) } ``` 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 fc15752 commit 9dae7fc

21 files changed

+482
-34
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,10 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
21612161
};
21622162

21632163
const bool IsGOTLoad = MI.getOpcode() == AArch64::LOADgotPAC;
2164+
const bool IsELFSignedGOT = MI.getParent()
2165+
->getParent()
2166+
->getInfo<AArch64FunctionInfo>()
2167+
->hasELFSignedGOT();
21642168
MachineOperand GAOp = MI.getOperand(0);
21652169
const uint64_t KeyC = MI.getOperand(1).getImm();
21662170
assert(KeyC <= AArch64PACKey::LAST &&
@@ -2177,9 +2181,16 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
21772181
// Emit:
21782182
// target materialization:
21792183
// - via GOT:
2180-
// adrp x16, :got:target
2181-
// ldr x16, [x16, :got_lo12:target]
2182-
// add offset to x16 if offset != 0
2184+
// - unsigned GOT:
2185+
// adrp x16, :got:target
2186+
// ldr x16, [x16, :got_lo12:target]
2187+
// add offset to x16 if offset != 0
2188+
// - ELF signed GOT:
2189+
// adrp x17, :got:target
2190+
// add x17, x17, :got_auth_lo12:target
2191+
// ldr x16, [x17]
2192+
// aut{i|d}a x16, x17
2193+
// add offset to x16 if offset != 0
21832194
//
21842195
// - direct:
21852196
// adrp x16, target
@@ -2222,13 +2233,40 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
22222233
MCInstLowering.lowerOperand(GAMOLo, GAMCLo);
22232234

22242235
EmitAndIncrement(
2225-
MCInstBuilder(AArch64::ADRP).addReg(AArch64::X16).addOperand(GAMCHi));
2236+
MCInstBuilder(AArch64::ADRP)
2237+
.addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
2238+
.addOperand(GAMCHi));
22262239

22272240
if (IsGOTLoad) {
2228-
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2229-
.addReg(AArch64::X16)
2230-
.addReg(AArch64::X16)
2231-
.addOperand(GAMCLo));
2241+
if (IsELFSignedGOT) {
2242+
EmitAndIncrement(MCInstBuilder(AArch64::ADDXri)
2243+
.addReg(AArch64::X17)
2244+
.addReg(AArch64::X17)
2245+
.addOperand(GAMCLo)
2246+
.addImm(0));
2247+
2248+
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2249+
.addReg(AArch64::X16)
2250+
.addReg(AArch64::X17)
2251+
.addImm(0));
2252+
2253+
assert(GAOp.isGlobal());
2254+
assert(GAOp.getGlobal()->getValueType() != nullptr);
2255+
unsigned AuthOpcode = GAOp.getGlobal()->getValueType()->isFunctionTy()
2256+
? AArch64::AUTIA
2257+
: AArch64::AUTDA;
2258+
2259+
EmitAndIncrement(MCInstBuilder(AuthOpcode)
2260+
.addReg(AArch64::X16)
2261+
.addReg(AArch64::X16)
2262+
.addReg(AArch64::X17));
2263+
2264+
} else {
2265+
EmitAndIncrement(MCInstBuilder(AArch64::LDRXui)
2266+
.addReg(AArch64::X16)
2267+
.addReg(AArch64::X16)
2268+
.addOperand(GAMCLo));
2269+
}
22322270
} else {
22332271
EmitAndIncrement(MCInstBuilder(AArch64::ADDXri)
22342272
.addReg(AArch64::X16)

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
@@ -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
@@ -9225,6 +9225,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG,
92259225
SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
92269226
// FIXME: Once remat is capable of dealing with instructions with register
92279227
// operands, expand this into two nodes instead of using a wrapper node.
9228+
if (DAG.getMachineFunction()
9229+
.getInfo<AArch64FunctionInfo>()
9230+
->hasELFSignedGOT())
9231+
return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr),
9232+
0);
92289233
return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
92299234
}
92309235

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1872,7 +1872,7 @@ let Predicates = [HasPAuth] in {
18721872
Sched<[WriteI, ReadI]> {
18731873
let isReMaterializable = 1;
18741874
let isCodeGenOnly = 1;
1875-
let Size = 40; // 12 fixed + 28 variable, for pointer offset, and discriminator
1875+
let Size = 48; // 12 fixed + 36 variable, for pointer offset, and discriminator
18761876
let Defs = [X16,X17];
18771877
}
18781878

@@ -1911,6 +1911,11 @@ let Predicates = [HasPAuth] in {
19111911
tcGPR64:$AddrDisc),
19121912
(AUTH_TCRETURN_BTI tcGPRx16x17:$dst, imm:$FPDiff, imm:$Key,
19131913
imm:$Disc, tcGPR64:$AddrDisc)>;
1914+
1915+
def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
1916+
Sched<[WriteI, ReadI]> {
1917+
let Defs = [X16];
1918+
}
19141919
}
19151920

19161921
// 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: 25 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,29 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
7273
return Key == "b_key";
7374
}
7475

76+
// Determine if we need to treat pointers in GOT as signed (as described in
77+
// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#appendix-signed-got)
78+
// based on PAuth core info encoded as "aarch64-elf-pauthabi-platform" and
79+
// "aarch64-elf-pauthabi-version" module flags. Currently, only
80+
// AARCH64_PAUTH_PLATFORM_LLVM_LINUX platform supports signed GOT with
81+
// AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT bit in version value set.
82+
static bool hasELFSignedGOTHelper(const Function &F,
83+
const AArch64Subtarget *STI) {
84+
if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
85+
return false;
86+
const Module *M = F.getParent();
87+
const auto *PAP = mdconst::extract_or_null<ConstantInt>(
88+
M->getModuleFlag("aarch64-elf-pauthabi-platform"));
89+
if (!PAP || PAP->getZExtValue() != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
90+
return false;
91+
const auto *PAV = mdconst::extract_or_null<ConstantInt>(
92+
M->getModuleFlag("aarch64-elf-pauthabi-version"));
93+
if (!PAV)
94+
return false;
95+
return PAV->getZExtValue() &
96+
(1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT);
97+
}
98+
7599
AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
76100
const AArch64Subtarget *STI) {
77101
// If we already know that the function doesn't have a redzone, set
@@ -80,6 +104,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
80104
HasRedZone = false;
81105
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
82106
SignWithBKey = ShouldSignWithBKey(F, *STI);
107+
HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
83108
// TODO: skip functions that have no instrumented allocas for optimization
84109
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
85110

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ 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 the following flags:
182+
/// - aarch64-elf-pauthabi-platform flag equal to
183+
/// AARCH64_PAUTH_PLATFORM_LLVM_LINUX;
184+
/// - aarch64-elf-pauthabi-version flag with
185+
/// AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT bit set.
186+
bool HasELFSignedGOT = false;
187+
180188
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
181189
/// within the prologue, so it can be re-used for authentication in the
182190
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
@@ -509,6 +517,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
509517

510518
bool shouldSignWithBKey() const { return SignWithBKey; }
511519

520+
bool hasELFSignedGOT() const { return HasELFSignedGOT; }
521+
512522
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
513523
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
514524

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
@@ -2845,7 +2845,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
28452845
}
28462846

28472847
if (OpFlags & AArch64II::MO_GOT) {
2848-
I.setDesc(TII.get(AArch64::LOADgot));
2848+
I.setDesc(TII.get(MF.getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
2849+
? AArch64::LOADgotAUTH
2850+
: AArch64::LOADgot));
28492851
I.getOperand(1).setTargetFlags(OpFlags);
28502852
} else if (TM.getCodeModel() == CodeModel::Large &&
28512853
!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_LD64_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)

0 commit comments

Comments
 (0)