[PAC][CodeGen][ELF][AArch64] Support signed GOT (#113811)
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 auth instruction is emitted, a check+trap sequence similar to one used for `AUT` pseudo is emitted to ensure auth success. 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
This commit is contained in:
parent
2337990cae
commit
da083e358e
@ -169,6 +169,11 @@ public:
|
|||||||
// adrp-add followed by PAC sign)
|
// adrp-add followed by PAC sign)
|
||||||
void LowerMOVaddrPAC(const MachineInstr &MI);
|
void LowerMOVaddrPAC(const MachineInstr &MI);
|
||||||
|
|
||||||
|
// Emit the sequence for LOADgotAUTH (load signed pointer from signed ELF GOT
|
||||||
|
// and authenticate it with, if FPAC bit is not set, check+trap sequence after
|
||||||
|
// authenticating)
|
||||||
|
void LowerLOADgotAUTH(const MachineInstr &MI);
|
||||||
|
|
||||||
/// tblgen'erated driver function for lowering simple MI->MC
|
/// tblgen'erated driver function for lowering simple MI->MC
|
||||||
/// pseudo instructions.
|
/// pseudo instructions.
|
||||||
bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst);
|
bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst);
|
||||||
@ -873,6 +878,22 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
|
|||||||
|
|
||||||
OutStreamer->addBlankLine();
|
OutStreamer->addBlankLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// With signed ELF GOT enabled, the linker looks at the symbol type to
|
||||||
|
// choose between keys IA (for STT_FUNC) and DA (for other types). Symbols
|
||||||
|
// for functions not defined in the module have STT_NOTYPE type by default.
|
||||||
|
// This makes linker to emit signing schema with DA key (instead of IA) for
|
||||||
|
// corresponding R_AARCH64_AUTH_GLOB_DAT dynamic reloc. To avoid that, force
|
||||||
|
// all function symbols used in the module to have STT_FUNC type. See
|
||||||
|
// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#default-signing-schema
|
||||||
|
const auto *PtrAuthELFGOTFlag = mdconst::extract_or_null<ConstantInt>(
|
||||||
|
M.getModuleFlag("ptrauth-elf-got"));
|
||||||
|
if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1)
|
||||||
|
for (const GlobalValue &GV : M.global_values())
|
||||||
|
if (!GV.use_empty() && isa<Function>(GV) &&
|
||||||
|
!GV.getName().starts_with("llvm."))
|
||||||
|
OutStreamer->emitSymbolAttribute(getSymbol(&GV),
|
||||||
|
MCSA_ELF_TypeFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit stack and fault map information.
|
// Emit stack and fault map information.
|
||||||
@ -2068,6 +2089,10 @@ void AArch64AsmPrinter::LowerLOADauthptrstatic(const MachineInstr &MI) {
|
|||||||
|
|
||||||
void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
|
void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
|
||||||
const bool IsGOTLoad = MI.getOpcode() == AArch64::LOADgotPAC;
|
const bool IsGOTLoad = MI.getOpcode() == AArch64::LOADgotPAC;
|
||||||
|
const bool IsELFSignedGOT = MI.getParent()
|
||||||
|
->getParent()
|
||||||
|
->getInfo<AArch64FunctionInfo>()
|
||||||
|
->hasELFSignedGOT();
|
||||||
MachineOperand GAOp = MI.getOperand(0);
|
MachineOperand GAOp = MI.getOperand(0);
|
||||||
const uint64_t KeyC = MI.getOperand(1).getImm();
|
const uint64_t KeyC = MI.getOperand(1).getImm();
|
||||||
assert(KeyC <= AArch64PACKey::LAST &&
|
assert(KeyC <= AArch64PACKey::LAST &&
|
||||||
@ -2084,9 +2109,17 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
|
|||||||
// Emit:
|
// Emit:
|
||||||
// target materialization:
|
// target materialization:
|
||||||
// - via GOT:
|
// - via GOT:
|
||||||
// adrp x16, :got:target
|
// - unsigned GOT:
|
||||||
// ldr x16, [x16, :got_lo12:target]
|
// adrp x16, :got:target
|
||||||
// add offset to x16 if offset != 0
|
// ldr x16, [x16, :got_lo12:target]
|
||||||
|
// add offset to x16 if offset != 0
|
||||||
|
// - ELF signed GOT:
|
||||||
|
// adrp x17, :got:target
|
||||||
|
// add x17, x17, :got_auth_lo12:target
|
||||||
|
// ldr x16, [x17]
|
||||||
|
// aut{i|d}a x16, x17
|
||||||
|
// check+trap sequence (if no FPAC)
|
||||||
|
// add offset to x16 if offset != 0
|
||||||
//
|
//
|
||||||
// - direct:
|
// - direct:
|
||||||
// adrp x16, target
|
// adrp x16, target
|
||||||
@ -2129,13 +2162,48 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
|
|||||||
MCInstLowering.lowerOperand(GAMOLo, GAMCLo);
|
MCInstLowering.lowerOperand(GAMOLo, GAMCLo);
|
||||||
|
|
||||||
EmitToStreamer(
|
EmitToStreamer(
|
||||||
MCInstBuilder(AArch64::ADRP).addReg(AArch64::X16).addOperand(GAMCHi));
|
MCInstBuilder(AArch64::ADRP)
|
||||||
|
.addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
|
||||||
|
.addOperand(GAMCHi));
|
||||||
|
|
||||||
if (IsGOTLoad) {
|
if (IsGOTLoad) {
|
||||||
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
|
if (IsELFSignedGOT) {
|
||||||
.addReg(AArch64::X16)
|
EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
|
||||||
.addReg(AArch64::X16)
|
.addReg(AArch64::X17)
|
||||||
.addOperand(GAMCLo));
|
.addReg(AArch64::X17)
|
||||||
|
.addOperand(GAMCLo)
|
||||||
|
.addImm(0));
|
||||||
|
|
||||||
|
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
|
||||||
|
.addReg(AArch64::X16)
|
||||||
|
.addReg(AArch64::X17)
|
||||||
|
.addImm(0));
|
||||||
|
|
||||||
|
assert(GAOp.isGlobal());
|
||||||
|
assert(GAOp.getGlobal()->getValueType() != nullptr);
|
||||||
|
unsigned AuthOpcode = GAOp.getGlobal()->getValueType()->isFunctionTy()
|
||||||
|
? AArch64::AUTIA
|
||||||
|
: AArch64::AUTDA;
|
||||||
|
|
||||||
|
EmitToStreamer(MCInstBuilder(AuthOpcode)
|
||||||
|
.addReg(AArch64::X16)
|
||||||
|
.addReg(AArch64::X16)
|
||||||
|
.addReg(AArch64::X17));
|
||||||
|
|
||||||
|
if (!STI->hasFPAC()) {
|
||||||
|
auto AuthKey = (AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA
|
||||||
|
: AArch64PACKey::DA);
|
||||||
|
|
||||||
|
emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
|
||||||
|
/*ShouldTrap=*/true,
|
||||||
|
/*OnFailure=*/nullptr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
|
||||||
|
.addReg(AArch64::X16)
|
||||||
|
.addReg(AArch64::X16)
|
||||||
|
.addOperand(GAMCLo));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
|
EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
|
||||||
.addReg(AArch64::X16)
|
.addReg(AArch64::X16)
|
||||||
@ -2203,6 +2271,69 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
|
|||||||
EmitToStreamer(MIB);
|
EmitToStreamer(MIB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
|
||||||
|
Register DstReg = MI.getOperand(0).getReg();
|
||||||
|
Register AuthResultReg = STI->hasFPAC() ? DstReg : AArch64::X16;
|
||||||
|
const MachineOperand &GAMO = MI.getOperand(1);
|
||||||
|
assert(GAMO.getOffset() == 0);
|
||||||
|
|
||||||
|
MachineOperand GAHiOp(GAMO);
|
||||||
|
MachineOperand GALoOp(GAMO);
|
||||||
|
GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
|
||||||
|
GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
||||||
|
|
||||||
|
MCOperand GAMCHi, GAMCLo;
|
||||||
|
MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
|
||||||
|
MCInstLowering.lowerOperand(GALoOp, GAMCLo);
|
||||||
|
|
||||||
|
EmitToStreamer(
|
||||||
|
MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi));
|
||||||
|
|
||||||
|
EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
|
||||||
|
.addReg(AArch64::X17)
|
||||||
|
.addReg(AArch64::X17)
|
||||||
|
.addOperand(GAMCLo)
|
||||||
|
.addImm(0));
|
||||||
|
|
||||||
|
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
|
||||||
|
.addReg(AuthResultReg)
|
||||||
|
.addReg(AArch64::X17)
|
||||||
|
.addImm(0));
|
||||||
|
|
||||||
|
assert(GAMO.isGlobal());
|
||||||
|
MCSymbol *UndefWeakSym;
|
||||||
|
if (GAMO.getGlobal()->hasExternalWeakLinkage()) {
|
||||||
|
UndefWeakSym = createTempSymbol("undef_weak");
|
||||||
|
EmitToStreamer(
|
||||||
|
MCInstBuilder(AArch64::CBZX)
|
||||||
|
.addReg(AuthResultReg)
|
||||||
|
.addExpr(MCSymbolRefExpr::create(UndefWeakSym, OutContext)));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(GAMO.getGlobal()->getValueType() != nullptr);
|
||||||
|
unsigned AuthOpcode = GAMO.getGlobal()->getValueType()->isFunctionTy()
|
||||||
|
? AArch64::AUTIA
|
||||||
|
: AArch64::AUTDA;
|
||||||
|
EmitToStreamer(MCInstBuilder(AuthOpcode)
|
||||||
|
.addReg(AuthResultReg)
|
||||||
|
.addReg(AuthResultReg)
|
||||||
|
.addReg(AArch64::X17));
|
||||||
|
|
||||||
|
if (GAMO.getGlobal()->hasExternalWeakLinkage())
|
||||||
|
OutStreamer->emitLabel(UndefWeakSym);
|
||||||
|
|
||||||
|
if (!STI->hasFPAC()) {
|
||||||
|
auto AuthKey =
|
||||||
|
(AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA : AArch64PACKey::DA);
|
||||||
|
|
||||||
|
emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
|
||||||
|
/*ShouldTrap=*/true,
|
||||||
|
/*OnFailure=*/nullptr);
|
||||||
|
|
||||||
|
emitMovXReg(DstReg, AuthResultReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const MCExpr *
|
const MCExpr *
|
||||||
AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
|
AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
|
||||||
const MCExpr *BAE = AsmPrinter::lowerBlockAddressConstant(BA);
|
const MCExpr *BAE = AsmPrinter::lowerBlockAddressConstant(BA);
|
||||||
@ -2381,6 +2512,10 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
|
|||||||
LowerMOVaddrPAC(*MI);
|
LowerMOVaddrPAC(*MI);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case AArch64::LOADgotAUTH:
|
||||||
|
LowerLOADgotAUTH(*MI);
|
||||||
|
return;
|
||||||
|
|
||||||
case AArch64::BRA:
|
case AArch64::BRA:
|
||||||
case AArch64::BLRA:
|
case AArch64::BLRA:
|
||||||
emitPtrauthBranch(MI);
|
emitPtrauthBranch(MI);
|
||||||
|
@ -454,6 +454,9 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) {
|
|||||||
if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO())
|
if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT())
|
||||||
|
return 0;
|
||||||
|
|
||||||
unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
|
unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
|
||||||
|
|
||||||
EVT DestEVT = TLI.getValueType(DL, GV->getType(), true);
|
EVT DestEVT = TLI.getValueType(DL, GV->getType(), true);
|
||||||
|
@ -9599,6 +9599,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG,
|
|||||||
SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
|
SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
|
||||||
// FIXME: Once remat is capable of dealing with instructions with register
|
// FIXME: Once remat is capable of dealing with instructions with register
|
||||||
// operands, expand this into two nodes instead of using a wrapper node.
|
// operands, expand this into two nodes instead of using a wrapper node.
|
||||||
|
if (DAG.getMachineFunction()
|
||||||
|
.getInfo<AArch64FunctionInfo>()
|
||||||
|
->hasELFSignedGOT())
|
||||||
|
return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr),
|
||||||
|
0);
|
||||||
return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
|
return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1942,8 +1942,15 @@ let Predicates = [HasPAuth] in {
|
|||||||
Sched<[WriteI, ReadI]> {
|
Sched<[WriteI, ReadI]> {
|
||||||
let isReMaterializable = 1;
|
let isReMaterializable = 1;
|
||||||
let isCodeGenOnly = 1;
|
let isCodeGenOnly = 1;
|
||||||
let Size = 40; // 12 fixed + 28 variable, for pointer offset, and discriminator
|
let Size = 68; // 12 fixed + 56 variable, for pointer offset, discriminator and
|
||||||
let Defs = [X16,X17];
|
// ELF signed GOT signed pointer authentication (if no FPAC)
|
||||||
|
let Defs = [X16,X17,NZCV];
|
||||||
|
}
|
||||||
|
|
||||||
|
def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
|
||||||
|
Sched<[WriteI, ReadI]> {
|
||||||
|
let Defs = [X16,X17,NZCV];
|
||||||
|
let Size = 44;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a signed global address from a special $auth_ptr$ stub slot.
|
// Load a signed global address from a special $auth_ptr$ stub slot.
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "AArch64MCInstLower.h"
|
#include "AArch64MCInstLower.h"
|
||||||
|
#include "AArch64MachineFunctionInfo.h"
|
||||||
#include "MCTargetDesc/AArch64MCExpr.h"
|
#include "MCTargetDesc/AArch64MCExpr.h"
|
||||||
#include "Utils/AArch64BaseInfo.h"
|
#include "Utils/AArch64BaseInfo.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
@ -185,9 +186,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
|
|||||||
MCSymbol *Sym) const {
|
MCSymbol *Sym) const {
|
||||||
uint32_t RefFlags = 0;
|
uint32_t RefFlags = 0;
|
||||||
|
|
||||||
if (MO.getTargetFlags() & AArch64II::MO_GOT)
|
if (MO.getTargetFlags() & AArch64II::MO_GOT) {
|
||||||
RefFlags |= AArch64MCExpr::VK_GOT;
|
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
|
||||||
else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
|
RefFlags |= (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
|
||||||
|
? AArch64MCExpr::VK_GOT_AUTH
|
||||||
|
: AArch64MCExpr::VK_GOT);
|
||||||
|
} else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
|
||||||
TLSModel::Model Model;
|
TLSModel::Model Model;
|
||||||
if (MO.isGlobal()) {
|
if (MO.isGlobal()) {
|
||||||
const GlobalValue *GV = MO.getGlobal();
|
const GlobalValue *GV = MO.getGlobal();
|
||||||
|
@ -72,6 +72,18 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
|
|||||||
return Key == "b_key";
|
return Key == "b_key";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasELFSignedGOTHelper(const Function &F,
|
||||||
|
const AArch64Subtarget *STI) {
|
||||||
|
if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
|
||||||
|
return false;
|
||||||
|
const Module *M = F.getParent();
|
||||||
|
const auto *Flag = mdconst::extract_or_null<ConstantInt>(
|
||||||
|
M->getModuleFlag("ptrauth-elf-got"));
|
||||||
|
if (Flag && Flag->getZExtValue() == 1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
|
AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
|
||||||
const AArch64Subtarget *STI) {
|
const AArch64Subtarget *STI) {
|
||||||
// If we already know that the function doesn't have a redzone, set
|
// If we already know that the function doesn't have a redzone, set
|
||||||
@ -80,6 +92,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
|
|||||||
HasRedZone = false;
|
HasRedZone = false;
|
||||||
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
|
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
|
||||||
SignWithBKey = ShouldSignWithBKey(F, *STI);
|
SignWithBKey = ShouldSignWithBKey(F, *STI);
|
||||||
|
HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
|
||||||
// TODO: skip functions that have no instrumented allocas for optimization
|
// TODO: skip functions that have no instrumented allocas for optimization
|
||||||
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
|
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
|
||||||
|
|
||||||
|
@ -177,6 +177,11 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
|
|||||||
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
|
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
|
||||||
bool SignWithBKey = false;
|
bool SignWithBKey = false;
|
||||||
|
|
||||||
|
/// HasELFSignedGOT is true if the target binary format is ELF and the IR
|
||||||
|
/// module containing the corresponding function has "ptrauth-elf-got" flag
|
||||||
|
/// set to 1.
|
||||||
|
bool HasELFSignedGOT = false;
|
||||||
|
|
||||||
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
|
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
|
||||||
/// within the prologue, so it can be re-used for authentication in the
|
/// within the prologue, so it can be re-used for authentication in the
|
||||||
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
|
/// epilogue when using PC as a second salt (FEAT_PAuth_LR)
|
||||||
@ -509,6 +514,8 @@ public:
|
|||||||
|
|
||||||
bool shouldSignWithBKey() const { return SignWithBKey; }
|
bool shouldSignWithBKey() const { return SignWithBKey; }
|
||||||
|
|
||||||
|
bool hasELFSignedGOT() const { return HasELFSignedGOT; }
|
||||||
|
|
||||||
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
|
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
|
||||||
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
|
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
|
||||||
|
|
||||||
|
@ -897,6 +897,7 @@ public:
|
|||||||
if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
|
if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_LO12 ||
|
ELFRefKind == AArch64MCExpr::VK_LO12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
|
ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
|
||||||
|
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
|
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
|
||||||
@ -1008,19 +1009,20 @@ public:
|
|||||||
int64_t Addend;
|
int64_t Addend;
|
||||||
if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
|
if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
|
||||||
DarwinRefKind, Addend)) {
|
DarwinRefKind, Addend)) {
|
||||||
return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
|
return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
|
||||||
|| DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
|
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF ||
|
||||||
|| (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
|
(DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_LO12
|
ELFRefKind == AArch64MCExpr::VK_LO12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
|
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
|
ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
|
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12
|
ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_SECREL_HI12
|
ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
|
||||||
|| ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
|
ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
|
||||||
|
ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's a constant, it should be a real immediate in range.
|
// If it's a constant, it should be a real immediate in range.
|
||||||
@ -3309,6 +3311,7 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
|
|||||||
DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
|
DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
|
||||||
ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
|
ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
|
||||||
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
|
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
|
||||||
|
ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
|
||||||
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
|
ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
|
||||||
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
|
ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
|
||||||
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
|
ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
|
||||||
@ -4428,6 +4431,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
|
|||||||
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
|
.Case("got", AArch64MCExpr::VK_GOT_PAGE)
|
||||||
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
|
.Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
|
||||||
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
|
.Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
|
||||||
|
.Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
|
||||||
|
.Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
|
||||||
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
|
.Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
|
||||||
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
|
.Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
|
||||||
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
|
.Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
|
||||||
@ -5801,6 +5806,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
|
|||||||
|
|
||||||
// Only allow these with ADDXri/ADDWri
|
// Only allow these with ADDXri/ADDWri
|
||||||
if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
|
if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
|
||||||
|
ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
|
||||||
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
|
ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
|
||||||
|
@ -2967,7 +2967,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (OpFlags & AArch64II::MO_GOT) {
|
if (OpFlags & AArch64II::MO_GOT) {
|
||||||
I.setDesc(TII.get(AArch64::LOADgot));
|
I.setDesc(TII.get(MF.getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
|
||||||
|
? AArch64::LOADgotAUTH
|
||||||
|
: AArch64::LOADgot));
|
||||||
I.getOperand(1).setTargetFlags(OpFlags);
|
I.getOperand(1).setTargetFlags(OpFlags);
|
||||||
} else if (TM.getCodeModel() == CodeModel::Large &&
|
} else if (TM.getCodeModel() == CodeModel::Large &&
|
||||||
!TM.isPositionIndependent()) {
|
!TM.isPositionIndependent()) {
|
||||||
|
@ -165,6 +165,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
|
|||||||
}
|
}
|
||||||
if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
|
if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
|
||||||
return R_CLS(ADR_GOT_PAGE);
|
return R_CLS(ADR_GOT_PAGE);
|
||||||
|
if (SymLoc == AArch64MCExpr::VK_GOT_AUTH && !IsNC) {
|
||||||
|
if (IsILP32) {
|
||||||
|
Ctx.reportError(Fixup.getLoc(),
|
||||||
|
"ILP32 ADRP AUTH relocation not supported "
|
||||||
|
"(LP64 eqv: AUTH_ADR_GOT_PAGE)");
|
||||||
|
return ELF::R_AARCH64_NONE;
|
||||||
|
}
|
||||||
|
return ELF::R_AARCH64_AUTH_ADR_GOT_PAGE;
|
||||||
|
}
|
||||||
if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
|
if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
|
||||||
return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
|
return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
|
||||||
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
|
if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
|
||||||
@ -240,6 +249,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
|
|||||||
return R_CLS(TLSLE_ADD_TPREL_LO12);
|
return R_CLS(TLSLE_ADD_TPREL_LO12);
|
||||||
if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
|
if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
|
||||||
return R_CLS(TLSDESC_ADD_LO12);
|
return R_CLS(TLSDESC_ADD_LO12);
|
||||||
|
if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
|
||||||
|
if (IsILP32) {
|
||||||
|
Ctx.reportError(Fixup.getLoc(),
|
||||||
|
"ILP32 ADD AUTH relocation not supported "
|
||||||
|
"(LP64 eqv: AUTH_GOT_ADD_LO12_NC)");
|
||||||
|
return ELF::R_AARCH64_NONE;
|
||||||
|
}
|
||||||
|
return ELF::R_AARCH64_AUTH_GOT_ADD_LO12_NC;
|
||||||
|
}
|
||||||
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
|
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
|
||||||
return R_CLS(ADD_ABS_LO12_NC);
|
return R_CLS(ADD_ABS_LO12_NC);
|
||||||
|
|
||||||
@ -332,17 +350,23 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
|
|||||||
case AArch64::fixup_aarch64_ldst_imm12_scale8:
|
case AArch64::fixup_aarch64_ldst_imm12_scale8:
|
||||||
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
|
if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
|
||||||
return R_CLS(LDST64_ABS_LO12_NC);
|
return R_CLS(LDST64_ABS_LO12_NC);
|
||||||
if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
|
if ((SymLoc == AArch64MCExpr::VK_GOT ||
|
||||||
|
SymLoc == AArch64MCExpr::VK_GOT_AUTH) &&
|
||||||
|
IsNC) {
|
||||||
AArch64MCExpr::VariantKind AddressLoc =
|
AArch64MCExpr::VariantKind AddressLoc =
|
||||||
AArch64MCExpr::getAddressFrag(RefKind);
|
AArch64MCExpr::getAddressFrag(RefKind);
|
||||||
|
bool IsAuth = (SymLoc == AArch64MCExpr::VK_GOT_AUTH);
|
||||||
if (!IsILP32) {
|
if (!IsILP32) {
|
||||||
if (AddressLoc == AArch64MCExpr::VK_LO15)
|
if (AddressLoc == AArch64MCExpr::VK_LO15)
|
||||||
return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
|
return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
|
||||||
return ELF::R_AARCH64_LD64_GOT_LO12_NC;
|
return (IsAuth ? ELF::R_AARCH64_AUTH_LD64_GOT_LO12_NC
|
||||||
|
: ELF::R_AARCH64_LD64_GOT_LO12_NC);
|
||||||
}
|
}
|
||||||
Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
|
Ctx.reportError(Fixup.getLoc(),
|
||||||
"relocation not supported (LP64 eqv: "
|
Twine("ILP32 64-bit load/store "
|
||||||
"LD64_GOT_LO12_NC)");
|
"relocation not supported (LP64 eqv: ") +
|
||||||
|
(IsAuth ? "AUTH_GOT_LO12_NC" : "LD64_GOT_LO12_NC") +
|
||||||
|
Twine(')'));
|
||||||
return ELF::R_AARCH64_NONE;
|
return ELF::R_AARCH64_NONE;
|
||||||
}
|
}
|
||||||
if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
|
if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
|
||||||
|
@ -30,6 +30,7 @@ const AArch64MCExpr *AArch64MCExpr::create(const MCExpr *Expr, VariantKind Kind,
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef AArch64MCExpr::getVariantKindName() const {
|
StringRef AArch64MCExpr::getVariantKindName() const {
|
||||||
|
// clang-format off
|
||||||
switch (static_cast<uint32_t>(getKind())) {
|
switch (static_cast<uint32_t>(getKind())) {
|
||||||
case VK_CALL: return "";
|
case VK_CALL: return "";
|
||||||
case VK_LO12: return ":lo12:";
|
case VK_LO12: return ":lo12:";
|
||||||
@ -82,9 +83,13 @@ StringRef AArch64MCExpr::getVariantKindName() const {
|
|||||||
case VK_TLSDESC_PAGE: return ":tlsdesc:";
|
case VK_TLSDESC_PAGE: return ":tlsdesc:";
|
||||||
case VK_SECREL_LO12: return ":secrel_lo12:";
|
case VK_SECREL_LO12: return ":secrel_lo12:";
|
||||||
case VK_SECREL_HI12: return ":secrel_hi12:";
|
case VK_SECREL_HI12: return ":secrel_hi12:";
|
||||||
|
case VK_GOT_AUTH: return ":got_auth:";
|
||||||
|
case VK_GOT_AUTH_PAGE: return ":got_auth:";
|
||||||
|
case VK_GOT_AUTH_LO12: return ":got_auth_lo12:";
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Invalid ELF symbol kind");
|
llvm_unreachable("Invalid ELF symbol kind");
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
void AArch64MCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
|
void AArch64MCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
|
||||||
|
@ -24,6 +24,7 @@ namespace llvm {
|
|||||||
class AArch64MCExpr : public MCTargetExpr {
|
class AArch64MCExpr : public MCTargetExpr {
|
||||||
public:
|
public:
|
||||||
enum VariantKind {
|
enum VariantKind {
|
||||||
|
// clang-format off
|
||||||
// Symbol locations specifying (roughly speaking) what calculation should be
|
// Symbol locations specifying (roughly speaking) what calculation should be
|
||||||
// performed to construct the final address for the relocated
|
// performed to construct the final address for the relocated
|
||||||
// symbol. E.g. direct, via the GOT, ...
|
// symbol. E.g. direct, via the GOT, ...
|
||||||
@ -38,6 +39,7 @@ public:
|
|||||||
VK_SECREL = 0x009,
|
VK_SECREL = 0x009,
|
||||||
VK_AUTH = 0x00a,
|
VK_AUTH = 0x00a,
|
||||||
VK_AUTHADDR = 0x00b,
|
VK_AUTHADDR = 0x00b,
|
||||||
|
VK_GOT_AUTH = 0x00c,
|
||||||
VK_SymLocBits = 0x00f,
|
VK_SymLocBits = 0x00f,
|
||||||
|
|
||||||
// Variants specifying which part of the final address calculation is
|
// Variants specifying which part of the final address calculation is
|
||||||
@ -88,6 +90,8 @@ public:
|
|||||||
VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC,
|
VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC,
|
||||||
VK_GOT_PAGE = VK_GOT | VK_PAGE,
|
VK_GOT_PAGE = VK_GOT | VK_PAGE,
|
||||||
VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC,
|
VK_GOT_PAGE_LO15 = VK_GOT | VK_LO15 | VK_NC,
|
||||||
|
VK_GOT_AUTH_LO12 = VK_GOT_AUTH | VK_PAGEOFF | VK_NC,
|
||||||
|
VK_GOT_AUTH_PAGE = VK_GOT_AUTH | VK_PAGE,
|
||||||
VK_DTPREL_G2 = VK_DTPREL | VK_G2,
|
VK_DTPREL_G2 = VK_DTPREL | VK_G2,
|
||||||
VK_DTPREL_G1 = VK_DTPREL | VK_G1,
|
VK_DTPREL_G1 = VK_DTPREL | VK_G1,
|
||||||
VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC,
|
VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC,
|
||||||
@ -114,6 +118,7 @@ public:
|
|||||||
VK_SECREL_HI12 = VK_SECREL | VK_HI12,
|
VK_SECREL_HI12 = VK_SECREL | VK_HI12,
|
||||||
|
|
||||||
VK_INVALID = 0xfff
|
VK_INVALID = 0xfff
|
||||||
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
127
llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll
Normal file
127
llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=0 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac %s -o - | FileCheck %s --check-prefixes=CHECK,NOTRAP
|
||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=0 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK,TRAP
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=1 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac %s -o - | FileCheck %s --check-prefixes=CHECK,NOTRAP
|
||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=1 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK,TRAP
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=1 -global-isel-abort=1 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac %s -o - | FileCheck %s --check-prefixes=CHECK,NOTRAP
|
||||||
|
; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=1 -global-isel-abort=1 -verify-machineinstrs \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK,TRAP
|
||||||
|
|
||||||
|
;; Note: for FastISel, we fall back to SelectionDAG
|
||||||
|
|
||||||
|
@var = global i32 0
|
||||||
|
|
||||||
|
define i32 @get_globalvar() {
|
||||||
|
; CHECK-LABEL: get_globalvar:
|
||||||
|
; CHECK: adrp x17, :got_auth:var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var
|
||||||
|
; NOTRAP-NEXT: ldr x8, [x17]
|
||||||
|
; NOTRAP-NEXT: autda x8, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_0
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_0:
|
||||||
|
; TRAP-NEXT: mov x8, x16
|
||||||
|
; CHECK-NEXT: ldr w0, [x8]
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
%val = load i32, ptr @var
|
||||||
|
ret i32 %val
|
||||||
|
}
|
||||||
|
|
||||||
|
define ptr @get_globalvaraddr() {
|
||||||
|
; CHECK-LABEL: get_globalvaraddr:
|
||||||
|
; CHECK: adrp x17, :got_auth:var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var
|
||||||
|
; NOTRAP-NEXT: ldr x0, [x17]
|
||||||
|
; NOTRAP-NEXT: autda x0, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_1
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_1:
|
||||||
|
; TRAP-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
%val = load i32, ptr @var
|
||||||
|
ret ptr @var
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @foo()
|
||||||
|
|
||||||
|
define ptr @resign_globalfunc() {
|
||||||
|
; CHECK-LABEL: resign_globalfunc:
|
||||||
|
; CHECK: adrp x17, :got_auth:foo
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:foo
|
||||||
|
; CHECK-NEXT: ldr x16, [x17]
|
||||||
|
; CHECK-NEXT: autia x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpaci x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_2
|
||||||
|
; TRAP-NEXT: brk #0xc470
|
||||||
|
; TRAP-NEXT: .Lauth_success_2:
|
||||||
|
; CHECK-NEXT: mov x17, #42
|
||||||
|
; CHECK-NEXT: pacia x16, x17
|
||||||
|
; CHECK-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
ret ptr ptrauth (ptr @foo, i32 0, i64 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
define ptr @resign_globalvar() {
|
||||||
|
; CHECK-LABEL: resign_globalvar:
|
||||||
|
; CHECK: adrp x17, :got_auth:var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var
|
||||||
|
; CHECK-NEXT: ldr x16, [x17]
|
||||||
|
; CHECK-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_3
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_3:
|
||||||
|
; CHECK-NEXT: mov x17, #43
|
||||||
|
; CHECK-NEXT: pacdb x16, x17
|
||||||
|
; CHECK-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
ret ptr ptrauth (ptr @var, i32 3, i64 43)
|
||||||
|
}
|
||||||
|
|
||||||
|
define ptr @resign_globalvar_offset() {
|
||||||
|
; CHECK-LABEL: resign_globalvar_offset:
|
||||||
|
; CHECK: adrp x17, :got_auth:var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var
|
||||||
|
; CHECK-NEXT: ldr x16, [x17]
|
||||||
|
; CHECK-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_4
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_4:
|
||||||
|
; CHECK-NEXT: add x16, x16, #16
|
||||||
|
; CHECK-NEXT: mov x17, #44
|
||||||
|
; CHECK-NEXT: pacda x16, x17
|
||||||
|
; CHECK-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
ret ptr ptrauth (ptr getelementptr (i8, ptr @var, i64 16), i32 2, i64 44)
|
||||||
|
}
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
46
llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll
Normal file
46
llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=0 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth -mattr=+fpac | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=0 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=1 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth -mattr=+fpac | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=1 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=arm64 -global-isel=1 -global-isel-abort=1 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth -mattr=+fpac | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=arm64 -global-isel=1 -global-isel-abort=1 -relocation-model=pic -o - %s \
|
||||||
|
; RUN: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
;; Note: for FastISel, we fall back to SelectionDAG
|
||||||
|
|
||||||
|
@var8 = external global i8, align 1
|
||||||
|
|
||||||
|
define i8 @test_i8(i8 %new) {
|
||||||
|
%val = load i8, ptr @var8, align 1
|
||||||
|
store i8 %new, ptr @var8
|
||||||
|
ret i8 %val
|
||||||
|
|
||||||
|
; CHECK-LABEL: test_i8:
|
||||||
|
; CHECK: adrp x17, :got_auth:var8
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var8
|
||||||
|
; NOTRAP-NEXT: ldr x9, [x17]
|
||||||
|
; NOTRAP-NEXT: autda x9, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_0
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_0:
|
||||||
|
; TRAP-NEXT: mov x9, x16
|
||||||
|
; CHECK-NEXT: ldrb w8, [x9]
|
||||||
|
; CHECK-NEXT: strb w0, [x9]
|
||||||
|
; CHECK-NEXT: mov x0, x8
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
}
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
@ -0,0 +1,42 @@
|
|||||||
|
; RUN: llc -mtriple aarch64-linux-pauthtest -mattr +pauth -filetype=asm %s -o - | \
|
||||||
|
; RUN: FileCheck %s --check-prefix=ASM
|
||||||
|
; RUN: llc -mtriple aarch64-linux-pauthtest -mattr +pauth -filetype=obj %s -o - | \
|
||||||
|
; RUN: llvm-readelf -s - | FileCheck %s --check-prefix=OBJ
|
||||||
|
|
||||||
|
; ASM: .type foo,@function
|
||||||
|
; ASM-LABEL: foo:
|
||||||
|
; ASM: adrp x17, :got_auth:bar
|
||||||
|
; ASM-NEXT: add x17, x17, :got_auth_lo12:bar
|
||||||
|
; ASM-NEXT: ldr x16, [x17]
|
||||||
|
; ASM-NEXT: autia x16, x17
|
||||||
|
; ASM-NEXT: mov x17, x16
|
||||||
|
; ASM-NEXT: xpaci x17
|
||||||
|
; ASM-NEXT: cmp x16, x17
|
||||||
|
; ASM-NEXT: b.eq .Lauth_success_0
|
||||||
|
; ASM-NEXT: brk #0xc470
|
||||||
|
; ASM-NEXT: .Lauth_success_0:
|
||||||
|
; ASM-NEXT: paciza x16
|
||||||
|
; ASM-NEXT: adrp x8, .Lfptr
|
||||||
|
; ASM-NEXT: str x16, [x8, :lo12:.Lfptr]
|
||||||
|
; ASM-NEXT: ret
|
||||||
|
; ASM: .type .Lfptr,@object
|
||||||
|
; ASM-NEXT: .local .Lfptr
|
||||||
|
; ASM-NEXT: .comm .Lfptr,8,8
|
||||||
|
; ASM: .type bar,@function
|
||||||
|
|
||||||
|
; OBJ: Symbol table '.symtab' contains [[#]] entries:
|
||||||
|
; OBJ-NEXT: Num: Value Size Type Bind Vis Ndx Name
|
||||||
|
; OBJ: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bar
|
||||||
|
|
||||||
|
@fptr = private global ptr null
|
||||||
|
|
||||||
|
define void @foo() {
|
||||||
|
store ptr ptrauth (ptr @bar, i32 0), ptr @fptr
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i32 @bar()
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
74
llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
Normal file
74
llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=0 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=0 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=1 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=1 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1 -global-isel-abort=1 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1 -global-isel-abort=1 -relocation-model=pic \
|
||||||
|
; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
;; Note: for FastISel, we fall back to SelectionDAG
|
||||||
|
|
||||||
|
declare extern_weak dso_local i32 @var()
|
||||||
|
|
||||||
|
define ptr @foo() {
|
||||||
|
; The usual ADRP/ADD pair can't be used for a weak reference because it must
|
||||||
|
; evaluate to 0 if the symbol is undefined. We use a GOT entry for PIC
|
||||||
|
; otherwise a litpool entry.
|
||||||
|
ret ptr @var
|
||||||
|
|
||||||
|
; CHECK-LABEL: foo:
|
||||||
|
; CHECK: adrp x17, :got_auth:var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:var
|
||||||
|
; NOTRAP-NEXT: ldr x0, [x17]
|
||||||
|
; NOTRAP-NEXT: cbz x0, .Lundef_weak0
|
||||||
|
; NOTRAP-NEXT: autia x0, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: cbz x16, .Lundef_weak0
|
||||||
|
; TRAP-NEXT: autia x16, x17
|
||||||
|
; CHECK-NEXT: .Lundef_weak0:
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpaci x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_0
|
||||||
|
; TRAP-NEXT: brk #0xc470
|
||||||
|
; TRAP-NEXT: .Lauth_success_0:
|
||||||
|
; TRAP-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
}
|
||||||
|
|
||||||
|
@arr_var = extern_weak global [10 x i32]
|
||||||
|
|
||||||
|
define ptr @bar() {
|
||||||
|
%addr = getelementptr [10 x i32], ptr @arr_var, i32 0, i32 5
|
||||||
|
ret ptr %addr
|
||||||
|
|
||||||
|
; CHECK-LABEL: bar:
|
||||||
|
; CHECK: adrp x17, :got_auth:arr_var
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:arr_var
|
||||||
|
; NOTRAP-NEXT: ldr x8, [x17]
|
||||||
|
; NOTRAP-NEXT: cbz x8, .Lundef_weak1
|
||||||
|
; NOTRAP-NEXT: autda x8, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: cbz x16, .Lundef_weak1
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; CHECK-NEXT: .Lundef_weak1:
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_1
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_1:
|
||||||
|
; TRAP-NEXT: mov x8, x16
|
||||||
|
; CHECK-NEXT: add x0, x8, #20
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
}
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
88
llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll
Normal file
88
llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=0 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=0 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=1 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=1 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=1 -global-isel-abort=1 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -mattr=+fpac -o - %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=1 -global-isel-abort=1 \
|
||||||
|
; RUN: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
|
||||||
|
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=0 \
|
||||||
|
; RUN: -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=0 -fast-isel=1 \
|
||||||
|
; RUN: -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
|
||||||
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -asm-verbose=false -global-isel=1 -global-isel-abort=1 \
|
||||||
|
; RUN: -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
|
||||||
|
|
||||||
|
;; Note: for FastISel, we fall back to SelectionDAG
|
||||||
|
|
||||||
|
declare void @consume(i32)
|
||||||
|
declare void @func()
|
||||||
|
|
||||||
|
define void @aliasee_func() {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
@alias_func = alias void (), ptr @aliasee_func
|
||||||
|
|
||||||
|
@aliasee_global = global i32 42
|
||||||
|
@alias_global = alias i32, ptr @aliasee_global
|
||||||
|
|
||||||
|
define void @foo() nounwind {
|
||||||
|
; CHECK-LABEL: foo:
|
||||||
|
entry:
|
||||||
|
call void @consume(i32 ptrtoint (ptr @func to i32))
|
||||||
|
; CHECK: adrp x17, :got_auth:func
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:func
|
||||||
|
; NOTRAP-NEXT: ldr x[[TMP0:[0-9]+]], [x17]
|
||||||
|
; NOTRAP-NEXT: autia x[[TMP0]], x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autia x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpaci x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_0
|
||||||
|
; TRAP-NEXT: brk #0xc470
|
||||||
|
; TRAP-NEXT: .Lauth_success_0:
|
||||||
|
; TRAP-NEXT: mov x[[TMP0:[0-9]+]], x16
|
||||||
|
|
||||||
|
call void @consume(i32 ptrtoint (ptr @alias_func to i32))
|
||||||
|
; CHECK: adrp x17, :got_auth:alias_func
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:alias_func
|
||||||
|
; NOTRAP-NEXT: ldr x[[TMP1:[0-9]+]], [x17]
|
||||||
|
; NOTRAP-NEXT: autia x[[TMP1]], x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autia x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpaci x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_1
|
||||||
|
; TRAP-NEXT: brk #0xc470
|
||||||
|
; TRAP-NEXT: .Lauth_success_1:
|
||||||
|
; TRAP-NEXT: mov x[[TMP1:[0-9]+]], x16
|
||||||
|
|
||||||
|
call void @consume(i32 ptrtoint (ptr @alias_global to i32))
|
||||||
|
; CHECK: adrp x17, :got_auth:alias_global
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:alias_global
|
||||||
|
; NOTRAP-NEXT: ldr x[[TMP2:[0-9]+]], [x17]
|
||||||
|
; NOTRAP-NEXT: autda x[[TMP2]], x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_2
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_2:
|
||||||
|
; TRAP-NEXT: mov x[[TMP2:[0-9]+]], x16
|
||||||
|
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
117
llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll
Normal file
117
llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
; RUN: llc -global-isel=0 -fast-isel=0 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac | FileCheck %s --check-prefixes=CHECK,DAGISEL,NOTRAP,DAGISEL-NOTRAP
|
||||||
|
; RUN: llc -global-isel=0 -fast-isel=0 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL,TRAP,DAGISEL-TRAP
|
||||||
|
|
||||||
|
; RUN: llc -global-isel=0 -fast-isel=1 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac | FileCheck %s --check-prefixes=CHECK,DAGISEL,NOTRAP,DAGISEL-NOTRAP
|
||||||
|
; RUN: llc -global-isel=0 -fast-isel=1 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL,TRAP,DAGISEL-TRAP
|
||||||
|
|
||||||
|
; RUN: llc -global-isel=1 -global-isel-abort=1 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth -mattr=+fpac | FileCheck %s --check-prefixes=CHECK,GISEL,NOTRAP,GISEL-NOTRAP
|
||||||
|
; RUN: llc -global-isel=1 -global-isel-abort=1 -O0 --relocation-model=pic < %s \
|
||||||
|
; RUN: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,GISEL,TRAP,GISEL-TRAP
|
||||||
|
|
||||||
|
;; Note: for FastISel, we fall back to SelectionDAG
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
|
||||||
|
target triple = "aarch64-unknown-linux-android"
|
||||||
|
|
||||||
|
@global = external global i32
|
||||||
|
declare void @func()
|
||||||
|
|
||||||
|
define ptr @global_addr() #0 {
|
||||||
|
; CHECK-LABEL: global_addr:
|
||||||
|
; CHECK: adrp x17, :got_auth:global
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:global
|
||||||
|
; NOTRAP-NEXT: ldr x0, [x17]
|
||||||
|
; NOTRAP-NEXT: autda x0, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_0
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_0:
|
||||||
|
; TRAP-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
ret ptr @global
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @global_load() #0 {
|
||||||
|
; CHECK-LABEL: global_load:
|
||||||
|
; CHECK: adrp x17, :got_auth:global
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:global
|
||||||
|
; NOTRAP-NEXT: ldr x8, [x17]
|
||||||
|
; NOTRAP-NEXT: autda x8, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_1
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_1:
|
||||||
|
; TRAP-NEXT: mov x8, x16
|
||||||
|
; CHECK-NEXT: ldr w0, [x8]
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
%load = load i32, ptr @global
|
||||||
|
ret i32 %load
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @global_store() #0 {
|
||||||
|
; CHECK-LABEL: global_store:
|
||||||
|
; CHECK: adrp x17, :got_auth:global
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:global
|
||||||
|
; GISEL-NOTRAP-NEXT: ldr x8, [x17]
|
||||||
|
; GISEL-NOTRAP-NEXT: autda x8, x17
|
||||||
|
; GISEL-TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; GISEL-TRAP-NEXT: autda x16, x17
|
||||||
|
; DAGISEL-NOTRAP-NEXT: ldr x9, [x17]
|
||||||
|
; DAGISEL-NOTRAP-NEXT: autda x9, x17
|
||||||
|
; DAGISEL-TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; DAGISEL-TRAP-NEXT: autda x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpacd x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_2
|
||||||
|
; TRAP-NEXT: brk #0xc472
|
||||||
|
; TRAP-NEXT: .Lauth_success_2:
|
||||||
|
; GISEL-TRAP-NEXT: mov x8, x16
|
||||||
|
; DAGISEL-TRAP-NEXT: mov x9, x16
|
||||||
|
; GISEL-NEXT: str wzr, [x8]
|
||||||
|
; DAGISEL-NEXT: mov w8, wzr
|
||||||
|
; DAGISEL-NEXT: str w8, [x9]
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
store i32 0, ptr @global
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define ptr @func_addr() #0 {
|
||||||
|
; CHECK-LABEL: func_addr:
|
||||||
|
; CHECK: adrp x17, :got_auth:func
|
||||||
|
; CHECK-NEXT: add x17, x17, :got_auth_lo12:func
|
||||||
|
; NOTRAP-NEXT: ldr x0, [x17]
|
||||||
|
; NOTRAP-NEXT: autia x0, x17
|
||||||
|
; TRAP-NEXT: ldr x16, [x17]
|
||||||
|
; TRAP-NEXT: autia x16, x17
|
||||||
|
; TRAP-NEXT: mov x17, x16
|
||||||
|
; TRAP-NEXT: xpaci x17
|
||||||
|
; TRAP-NEXT: cmp x16, x17
|
||||||
|
; TRAP-NEXT: b.eq .Lauth_success_3
|
||||||
|
; TRAP-NEXT: brk #0xc470
|
||||||
|
; TRAP-NEXT: .Lauth_success_3:
|
||||||
|
; TRAP-NEXT: mov x0, x16
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
|
||||||
|
ret ptr @func
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { "target-features"="+tagged-globals" }
|
||||||
|
|
||||||
|
!llvm.module.flags = !{!0}
|
||||||
|
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
|
12
llvm/test/MC/AArch64/adrp-auth-relocation.s
Normal file
12
llvm/test/MC/AArch64/adrp-auth-relocation.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o - %s | llvm-readobj -r - | FileCheck %s
|
||||||
|
// RUN: not llvm-mc -triple=aarch64-linux-gnu_ilp32 -filetype=obj \
|
||||||
|
// RUN: -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-ILP32 %s
|
||||||
|
|
||||||
|
.text
|
||||||
|
adrp x0, :got_auth:sym
|
||||||
|
|
||||||
|
.global sym
|
||||||
|
sym:
|
||||||
|
|
||||||
|
// CHECK: R_AARCH64_AUTH_ADR_GOT_PAGE sym
|
||||||
|
// CHECK-ILP32: error: ILP32 ADRP AUTH relocation not supported (LP64 eqv: AUTH_ADR_GOT_PAGE)
|
@ -81,13 +81,17 @@
|
|||||||
// CHECK: adrp x15, :got:sym
|
// CHECK: adrp x15, :got:sym
|
||||||
// CHECK-OBJ-LP64: 58 R_AARCH64_ADR_GOT_PAGE sym
|
// CHECK-OBJ-LP64: 58 R_AARCH64_ADR_GOT_PAGE sym
|
||||||
|
|
||||||
|
adrp x15, :got_auth:sym
|
||||||
|
// CHECK: adrp x15, :got_auth:sym
|
||||||
|
// CHECK-OBJ-LP64: 5c R_AARCH64_AUTH_ADR_GOT_PAGE sym
|
||||||
|
|
||||||
adrp x29, :gottprel:sym
|
adrp x29, :gottprel:sym
|
||||||
// CHECK: adrp x29, :gottprel:sym
|
// CHECK: adrp x29, :gottprel:sym
|
||||||
// CHECK-OBJ-LP64: 5c R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
|
// CHECK-OBJ-LP64: 60 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
|
||||||
|
|
||||||
adrp x2, :tlsdesc:sym
|
adrp x2, :tlsdesc:sym
|
||||||
// CHECK: adrp x2, :tlsdesc:sym
|
// CHECK: adrp x2, :tlsdesc:sym
|
||||||
// CHECK-OBJ-LP64: 60 R_AARCH64_TLSDESC_ADR_PAGE21 sym
|
// CHECK-OBJ-LP64: 64 R_AARCH64_TLSDESC_ADR_PAGE21 sym
|
||||||
|
|
||||||
// LLVM is not competent enough to do this relocation because the
|
// LLVM is not competent enough to do this relocation because the
|
||||||
// page boundary could occur anywhere after linking. A relocation
|
// page boundary could occur anywhere after linking. A relocation
|
||||||
@ -96,7 +100,7 @@
|
|||||||
.global trickQuestion
|
.global trickQuestion
|
||||||
trickQuestion:
|
trickQuestion:
|
||||||
// CHECK: adrp x3, trickQuestion
|
// CHECK: adrp x3, trickQuestion
|
||||||
// CHECK-OBJ-LP64: 64 R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
|
// CHECK-OBJ-LP64: 68 R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
|
||||||
|
|
||||||
ldrb w2, [x3, :lo12:sym]
|
ldrb w2, [x3, :lo12:sym]
|
||||||
ldrsb w5, [x7, #:lo12:sym]
|
ldrsb w5, [x7, #:lo12:sym]
|
||||||
@ -245,6 +249,16 @@ trickQuestion:
|
|||||||
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym
|
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym
|
||||||
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym+0x7
|
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym+0x7
|
||||||
|
|
||||||
|
ldr x24, [x23, #:got_auth_lo12:sym]
|
||||||
|
ldr d22, [x21, :got_auth_lo12:sym]
|
||||||
|
ldr x24, [x23, :got_auth_lo12:sym+7]
|
||||||
|
// CHECK: ldr x24, [x23, :got_auth_lo12:sym]
|
||||||
|
// CHECK: ldr d22, [x21, :got_auth_lo12:sym]
|
||||||
|
// CHECK: ldr x24, [x23, :got_auth_lo12:sym+7]
|
||||||
|
// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym
|
||||||
|
// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym
|
||||||
|
// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym+0x7
|
||||||
|
|
||||||
ldr x24, [x23, #:gotpage_lo15:sym]
|
ldr x24, [x23, #:gotpage_lo15:sym]
|
||||||
ldr d22, [x21, :gotpage_lo15:sym]
|
ldr d22, [x21, :gotpage_lo15:sym]
|
||||||
ldr d22, [x23, :gotpage_lo15:sym+7]
|
ldr d22, [x23, :gotpage_lo15:sym+7]
|
||||||
|
@ -69,6 +69,12 @@ ldr x10, [x0, #:gottprel_lo12:var]
|
|||||||
ldr x24, [x23, #:got_lo12:sym]
|
ldr x24, [x23, #:got_lo12:sym]
|
||||||
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: LD64_GOT_LO12_NC)
|
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: LD64_GOT_LO12_NC)
|
||||||
|
|
||||||
|
ldr x24, [x23, #:got_auth_lo12:sym]
|
||||||
|
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: AUTH_GOT_LO12_NC)
|
||||||
|
|
||||||
|
add x24, x23, #:got_auth_lo12:sym
|
||||||
|
// ERROR: [[#@LINE-1]]:1: error: ILP32 ADD AUTH relocation not supported (LP64 eqv: AUTH_GOT_ADD_LO12_NC)
|
||||||
|
|
||||||
ldr x24, [x23, :gottprel_lo12:sym]
|
ldr x24, [x23, :gottprel_lo12:sym]
|
||||||
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC)
|
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user