From 319c99c79a9792eed83722f21c0754b1ebffcea2 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Fri, 1 Nov 2024 12:21:10 +0300 Subject: [PATCH 01/10] 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 Signed-off-by:baojingjing --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 77 ++++++++++- llvm/lib/Target/AArch64/AArch64FastISel.cpp | 4 +- .../Target/AArch64/AArch64ISelLowering.cpp | 5 + llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 +- .../lib/Target/AArch64/AArch64MCInstLower.cpp | 10 +- .../AArch64/AArch64MachineFunctionInfo.cpp | 13 ++ .../AArch64/AArch64MachineFunctionInfo.h | 7 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 6 + .../GISel/AArch64InstructionSelector.cpp | 4 +- .../MCTargetDesc/AArch64ELFObjectWriter.cpp | 34 ++++- .../AArch64/MCTargetDesc/AArch64MCExpr.cpp | 3 + .../AArch64/MCTargetDesc/AArch64MCExpr.h | 3 + .../test/CodeGen/AArch64/ptrauth-basic-pic.ll | 127 ++++++++++++++++++ .../AArch64/ptrauth-elf-globals-pic.ll | 46 +++++++ .../ptrauth-elf-got-function-symbols.ll | 42 ++++++ .../CodeGen/AArch64/ptrauth-extern-weak.ll | 74 ++++++++++ .../test/CodeGen/AArch64/ptrauth-got-abuse.ll | 88 ++++++++++++ .../AArch64/ptrauth-tagged-globals-pic.ll | 117 ++++++++++++++++ llvm/test/MC/AArch64/adrp-auth-relocation.s | 12 ++ llvm/test/MC/AArch64/arm64-elf-relocs.s | 20 ++- llvm/test/MC/AArch64/ilp32-diagnostics.s | 6 + 21 files changed, 688 insertions(+), 16 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll create mode 100644 llvm/test/MC/AArch64/adrp-auth-relocation.s diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 87f3982208fb..19cf48adb4b3 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -158,6 +158,10 @@ public: // We didn't modify anything. return false; } + // 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); private: void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O); @@ -579,7 +583,23 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - + if (TT.isOSBinFormatELF()) { + // 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( + M.getModuleFlag("ptrauth-elf-got")); + if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1) + for (const GlobalValue &GV : M.global_values()) + if (!GV.use_empty() && isa(GV) && + !GV.getName().startswith("llvm.")) + OutStreamer->emitSymbolAttribute(getSymbol(&GV), + MCSA_ELF_TypeFunction); + } // Emit stack and fault map information. emitStackMaps(SM); FM.serializeToFaultMapSection(); @@ -1168,6 +1188,58 @@ void AArch64AsmPrinter::emitFMov0(const MachineInstr &MI) { } } +void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) { + Register DstReg = MI.getOperand(0).getReg(); + Register AuthResultReg = DstReg; + 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(*OutStreamer, + 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(*OutStreamer, MCInstBuilder(AuthOpcode) + .addReg(AuthResultReg) + .addReg(AuthResultReg) + .addReg(AArch64::X17)); + + if (GAMO.getGlobal()->hasExternalWeakLinkage()) + OutStreamer->emitLabel(UndefWeakSym); +} + // Simple pseudo-instructions have their lowering (with expansion to real // instructions) auto-generated. #include "AArch64GenMCPseudoLowering.inc" @@ -1297,6 +1369,9 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { OutStreamer->emitCFIMTETaggedFrame(); return; } + case AArch64::LOADgotAUTH: + LowerLOADgotAUTH(*MI); + return; // Tail calls use pseudo instructions so they have the proper code-gen // attributes (isCall, isReturn, etc.). We lower them to the real diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 9b4ddd03b9a0..b738ddbfb79a 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -448,7 +448,9 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) { // movz/movk sequences, which FastISel doesn't handle yet. if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO()) return 0; - + if (FuncInfo.MF->getInfo()->hasELFSignedGOT()) + return 0; + unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM); EVT DestEVT = TLI.getValueType(DL, GV->getType(), true); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index fa0dd4421823..4c4c3532d885 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7188,6 +7188,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG, SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags); // FIXME: Once remat is capable of dealing with instructions with register // operands, expand this into two nodes instead of using a wrapper node. + if (DAG.getMachineFunction() + .getInfo() + ->hasELFSignedGOT()) + return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr), + 0); return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr); } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 3c2a1f24d679..a7fe45472a42 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -1387,7 +1387,11 @@ let Predicates = [HasPAuth] in { defm LDRAA : AuthLoad<0, "ldraa", simm10Scaled>; defm LDRAB : AuthLoad<1, "ldrab", simm10Scaled>; - + def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>, + Sched<[WriteI, ReadI]> { + let Defs = [X16,X17,NZCV]; + let Size = 44; + } } // v8.3a floating point conversion for javascript diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp index 450c270fcc9b..f74c7116b7fa 100644 --- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp +++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "AArch64MCInstLower.h" +#include "AArch64MachineFunctionInfo.h" #include "MCTargetDesc/AArch64MCExpr.h" #include "Utils/AArch64BaseInfo.h" #include "llvm/CodeGen/AsmPrinter.h" @@ -115,9 +116,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO, MCSymbol *Sym) const { uint32_t RefFlags = 0; - if (MO.getTargetFlags() & AArch64II::MO_GOT) - RefFlags |= AArch64MCExpr::VK_GOT; - else if (MO.getTargetFlags() & AArch64II::MO_TLS) { + if (MO.getTargetFlags() & AArch64II::MO_GOT) { + const MachineFunction *MF = MO.getParent()->getParent()->getParent(); + RefFlags |= (MF->getInfo()->hasELFSignedGOT() + ? AArch64MCExpr::VK_GOT_AUTH + : AArch64MCExpr::VK_GOT); + } else if (MO.getTargetFlags() & AArch64II::MO_TLS) { TLSModel::Model Model; if (MO.isGlobal()) { const GlobalValue *GV = MO.getGlobal(); diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp index a2ab2b855d80..45a221de7d4e 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp @@ -80,6 +80,18 @@ static bool ShouldSignWithBKey(const Function &F) { return Key.equals_insensitive("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( + M->getModuleFlag("ptrauth-elf-got")); + if (Flag && Flag->getZExtValue() == 1) + return true; + return false; +} + AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF_) : MF(&MF_) { // If we already know that the function doesn't have a redzone, set // HasRedZone here. @@ -89,6 +101,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF_) : MF(&MF_) { const Function &F = MF->getFunction(); std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); SignWithBKey = ShouldSignWithBKey(F); + HasELFSignedGOT = hasELFSignedGOTHelper(F, MF->getSubtarget()); // TODO: skip functions that have no instrumented allocas for optimization IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag); diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index 707c542685db..dfaaa3eeb03c 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -193,6 +193,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { #ifdef ARK_GC_SUPPORT SmallVector ArkArgInfos; // OHOS_LOCAL #endif + /// 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; public: explicit AArch64FunctionInfo(MachineFunction &MF); @@ -453,7 +457,8 @@ public: } #endif - // OHOS_LOCAL end + // OHOS_LOCAL end + bool hasELFSignedGOT() const { return HasELFSignedGOT; } private: // Hold the lists of LOHs. MILOHContainer LOHContainerSet; diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index ade23f643538..59a143d02120 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -805,6 +805,7 @@ public: if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF || ELFRefKind == AArch64MCExpr::VK_LO12 || ELFRefKind == AArch64MCExpr::VK_GOT_LO12 || + ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 || @@ -918,6 +919,7 @@ public: || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) || ELFRefKind == AArch64MCExpr::VK_LO12 + || ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC @@ -2860,6 +2862,7 @@ AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) { DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE && ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC && ELFRefKind != AArch64MCExpr::VK_GOT_PAGE && + ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE && ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 && ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE && ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) { @@ -3832,6 +3835,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) { .Case("got", AArch64MCExpr::VK_GOT_PAGE) .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15) .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_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC) .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1) @@ -5085,6 +5090,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc, // Only allow these with ADDXri/ADDWri if ((ELFRefKind == AArch64MCExpr::VK_LO12 || + ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC || diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index 6d29504c7ce3..fc6b0f1415e5 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -2747,7 +2747,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) { } if (OpFlags & AArch64II::MO_GOT) { - I.setDesc(TII.get(AArch64::LOADgot)); + I.setDesc(TII.get(MF.getInfo()->hasELFSignedGOT() + ? AArch64::LOADgotAUTH + : AArch64::LOADgot)); I.getOperand(1).setTargetFlags(OpFlags); } else if (TM.getCodeModel() == CodeModel::Large) { // Materialize the global using movz/movk instructions. diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp index 2f9c17245b5f..5bc2c46ff056 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -163,6 +163,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, } if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) 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) return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21); if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) @@ -222,6 +231,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, return R_CLS(TLSLE_ADD_TPREL_LO12); if (RefKind == AArch64MCExpr::VK_TLSDESC_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) return R_CLS(ADD_ABS_LO12_NC); @@ -321,17 +339,23 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, case AArch64::fixup_aarch64_ldst_imm12_scale8: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 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::getAddressFrag(RefKind); + bool IsAuth = (SymLoc == AArch64MCExpr::VK_GOT_AUTH); if (!IsILP32) { if (AddressLoc == AArch64MCExpr::VK_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); } else { - Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " - "relocation not supported (LP64 eqv: " - "LD64_GOT_LO12_NC)"); + Ctx.reportError(Fixup.getLoc(), + Twine("ILP32 64-bit load/store " + "relocation not supported (LP64 eqv: ") + + (IsAuth ? "AUTH_GOT_LO12_NC" : "LD64_GOT_LO12_NC") + + Twine(')')); return ELF::R_AARCH64_NONE; } } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp index cb39c2a11487..91a11d926c37 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp @@ -82,6 +82,9 @@ StringRef AArch64MCExpr::getVariantKindName() const { case VK_TLSDESC_PAGE: return ":tlsdesc:"; case VK_SECREL_LO12: return ":secrel_lo12:"; 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: llvm_unreachable("Invalid ELF symbol kind"); } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h index d3e834a140b2..57b85fbb8dd3 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h @@ -34,6 +34,7 @@ public: VK_TPREL = 0x007, VK_TLSDESC = 0x008, VK_SECREL = 0x009, + VK_GOT_AUTH = 0x00c, VK_SymLocBits = 0x00f, // Variants specifying which part of the final address calculation is @@ -84,6 +85,8 @@ public: VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC, VK_GOT_PAGE = VK_GOT | VK_PAGE, 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_G1 = VK_DTPREL | VK_G1, VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC, diff --git a/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll new file mode 100644 index 000000000000..517a0a86ef14 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll @@ -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} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll new file mode 100644 index 000000000000..23357cd80257 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll @@ -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} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll new file mode 100644 index 000000000000..e75acceaa0d1 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll @@ -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} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll new file mode 100644 index 000000000000..5d0a3f556c4c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll @@ -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} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll b/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll new file mode 100644 index 000000000000..3c4747c32185 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll @@ -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} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll new file mode 100644 index 000000000000..ee34b439daec --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll @@ -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} diff --git a/llvm/test/MC/AArch64/adrp-auth-relocation.s b/llvm/test/MC/AArch64/adrp-auth-relocation.s new file mode 100644 index 000000000000..57021c71632f --- /dev/null +++ b/llvm/test/MC/AArch64/adrp-auth-relocation.s @@ -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) diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s index e958f300b47a..88681198f9f3 100644 --- a/llvm/test/MC/AArch64/arm64-elf-relocs.s +++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s @@ -81,13 +81,17 @@ // CHECK: adrp x15, :got: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 // 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 // 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 // page boundary could occur anywhere after linking. A relocation @@ -96,7 +100,7 @@ .global trickQuestion 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] 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+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 d22, [x21, :gotpage_lo15:sym] ldr d22, [x23, :gotpage_lo15:sym+7] diff --git a/llvm/test/MC/AArch64/ilp32-diagnostics.s b/llvm/test/MC/AArch64/ilp32-diagnostics.s index 65c9e4ea5a1c..5e3394bc79ed 100644 --- a/llvm/test/MC/AArch64/ilp32-diagnostics.s +++ b/llvm/test/MC/AArch64/ilp32-diagnostics.s @@ -79,6 +79,12 @@ // CHECK-ERROR: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: LD64_GOT_LO12_NC) // CHECK-ERROR: ^ + 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] // CHECK-ERROR: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC) // CHECK-ERROR: ^ -- Gitee From b3c6b3eb417c0213cfef6098221ca7c65f85f3ed Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 17 Dec 2024 15:23:01 +0800 Subject: [PATCH 02/10] Support signed GOT (#113815) Depends on #113811 Support `R_AARCH64_AUTH_ADR_GOT_PAGE`, `R_AARCH64_AUTH_GOT_LO12_NC` and `R_AARCH64_AUTH_GOT_ADD_LO12_NC` GOT-generating relocations. For preemptible symbols, dynamic relocation `R_AARCH64_AUTH_GLOB_DAT` is emitted. Otherwise, we unconditionally emit `R_AARCH64_AUTH_RELATIVE` dynamic relocation since pointers in signed GOT needs to be signed during dynamic link time. Signed-off-by:baojingjing --- lld/ELF/Arch/AArch64.cpp | 9 ++ lld/ELF/InputSection.cpp | 2 + lld/ELF/Relocations.cpp | 45 ++++++++-- lld/ELF/Relocations.h | 2 + lld/ELF/Symbols.h | 5 +- lld/ELF/SyntheticSections.cpp | 19 +++++ lld/ELF/SyntheticSections.h | 6 ++ lld/test/ELF/aarch64-got-relocations-pauth.s | 90 ++++++++++++++++++++ 8 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 lld/test/ELF/aarch64-got-relocations-pauth.s diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index b23684819a23..b78a9e71e8e8 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -145,11 +145,16 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, case R_AARCH64_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: return R_GOT; + case R_AARCH64_AUTH_LD64_GOT_LO12_NC: + case R_AARCH64_AUTH_GOT_ADD_LO12_NC: + return RE_AARCH64_AUTH_GOT; case R_AARCH64_LD64_GOTPAGE_LO15: return R_AARCH64_GOT_PAGE; case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: return R_AARCH64_GOT_PAGE_PC; + case R_AARCH64_AUTH_ADR_GOT_PAGE: + return RE_AARCH64_AUTH_GOT_PAGE_PC; case R_AARCH64_NONE: return R_NONE; default: @@ -197,6 +202,7 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const { case R_AARCH64_TLSDESC: return read64(buf + 8); case R_AARCH64_NONE: + case R_AARCH64_AUTH_GLOB_DAT: return 0; case R_AARCH64_PREL32: return SignExtend64<32>(read32(buf)); @@ -357,9 +363,11 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, write64(loc, val); break; case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_AUTH_GOT_ADD_LO12_NC: or32AArch64Imm(loc, val); break; case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_AUTH_ADR_GOT_PAGE: case R_AARCH64_ADR_PREL_PG_HI21: case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: case R_AARCH64_TLSDESC_ADR_PAGE21: @@ -408,6 +416,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, break; case R_AARCH64_LDST64_ABS_LO12_NC: case R_AARCH64_LD64_GOT_LO12_NC: + case R_AARCH64_AUTH_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: case R_AARCH64_TLSDESC_LD64_LO12: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 1420d8ce4e58..8b470855ff22 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -629,6 +629,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, case R_ARM_SBREL: return sym.getVA(a) - getARMStaticBase(sym); case R_GOT: + case RE_AARCH64_AUTH_GOT: case R_RELAX_TLS_GD_TO_IE_ABS: return sym.getGotVA() + a; case R_LOONGARCH_GOT: @@ -656,6 +657,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, case R_RELAX_TLS_GD_TO_IE_GOT_OFF: return sym.getGotOffset() + a; case R_AARCH64_GOT_PAGE_PC: + case RE_AARCH64_AUTH_GOT_PAGE_PC: case R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC: return getAArch64Page(sym.getGotVA() + a) - getAArch64Page(p); case R_AARCH64_GOT_PAGE: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index a617d55bfe00..e6b37b03d57b 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -198,8 +198,9 @@ static bool needsPlt(RelExpr expr) { // returns false for TLS variables even though they need GOT, because // TLS variables uses GOT differently than the regular variables. static bool needsGot(RelExpr expr) { - return oneof( expr); } @@ -918,6 +919,25 @@ static void addGotEntry(Symbol &sym) { addRelativeReloc(*in.got, off, sym, 0, R_ABS, target->symbolicRel); } +static void addGotAuthEntry(Symbol &sym) { + in.got->addEntry(sym); + in.got->addAuthEntry(sym); + uint64_t off = sym.getGotOffset(); + + // If preemptible, emit a GLOB_DAT relocation. + if (sym.isPreemptible) { + mainPart->relaDyn->addReloc({R_AARCH64_AUTH_GLOB_DAT, in.got.get(), + off, DynamicReloc::AgainstSymbol, sym, 0, + R_ABS}); + return; + } + + // Signed GOT requires dynamic relocation. + in.got->getPartition().relaDyn->addReloc( + {R_AARCH64_AUTH_RELATIVE, in.got.get(), off, + DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS}); +} + static void addTpOffsetGotEntry(Symbol &sym) { in.got->addEntry(sym); uint64_t off = sym.getGotOffset(); @@ -965,9 +985,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type, // These expressions always compute a constant if (oneof( e)) return true; @@ -1445,6 +1465,8 @@ template void RelocationScanner::scanOne(RelTy *&i) { // Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which // case the `needsGot` flag shouldn't get set. sym.needsGot = true; + if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC) + sym.needsGotAuth = true; } } else if (needsPlt(expr)) { sym.needsPlt = true; @@ -1625,8 +1647,11 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) { // don't try to call the PLT as if it were an ifunc resolver. d.type = STT_FUNC; - if (sym.needsGot) + if (sym.needsGot) { + assert(!(sym.needsGotAuth) && + "R_AARCH64_AUTH_IRELATIVE is not supported yet"); addGotEntry(sym); + } } else if (sym.needsGot) { // Redirect GOT accesses to point to the Igot. sym.gotInIgot = true; @@ -1642,8 +1667,12 @@ void elf::postScanRelocations() { return; sym.allocateAux(); - if (sym.needsGot) - addGotEntry(sym); + if (sym.needsGot) { + if (sym.needsGotAuth) + addGotAuthEntry(sym); + else + addGotEntry(sym); + } if (sym.needsPlt) addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym); if (sym.needsCopy) { diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index f512047802ef..25eafcc28c40 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -81,7 +81,9 @@ enum RelExpr { // of a relocation type, there are some relocations whose semantics are // unique to a target. Such relocation are marked with R_. R_AARCH64_GOT_PAGE_PC, + RE_AARCH64_AUTH_GOT_PAGE_PC, R_AARCH64_GOT_PAGE, + RE_AARCH64_AUTH_GOT, R_AARCH64_PAGE_PC, R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC, R_AARCH64_TLSDESC_PAGE, diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 657c19a00ba3..5e553c5d805f 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -253,7 +253,7 @@ protected: scriptDefined(false), needsCopy(false), needsGot(false), needsPlt(false), needsTlsDesc(false), needsTlsGd(false), needsTlsGdToIe(false), needsGotDtprel(false), needsTlsIe(false), - hasDirectReloc(false) {} + hasDirectReloc(false), needsGotAuth(false) {} public: // True if this symbol is in the Iplt sub-section of the Plt and the Igot @@ -290,7 +290,8 @@ public: uint8_t needsTlsGdToIe : 1; uint8_t needsGotDtprel : 1; uint8_t needsTlsIe : 1; - uint8_t hasDirectReloc : 1; + uint8_t hasDirectReloc : 1; + uint8_t needsGotAuth : 1; // A symAux index used to access GOT/PLT entry indexes. This is allocated in // postScanRelocations(). diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index f298b83bda0e..2d73481c417f 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -713,6 +713,10 @@ void GotSection::addEntry(Symbol &sym) { symAux.back().gotIdx = numEntries++; } +void GotSection::addAuthEntry(const Symbol &sym) { + authEntries.push_back({(numEntries - 1) * config->wordsize, sym.isFunc()}); +} + bool GotSection::addTlsDescEntry(Symbol &sym) { assert(sym.auxIdx == symAux.size() - 1); symAux.back().tlsDescIdx = numEntries; @@ -774,6 +778,21 @@ void GotSection::writeTo(uint8_t *buf) { return; target->writeGotHeader(buf); relocateAlloc(buf, buf + size); + for (const AuthEntryInfo &authEntry : authEntries) { + // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#default-signing-schema + // Signed GOT entries use the IA key for symbols of type STT_FUNC and the + // DA key for all other symbol types, with the address of the GOT entry as + // the modifier. The static linker must encode the signing schema into the + // GOT slot. + // + // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#encoding-the-signing-schema + // If address diversity is set and the discriminator + // is 0 then modifier = Place + uint8_t *dest = buf + authEntry.offset; + uint64_t key = authEntry.isSymbolFunc ? /*IA=*/0b00 : /*DA=*/0b10; + uint64_t addrDiversity = 1; + write64(dest, (addrDiversity << 63) | (key << 60)); + } } static uint64_t getMipsPageAddr(uint64_t addr) { diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 83a2bd7d34df..953833abf2e1 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -128,6 +128,7 @@ public: void writeTo(uint8_t *buf) override; void addEntry(Symbol &sym); + void addAuthEntry(const Symbol &sym); bool addTlsDescEntry(Symbol &sym); bool addDynTlsEntry(Symbol &sym); bool addTlsIndex(); @@ -147,6 +148,11 @@ protected: size_t numEntries = 0; uint32_t tlsIndexOff = -1; uint64_t size = 0; + struct AuthEntryInfo { + size_t offset; + bool isSymbolFunc; + }; + SmallVector authEntries; }; // .note.GNU-stack section. diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s new file mode 100644 index 000000000000..4456fe3ad771 --- /dev/null +++ b/lld/test/ELF/aarch64-got-relocations-pauth.s @@ -0,0 +1,90 @@ +# REQUIRES: aarch64 + +# RUN: rm -rf %t && split-file %s %t && cd %t + +# RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared.s -o a.o +# RUN: ld.lld -shared a.o -o a.so + +#--- ok.s +# RUN: llvm-mc -filetype=obj -triple=aarch64 ok.s -o ok.o + +# RUN: ld.lld ok.o a.so -pie -o ok1 +# RUN: llvm-readelf -r -S -x .got ok1 | FileCheck %s --check-prefix=OK1 + +# RUN: ld.lld ok.o a.o -pie -o ok2 +# RUN: llvm-readelf -r -S -x .got -s ok2 | FileCheck %s --check-prefix=OK2 + +# OK1: Offset Info Type Symbol's Value Symbol's Name + Addend +# OK1-NEXT: 0000000000020380 0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0 +# OK1-NEXT: 0000000000020388 0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0 + +## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s) +# OK2: Offset Info Type Symbol's Value Symbol's Name + Addend +# OK2-NEXT: 0000000000020320 0000000000000411 R_AARCH64_AUTH_RELATIVE 10260 +# OK2-NEXT: 0000000000020328 0000000000000411 R_AARCH64_AUTH_RELATIVE 10260 + +# OK1: Hex dump of section '.got': +# OK1-NEXT: 0x00020380 00000000 00000080 00000000 000000a0 +## ^^ +## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA +## ^^ +## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA + +# OK2: Symbol table '.symtab' contains {{.*}} entries: +# OK2: Num: Value Size Type Bind Vis Ndx Name +# OK2: 0000000000010260 0 FUNC GLOBAL DEFAULT 6 bar +# OK2: 0000000000010260 0 NOTYPE GLOBAL DEFAULT 6 zed + +# OK2: Hex dump of section '.got': +# OK2-NEXT: 0x00020320 00000000 00000080 00000000 000000a0 +## ^^ +## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA +## ^^ +## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA + +# RUN: llvm-objdump -d ok1 | FileCheck %s --check-prefix=OK1-ASM + +# OK1-ASM: <_start>: +# OK1-ASM-NEXT: adrp x0, 0x20000 +# OK1-ASM-NEXT: ldr x0, [x0, #0x380] +# OK1-ASM-NEXT: adrp x1, 0x20000 +# OK1-ASM-NEXT: add x1, x1, #0x380 +# OK1-ASM-NEXT: adrp x0, 0x20000 +# OK1-ASM-NEXT: ldr x0, [x0, #0x388] +# OK1-ASM-NEXT: adrp x1, 0x20000 +# OK1-ASM-NEXT: add x1, x1, #0x388 + +# RUN: llvm-objdump -d ok2 | FileCheck %s --check-prefix=OK2-ASM + +# OK2-ASM: <_start>: +# OK2-ASM-NEXT: adrp x0, 0x20000 +# OK2-ASM-NEXT: ldr x0, [x0, #0x320] +# OK2-ASM-NEXT: adrp x1, 0x20000 +# OK2-ASM-NEXT: add x1, x1, #0x320 +# OK2-ASM-NEXT: adrp x0, 0x20000 +# OK2-ASM-NEXT: ldr x0, [x0, #0x328] +# OK2-ASM-NEXT: adrp x1, 0x20000 +# OK2-ASM-NEXT: add x1, x1, #0x328 + +.globl _start +_start: + adrp x0, :got_auth:bar + ldr x0, [x0, :got_auth_lo12:bar] + adrp x1, :got_auth:bar + add x1, x1, :got_auth_lo12:bar + adrp x0, :got_auth:zed + ldr x0, [x0, :got_auth_lo12:zed] + adrp x1, :got_auth:zed + add x1, x1, :got_auth_lo12:zed + +#--- err.s +# RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o +# RUN: not ld.lld err.o a.so -pie 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error: +# ERR: error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported + +.globl _start +_start: + adrp x0, :got_auth:bar + ldr x0, [x0, :got_auth_lo12:bar] + adrp x0, :got:bar + ldr x0, [x0, :got_lo12:bar] -- Gitee From 950b8db15ac645fccd5cd0af8d592036680b2406 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 19 Nov 2024 15:20:15 +0800 Subject: [PATCH 03/10] Add signed GOT cc1 flag (#96160) Add `-fptrauth-elf-got` clang cc1 flag and set `ptrauth_elf_got` preprocessor feature and `PointerAuthELFGOT` LangOption correspondingly. No additional checks like ensuring OS binary format is ELF are performed: it should be done on clang driver level when a pauth-enabled environment implying signed GOT enabled is requested. If the cc1 flag is passed, "ptrauth-elf-got" IR module flag is set. Signed-off-by:baojingjing --- clang/include/clang/Basic/Features.def | 1 + clang/include/clang/Basic/LangOptions.def | 2 ++ clang/include/clang/Driver/Options.td | 2 ++ clang/lib/CodeGen/CodeGenModule.cpp | 2 ++ clang/lib/Driver/ToolChains/Clang.cpp | 3 +++ clang/lib/Frontend/CompilerInvocation.cpp | 14 ++++++++++++++ clang/test/CodeGen/ptrauth-module-flags.c | 8 ++++++++ 7 files changed, 32 insertions(+) create mode 100644 clang/test/CodeGen/ptrauth-module-flags.c diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 0b257340cf8e..8155b4d4ed09 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -105,6 +105,7 @@ FEATURE(gwp_asan, LangOpts.Sanitize.hasOneOf(SanitizerKind::GWPAsan)) FEATURE(swiftasynccc, PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) == clang::TargetInfo::CCCR_OK) +FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) // Objective-C features FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 5d7fd36723e2..64fd409ef8c8 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -157,6 +157,8 @@ LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods" LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") +LANGOPT(PointerAuthELFGOT, 1, 0, "authenticate pointers from GOT") + LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") COMPATIBLE_LANGOPT(RecoveryAST, 1, 1, "Preserve expressions in AST when encountering errors") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6f3a3cb8d6d9..cdd67ed353c1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3073,6 +3073,8 @@ defm strict_return : BoolFOption<"strict-return", " of a non-void function as unreachable">, PosFlag>; +defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">; + def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, Flags<[CC1Option]>, HelpText<"Enable matrix data type and related builtin functions">, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4a5115078270..dbac93453136 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -824,6 +824,8 @@ void CodeGenModule::Release() { if (!LangOpts.isSignReturnAddressWithAKey()) getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 1); + if (LangOpts.PointerAuthELFGOT) + getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); } if (!CodeGenOpts.MemoryProfileOutput.empty()) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 21699557075a..dbad09e75251 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1975,6 +1975,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, CmdArgs.push_back(A->getValue()); } + if (Args.hasArg(options::OPT_fptrauth_elf_got)) + CmdArgs.push_back("-fptrauth-elf-got"); + AddUnalignedAccessWarning(CmdArgs); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 17c8951ebd65..b4ad3cbf1555 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3211,6 +3211,18 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, return Diags.getNumErrors() == NumErrorsBefore; } +static void GeneratePointerAuthArgs(const LangOptions &Opts, + SmallVectorImpl &Args, + CompilerInvocation::StringAllocator SA) { + if (Opts.PointerAuthELFGOT) + GenerateArg(Args, OPT_fptrauth_elf_got, SA); +} + +static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags) { + Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got); +} + /// Check if input file kind and language standard are compatible. static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S) { @@ -4486,6 +4498,7 @@ bool CompilerInvocation::CreateFromArgsImpl( llvm::Triple T(Res.getTargetOpts().Triple); ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags, Res.getFileSystemOpts().WorkingDir); + ParsePointerAuthArgs(LangOpts, Args, Diags); ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes, Diags); @@ -4682,6 +4695,7 @@ void CompilerInvocation::generateCC1CommandLine( GeneratePreprocessorOutputArgs(PreprocessorOutputOpts, Args, SA, FrontendOpts.ProgramAction); GenerateDependencyOutputArgs(DependencyOutputOpts, Args, SA); + GeneratePointerAuthArgs(*LangOpts, Args, SA); } IntrusiveRefCntPtr diff --git a/clang/test/CodeGen/ptrauth-module-flags.c b/clang/test/CodeGen/ptrauth-module-flags.c new file mode 100644 index 000000000000..5a7e9a7c2a36 --- /dev/null +++ b/clang/test/CodeGen/ptrauth-module-flags.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OFF +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-elf-got -emit-llvm %s -o - | FileCheck %s --check-prefix=ELFGOT + +// ELFGOT: !llvm.module.flags = !{ +// ELFGOT-SAME: !1 +// ELFGOT: !1 = !{i32 8, !"ptrauth-elf-got", i32 1} + +// OFF-NOT: "ptrauth- -- Gitee From d44a00256aa835a62cf0edeb6d48b601b243d033 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Mon, 2 Dec 2024 13:53:49 +0800 Subject: [PATCH 04/10] Move PAuth GOT relocs out of private space (#118214) Apply change from the spec https://github.com/ARM-software/abi-aa/pull/300 Signed-off-by:baojingjing --- .../llvm/BinaryFormat/ELFRelocs/AArch64.def | 7 +++++++ .../llvm-readobj/ELF/reloc-types-aarch64.test | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def index 96a4efe82560..025fa9b349db 100644 --- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def +++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def @@ -121,6 +121,11 @@ ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 0x23a) ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 0x23b) ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 0x23c) ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 0x23d) +ELF_RELOC(R_AARCH64_AUTH_GOT_LD_PREL19, 0x24c) +ELF_RELOC(R_AARCH64_AUTH_ADR_GOT_PAGE, 0x24e) +ELF_RELOC(R_AARCH64_AUTH_LD64_GOT_LO12_NC, 0x24f) +ELF_RELOC(R_AARCH64_AUTH_GOT_ADD_LO12_NC, 0x251) +ELF_RELOC(R_AARCH64_AUTH_GOT_ADR_PREL_LO21, 0x252) // Dynamic relocations start ELF_RELOC(R_AARCH64_COPY, 0x400) ELF_RELOC(R_AARCH64_GLOB_DAT, 0x401) @@ -134,6 +139,8 @@ ELF_RELOC(R_AARCH64_TLS_DTPREL64, 0x405) ELF_RELOC(R_AARCH64_TLS_TPREL64, 0x406) ELF_RELOC(R_AARCH64_TLSDESC, 0x407) ELF_RELOC(R_AARCH64_IRELATIVE, 0x408) +ELF_RELOC(R_AARCH64_AUTH_RELATIVE, 0x411) +ELF_RELOC(R_AARCH64_AUTH_GLOB_DAT, 0x412) // ELF_RELOC(R_AARCH64_P32_NONE, 0) ELF_RELOC(R_AARCH64_P32_ABS32, 0x001) diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test b/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test index 729128281104..2756e51d3fb3 100644 --- a/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test +++ b/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test @@ -119,6 +119,11 @@ # CHECK: Type: R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC (571) # CHECK: Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12 (572) # CHECK: Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC (573) +# CHECK: Type: R_AARCH64_AUTH_GOT_LD_PREL19 (588) +# CHECK: Type: R_AARCH64_AUTH_ADR_GOT_PAGE (590) +# CHECK: Type: R_AARCH64_AUTH_LD64_GOT_LO12_NC (591) +# CHECK: Type: R_AARCH64_AUTH_GOT_ADD_LO12_NC (593) +# CHECK: Type: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 (594) # CHECK: Type: R_AARCH64_COPY (1024) # CHECK: Type: R_AARCH64_GLOB_DAT (1025) # CHECK: Type: R_AARCH64_JUMP_SLOT (1026) @@ -128,7 +133,9 @@ # CHECK: Type: R_AARCH64_TLS_TPREL64 (1030) # CHECK: Type: R_AARCH64_TLSDESC (1031) # CHECK: Type: R_AARCH64_IRELATIVE (1032) - +# CHECK: Type: R_AARCH64_AUTH_GLOB_DAT (1042) +# CHECK: Type: R_AARCH64_AUTH_TLSDESC (1043) +# CHECK: Type: R_AARCH64_AUTH_IRELATIVE (1044) --- !ELF FileHeader: Class: ELFCLASS64 @@ -254,6 +261,11 @@ Sections: - Type: R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC - Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12 - Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC + - Type: R_AARCH64_AUTH_GOT_LD_PREL19 + - Type: R_AARCH64_AUTH_ADR_GOT_PAGE + - Type: R_AARCH64_AUTH_LD64_GOT_LO12_NC + - Type: R_AARCH64_AUTH_GOT_ADD_LO12_NC + - Type: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 - Type: R_AARCH64_COPY - Type: R_AARCH64_GLOB_DAT - Type: R_AARCH64_JUMP_SLOT @@ -263,3 +275,6 @@ Sections: - Type: R_AARCH64_TLS_TPREL64 - Type: R_AARCH64_TLSDESC - Type: R_AARCH64_IRELATIVE + - Type: R_AARCH64_AUTH_GLOB_DAT + - Type: R_AARCH64_AUTH_TLSDESC + - Type: R_AARCH64_AUTH_IRELATIVE -- Gitee From 91b3e85dec3da37ba02ffa37c33839104a9e612d Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 10 Dec 2024 14:43:12 +0300 Subject: [PATCH 05/10] Support signed GOT with tiny code model (#114525) Support the following relocations and assembly operators: - `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` (`:got_auth:` for `adr`) - `R_AARCH64_AUTH_GOT_LD_PREL19` (`:got_auth:` for `ldr`) `LOADgotAUTH` pseudo-instruction is expanded to actual instruction sequence like the following. ``` adr x16, :got_auth:sym ldr x0, [x16] autia x0, x16 ``` Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG. Tests starting with 'ptrauth-' have corresponding variants w/o this prefix. Signed-off-by:baojingjing --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 55 +++--- .../AArch64/AsmParser/AArch64AsmParser.cpp | 8 +- .../MCTargetDesc/AArch64ELFObjectWriter.cpp | 18 ++ .../CodeGen/AArch64/ptrauth-extern-weak.ll | 42 ++++ .../CodeGen/AArch64/ptrauth-tiny-model-pic.ll | 182 ++++++++++++++++++ .../AArch64/ptrauth-tiny-model-static.ll | 157 +++++++++++++++ llvm/test/MC/AArch64/arm64-elf-relocs.s | 13 ++ llvm/test/MC/AArch64/ilp32-diagnostics.s | 6 + 8 files changed, 458 insertions(+), 23 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 19cf48adb4b3..b0d07c86ef4d 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1194,28 +1194,39 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) { 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)); + if (MI.getMF()->getTarget().getCodeModel() == CodeModel::Tiny) { + MCOperand GAMC; + MCInstLowering.lowerOperand(GAMO, GAMC); + EmitToStreamer( + *OutStreamer, MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addOperand(GAMC)); + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRXui) + .addReg(AuthResultReg) + .addReg(AArch64::X17) + .addImm(0)); + } else { + 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( + *OutStreamer, MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi)); + + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXri) + .addReg(AArch64::X17) + .addReg(AArch64::X17) + .addOperand(GAMCLo) + .addImm(0)); + + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRXui) + .addReg(AuthResultReg) + .addReg(AArch64::X17) + .addImm(0)); + } assert(GAMO.isGlobal()); MCSymbol *UndefWeakSym; diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 59a143d02120..6715ae699660 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -2907,7 +2907,13 @@ AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) { // No modifier was specified at all; this is the syntax for an ELF basic // ADR relocation (unfortunately). Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext()); - } else { + } else if (ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE) { + // For tiny code model, we use :got_auth: operator to fill 21-bit imm of + // adr. It's not actually GOT entry page address but the GOT address + // itself - we just share the same variant kind with :got_auth: operator + // applied for adrp. + // TODO: can we somehow get current TargetMachine object to call + // getCodeModel() on it to ensure we are using tiny code model? Error(S, "unexpected adr label"); return MatchOperand_ParseFail; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp index 5bc2c46ff056..9988b959cebe 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -144,6 +144,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, } else return ELF::R_AARCH64_PREL64; case AArch64::fixup_aarch64_pcrel_adr_imm21: + if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) { + if (IsILP32) { + Ctx.reportError(Fixup.getLoc(), + "ILP32 ADR AUTH relocation not supported " + "(LP64 eqv: AUTH_GOT_ADR_PREL_LO21)"); + return ELF::R_AARCH64_NONE; + } + return ELF::R_AARCH64_AUTH_GOT_ADR_PREL_LO21; + } if (SymLoc != AArch64MCExpr::VK_ABS) Ctx.reportError(Fixup.getLoc(), "invalid symbol kind for ADR relocation"); @@ -188,6 +197,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, return R_CLS(TLSIE_LD_GOTTPREL_PREL19); if (SymLoc == AArch64MCExpr::VK_GOT) return R_CLS(GOT_LD_PREL19); + if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) { + if (IsILP32) { + Ctx.reportError(Fixup.getLoc(), + "ILP32 LDR AUTH relocation not supported " + "(LP64 eqv: AUTH_GOT_LD_PREL19)"); + return ELF::R_AARCH64_NONE; + } + return ELF::R_AARCH64_AUTH_GOT_LD_PREL19; + } return R_CLS(LD_PREL_LO19); case AArch64::fixup_aarch64_pcrel_branch14: return R_CLS(TSTBR14); diff --git a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll index 5d0a3f556c4c..141af917fa3e 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll @@ -13,6 +13,11 @@ ; 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 +; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -mattr=+fpac -o - %s | \ +; RUN: FileCheck --check-prefixes=CHECK-TINY,NOTRAP-TINY %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -o - %s | \ +; RUN: FileCheck --check-prefixes=CHECK-TINY,TRAP-TINY %s + ;; Note: for FastISel, we fall back to SelectionDAG declare extern_weak dso_local i32 @var() @@ -41,6 +46,24 @@ define ptr @foo() { ; TRAP-NEXT: .Lauth_success_0: ; TRAP-NEXT: mov x0, x16 ; CHECK-NEXT: ret + +; CHECK-TINY-LABEL: foo: +; CHECK-TINY: adr x17, :got_auth:var +; NOTRAP-TINY-NEXT: ldr x0, [x17] +; NOTRAP-TINY-NEXT: cbz x0, .Lundef_weak0 +; NOTRAP-TINY-NEXT: autia x0, x17 +; TRAP-TINY-NEXT: ldr x16, [x17] +; TRAP-TINY-NEXT: cbz x16, .Lundef_weak0 +; TRAP-TINY-NEXT: autia x16, x17 +; CHECK-TINY-NEXT: .Lundef_weak0: +; TRAP-TINY-NEXT: mov x17, x16 +; TRAP-TINY-NEXT: xpaci x17 +; TRAP-TINY-NEXT: cmp x16, x17 +; TRAP-TINY-NEXT: b.eq .Lauth_success_0 +; TRAP-TINY-NEXT: brk #0xc470 +; TRAP-TINY-NEXT: .Lauth_success_0: +; TRAP-TINY-NEXT: mov x0, x16 +; CHECK-TINY-NEXT: ret } @arr_var = extern_weak global [10 x i32] @@ -68,6 +91,25 @@ define ptr @bar() { ; TRAP-NEXT: mov x8, x16 ; CHECK-NEXT: add x0, x8, #20 ; CHECK-NEXT: ret + +; CHECK-TINY-LABEL: bar: +; CHECK-TINY: adr x17, :got_auth:arr_var +; NOTRAP-TINY-NEXT: ldr x8, [x17] +; NOTRAP-TINY-NEXT: cbz x8, .Lundef_weak1 +; NOTRAP-TINY-NEXT: autda x8, x17 +; TRAP-TINY-NEXT: ldr x16, [x17] +; TRAP-TINY-NEXT: cbz x16, .Lundef_weak1 +; TRAP-TINY-NEXT: autda x16, x17 +; CHECK-TINY-NEXT: .Lundef_weak1: +; TRAP-TINY-NEXT: mov x17, x16 +; TRAP-TINY-NEXT: xpacd x17 +; TRAP-TINY-NEXT: cmp x16, x17 +; TRAP-TINY-NEXT: b.eq .Lauth_success_1 +; TRAP-TINY-NEXT: brk #0xc472 +; TRAP-TINY-NEXT: .Lauth_success_1: +; TRAP-TINY-NEXT: mov x8, x16 +; CHECK-TINY-NEXT: add x0, x8, #20 +; CHECK-TINY-NEXT: ret } !llvm.module.flags = !{!0} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll new file mode 100644 index 000000000000..9d13714bbefe --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll @@ -0,0 +1,182 @@ +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ +; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ +; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ +; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ +; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ +; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ +; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; Note: fast-isel tests here will fall back to isel + +@src = external local_unnamed_addr global [65536 x i8], align 1 +@dst = external global [65536 x i8], align 1 +@ptr = external local_unnamed_addr global ptr, align 8 + +define dso_preemptable void @foo1() { +; CHECK-LABEL: foo1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:src +; 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: ldrb w8, [x8] +; CHECK-NEXT: adr x17, :got_auth:dst +; 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_1 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_1: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: strb w8, [x9] +; CHECK-NEXT: ret + +entry: + %0 = load i8, ptr @src, align 1 + store i8 %0, ptr @dst, align 1 + ret void +} + +define dso_preemptable void @foo2() { +; CHECK-LABEL: foo2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:ptr +; 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_2 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_2: +; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: adr x17, :got_auth:dst +; 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_3 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_3: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: str x9, [x8] +; CHECK-NEXT: ret + +entry: + store ptr @dst, ptr @ptr, align 8 + ret void +} + +define dso_preemptable void @foo3() { +; CHECK-LABEL: foo3: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:src +; 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_4 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_4: +; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldrb w8, [x8] +; CHECK-NEXT: adr x17, :got_auth:ptr +; 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_5 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_5: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x9] +; CHECK-NEXT: strb w8, [x9] +; CHECK-NEXT: ret + +entry: + %0 = load i8, ptr @src, align 1 + %1 = load ptr, ptr @ptr, align 8 + store i8 %0, ptr %1, align 1 + ret void +} + +@lsrc = internal global i8 0, align 4 +@ldst = internal global i8 0, align 4 +@lptr = internal global ptr null, align 8 + +declare void @func(...) + +define dso_preemptable ptr @externfuncaddr() { +; CHECK-LABEL: externfuncaddr: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth: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_6 +; TRAP-NEXT: brk #0xc470 +; TRAP-NEXT: .Lauth_success_6: +; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ret + +entry: + ret ptr @func +} + +define dso_preemptable ptr @localfuncaddr() { +; CHECK-LABEL: localfuncaddr: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:externfuncaddr +; 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_7 +; TRAP-NEXT: brk #0xc470 +; TRAP-NEXT: .Lauth_success_7: +; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ret + +entry: + ret ptr @externfuncaddr +} + +!llvm.module.flags = !{!0} +!0 = !{i32 8, !"ptrauth-elf-got", i32 1} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll new file mode 100644 index 000000000000..2d098b70accc --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll @@ -0,0 +1,157 @@ +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ +; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ +; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ +; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ +; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ +; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s +; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ +; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s + +; Note fast-isel tests here will fall back to isel + +@src = external local_unnamed_addr global [65536 x i8], align 1 +@dst = external global [65536 x i8], align 1 +@ptr = external local_unnamed_addr global ptr, align 8 + +define dso_local void @foo1() { +; CHECK-LABEL: foo1: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:src +; 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: ldrb w8, [x8] +; CHECK-NEXT: adr x17, :got_auth:dst +; 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_1 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_1: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: strb w8, [x9] +; CHECK-NEXT: ret + +entry: + %0 = load i8, ptr @src, align 1 + store i8 %0, ptr @dst, align 1 + ret void +} + +define dso_local void @foo2() { +; CHECK-LABEL: foo2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:ptr +; 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_2 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_2: +; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: adr x17, :got_auth:dst +; 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_3 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_3: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: str x9, [x8] +; CHECK-NEXT: ret + +entry: + store ptr @dst, ptr @ptr, align 8 + ret void +} + +define dso_local void @foo3() { +; CHECK-LABEL: foo3: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth:src +; 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_4 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_4: +; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldrb w8, [x8] +; CHECK-NEXT: adr x17, :got_auth:ptr +; 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_5 +; TRAP-NEXT: brk #0xc472 +; TRAP-NEXT: .Lauth_success_5: +; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x9] +; CHECK-NEXT: strb w8, [x9] +; CHECK-NEXT: ret + +entry: + %0 = load i8, ptr @src, align 1 + %1 = load ptr, ptr @ptr, align 8 + store i8 %0, ptr %1, align 1 + ret void +} + +declare void @func(...) + +define dso_local ptr @externfuncaddr() { +; CHECK-LABEL: externfuncaddr: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: adr x17, :got_auth: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_6 +; TRAP-NEXT: brk #0xc470 +; TRAP-NEXT: .Lauth_success_6: +; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ret + +entry: + ret ptr @func +} + +!llvm.module.flags = !{!0} +!0 = !{i32 8, !"ptrauth-elf-got", i32 1} diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s index 88681198f9f3..6fdf8af19f6a 100644 --- a/llvm/test/MC/AArch64/arm64-elf-relocs.s +++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s @@ -330,3 +330,16 @@ trickQuestion: // CHECK: ldr d22, :got:sym // CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym // CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym + + adr x24, #:got_auth:sym + adr x24, :got_auth:sym + ldr x24, #:got_auth:sym + ldr x24, :got_auth:sym +// CHECK: adr x24, :got_auth:sym +// CHECK: adr x24, :got_auth:sym +// CHECK: ldr x24, :got_auth:sym +// CHECK: ldr x24, :got_auth:sym +// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 sym +// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 sym +// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LD_PREL19 sym +// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LD_PREL19 sym diff --git a/llvm/test/MC/AArch64/ilp32-diagnostics.s b/llvm/test/MC/AArch64/ilp32-diagnostics.s index 5e3394bc79ed..b637c66d7b3d 100644 --- a/llvm/test/MC/AArch64/ilp32-diagnostics.s +++ b/llvm/test/MC/AArch64/ilp32-diagnostics.s @@ -101,3 +101,9 @@ ldr x24, [x23, :gottprel_lo12:sym] // CHECK-ERROR: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC) // CHECK-ERROR: ^ + +ldr x24, :got_auth:sym +// ERROR: [[#@LINE-1]]:1: error: ILP32 LDR AUTH relocation not supported (LP64 eqv: AUTH_GOT_LD_PREL19) + +adr x24, :got_auth:sym +// ERROR: [[#@LINE-1]]:1: error: ILP32 ADR AUTH relocation not supported (LP64 eqv: AUTH_GOT_ADR_PREL_LO21) -- Gitee From dc5ac04fd665ead9425690183e079e6941e0a8ed Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 18 Dec 2024 14:41:54 +0800 Subject: [PATCH 06/10] Support signed GOT with tiny code model (#113816) Depends on #114525 Support `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` and `R_AARCH64_AUTH_GOT_LD_PREL19` GOT-generating relocations. A corresponding `RE_AARCH64_AUTH_GOT_PC` member of `RelExpr` is added, which is an AUTH-specific variant of `R_GOT_PC`. Signed-off-by:baojingjing --- lld/ELF/Arch/AArch64.cpp | 26 +++++++++- lld/ELF/InputSection.cpp | 1 + lld/ELF/Relocations.cpp | 11 ++-- lld/ELF/Relocations.h | 1 + lld/test/ELF/aarch64-got-relocations-pauth.s | 54 ++++++++++++++++++++ 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index b78a9e71e8e8..76d7e01c108f 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -148,6 +148,9 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, case R_AARCH64_AUTH_LD64_GOT_LO12_NC: case R_AARCH64_AUTH_GOT_ADD_LO12_NC: return RE_AARCH64_AUTH_GOT; + case R_AARCH64_AUTH_GOT_LD_PREL19: + case R_AARCH64_AUTH_GOT_ADR_PREL_LO21: + return RE_AARCH64_AUTH_GOT_PC; case R_AARCH64_LD64_GOTPAGE_LO15: return R_AARCH64_GOT_PAGE; case R_AARCH64_ADR_GOT_PAGE: @@ -321,6 +324,14 @@ static void or32AArch64Imm(uint8_t *l, uint64_t imm) { or32le(l, (imm & 0xFFF) << 10); } +static void writeMaskedBits32le(uint8_t *p, int32_t v, uint32_t mask) { + write32le(p, (read32le(p) & ~mask) | v); +} + +static void write32Imm12(uint8_t *l, uint64_t imm) { + writeMaskedBits32le(l, (imm & 0xFFF) << 10, 0XFFF << 10); +} + // Update the immediate field in an AArch64 movk, movn or movz instruction // for a signed relocation, and update the opcode of a movn or movz instruction // to match the sign of the operand. @@ -363,9 +374,11 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, write64(loc, val); break; case R_AARCH64_ADD_ABS_LO12_NC: - case R_AARCH64_AUTH_GOT_ADD_LO12_NC: or32AArch64Imm(loc, val); break; + case R_AARCH64_AUTH_GOT_ADD_LO12_NC: + write32Imm12(loc, val); + break; case R_AARCH64_ADR_GOT_PAGE: case R_AARCH64_AUTH_ADR_GOT_PAGE: case R_AARCH64_ADR_PREL_PG_HI21: @@ -377,6 +390,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, write32AArch64Addr(loc, val >> 12); break; case R_AARCH64_ADR_PREL_LO21: + case R_AARCH64_AUTH_GOT_ADR_PREL_LO21: checkInt(loc, val, 21, rel); write32AArch64Addr(loc, val); break; @@ -400,6 +414,11 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, checkInt(loc, val, 21, rel); or32le(loc, (val & 0x1FFFFC) << 3); break; + case R_AARCH64_AUTH_GOT_LD_PREL19: + checkAlignment(loc, val, 4, rel); + checkInt(loc, val, 21, rel); + writeMaskedBits32le(loc, (val & 0x1FFFFC) << 3, 0x1FFFFC << 3); + break; case R_AARCH64_LDST8_ABS_LO12_NC: case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: or32AArch64Imm(loc, getBits(val, 0, 11)); @@ -416,13 +435,16 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, break; case R_AARCH64_LDST64_ABS_LO12_NC: case R_AARCH64_LD64_GOT_LO12_NC: - case R_AARCH64_AUTH_LD64_GOT_LO12_NC: case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: case R_AARCH64_TLSDESC_LD64_LO12: checkAlignment(loc, val, 8, rel); or32AArch64Imm(loc, getBits(val, 3, 11)); break; + case R_AARCH64_AUTH_LD64_GOT_LO12_NC: + checkAlignment(loc, val, 8, rel); + write32Imm12(loc, getBits(val, 3, 11)); + break; case R_AARCH64_LDST128_ABS_LO12_NC: case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: checkAlignment(loc, val, 16, rel); diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 8b470855ff22..a10a7da6935b 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -663,6 +663,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type, case R_AARCH64_GOT_PAGE: return sym.getGotVA() + a - getAArch64Page(in.got->getVA()); case R_GOT_PC: + case RE_AARCH64_AUTH_GOT_PC: case R_RELAX_TLS_GD_TO_IE: return sym.getGotVA() + a - p; case R_LOONGARCH_GOT_PAGE_PC: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index e6b37b03d57b..f5d74a357f13 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -198,9 +198,10 @@ static bool needsPlt(RelExpr expr) { // returns false for TLS variables even though they need GOT, because // TLS variables uses GOT differently than the regular variables. static bool needsGot(RelExpr expr) { - return oneof( expr); } @@ -988,6 +989,7 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type, R_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTPLT, R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE, RE_AARCH64_AUTH_GOT, + RE_AARCH64_AUTH_GOT_PC, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>( e)) return true; @@ -1465,7 +1467,8 @@ template void RelocationScanner::scanOne(RelTy *&i) { // Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which // case the `needsGot` flag shouldn't get set. sym.needsGot = true; - if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC) + if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC || + expr == RE_AARCH64_AUTH_GOT_PC) sym.needsGotAuth = true; } } else if (needsPlt(expr)) { diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index 25eafcc28c40..feb425553da1 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -84,6 +84,7 @@ enum RelExpr { RE_AARCH64_AUTH_GOT_PAGE_PC, R_AARCH64_GOT_PAGE, RE_AARCH64_AUTH_GOT, + RE_AARCH64_AUTH_GOT_PC, R_AARCH64_PAGE_PC, R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC, R_AARCH64_TLSDESC_PAGE, diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s index 4456fe3ad771..2d37123f1cca 100644 --- a/lld/test/ELF/aarch64-got-relocations-pauth.s +++ b/lld/test/ELF/aarch64-got-relocations-pauth.s @@ -77,6 +77,60 @@ _start: adrp x1, :got_auth:zed add x1, x1, :got_auth_lo12:zed +#--- ok-tiny.s +# RUN: llvm-mc -filetype=obj -triple=aarch64 ok-tiny.s -o ok-tiny.o + +# RUN: ld.lld ok-tiny.o a.so -pie -o tiny1 +# RUN: llvm-readelf -r -S -x .got tiny1 | FileCheck %s --check-prefix=TINY1 + +# RUN: ld.lld ok-tiny.o a.o -pie -o tiny2 +# RUN: llvm-readelf -r -S -x .got -s tiny2 | FileCheck %s --check-prefix=TINY2 + +# TINY1: Offset Info Type Symbol's Value Symbol's Name + Addend +# TINY1-NEXT: 0000000000020368 0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0 +# TINY1-NEXT: 0000000000020370 0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0 + +## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s) +# TINY2: Offset Info Type Symbol's Value Symbol's Name + Addend +# TINY2-NEXT: 0000000000020308 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248 +# TINY2-NEXT: 0000000000020310 0000000000000411 R_AARCH64_AUTH_RELATIVE 10248 + +# TINY1: Hex dump of section '.got': +# TINY1-NEXT: 0x00020368 00000000 00000080 00000000 000000a0 +## ^^ +## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA +## ^^ +## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA + +# TINY2: Symbol table '.symtab' contains {{.*}} entries: +# TINY2: Num: Value Size Type Bind Vis Ndx Name +# TINY2: 0000000000010248 0 FUNC GLOBAL DEFAULT 6 bar +# TINY2: 0000000000010248 0 NOTYPE GLOBAL DEFAULT 6 zed + +# TINY2: Hex dump of section '.got': +# TINY2-NEXT: 0x00020308 00000000 00000080 00000000 000000a0 +## ^^ +## 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA +## ^^ +## 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA + +# RUN: llvm-objdump -d tiny1 | FileCheck %s --check-prefix=TINY1-ASM + +# TINY1-ASM: <_start>: +# TINY1-ASM-NEXT: adr x0, 0x20368 +# TINY1-ASM-NEXT: ldr x1, 0x20370 + +# RUN: llvm-objdump -d tiny2 | FileCheck %s --check-prefix=TINY2-ASM + +# TINY2-ASM: <_start>: +# TINY2-ASM-NEXT: adr x0, 0x20308 +# TINY2-ASM-NEXT: ldr x1, 0x20310 + +.globl _start +_start: + adr x0, :got_auth:bar + ldr x1, :got_auth:zed + #--- err.s # RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o # RUN: not ld.lld err.o a.so -pie 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error: -- Gitee From 4f6bc339bd0e17ccf32258f1b0da23ace5868f33 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Wed, 18 Jun 2025 11:11:02 +0800 Subject: [PATCH 07/10] add option for function pointer auth Signed-off-by:baojingjing --- clang/include/clang/Basic/Features.def | 5 +++- clang/include/clang/Basic/LangOptions.def | 3 +++ clang/include/clang/Driver/Options.td | 3 +++ clang/lib/CodeGen/CodeGenModule.cpp | 6 ++++- clang/lib/Driver/ToolChains/Clang.cpp | 6 ++++- clang/lib/Frontend/CompilerInvocation.cpp | 7 ++++++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 7 +++++- llvm/lib/Target/AArch64/AArch64FastISel.cpp | 6 ++++- .../Target/AArch64/AArch64ISelLowering.cpp | 25 ++++++++++++++++--- llvm/lib/Target/AArch64/AArch64ISelLowering.h | 4 +++ .../lib/Target/AArch64/AArch64MCInstLower.cpp | 7 +++++- .../AArch64/AArch64MachineFunctionInfo.cpp | 18 +++++++++---- .../AArch64/AArch64MachineFunctionInfo.h | 2 ++ .../GISel/AArch64InstructionSelector.cpp | 7 +++++- 14 files changed, 90 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 8155b4d4ed09..764f6835bb0d 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -105,7 +105,10 @@ FEATURE(gwp_asan, LangOpts.Sanitize.hasOneOf(SanitizerKind::GWPAsan)) FEATURE(swiftasynccc, PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) == clang::TargetInfo::CCCR_OK) -FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) +FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) +// OHOS_LOCAL begin +FEATURE(ptrauth_elf_got_func, LangOpts.PointerAuthFuncELFGOT) +// OHOS_LOCAL end // Objective-C features FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? FEATURE(objc_arc, LangOpts.ObjCAutoRefCount) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 64fd409ef8c8..f6632b0bd4a0 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -158,6 +158,9 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") LANGOPT(PointerAuthELFGOT, 1, 0, "authenticate pointers from GOT") +// OHOS_LOCAL begin +LANGOPT(PointerAuthFuncELFGOT, 1, 0, "authenticate function pointers from GOT") +// OHOS_LOCAL end LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index cdd67ed353c1..9d6b0545887c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3074,6 +3074,9 @@ defm strict_return : BoolFOption<"strict-return", PosFlag>; defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">; +// OHOS_LOCAL begin +defm ptrauth_elf_got_func : OptInCC1FFlag<"ptrauth-elf-got-func", "Enable authentication of function pointers from GOT (ELF only)">; +// OHOS_LOCAL end def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, Flags<[CC1Option]>, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index dbac93453136..04fe1e2cb42d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -825,7 +825,11 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 1); if (LangOpts.PointerAuthELFGOT) - getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); + getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); + // OHOS_LOCAL begin + if (LangOpts.PointerAuthFuncELFGOT) + getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got-func", 1); + // OHOS_LOCAL end } if (!CodeGenOpts.MemoryProfileOutput.empty()) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index dbad09e75251..49af5907a506 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1977,7 +1977,11 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, if (Args.hasArg(options::OPT_fptrauth_elf_got)) CmdArgs.push_back("-fptrauth-elf-got"); - + // OHOS_LOCAL begin + if (Args.hasArg(options::OPT_fptrauth_elf_got_func)) + CmdArgs.push_back("-fptrauth-elf-got-func"); + // OHOS_LOCAL end + AddUnalignedAccessWarning(CmdArgs); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index b4ad3cbf1555..5b8bdd947ee1 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3216,11 +3216,18 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts, CompilerInvocation::StringAllocator SA) { if (Opts.PointerAuthELFGOT) GenerateArg(Args, OPT_fptrauth_elf_got, SA); + // OHOS_LOCAL begin + if (Opts.PointerAuthFuncELFGOT) + GenerateArg(Args, OPT_fptrauth_elf_got_func, SA); + // OHOS_LOCAL end } static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got); + // OHOS_LOCAL begin + Opts.PointerAuthFuncELFGOT = Args.hasArg(OPT_fptrauth_elf_got_func); + // OHOS_LOCAL end } /// Check if input file kind and language standard are compatible. diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index b0d07c86ef4d..1dd0dd97617b 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -593,7 +593,12 @@ void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) { // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#default-signing-schema const auto *PtrAuthELFGOTFlag = mdconst::extract_or_null( M.getModuleFlag("ptrauth-elf-got")); - if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1) + // OHOS_LOCAL begin + const auto *PtrAuthFuncELFGOTFlag = mdconst::extract_or_null( + M.getModuleFlag("ptrauth-elf-got-func")); + if ((PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1) || + (PtrAuthFuncELFGOTFlag && PtrAuthFuncELFGOTFlag->getZExtValue() == 1)) + // OHOS_LOCAL end for (const GlobalValue &GV : M.global_values()) if (!GV.use_empty() && isa(GV) && !GV.getName().startswith("llvm.")) diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index b738ddbfb79a..901d35aeef55 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -448,7 +448,11 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) { // movz/movk sequences, which FastISel doesn't handle yet. if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO()) return 0; - if (FuncInfo.MF->getInfo()->hasELFSignedGOT()) + // OHOS_LOCAL begin + if (FuncInfo.MF->getInfo()->hasELFSignedGOT() || + (FuncInfo.MF->getInfo()->hasELFSignedGOTFunc() && + GV->getValueType()->isFunctionTy())) + // OHOS_LOCAL end return 0; unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 4c4c3532d885..69fbc7b9317c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7188,13 +7188,30 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG, SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags); // FIXME: Once remat is capable of dealing with instructions with register // operands, expand this into two nodes instead of using a wrapper node. - if (DAG.getMachineFunction() - .getInfo() - ->hasELFSignedGOT()) + return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr); +} + +// OHOS_LOCAL begin +// (loadGOT sym) +template +SDValue AArch64TargetLowering::getGOTAuth(NodeTy *N, SelectionDAG &DAG, + unsigned Flags) const { + LLVM_DEBUG(dbgs() << "AArch64TargetLowering::getGOTAuth\n"); + SDLoc DL(N); + EVT Ty = getPointerTy(DAG.getDataLayout()); + SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags); + bool IsGotAuth = + DAG.getMachineFunction() + .getInfo()->hasELFSignedGOT() || + (DAG.getMachineFunction() + .getInfo()->hasELFSignedGOTFunc() && + N->getGlobal()->getValueType()->isFunctionTy()); + if (IsGotAuth) return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr), 0); return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr); } +// OHOS_LOCAL end // (wrapper %highest(sym), %higher(sym), %hi(sym), %lo(sym)) template @@ -7250,7 +7267,7 @@ SDValue AArch64TargetLowering::LowerGlobalAddress(SDValue Op, // This also catches the large code model case for Darwin, and tiny code // model with got relocations. if ((OpFlags & AArch64II::MO_GOT) != 0) { - return getGOT(GN, DAG, OpFlags); + return getGOTAuth(GN, DAG, OpFlags); } SDValue Result; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index ff3bfe897869..f8926cd8b009 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -946,6 +946,10 @@ private: unsigned Flag) const; template SDValue getGOT(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const; + // OHOS_LOCAL begin + template + SDValue getGOTAuth(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const; + // OHOS_LOCAL end template SDValue getAddrLarge(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const; template diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp index f74c7116b7fa..5ffd29b5139c 100644 --- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp +++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp @@ -118,9 +118,14 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO, if (MO.getTargetFlags() & AArch64II::MO_GOT) { const MachineFunction *MF = MO.getParent()->getParent()->getParent(); - RefFlags |= (MF->getInfo()->hasELFSignedGOT() + // OHOS_LOCAL begin + bool IsGotAuth = MF->getInfo()->hasELFSignedGOT() || + (MF->getInfo()->hasELFSignedGOTFunc() && + MO.getGlobal()->getValueType()->isFunctionTy()); + RefFlags |= (IsGotAuth ? AArch64MCExpr::VK_GOT_AUTH : AArch64MCExpr::VK_GOT); + // OHOS_LOCAL end } else if (MO.getTargetFlags() & AArch64II::MO_TLS) { TLSModel::Model Model; if (MO.isGlobal()) { diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp index 45a221de7d4e..2e7aa00df644 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp @@ -80,17 +80,23 @@ static bool ShouldSignWithBKey(const Function &F) { return Key.equals_insensitive("b_key"); } -static bool hasELFSignedGOTHelper(const Function &F, +// OHOS_LOCAL begin +static std::pair hasELFSignedGOTHelper(const Function &F, const AArch64Subtarget &STI) { if (!Triple(STI.getTargetTriple()).isOSBinFormatELF()) - return false; + return {false, false}; const Module *M = F.getParent(); const auto *Flag = mdconst::extract_or_null( M->getModuleFlag("ptrauth-elf-got")); if (Flag && Flag->getZExtValue() == 1) - return true; - return false; + return {true, false}; + const auto *FlagFunc = mdconst::extract_or_null( + M->getModuleFlag("ptrauth-elf-got-func")); + if (FlagFunc && FlagFunc->getZExtValue() == 1) + return {false, true}; + return {false, false}; } +// OHOS_LOCAL end AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF_) : MF(&MF_) { // If we already know that the function doesn't have a redzone, set @@ -101,7 +107,9 @@ AArch64FunctionInfo::AArch64FunctionInfo(MachineFunction &MF_) : MF(&MF_) { const Function &F = MF->getFunction(); std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); SignWithBKey = ShouldSignWithBKey(F); - HasELFSignedGOT = hasELFSignedGOTHelper(F, MF->getSubtarget()); + // OHOS_LOCAL begin + std::tie(HasELFSignedGOT, HasELFSignedGOTFunc) = hasELFSignedGOTHelper(F, MF->getSubtarget()); + // OHOS_LOCAL end // TODO: skip functions that have no instrumented allocas for optimization IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag); diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h index dfaaa3eeb03c..7121e9867468 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -197,6 +197,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo { /// module containing the corresponding function has "ptrauth-elf-got" flag /// set to 1. bool HasELFSignedGOT = false; + bool HasELFSignedGOTFunc = false; // OHOS_LOCAL public: explicit AArch64FunctionInfo(MachineFunction &MF); @@ -459,6 +460,7 @@ public: // OHOS_LOCAL end bool hasELFSignedGOT() const { return HasELFSignedGOT; } + bool hasELFSignedGOTFunc() const { return HasELFSignedGOTFunc; } // OHOS_LOCAL private: // Hold the lists of LOHs. MILOHContainer LOHContainerSet; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index fc6b0f1415e5..b8cc907d69bc 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -2747,7 +2747,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) { } if (OpFlags & AArch64II::MO_GOT) { - I.setDesc(TII.get(MF.getInfo()->hasELFSignedGOT() + // OHOS_LOCAL begin + bool IsGotAuth = MF.getInfo()->hasELFSignedGOT() || + (MF.getInfo()->hasELFSignedGOTFunc() && + GV->getValueType()->isFunctionTy()); + // OHOS_LOCAL end + I.setDesc(TII.get(IsGotAuth ? AArch64::LOADgotAUTH : AArch64::LOADgot)); I.getOperand(1).setTargetFlags(OpFlags); -- Gitee From 3651a7332add4f58028732383dba69b613574003 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Wed, 18 Jun 2025 16:31:22 +0800 Subject: [PATCH 08/10] [PAC] [GOT AUTH] Fix test case Signed-off-by:baojingjing --- lld/ELF/Relocations.cpp | 8 ++ lld/ELF/Symbols.h | 5 +- lld/test/ELF/aarch64-got-relocations-pauth.s | 20 +-- .../test/CodeGen/AArch64/ptrauth-basic-pic.ll | 85 +++---------- .../AArch64/ptrauth-elf-globals-pic.ll | 25 +--- .../ptrauth-elf-got-function-symbols.ll | 16 +-- .../CodeGen/AArch64/ptrauth-extern-weak.ll | 80 +++--------- .../test/CodeGen/AArch64/ptrauth-got-abuse.ll | 53 ++------ .../AArch64/ptrauth-tagged-globals-pic.ll | 71 ++--------- .../CodeGen/AArch64/ptrauth-tiny-model-pic.ll | 116 +++--------------- .../AArch64/ptrauth-tiny-model-static.ll | 103 +++------------- .../llvm-readobj/ELF/reloc-types-aarch64.test | 18 ++- 12 files changed, 131 insertions(+), 469 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index f5d74a357f13..8d6e3f822ba1 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1470,6 +1470,8 @@ template void RelocationScanner::scanOne(RelTy *&i) { if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC || expr == RE_AARCH64_AUTH_GOT_PC) sym.needsGotAuth = true; + else + sym.needsGotNoAuth = true; } } else if (needsPlt(expr)) { sym.needsPlt = true; @@ -1671,6 +1673,12 @@ void elf::postScanRelocations() { sym.allocateAux(); if (sym.needsGot) { + if (sym.needsGotAuth && sym.needsGotNoAuth) { + errorOrWarn("both AUTH and non-AUTH GOT entries for '" + sym.getName() + + "' requested, but only one type of GOT entry per symbol is " + + "supported"); + return; + } if (sym.needsGotAuth) addGotAuthEntry(sym); else diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 5e553c5d805f..dd55ef03077e 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -253,7 +253,7 @@ protected: scriptDefined(false), needsCopy(false), needsGot(false), needsPlt(false), needsTlsDesc(false), needsTlsGd(false), needsTlsGdToIe(false), needsGotDtprel(false), needsTlsIe(false), - hasDirectReloc(false), needsGotAuth(false) {} + hasDirectReloc(false), needsGotAuth(false), needsGotNoAuth(false) {} public: // True if this symbol is in the Iplt sub-section of the Plt and the Igot @@ -290,8 +290,9 @@ public: uint8_t needsTlsGdToIe : 1; uint8_t needsGotDtprel : 1; uint8_t needsTlsIe : 1; - uint8_t hasDirectReloc : 1; + uint8_t hasDirectReloc : 1; uint8_t needsGotAuth : 1; + uint8_t needsGotNoAuth : 1; // A symAux index used to access GOT/PLT entry indexes. This is allocated in // postScanRelocations(). diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s index 2d37123f1cca..ded9572b92c9 100644 --- a/lld/test/ELF/aarch64-got-relocations-pauth.s +++ b/lld/test/ELF/aarch64-got-relocations-pauth.s @@ -46,25 +46,25 @@ # OK1-ASM: <_start>: # OK1-ASM-NEXT: adrp x0, 0x20000 -# OK1-ASM-NEXT: ldr x0, [x0, #0x380] +# OK1-ASM-NEXT: ldr x0, [x0, #896] # OK1-ASM-NEXT: adrp x1, 0x20000 -# OK1-ASM-NEXT: add x1, x1, #0x380 +# OK1-ASM-NEXT: add x1, x1, #896 # OK1-ASM-NEXT: adrp x0, 0x20000 -# OK1-ASM-NEXT: ldr x0, [x0, #0x388] +# OK1-ASM-NEXT: ldr x0, [x0, #904] # OK1-ASM-NEXT: adrp x1, 0x20000 -# OK1-ASM-NEXT: add x1, x1, #0x388 +# OK1-ASM-NEXT: add x1, x1, #904 # RUN: llvm-objdump -d ok2 | FileCheck %s --check-prefix=OK2-ASM # OK2-ASM: <_start>: # OK2-ASM-NEXT: adrp x0, 0x20000 -# OK2-ASM-NEXT: ldr x0, [x0, #0x320] +# OK2-ASM-NEXT: ldr x0, [x0, #800] # OK2-ASM-NEXT: adrp x1, 0x20000 -# OK2-ASM-NEXT: add x1, x1, #0x320 +# OK2-ASM-NEXT: add x1, x1, #800 # OK2-ASM-NEXT: adrp x0, 0x20000 -# OK2-ASM-NEXT: ldr x0, [x0, #0x328] +# OK2-ASM-NEXT: ldr x0, [x0, #808] # OK2-ASM-NEXT: adrp x1, 0x20000 -# OK2-ASM-NEXT: add x1, x1, #0x328 +# OK2-ASM-NEXT: add x1, x1, #808 .globl _start _start: @@ -117,13 +117,13 @@ _start: # RUN: llvm-objdump -d tiny1 | FileCheck %s --check-prefix=TINY1-ASM # TINY1-ASM: <_start>: -# TINY1-ASM-NEXT: adr x0, 0x20368 +# TINY1-ASM-NEXT: adr x0, #65752 # TINY1-ASM-NEXT: ldr x1, 0x20370 # RUN: llvm-objdump -d tiny2 | FileCheck %s --check-prefix=TINY2-ASM # TINY2-ASM: <_start>: -# TINY2-ASM-NEXT: adr x0, 0x20308 +# TINY2-ASM-NEXT: adr x0, #65736 # TINY2-ASM-NEXT: ldr x1, 0x20310 .globl _start diff --git a/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll index 517a0a86ef14..7409175120af 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll @@ -1,17 +1,11 @@ ; 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: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK ; 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: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK ; 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 +; RUN: -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s --check-prefixes=CHECK ;; Note: for FastISel, we fall back to SelectionDAG @@ -21,17 +15,8 @@ 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 x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldr w0, [x8] ; CHECK-NEXT: ret @@ -43,17 +28,8 @@ 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: ldr x0, [x17] +; CHECK-NEXT: autda x0, x17 ; CHECK-NEXT: ret %val = load i32, ptr @var @@ -66,61 +42,34 @@ 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: ldr x0, [x17] +; CHECK-NEXT: autia x0, x17 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr @foo, i32 0, i64 42) + ret ptr @foo } 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: ldr x0, [x17] +; CHECK-NEXT: autda x0, x17 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr @var, i32 3, i64 43) + ret ptr @var } 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: ldr x8, [x17] +; CHECK-NEXT: autda x8, x17 +; CHECK-NEXT: add x0, x8, #16 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @var, i64 16), i32 2, i64 44) + ret ptr getelementptr (i8, ptr @var, i64 16) } !llvm.module.flags = !{!0} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll index 23357cd80257..bebf8d2cb820 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-elf-globals-pic.ll @@ -1,17 +1,11 @@ ; 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: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK %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: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK %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 +; RUN: -mcpu=cyclone -mattr=+pauth | FileCheck --check-prefixes=CHECK %s ;; Note: for FastISel, we fall back to SelectionDAG @@ -25,17 +19,8 @@ define i8 @test_i8(i8 %new) { ; 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: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: ldrb w8, [x9] ; CHECK-NEXT: strb w0, [x9] ; CHECK-NEXT: mov x0, x8 diff --git a/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll index e75acceaa0d1..c57e86e9b756 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll @@ -7,17 +7,9 @@ ; 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: ldr x9, [x17] +; ASM-NEXT: autia x9, x17 +; ASM-NEXT: str x9, [x8, :lo12:.Lfptr] ; ASM-NEXT: ret ; ASM: .type .Lfptr,@object ; ASM-NEXT: .local .Lfptr @@ -31,7 +23,7 @@ @fptr = private global ptr null define void @foo() { - store ptr ptrauth (ptr @bar, i32 0), ptr @fptr + store ptr @bar, ptr @fptr ret void } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll index 141af917fa3e..9dbe0c7ae80e 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll @@ -1,22 +1,14 @@ ; 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: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %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: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %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 +; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %s -; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -mattr=+fpac -o - %s | \ -; RUN: FileCheck --check-prefixes=CHECK-TINY,NOTRAP-TINY %s ; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -o - %s | \ -; RUN: FileCheck --check-prefixes=CHECK-TINY,TRAP-TINY %s +; RUN: FileCheck --check-prefixes=CHECK-TINY %s ;; Note: for FastISel, we fall back to SelectionDAG @@ -31,38 +23,18 @@ define ptr @foo() { ; 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: ldr x0, [x17] +; CHECK-NEXT: cbz x0, .Lundef_weak0 +; CHECK-NEXT: autia x0, 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 ; CHECK-TINY-LABEL: foo: ; CHECK-TINY: adr x17, :got_auth:var -; NOTRAP-TINY-NEXT: ldr x0, [x17] -; NOTRAP-TINY-NEXT: cbz x0, .Lundef_weak0 -; NOTRAP-TINY-NEXT: autia x0, x17 -; TRAP-TINY-NEXT: ldr x16, [x17] -; TRAP-TINY-NEXT: cbz x16, .Lundef_weak0 -; TRAP-TINY-NEXT: autia x16, x17 +; CHECK-TINY-NEXT: ldr x0, [x17] +; CHECK-TINY-NEXT: cbz x0, .Lundef_weak0 +; CHECK-TINY-NEXT: autia x0, x17 ; CHECK-TINY-NEXT: .Lundef_weak0: -; TRAP-TINY-NEXT: mov x17, x16 -; TRAP-TINY-NEXT: xpaci x17 -; TRAP-TINY-NEXT: cmp x16, x17 -; TRAP-TINY-NEXT: b.eq .Lauth_success_0 -; TRAP-TINY-NEXT: brk #0xc470 -; TRAP-TINY-NEXT: .Lauth_success_0: -; TRAP-TINY-NEXT: mov x0, x16 ; CHECK-TINY-NEXT: ret } @@ -75,39 +47,19 @@ define ptr @bar() { ; 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: ldr x8, [x17] +; CHECK-NEXT: cbz x8, .Lundef_weak1 +; CHECK-NEXT: autda x8, 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 ; CHECK-TINY-LABEL: bar: ; CHECK-TINY: adr x17, :got_auth:arr_var -; NOTRAP-TINY-NEXT: ldr x8, [x17] -; NOTRAP-TINY-NEXT: cbz x8, .Lundef_weak1 -; NOTRAP-TINY-NEXT: autda x8, x17 -; TRAP-TINY-NEXT: ldr x16, [x17] -; TRAP-TINY-NEXT: cbz x16, .Lundef_weak1 -; TRAP-TINY-NEXT: autda x16, x17 +; CHECK-TINY-NEXT: ldr x8, [x17] +; CHECK-TINY-NEXT: cbz x8, .Lundef_weak1 +; CHECK-TINY-NEXT: autda x8, x17 ; CHECK-TINY-NEXT: .Lundef_weak1: -; TRAP-TINY-NEXT: mov x17, x16 -; TRAP-TINY-NEXT: xpacd x17 -; TRAP-TINY-NEXT: cmp x16, x17 -; TRAP-TINY-NEXT: b.eq .Lauth_success_1 -; TRAP-TINY-NEXT: brk #0xc472 -; TRAP-TINY-NEXT: .Lauth_success_1: -; TRAP-TINY-NEXT: mov x8, x16 ; CHECK-TINY-NEXT: add x0, x8, #20 ; CHECK-TINY-NEXT: ret } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll b/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll index 3c4747c32185..0af6185f3056 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-got-abuse.ll @@ -1,17 +1,11 @@ ; 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: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %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: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %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: -relocation-model=pic -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK %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 @@ -39,47 +33,22 @@ 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 +; CHECK-NEXT: ldr x[[TMP0:[0-9]+]], [x17] +; CHECK-NEXT: autia x[[TMP0]], x17 + 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 +; CHECK-NEXT: ldr x[[TMP1:[0-9]+]], [x17] +; CHECK-NEXT: autia x[[TMP1]], x17 + 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 +; CHECK-NEXT: ldr x[[TMP2:[0-9]+]], [x17] +; CHECK-NEXT: autda x[[TMP2]], x17 ret void } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll index ee34b439daec..858709310da3 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-tagged-globals-pic.ll @@ -1,17 +1,11 @@ ; 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: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL ; 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: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL ; 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 +; RUN: -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,GISEL ;; Note: for FastISel, we fall back to SelectionDAG @@ -25,17 +19,8 @@ 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: ldr x0, [x17] +; CHECK-NEXT: autda x0, x17 ; CHECK-NEXT: ret ret ptr @global @@ -45,17 +30,8 @@ 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 x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldr w0, [x8] ; CHECK-NEXT: ret @@ -67,22 +43,10 @@ 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: ldr x8, [x17] +; GISEL-NEXT: autda x8, x17 +; DAGISEL-NEXT: ldr x9, [x17] +; DAGISEL-NEXT: autda x9, x17 ; GISEL-NEXT: str wzr, [x8] ; DAGISEL-NEXT: mov w8, wzr ; DAGISEL-NEXT: str w8, [x9] @@ -95,17 +59,8 @@ 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: ldr x0, [x17] +; CHECK-NEXT: autia x0, x17 ; CHECK-NEXT: ret ret ptr @func diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll index 9d13714bbefe..967b0b233ad1 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll @@ -1,17 +1,11 @@ -; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ -; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ -; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK %s -; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ -; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ -; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK %s -; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ -; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \ -; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK %s ; Note: fast-isel tests here will fall back to isel @@ -23,30 +17,12 @@ define dso_preemptable void @foo1() { ; CHECK-LABEL: foo1: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:src -; 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 x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldrb w8, [x8] ; CHECK-NEXT: adr x17, :got_auth:dst -; 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_1 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_1: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: strb w8, [x9] ; CHECK-NEXT: ret @@ -60,29 +36,11 @@ define dso_preemptable void @foo2() { ; CHECK-LABEL: foo2: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:ptr -; 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_2 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_2: -; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldr x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: adr x17, :got_auth:dst -; 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_3 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_3: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: str x9, [x8] ; CHECK-NEXT: ret @@ -95,30 +53,12 @@ define dso_preemptable void @foo3() { ; CHECK-LABEL: foo3: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:src -; 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_4 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_4: -; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldr x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldrb w8, [x8] ; CHECK-NEXT: adr x17, :got_auth:ptr -; 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_5 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_5: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: ldr x9, [x9] ; CHECK-NEXT: strb w8, [x9] ; CHECK-NEXT: ret @@ -140,17 +80,8 @@ define dso_preemptable ptr @externfuncaddr() { ; CHECK-LABEL: externfuncaddr: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth: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_6 -; TRAP-NEXT: brk #0xc470 -; TRAP-NEXT: .Lauth_success_6: -; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ldr x0, [x17] +; CHECK-NEXT: autia x0, x17 ; CHECK-NEXT: ret entry: @@ -161,17 +92,8 @@ define dso_preemptable ptr @localfuncaddr() { ; CHECK-LABEL: localfuncaddr: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:externfuncaddr -; 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_7 -; TRAP-NEXT: brk #0xc470 -; TRAP-NEXT: .Lauth_success_7: -; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ldr x0, [x17] +; CHECK-NEXT: autia x0, x17 ; CHECK-NEXT: ret entry: diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll index 2d098b70accc..8bf364b5b429 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll @@ -1,17 +1,11 @@ -; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ -; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ -; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK %s -; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ -; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ -; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK %s -; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \ -; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s ; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \ -; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s +; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK %s ; Note fast-isel tests here will fall back to isel @@ -23,30 +17,12 @@ define dso_local void @foo1() { ; CHECK-LABEL: foo1: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:src -; 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 x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldrb w8, [x8] ; CHECK-NEXT: adr x17, :got_auth:dst -; 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_1 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_1: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: strb w8, [x9] ; CHECK-NEXT: ret @@ -60,29 +36,11 @@ define dso_local void @foo2() { ; CHECK-LABEL: foo2: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:ptr -; 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_2 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_2: -; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldr x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: adr x17, :got_auth:dst -; 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_3 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_3: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: str x9, [x8] ; CHECK-NEXT: ret @@ -95,30 +53,12 @@ define dso_local void @foo3() { ; CHECK-LABEL: foo3: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth:src -; 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_4 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_4: -; TRAP-NEXT: mov x8, x16 +; CHECK-NEXT: ldr x8, [x17] +; CHECK-NEXT: autda x8, x17 ; CHECK-NEXT: ldrb w8, [x8] ; CHECK-NEXT: adr x17, :got_auth:ptr -; 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_5 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: .Lauth_success_5: -; TRAP-NEXT: mov x9, x16 +; CHECK-NEXT: ldr x9, [x17] +; CHECK-NEXT: autda x9, x17 ; CHECK-NEXT: ldr x9, [x9] ; CHECK-NEXT: strb w8, [x9] ; CHECK-NEXT: ret @@ -136,17 +76,8 @@ define dso_local ptr @externfuncaddr() { ; CHECK-LABEL: externfuncaddr: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: adr x17, :got_auth: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_6 -; TRAP-NEXT: brk #0xc470 -; TRAP-NEXT: .Lauth_success_6: -; TRAP-NEXT: mov x0, x16 +; CHECK-NEXT: ldr x0, [x17] +; CHECK-NEXT: autia x0, x17 ; CHECK-NEXT: ret entry: diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test b/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test index 2756e51d3fb3..6b57bc0cae2c 100644 --- a/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test +++ b/llvm/test/tools/llvm-readobj/ELF/reloc-types-aarch64.test @@ -133,9 +133,8 @@ # CHECK: Type: R_AARCH64_TLS_TPREL64 (1030) # CHECK: Type: R_AARCH64_TLSDESC (1031) # CHECK: Type: R_AARCH64_IRELATIVE (1032) +# CHECK: Type: R_AARCH64_AUTH_RELATIVE (1041) # CHECK: Type: R_AARCH64_AUTH_GLOB_DAT (1042) -# CHECK: Type: R_AARCH64_AUTH_TLSDESC (1043) -# CHECK: Type: R_AARCH64_AUTH_IRELATIVE (1044) --- !ELF FileHeader: Class: ELFCLASS64 @@ -261,11 +260,11 @@ Sections: - Type: R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC - Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12 - Type: R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC - - Type: R_AARCH64_AUTH_GOT_LD_PREL19 - - Type: R_AARCH64_AUTH_ADR_GOT_PAGE - - Type: R_AARCH64_AUTH_LD64_GOT_LO12_NC - - Type: R_AARCH64_AUTH_GOT_ADD_LO12_NC - - Type: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 + - Type: R_AARCH64_AUTH_GOT_LD_PREL19 + - Type: R_AARCH64_AUTH_ADR_GOT_PAGE + - Type: R_AARCH64_AUTH_LD64_GOT_LO12_NC + - Type: R_AARCH64_AUTH_GOT_ADD_LO12_NC + - Type: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 - Type: R_AARCH64_COPY - Type: R_AARCH64_GLOB_DAT - Type: R_AARCH64_JUMP_SLOT @@ -275,6 +274,5 @@ Sections: - Type: R_AARCH64_TLS_TPREL64 - Type: R_AARCH64_TLSDESC - Type: R_AARCH64_IRELATIVE - - Type: R_AARCH64_AUTH_GLOB_DAT - - Type: R_AARCH64_AUTH_TLSDESC - - Type: R_AARCH64_AUTH_IRELATIVE + - Type: R_AARCH64_AUTH_RELATIVE + - Type: R_AARCH64_AUTH_GLOB_DAT -- Gitee From 2c61d8b5c00442dfa39543ece150cc4a815f3631 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 26 Jun 2025 17:48:54 +0800 Subject: [PATCH 09/10] [PAC] [GOT AUTH] Fix code check Signed-off-by:baojingjing --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 6 +++--- llvm/lib/Target/AArch64/AArch64MCInstLower.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 69fbc7b9317c..84a0118ae549 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7195,15 +7195,15 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG, // (loadGOT sym) template SDValue AArch64TargetLowering::getGOTAuth(NodeTy *N, SelectionDAG &DAG, - unsigned Flags) const { + unsigned Flags) const { LLVM_DEBUG(dbgs() << "AArch64TargetLowering::getGOTAuth\n"); SDLoc DL(N); EVT Ty = getPointerTy(DAG.getDataLayout()); SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags); bool IsGotAuth = - DAG.getMachineFunction() + DAG.getMachineFunction() .getInfo()->hasELFSignedGOT() || - (DAG.getMachineFunction() + (DAG.getMachineFunction() .getInfo()->hasELFSignedGOTFunc() && N->getGlobal()->getValueType()->isFunctionTy()); if (IsGotAuth) diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp index 5ffd29b5139c..646b6ee1bbec 100644 --- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp +++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp @@ -119,12 +119,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO, if (MO.getTargetFlags() & AArch64II::MO_GOT) { const MachineFunction *MF = MO.getParent()->getParent()->getParent(); // OHOS_LOCAL begin - bool IsGotAuth = MF->getInfo()->hasELFSignedGOT() || - (MF->getInfo()->hasELFSignedGOTFunc() && - MO.getGlobal()->getValueType()->isFunctionTy()); - RefFlags |= (IsGotAuth - ? AArch64MCExpr::VK_GOT_AUTH - : AArch64MCExpr::VK_GOT); + bool IsGotAuth = + MF->getInfo()->hasELFSignedGOT() || + (MF->getInfo()->hasELFSignedGOTFunc() && + MO.getGlobal()->getValueType()->isFunctionTy()); + RefFlags |= + (IsGotAuth ? AArch64MCExpr::VK_GOT_AUTH : AArch64MCExpr::VK_GOT); // OHOS_LOCAL end } else if (MO.getTargetFlags() & AArch64II::MO_TLS) { TLSModel::Model Model; -- Gitee From 68e73fe67f8ce424a894813b0db21198ad6a8349 Mon Sep 17 00:00:00 2001 From: baojingjing Date: Thu, 26 Jun 2025 18:06:45 +0800 Subject: [PATCH 10/10] [PAC] [GOT AUTH] Fix indent Signed-off-by:baojingjing --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 84a0118ae549..3e61026e7ce6 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7202,9 +7202,9 @@ SDValue AArch64TargetLowering::getGOTAuth(NodeTy *N, SelectionDAG &DAG, SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags); bool IsGotAuth = DAG.getMachineFunction() - .getInfo()->hasELFSignedGOT() || + .getInfo()->hasELFSignedGOT() || (DAG.getMachineFunction() - .getInfo()->hasELFSignedGOTFunc() && + .getInfo()->hasELFSignedGOTFunc() && N->getGlobal()->getValueType()->isFunctionTy()); if (IsGotAuth) return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr), -- Gitee