diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index d55947fc5103ac..9336f2a454ae47 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -1238,6 +1238,7 @@ HANDLE_DW_CFA(0x16, val_expression) // Vendor extensions: HANDLE_DW_CFA_PRED(0x1d, MIPS_advance_loc8, SELECT_MIPS64) HANDLE_DW_CFA_PRED(0x2d, GNU_window_save, SELECT_SPARC) +HANDLE_DW_CFA_PRED(0x2c, AARCH64_negate_ra_state_with_pc, SELECT_AARCH64) HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64) HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86) // Heterogeneous Debugging Extension defined at diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index bea79545d1ab96..2ceea906ea57a7 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -515,6 +515,7 @@ class MCCFIInstruction { OpRegister, OpWindowSave, OpNegateRAState, + OpNegateRAStateWithPC, OpGnuArgsSize, OpLabel, }; @@ -642,6 +643,13 @@ class MCCFIInstruction { return MCCFIInstruction(OpNegateRAState, L, 0, INT64_C(0), Loc); } + /// .cfi_negate_ra_state_with_pc AArch64 negate RA state with PC. + static MCCFIInstruction createNegateRAStateWithPC(MCSymbol *L, + SMLoc Loc = {}) { + return MCCFIInstruction(OpNegateRAStateWithPC, L, 0, INT64_C(0), Loc); + } + + /// .cfi_restore says that the rule for Register is now the same as it /// was at the beginning of the function, after all initial instructions added /// by .cfi_startproc were executed. diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 707aecc5dc578e..a376ba810ba515 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -1022,6 +1022,7 @@ class MCStreamer { SMLoc Loc = {}); virtual void emitCFIWindowSave(SMLoc Loc = {}); virtual void emitCFINegateRAState(SMLoc Loc = {}); + virtual void emitCFINegateRAStateWithPC(SMLoc Loc = {}); virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name); virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc()); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 21d0d070c247f4..daad82d26da652 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -236,6 +236,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { case MCCFIInstruction::OpNegateRAState: OutStreamer->emitCFINegateRAState(Loc); break; + case MCCFIInstruction::OpNegateRAStateWithPC: + OutStreamer->emitCFINegateRAStateWithPC(Loc); + break; case MCCFIInstruction::OpSameValue: OutStreamer->emitCFISameValue(Inst.getRegister(), Loc); break; diff --git a/llvm/lib/CodeGen/CFIInstrInserter.cpp b/llvm/lib/CodeGen/CFIInstrInserter.cpp index f5bedc7b8ecdfc..4217ec6a1cca8a 100644 --- a/llvm/lib/CodeGen/CFIInstrInserter.cpp +++ b/llvm/lib/CodeGen/CFIInstrInserter.cpp @@ -260,6 +260,7 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) { case MCCFIInstruction::OpEscape: case MCCFIInstruction::OpWindowSave: case MCCFIInstruction::OpNegateRAState: + case MCCFIInstruction::OpNegateRAStateWithPC: case MCCFIInstruction::OpGnuArgsSize: case MCCFIInstruction::OpLabel: break; diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp index 0809f88fde56b1..5a3806ce57335a 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -238,6 +238,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("window_save", MIToken::kw_cfi_window_save) .Case("negate_ra_sign_state", MIToken::kw_cfi_aarch64_negate_ra_sign_state) + .Case("negate_ra_sign_state_with_pc", + MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc) .Case("blockaddress", MIToken::kw_blockaddress) .Case("intrinsic", MIToken::kw_intrinsic) .Case("target-index", MIToken::kw_target_index) diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h index 22547483a8a86b..3931da3eaae1d3 100644 --- a/llvm/lib/CodeGen/MIRParser/MILexer.h +++ b/llvm/lib/CodeGen/MIRParser/MILexer.h @@ -96,6 +96,7 @@ struct MIToken { kw_cfi_undefined, kw_cfi_window_save, kw_cfi_aarch64_negate_ra_sign_state, + kw_cfi_aarch64_negate_ra_sign_state_with_pc, kw_blockaddress, kw_intrinsic, kw_target_index, diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 7aaa0f409d5ef9..45847b5830da65 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -2576,6 +2576,10 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) { case MIToken::kw_cfi_aarch64_negate_ra_sign_state: CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); break; + case MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc: + CFIIndex = + MF.addFrameInst(MCCFIInstruction::createNegateRAStateWithPC(nullptr)); + break; case MIToken::kw_cfi_escape: { std::string Values; if (parseCFIEscapeValues(Values)) @@ -2931,6 +2935,7 @@ bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, case MIToken::kw_cfi_undefined: case MIToken::kw_cfi_window_save: case MIToken::kw_cfi_aarch64_negate_ra_sign_state: + case MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc: return parseCFIOperand(Dest); case MIToken::kw_blockaddress: return parseBlockAddressOperand(Dest); diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp index 89d32c3f005e00..cd94213da79893 100644 --- a/llvm/lib/CodeGen/MachineOperand.cpp +++ b/llvm/lib/CodeGen/MachineOperand.cpp @@ -768,6 +768,10 @@ static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, if (MCSymbol *Label = CFI.getLabel()) MachineOperand::printSymbol(OS, *Label); break; + case MCCFIInstruction::OpNegateRAStateWithPC: + OS << "negate_ra_sign_state_with_pc "; + if (MCSymbol *Label = CFI.getLabel()) + MachineOperand::printSymbol(OS, *Label); default: // TODO: Print the other CFI Operations. OS << ""; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index aff26824dda104..38e264f233e39b 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -288,6 +288,7 @@ Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset, case DW_CFA_remember_state: case DW_CFA_restore_state: case DW_CFA_GNU_window_save: + case DW_CFA_AARCH64_negate_ra_state_with_pc: // No operands addInstruction(Opcode); break; @@ -666,6 +667,28 @@ Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row, } break; + case dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc: { + constexpr uint32_t AArch64DWARFPAuthRaState = 34; + auto LRLoc = Row.getRegisterLocations().getRegisterLocation( + AArch64DWARFPAuthRaState); + if (LRLoc) { + if (LRLoc->getLocation() == UnwindLocation::Constant) { + // Toggle the constant value of bits[1:0] from 0 to 1 or 1 to 0. + LRLoc->setConstant(LRLoc->getConstant() ^ 0x3); + } else { + return createStringError( + errc::invalid_argument, + "%s encountered when existing rule for this register is not " + "a constant", + CFIP.callFrameString(Inst.Opcode).str().c_str()); + } + } else { + Row.getRegisterLocations().setRegisterLocation( + AArch64DWARFPAuthRaState, UnwindLocation::createIsConstant(0x3)); + } + break; + } + case dwarf::DW_CFA_undefined: { llvm::Expected RegNum = Inst.getOperandAsUnsigned(CFIP, 0); if (!RegNum) @@ -847,6 +870,7 @@ CFIProgram::getOperandTypes() { DECLARE_OP0(DW_CFA_remember_state); DECLARE_OP0(DW_CFA_restore_state); DECLARE_OP0(DW_CFA_GNU_window_save); + DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc); DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset); DECLARE_OP0(DW_CFA_nop); diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 31b519a3e5c56a..b9ad0b4eac9c7b 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -373,6 +373,7 @@ class MCAsmStreamer final : public MCStreamer { SMLoc Loc) override; void emitCFIWindowSave(SMLoc Loc) override; void emitCFINegateRAState(SMLoc Loc) override; + void emitCFINegateRAStateWithPC(SMLoc Loc) override; void emitCFIReturnColumn(int64_t Register) override; void emitCFILabelDirective(SMLoc Loc, StringRef Name) override; @@ -2145,6 +2146,12 @@ void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) { EmitEOL(); } +void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) { + MCStreamer::emitCFINegateRAStateWithPC(Loc); + OS << "\t.cfi_negate_ra_state_with_pc"; + EmitEOL(); +} + void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) { MCStreamer::emitCFIReturnColumn(Register); OS << "\t.cfi_return_column "; diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 8ff097f29aebd1..e058358fb8ad4b 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1381,6 +1381,10 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) { Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state); return; + case MCCFIInstruction::OpNegateRAStateWithPC: + Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc); + return; + case MCCFIInstruction::OpUndefined: { unsigned Reg = Instr.getRegister(); Streamer.emitInt8(dwarf::DW_CFA_undefined); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 13b162768578c5..5474db1315f141 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -688,6 +688,16 @@ void MCStreamer::emitCFINegateRAState(SMLoc Loc) { CurFrame->Instructions.push_back(Instruction); } +void MCStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) { + MCSymbol *Label = emitCFILabel(); + MCCFIInstruction Instruction = + MCCFIInstruction::createNegateRAStateWithPC(Label, Loc); + MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); + if (!CurFrame) + return; + CurFrame->Instructions.push_back(Instruction); +} + void MCStreamer::emitCFIReturnColumn(int64_t Register) { MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); if (!CurFrame) diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 1b8eac7fac21f7..c12540809e727d 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -702,7 +702,10 @@ void AArch64FrameLowering::resetCFIToInitialState( // Flip the RA sign state. if (MFI.shouldSignReturnAddress(MF)) { - CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); + auto CFIInst = MFI.branchProtectionPAuthLR() + ? MCCFIInstruction::createNegateRAStateWithPC(nullptr) + : MCCFIInstruction::createNegateRAState(nullptr); + CFIIndex = MF.addFrameInst(CFIInst); BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex); } diff --git a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp index 92ab4b5c3d251f..0879b5aec37aea 100644 --- a/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp +++ b/llvm/lib/Target/AArch64/AArch64PointerAuth.cpp @@ -71,6 +71,18 @@ FunctionPass *llvm::createAArch64PointerAuthPass() { char AArch64PointerAuth::ID = 0; +static void emitPACSymOffsetIntoX16(const TargetInstrInfo &TII, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, DebugLoc DL, + MCSymbol *PACSym) { + BuildMI(MBB, I, DL, TII.get(AArch64::ADRP), AArch64::X16) + .addSym(PACSym, AArch64II::MO_PAGE); + BuildMI(MBB, I, DL, TII.get(AArch64::ADDXri), AArch64::X16) + .addReg(AArch64::X16) + .addSym(PACSym, AArch64II::MO_PAGEOFF | AArch64II::MO_NC) + .addImm(0); +} + // Where PAuthLR support is not known at compile time, it is supported using // PACM. PACM is in the hint space so has no effect when PAuthLR is not // supported by the hardware, but will alter the behaviour of PACI*SP, AUTI*SP @@ -81,12 +93,10 @@ static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB, const TargetInstrInfo *TII = Subtarget.getInstrInfo(); auto &MFnI = *MBB.getParent()->getInfo(); - // ADR X16, + // Offset to PAC*SP using ADRP + ADD. if (PACSym) { assert(Flags == MachineInstr::FrameDestroy); - BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADR)) - .addReg(AArch64::X16, RegState::Define) - .addSym(PACSym); + emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym); } // Only emit PACM if -mbranch-protection has +pc and the target does not @@ -95,12 +105,49 @@ static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB, BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACM)).setMIFlag(Flags); } +static void emitPACCFI(const AArch64Subtarget &Subtarget, + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + DebugLoc DL, MachineInstr::MIFlag Flags, bool EmitCFI) { + if (!EmitCFI) + return; + + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + auto &MF = *MBB.getParent(); + auto &MFnI = *MF.getInfo(); + bool EmitAsyncCFI = MFnI.needsAsyncDwarfUnwindInfo(MF); + + auto CFIInst = MFnI.branchProtectionPAuthLR() + ? MCCFIInstruction::createNegateRAStateWithPC(nullptr) + : MCCFIInstruction::createNegateRAState(nullptr); + + // Because of PAuthLR, when using NegateRAStateWithPC, the CFI instruction cannot + // be bundled with other CFI instructions in the prolog, as it needs to directly + // follow the signing instruction. This ensures the PC value is captured incase of + // an error in the following the following instructions. + if (!EmitAsyncCFI && !(MFnI.branchProtectionPAuthLR())) { + // Reduce the size of the generated call frame information for synchronous + // CFI by bundling the new CFI instruction with others in the prolog, so + // that no additional DW_CFA_advance_loc is needed. + for (auto I = MBBI; I != MBB.end(); ++I) { + if (I->getOpcode() == TargetOpcode::CFI_INSTRUCTION && + I->getFlag(MachineInstr::FrameSetup)) { + MBBI = I; + break; + } + } + } + + unsigned CFIIndex = MF.addFrameInst(CFIInst); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(Flags); +} + void AArch64PointerAuth::signLR(MachineFunction &MF, MachineBasicBlock::iterator MBBI) const { auto &MFnI = *MF.getInfo(); bool UseBKey = MFnI.shouldSignWithBKey(); bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF); - bool EmitAsyncCFI = MFnI.needsAsyncDwarfUnwindInfo(MF); bool NeedsWinCFI = MF.hasWinCFI(); MachineBasicBlock &MBB = *MBBI->getParent(); @@ -128,6 +175,7 @@ void AArch64PointerAuth::signLR(MachineFunction &MF, : AArch64::PACIASPPC)) .setMIFlag(MachineInstr::FrameSetup) ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel()); + emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI); } else { BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup); BuildMI(MBB, MBBI, DL, @@ -135,27 +183,10 @@ void AArch64PointerAuth::signLR(MachineFunction &MF, : AArch64::PACIASP)) .setMIFlag(MachineInstr::FrameSetup) ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel()); + emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI); } - if (EmitCFI) { - if (!EmitAsyncCFI) { - // Reduce the size of the generated call frame information for synchronous - // CFI by bundling the new CFI instruction with others in the prolog, so - // that no additional DW_CFA_advance_loc is needed. - for (auto I = MBBI; I != MBB.end(); ++I) { - if (I->getOpcode() == TargetOpcode::CFI_INSTRUCTION && - I->getFlag(MachineInstr::FrameSetup)) { - MBBI = I; - break; - } - } - } - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - } else if (NeedsWinCFI) { + if (!EmitCFI && NeedsWinCFI) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) .setMIFlag(MachineInstr::FrameSetup); } @@ -190,6 +221,7 @@ void AArch64PointerAuth::authenticateLR( !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) { if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) { assert(PACSym && "No PAC instruction to refer to"); + emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym); BuildMI(MBB, TI, DL, TII->get(UseBKey ? AArch64::RETABSPPCi : AArch64::RETAASPPCi)) .addSym(PACSym) @@ -205,24 +237,20 @@ void AArch64PointerAuth::authenticateLR( } else { if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) { assert(PACSym && "No PAC instruction to refer to"); + emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym); BuildMI(MBB, MBBI, DL, TII->get(UseBKey ? AArch64::AUTIBSPPCi : AArch64::AUTIASPPCi)) .addSym(PACSym) .setMIFlag(MachineInstr::FrameDestroy); + emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, EmitAsyncCFI); } else { BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, PACSym); BuildMI(MBB, MBBI, DL, TII->get(UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP)) .setMIFlag(MachineInstr::FrameDestroy); + emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, EmitAsyncCFI); } - if (EmitAsyncCFI) { - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameDestroy); - } if (NeedsWinCFI) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR)) .setMIFlag(MachineInstr::FrameDestroy); diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index df69c20b1359fc..cbd8bd1f20558c 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -195,6 +195,7 @@ class AArch64AsmParser : public MCTargetAsmParser { bool parseDirectiveReq(StringRef Name, SMLoc L); bool parseDirectiveUnreq(SMLoc L); bool parseDirectiveCFINegateRAState(); + bool parseDirectiveCFINegateRAStateWithPC(); bool parseDirectiveCFIBKeyFrame(); bool parseDirectiveCFIMTETaggedFrame(); @@ -6821,6 +6822,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { parseDirectiveInst(Loc); else if (IDVal == ".cfi_negate_ra_state") parseDirectiveCFINegateRAState(); + else if (IDVal == ".cfi_negate_ra_state_with_pc") + parseDirectiveCFINegateRAStateWithPC(); else if (IDVal == ".cfi_b_key_frame") parseDirectiveCFIBKeyFrame(); else if (IDVal == ".cfi_mte_tagged_frame") @@ -7271,6 +7274,13 @@ bool AArch64AsmParser::parseDirectiveCFINegateRAState() { return false; } +bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() { + if (parseEOL()) + return true; + getStreamer().emitCFINegateRAStateWithPC(); + return false; +} + /// parseDirectiveCFIBKeyFrame /// ::= .cfi_b_key bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() { diff --git a/llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll b/llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll index eb224bbbd601fb..fbf571eabd8015 100644 --- a/llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll +++ b/llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll @@ -229,7 +229,6 @@ attributes #0 = { "sign-return-address"="all" } ; CHECK-DUMP: DW_CFA_restore_state: ; CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state: -; CHECK-DUMP: CFA=WSP{{$}} ;; First DW_CFA_AARCH64_negate_ra_state: ; CHECK-DUMP: reg34=1 ;; Second DW_CFA_AARCH64_negate_ra_state: @@ -238,7 +237,7 @@ attributes #0 = { "sign-return-address"="all" } ; CHECK-DUMP: reg34=1 ;; Third DW_CFA_AARCH64_negate_ra_state: ; CHECK-DUMP: reg34=0 -; CHECK-DUMP-NOT: reg34= +; CHECK-DUMP-NOT: reg34=1 ; baz_sync ; CHECK-DUMP-LABEL: FDE diff --git a/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll b/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll index 3d133e02106bc8..fa689d2b9d7fdd 100644 --- a/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll +++ b/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll @@ -62,8 +62,9 @@ define i32 @leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-addr ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp0: ; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: adr x16, .Ltmp0 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc +; COMPAT-NEXT: adrp x16, .Ltmp0 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp0 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -73,8 +74,9 @@ define i32 @leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-addr ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp0: ; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: adr x16, .Ltmp0 +; V83A-NEXT: .cfi_negate_ra_state_with_pc +; V83A-NEXT: adrp x16, .Ltmp0 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp0 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -82,7 +84,9 @@ define i32 @leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-addr ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp0: ; PAUTHLR-NEXT: paciasppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp0 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp0 ; PAUTHLR-NEXT: retaasppc .Ltmp0 ret i32 %x } @@ -93,15 +97,16 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp1: ; COMPAT-NEXT: hint #25 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_negate_ra_state ; COMPAT-NEXT: .cfi_def_cfa_offset 16 ; COMPAT-NEXT: .cfi_offset w30, -16 ; COMPAT-NEXT: //APP ; COMPAT-NEXT: mov x30, x0 ; COMPAT-NEXT: //NO_APP ; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: adr x16, .Ltmp1 +; COMPAT-NEXT: adrp x16, .Ltmp1 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp1 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -111,15 +116,16 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp1: ; V83A-NEXT: paciasp +; V83A-NEXT: .cfi_negate_ra_state_with_pc ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_negate_ra_state ; V83A-NEXT: .cfi_def_cfa_offset 16 ; V83A-NEXT: .cfi_offset w30, -16 ; V83A-NEXT: //APP ; V83A-NEXT: mov x30, x0 ; V83A-NEXT: //NO_APP ; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: adr x16, .Ltmp1 +; V83A-NEXT: adrp x16, .Ltmp1 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp1 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -127,14 +133,16 @@ define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-a ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp1: ; PAUTHLR-NEXT: paciasppc +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc ; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; PAUTHLR-NEXT: .cfi_negate_ra_state ; PAUTHLR-NEXT: .cfi_def_cfa_offset 16 ; PAUTHLR-NEXT: .cfi_offset w30, -16 ; PAUTHLR-NEXT: //APP ; PAUTHLR-NEXT: mov x30, x0 ; PAUTHLR-NEXT: //NO_APP ; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; PAUTHLR-NEXT: adrp x16, .Ltmp1 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp1 ; PAUTHLR-NEXT: retaasppc .Ltmp1 call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 ret i64 %x @@ -148,13 +156,14 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return- ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp2: ; COMPAT-NEXT: hint #25 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_negate_ra_state ; COMPAT-NEXT: .cfi_def_cfa_offset 16 ; COMPAT-NEXT: .cfi_offset w30, -16 ; COMPAT-NEXT: bl foo ; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: adr x16, .Ltmp2 +; COMPAT-NEXT: adrp x16, .Ltmp2 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp2 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -164,13 +173,14 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return- ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp2: ; V83A-NEXT: paciasp +; V83A-NEXT: .cfi_negate_ra_state_with_pc ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_negate_ra_state ; V83A-NEXT: .cfi_def_cfa_offset 16 ; V83A-NEXT: .cfi_offset w30, -16 ; V83A-NEXT: bl foo ; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: adr x16, .Ltmp2 +; V83A-NEXT: adrp x16, .Ltmp2 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp2 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -178,12 +188,14 @@ define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return- ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp2: ; PAUTHLR-NEXT: paciasppc +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc ; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; PAUTHLR-NEXT: .cfi_negate_ra_state ; PAUTHLR-NEXT: .cfi_def_cfa_offset 16 ; PAUTHLR-NEXT: .cfi_offset w30, -16 ; PAUTHLR-NEXT: bl foo ; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; PAUTHLR-NEXT: adrp x16, .Ltmp2 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp2 ; PAUTHLR-NEXT: retaasppc .Ltmp2 %call = call i32 @foo(i32 %x) ret i32 %call @@ -195,13 +207,14 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp3: ; COMPAT-NEXT: hint #25 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_negate_ra_state ; COMPAT-NEXT: .cfi_def_cfa_offset 16 ; COMPAT-NEXT: .cfi_offset w30, -16 ; COMPAT-NEXT: bl foo ; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: adr x16, .Ltmp3 +; COMPAT-NEXT: adrp x16, .Ltmp3 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp3 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -211,13 +224,14 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp3: ; V83A-NEXT: paciasp +; V83A-NEXT: .cfi_negate_ra_state_with_pc ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_negate_ra_state ; V83A-NEXT: .cfi_def_cfa_offset 16 ; V83A-NEXT: .cfi_offset w30, -16 ; V83A-NEXT: bl foo ; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: adr x16, .Ltmp3 +; V83A-NEXT: adrp x16, .Ltmp3 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp3 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -225,12 +239,14 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-re ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp3: ; PAUTHLR-NEXT: paciasppc +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc ; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; PAUTHLR-NEXT: .cfi_negate_ra_state ; PAUTHLR-NEXT: .cfi_def_cfa_offset 16 ; PAUTHLR-NEXT: .cfi_offset w30, -16 ; PAUTHLR-NEXT: bl foo ; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; PAUTHLR-NEXT: adrp x16, .Ltmp3 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp3 ; PAUTHLR-NEXT: retaasppc .Ltmp3 %call = call i32 @foo(i32 %x) ret i32 %call @@ -245,13 +261,14 @@ define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-addre ; CHECK-NEXT: hint #39 ; CHECK-NEXT: .Ltmp4: ; CHECK-NEXT: paciasp +; CHECK-NEXT: .cfi_negate_ra_state_with_pc ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; CHECK-NEXT: .cfi_negate_ra_state ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_offset w30, -16 ; CHECK-NEXT: bl foo ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; CHECK-NEXT: adr x16, .Ltmp4 +; CHECK-NEXT: adrp x16, .Ltmp4 +; CHECK-NEXT: add x16, x16, :lo12:.Ltmp4 ; CHECK-NEXT: hint #39 ; CHECK-NEXT: autiasp ; CHECK-NEXT: ldr x30, [x18, #-8]! @@ -263,12 +280,14 @@ define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-addre ; PAUTHLR-NEXT: .cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78 // ; PAUTHLR-NEXT: .Ltmp4: ; PAUTHLR-NEXT: paciasppc +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc ; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; PAUTHLR-NEXT: .cfi_negate_ra_state ; PAUTHLR-NEXT: .cfi_def_cfa_offset 16 ; PAUTHLR-NEXT: .cfi_offset w30, -16 ; PAUTHLR-NEXT: bl foo ; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; PAUTHLR-NEXT: adrp x16, .Ltmp4 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp4 ; PAUTHLR-NEXT: autiasppc .Ltmp4 ; PAUTHLR-NEXT: ldr x30, [x18, #-8]! ; PAUTHLR-NEXT: ret @@ -282,8 +301,9 @@ define i32 @leaf_sign_all_v83(i32 %x) "branch-protection-pauth-lr" "sign-return- ; CHECK-NEXT: hint #39 ; CHECK-NEXT: .Ltmp5: ; CHECK-NEXT: paciasp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: adr x16, .Ltmp5 +; CHECK-NEXT: .cfi_negate_ra_state_with_pc +; CHECK-NEXT: adrp x16, .Ltmp5 +; CHECK-NEXT: add x16, x16, :lo12:.Ltmp5 ; CHECK-NEXT: hint #39 ; CHECK-NEXT: retaa ; @@ -291,7 +311,9 @@ define i32 @leaf_sign_all_v83(i32 %x) "branch-protection-pauth-lr" "sign-return- ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp5: ; PAUTHLR-NEXT: paciasppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp5 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp5 ; PAUTHLR-NEXT: retaasppc .Ltmp5 ret i32 %x } @@ -304,15 +326,16 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr" ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp6: ; COMPAT-NEXT: hint #25 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc ; COMPAT-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; COMPAT-NEXT: .cfi_negate_ra_state ; COMPAT-NEXT: .cfi_def_cfa_offset 16 ; COMPAT-NEXT: .cfi_offset w30, -16 ; COMPAT-NEXT: //APP ; COMPAT-NEXT: mov x30, x0 ; COMPAT-NEXT: //NO_APP ; COMPAT-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; COMPAT-NEXT: adr x16, .Ltmp6 +; COMPAT-NEXT: adrp x16, .Ltmp6 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp6 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: b bar @@ -322,15 +345,16 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr" ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp6: ; V83A-NEXT: paciasp +; V83A-NEXT: .cfi_negate_ra_state_with_pc ; V83A-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; V83A-NEXT: .cfi_negate_ra_state ; V83A-NEXT: .cfi_def_cfa_offset 16 ; V83A-NEXT: .cfi_offset w30, -16 ; V83A-NEXT: //APP ; V83A-NEXT: mov x30, x0 ; V83A-NEXT: //NO_APP ; V83A-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload -; V83A-NEXT: adr x16, .Ltmp6 +; V83A-NEXT: adrp x16, .Ltmp6 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp6 ; V83A-NEXT: hint #39 ; V83A-NEXT: autiasp ; V83A-NEXT: b bar @@ -339,14 +363,16 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr" ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp6: ; PAUTHLR-NEXT: paciasppc +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc ; PAUTHLR-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill -; PAUTHLR-NEXT: .cfi_negate_ra_state ; PAUTHLR-NEXT: .cfi_def_cfa_offset 16 ; PAUTHLR-NEXT: .cfi_offset w30, -16 ; PAUTHLR-NEXT: //APP ; PAUTHLR-NEXT: mov x30, x0 ; PAUTHLR-NEXT: //NO_APP ; PAUTHLR-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload +; PAUTHLR-NEXT: adrp x16, .Ltmp6 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp6 ; PAUTHLR-NEXT: autiasppc .Ltmp6 ; PAUTHLR-NEXT: b bar call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1 @@ -360,8 +386,9 @@ define i32 @leaf_sign_all_a_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp7: ; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: adr x16, .Ltmp7 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc +; COMPAT-NEXT: adrp x16, .Ltmp7 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp7 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -371,8 +398,9 @@ define i32 @leaf_sign_all_a_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp7: ; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: adr x16, .Ltmp7 +; V83A-NEXT: .cfi_negate_ra_state_with_pc +; V83A-NEXT: adrp x16, .Ltmp7 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp7 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -380,7 +408,9 @@ define i32 @leaf_sign_all_a_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; PAUTHLR: // %bb.0: ; PAUTHLR-NEXT: .Ltmp7: ; PAUTHLR-NEXT: paciasppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp7 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp7 ; PAUTHLR-NEXT: retaasppc .Ltmp7 ret i32 %x } @@ -392,8 +422,9 @@ define i32 @leaf_sign_all_b_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp8: ; COMPAT-NEXT: hint #27 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: adr x16, .Ltmp8 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc +; COMPAT-NEXT: adrp x16, .Ltmp8 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp8 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #31 ; COMPAT-NEXT: ret @@ -404,8 +435,9 @@ define i32 @leaf_sign_all_b_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp8: ; V83A-NEXT: pacibsp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: adr x16, .Ltmp8 +; V83A-NEXT: .cfi_negate_ra_state_with_pc +; V83A-NEXT: adrp x16, .Ltmp8 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp8 ; V83A-NEXT: hint #39 ; V83A-NEXT: retab ; @@ -414,7 +446,9 @@ define i32 @leaf_sign_all_b_key(i32 %x) "branch-protection-pauth-lr" "sign-retur ; PAUTHLR-NEXT: .cfi_b_key_frame ; PAUTHLR-NEXT: .Ltmp8: ; PAUTHLR-NEXT: pacibsppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp8 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp8 ; PAUTHLR-NEXT: retabsppc .Ltmp8 ret i32 %x } @@ -426,8 +460,9 @@ define i32 @leaf_sign_all_v83_b_key(i32 %x) "branch-protection-pauth-lr" "sign-r ; CHECK-NEXT: hint #39 ; CHECK-NEXT: .Ltmp9: ; CHECK-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: adr x16, .Ltmp9 +; CHECK-NEXT: .cfi_negate_ra_state_with_pc +; CHECK-NEXT: adrp x16, .Ltmp9 +; CHECK-NEXT: add x16, x16, :lo12:.Ltmp9 ; CHECK-NEXT: hint #39 ; CHECK-NEXT: retab ; @@ -436,7 +471,9 @@ define i32 @leaf_sign_all_v83_b_key(i32 %x) "branch-protection-pauth-lr" "sign-r ; PAUTHLR-NEXT: .cfi_b_key_frame ; PAUTHLR-NEXT: .Ltmp9: ; PAUTHLR-NEXT: pacibsppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp9 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp9 ; PAUTHLR-NEXT: retabsppc .Ltmp9 ret i32 %x } @@ -449,8 +486,9 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp10: ; COMPAT-NEXT: hint #25 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: adr x16, .Ltmp10 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc +; COMPAT-NEXT: adrp x16, .Ltmp10 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp10 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #29 ; COMPAT-NEXT: ret @@ -461,8 +499,9 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp10: ; V83A-NEXT: paciasp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: adr x16, .Ltmp10 +; V83A-NEXT: .cfi_negate_ra_state_with_pc +; V83A-NEXT: adrp x16, .Ltmp10 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp10 ; V83A-NEXT: hint #39 ; V83A-NEXT: retaa ; @@ -471,7 +510,9 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; PAUTHLR-NEXT: bti c ; PAUTHLR-NEXT: .Ltmp10: ; PAUTHLR-NEXT: paciasppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp10 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp10 ; PAUTHLR-NEXT: retaasppc .Ltmp10 ret i32 %x } @@ -485,8 +526,9 @@ define i32 @leaf_sign_all_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: .Ltmp11: ; COMPAT-NEXT: hint #27 -; COMPAT-NEXT: .cfi_negate_ra_state -; COMPAT-NEXT: adr x16, .Ltmp11 +; COMPAT-NEXT: .cfi_negate_ra_state_with_pc +; COMPAT-NEXT: adrp x16, .Ltmp11 +; COMPAT-NEXT: add x16, x16, :lo12:.Ltmp11 ; COMPAT-NEXT: hint #39 ; COMPAT-NEXT: hint #31 ; COMPAT-NEXT: ret @@ -498,8 +540,9 @@ define i32 @leaf_sign_all_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; V83A-NEXT: hint #39 ; V83A-NEXT: .Ltmp11: ; V83A-NEXT: pacibsp -; V83A-NEXT: .cfi_negate_ra_state -; V83A-NEXT: adr x16, .Ltmp11 +; V83A-NEXT: .cfi_negate_ra_state_with_pc +; V83A-NEXT: adrp x16, .Ltmp11 +; V83A-NEXT: add x16, x16, :lo12:.Ltmp11 ; V83A-NEXT: hint #39 ; V83A-NEXT: retab ; @@ -509,7 +552,9 @@ define i32 @leaf_sign_all_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-r ; PAUTHLR-NEXT: .cfi_b_key_frame ; PAUTHLR-NEXT: .Ltmp11: ; PAUTHLR-NEXT: pacibsppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp11 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp11 ; PAUTHLR-NEXT: retabsppc .Ltmp11 ret i32 %x } @@ -523,8 +568,9 @@ define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "branch-protection-pauth-lr" "si ; CHECK-NEXT: hint #39 ; CHECK-NEXT: .Ltmp12: ; CHECK-NEXT: pacibsp -; CHECK-NEXT: .cfi_negate_ra_state -; CHECK-NEXT: adr x16, .Ltmp12 +; CHECK-NEXT: .cfi_negate_ra_state_with_pc +; CHECK-NEXT: adrp x16, .Ltmp12 +; CHECK-NEXT: add x16, x16, :lo12:.Ltmp12 ; CHECK-NEXT: hint #39 ; CHECK-NEXT: retab ; @@ -534,7 +580,9 @@ define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "branch-protection-pauth-lr" "si ; PAUTHLR-NEXT: .cfi_b_key_frame ; PAUTHLR-NEXT: .Ltmp12: ; PAUTHLR-NEXT: pacibsppc -; PAUTHLR-NEXT: .cfi_negate_ra_state +; PAUTHLR-NEXT: .cfi_negate_ra_state_with_pc +; PAUTHLR-NEXT: adrp x16, .Ltmp12 +; PAUTHLR-NEXT: add x16, x16, :lo12:.Ltmp12 ; PAUTHLR-NEXT: retabsppc .Ltmp12 ret i32 %x } diff --git a/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir b/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir index a63bb8452ebbe1..d2b063a057139b 100644 --- a/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir +++ b/llvm/test/CodeGen/MIR/AArch64/return-address-signing.mir @@ -12,6 +12,11 @@ entry: ret i32 2 } + + define dso_local i32 @foobar() "sign-return-address"="all" "branch-protection-pauth-lr"="true" { + entry: + ret i32 2 + } ... --- #CHECK: foo @@ -46,3 +51,21 @@ body: | RET_ReallyLR implicit killed $w0 ... +--- +#CHECK: foobar +name: foobar +alignment: 4 +tracksRegLiveness: true +frameInfo: + maxCallFrameSize: 0 +#CHECK: frame-setup PACM +#CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp, pre-instr-symbol +#CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state_with_pc +#CHECK: frame-destroy PACM +#CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp +body: | + bb.0.entry: + $w0 = MOVi32imm 2 + RET_ReallyLR implicit killed $w0 + +... diff --git a/llvm/test/MC/AArch64/directives-case_insensitive.s b/llvm/test/MC/AArch64/directives-case_insensitive.s index be92e00cfad11a..35a90a1bffea8d 100644 --- a/llvm/test/MC/AArch64/directives-case_insensitive.s +++ b/llvm/test/MC/AArch64/directives-case_insensitive.s @@ -32,10 +32,12 @@ fred .REQ x5 .CFI_STARTPROC .CFI_NEGATE_RA_STATE +.CFI_NEGATE_RA_STATE_WITH_PC .CFI_B_KEY_FRAME .CFI_ENDPROC // CHECK: .cfi_startproc // CHECK: .cfi_negate_ra_state +// CHECK: .cfi_negate_ra_state_with_pc // CHECK: .cfi_b_key_frame // CHECK: .cfi_endproc diff --git a/llvm/test/MC/AArch64/negate_ra_state_with_pc.s b/llvm/test/MC/AArch64/negate_ra_state_with_pc.s new file mode 100644 index 00000000000000..44b8ab2df9a908 --- /dev/null +++ b/llvm/test/MC/AArch64/negate_ra_state_with_pc.s @@ -0,0 +1,7 @@ +//RUN: llvm-mc -triple=aarch64-arm-none-eabi -o - %s | FileCheck %s + +// CHECK: .cfi_negate_ra_state_with_pc +foo: + .cfi_startproc + .cfi_negate_ra_state_with_pc + .cfi_endproc diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp index 17fb18fc6b4d24..2be656547c92e0 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp @@ -174,6 +174,7 @@ TEST(DWARFDebugFrame, InvalidCFIOpcodesTest) { dwarf::DW_CFA_MIPS_advance_loc8, dwarf::DW_CFA_GNU_window_save, dwarf::DW_CFA_AARCH64_negate_ra_state, + dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc, dwarf::DW_CFA_GNU_args_size}; dwarf::CIE TestCIE = createCIE(/*IsDWARF64=*/false,