Skip to content

Commit 961092b

Browse files
committed
[PAuthLR] Add support for FEAT_PAuth_LR's DWARF frame instruction
This introduces compiler and dwarfdump support for emitting and parsing the new `DW_CFA_AARCH64_negate_ra_state_with_pc` DWARF instruction for FEAT_PAuth_LR. This does mean that, when using FEAT_PAuthLR, the improvements introduced in #96337 cannot be utilised. `.cfi_negate_ra_state_with_pc` must be emitted directly after the signing instruction, and when bundled with other CFI calls, leads to faults when running a program. There are no changes seen when not using FEAT_PAuthLR to how the CFI Instructions are generated. See ARM-software/abi-aa#245 for the ABI change that incororates FEAT_PAuthLR. Authored-by: pratlucas <[email protected]> Co-authored by: vhscampos <[email protected]> Co-authored by: Stylie777 <[email protected]>
1 parent 98681d5 commit 961092b

22 files changed

+283
-91
lines changed

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,7 @@ HANDLE_DW_CFA(0x16, val_expression)
12381238
// Vendor extensions:
12391239
HANDLE_DW_CFA_PRED(0x1d, MIPS_advance_loc8, SELECT_MIPS64)
12401240
HANDLE_DW_CFA_PRED(0x2d, GNU_window_save, SELECT_SPARC)
1241+
HANDLE_DW_CFA_PRED(0x2c, AARCH64_negate_ra_state_with_pc, SELECT_AARCH64)
12411242
HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
12421243
HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
12431244
// Heterogeneous Debugging Extension defined at

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ class MCCFIInstruction {
515515
OpRegister,
516516
OpWindowSave,
517517
OpNegateRAState,
518+
OpNegateRAStateWithPC,
518519
OpGnuArgsSize,
519520
OpLabel,
520521
};
@@ -642,6 +643,13 @@ class MCCFIInstruction {
642643
return MCCFIInstruction(OpNegateRAState, L, 0, INT64_C(0), Loc);
643644
}
644645

646+
/// .cfi_negate_ra_state_with_pc AArch64 negate RA state with PC.
647+
static MCCFIInstruction createNegateRAStateWithPC(MCSymbol *L,
648+
SMLoc Loc = {}) {
649+
return MCCFIInstruction(OpNegateRAStateWithPC, L, 0, INT64_C(0), Loc);
650+
}
651+
652+
645653
/// .cfi_restore says that the rule for Register is now the same as it
646654
/// was at the beginning of the function, after all initial instructions added
647655
/// by .cfi_startproc were executed.

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ class MCStreamer {
10221022
SMLoc Loc = {});
10231023
virtual void emitCFIWindowSave(SMLoc Loc = {});
10241024
virtual void emitCFINegateRAState(SMLoc Loc = {});
1025+
virtual void emitCFINegateRAStateWithPC(SMLoc Loc = {});
10251026
virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name);
10261027

10271028
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());

llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
236236
case MCCFIInstruction::OpNegateRAState:
237237
OutStreamer->emitCFINegateRAState(Loc);
238238
break;
239+
case MCCFIInstruction::OpNegateRAStateWithPC:
240+
OutStreamer->emitCFINegateRAStateWithPC(Loc);
241+
break;
239242
case MCCFIInstruction::OpSameValue:
240243
OutStreamer->emitCFISameValue(Inst.getRegister(), Loc);
241244
break;

llvm/lib/CodeGen/CFIInstrInserter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
260260
case MCCFIInstruction::OpEscape:
261261
case MCCFIInstruction::OpWindowSave:
262262
case MCCFIInstruction::OpNegateRAState:
263+
case MCCFIInstruction::OpNegateRAStateWithPC:
263264
case MCCFIInstruction::OpGnuArgsSize:
264265
case MCCFIInstruction::OpLabel:
265266
break;

llvm/lib/CodeGen/MIRParser/MILexer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
238238
.Case("window_save", MIToken::kw_cfi_window_save)
239239
.Case("negate_ra_sign_state",
240240
MIToken::kw_cfi_aarch64_negate_ra_sign_state)
241+
.Case("negate_ra_sign_state_with_pc",
242+
MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc)
241243
.Case("blockaddress", MIToken::kw_blockaddress)
242244
.Case("intrinsic", MIToken::kw_intrinsic)
243245
.Case("target-index", MIToken::kw_target_index)

llvm/lib/CodeGen/MIRParser/MILexer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct MIToken {
9696
kw_cfi_undefined,
9797
kw_cfi_window_save,
9898
kw_cfi_aarch64_negate_ra_sign_state,
99+
kw_cfi_aarch64_negate_ra_sign_state_with_pc,
99100
kw_blockaddress,
100101
kw_intrinsic,
101102
kw_target_index,

llvm/lib/CodeGen/MIRParser/MIParser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2576,6 +2576,10 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
25762576
case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
25772577
CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
25782578
break;
2579+
case MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc:
2580+
CFIIndex =
2581+
MF.addFrameInst(MCCFIInstruction::createNegateRAStateWithPC(nullptr));
2582+
break;
25792583
case MIToken::kw_cfi_escape: {
25802584
std::string Values;
25812585
if (parseCFIEscapeValues(Values))
@@ -2931,6 +2935,7 @@ bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
29312935
case MIToken::kw_cfi_undefined:
29322936
case MIToken::kw_cfi_window_save:
29332937
case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
2938+
case MIToken::kw_cfi_aarch64_negate_ra_sign_state_with_pc:
29342939
return parseCFIOperand(Dest);
29352940
case MIToken::kw_blockaddress:
29362941
return parseBlockAddressOperand(Dest);

llvm/lib/CodeGen/MachineOperand.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,10 @@ static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
768768
if (MCSymbol *Label = CFI.getLabel())
769769
MachineOperand::printSymbol(OS, *Label);
770770
break;
771+
case MCCFIInstruction::OpNegateRAStateWithPC:
772+
OS << "negate_ra_sign_state_with_pc ";
773+
if (MCSymbol *Label = CFI.getLabel())
774+
MachineOperand::printSymbol(OS, *Label);
771775
default:
772776
// TODO: Print the other CFI Operations.
773777
OS << "<unserializable cfi directive>";

llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
288288
case DW_CFA_remember_state:
289289
case DW_CFA_restore_state:
290290
case DW_CFA_GNU_window_save:
291+
case DW_CFA_AARCH64_negate_ra_state_with_pc:
291292
// No operands
292293
addInstruction(Opcode);
293294
break;
@@ -666,6 +667,28 @@ Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row,
666667
}
667668
break;
668669

670+
case dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc: {
671+
constexpr uint32_t AArch64DWARFPAuthRaState = 34;
672+
auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
673+
AArch64DWARFPAuthRaState);
674+
if (LRLoc) {
675+
if (LRLoc->getLocation() == UnwindLocation::Constant) {
676+
// Toggle the constant value of bits[1:0] from 0 to 1 or 1 to 0.
677+
LRLoc->setConstant(LRLoc->getConstant() ^ 0x3);
678+
} else {
679+
return createStringError(
680+
errc::invalid_argument,
681+
"%s encountered when existing rule for this register is not "
682+
"a constant",
683+
CFIP.callFrameString(Inst.Opcode).str().c_str());
684+
}
685+
} else {
686+
Row.getRegisterLocations().setRegisterLocation(
687+
AArch64DWARFPAuthRaState, UnwindLocation::createIsConstant(0x3));
688+
}
689+
break;
690+
}
691+
669692
case dwarf::DW_CFA_undefined: {
670693
llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
671694
if (!RegNum)
@@ -847,6 +870,7 @@ CFIProgram::getOperandTypes() {
847870
DECLARE_OP0(DW_CFA_remember_state);
848871
DECLARE_OP0(DW_CFA_restore_state);
849872
DECLARE_OP0(DW_CFA_GNU_window_save);
873+
DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);
850874
DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
851875
DECLARE_OP0(DW_CFA_nop);
852876

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ class MCAsmStreamer final : public MCStreamer {
373373
SMLoc Loc) override;
374374
void emitCFIWindowSave(SMLoc Loc) override;
375375
void emitCFINegateRAState(SMLoc Loc) override;
376+
void emitCFINegateRAStateWithPC(SMLoc Loc) override;
376377
void emitCFIReturnColumn(int64_t Register) override;
377378
void emitCFILabelDirective(SMLoc Loc, StringRef Name) override;
378379

@@ -2145,6 +2146,12 @@ void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
21452146
EmitEOL();
21462147
}
21472148

2149+
void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
2150+
MCStreamer::emitCFINegateRAStateWithPC(Loc);
2151+
OS << "\t.cfi_negate_ra_state_with_pc";
2152+
EmitEOL();
2153+
}
2154+
21482155
void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
21492156
MCStreamer::emitCFIReturnColumn(Register);
21502157
OS << "\t.cfi_return_column ";

llvm/lib/MC/MCDwarf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,10 @@ void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
13811381
Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
13821382
return;
13831383

1384+
case MCCFIInstruction::OpNegateRAStateWithPC:
1385+
Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1386+
return;
1387+
13841388
case MCCFIInstruction::OpUndefined: {
13851389
unsigned Reg = Instr.getRegister();
13861390
Streamer.emitInt8(dwarf::DW_CFA_undefined);

llvm/lib/MC/MCStreamer.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,16 @@ void MCStreamer::emitCFINegateRAState(SMLoc Loc) {
688688
CurFrame->Instructions.push_back(Instruction);
689689
}
690690

691+
void MCStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
692+
MCSymbol *Label = emitCFILabel();
693+
MCCFIInstruction Instruction =
694+
MCCFIInstruction::createNegateRAStateWithPC(Label, Loc);
695+
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
696+
if (!CurFrame)
697+
return;
698+
CurFrame->Instructions.push_back(Instruction);
699+
}
700+
691701
void MCStreamer::emitCFIReturnColumn(int64_t Register) {
692702
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
693703
if (!CurFrame)

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,10 @@ void AArch64FrameLowering::resetCFIToInitialState(
702702

703703
// Flip the RA sign state.
704704
if (MFI.shouldSignReturnAddress(MF)) {
705-
CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
705+
auto CFIInst = MFI.branchProtectionPAuthLR()
706+
? MCCFIInstruction::createNegateRAStateWithPC(nullptr)
707+
: MCCFIInstruction::createNegateRAState(nullptr);
708+
CFIIndex = MF.addFrameInst(CFIInst);
706709
BuildMI(MBB, InsertPt, DL, CFIDesc).addCFIIndex(CFIIndex);
707710
}
708711

llvm/lib/Target/AArch64/AArch64PointerAuth.cpp

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ FunctionPass *llvm::createAArch64PointerAuthPass() {
7171

7272
char AArch64PointerAuth::ID = 0;
7373

74+
static void emitPACSymOffsetIntoX16(const TargetInstrInfo &TII,
75+
MachineBasicBlock &MBB,
76+
MachineBasicBlock::iterator I, DebugLoc DL,
77+
MCSymbol *PACSym) {
78+
BuildMI(MBB, I, DL, TII.get(AArch64::ADRP), AArch64::X16)
79+
.addSym(PACSym, AArch64II::MO_PAGE);
80+
BuildMI(MBB, I, DL, TII.get(AArch64::ADDXri), AArch64::X16)
81+
.addReg(AArch64::X16)
82+
.addSym(PACSym, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
83+
.addImm(0);
84+
}
85+
7486
// Where PAuthLR support is not known at compile time, it is supported using
7587
// PACM. PACM is in the hint space so has no effect when PAuthLR is not
7688
// 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,
8193
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
8294
auto &MFnI = *MBB.getParent()->getInfo<AArch64FunctionInfo>();
8395

84-
// ADR X16,<address_of_PACIASP>
96+
// Offset to PAC*SP using ADRP + ADD.
8597
if (PACSym) {
8698
assert(Flags == MachineInstr::FrameDestroy);
87-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADR))
88-
.addReg(AArch64::X16, RegState::Define)
89-
.addSym(PACSym);
99+
emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
90100
}
91101

92102
// 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,
95105
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACM)).setMIFlag(Flags);
96106
}
97107

108+
static void emitPACCFI(const AArch64Subtarget &Subtarget,
109+
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
110+
DebugLoc DL, MachineInstr::MIFlag Flags, bool EmitCFI) {
111+
if (!EmitCFI)
112+
return;
113+
114+
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
115+
auto &MF = *MBB.getParent();
116+
auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
117+
bool EmitAsyncCFI = MFnI.needsAsyncDwarfUnwindInfo(MF);
118+
119+
auto CFIInst = MFnI.branchProtectionPAuthLR()
120+
? MCCFIInstruction::createNegateRAStateWithPC(nullptr)
121+
: MCCFIInstruction::createNegateRAState(nullptr);
122+
123+
// Because of PAuthLR, when using NegateRAStateWithPC, the CFI instruction cannot
124+
// be bundled with other CFI instructions in the prolog, as it needs to directly
125+
// follow the signing instruction. This ensures the PC value is captured incase of
126+
// an error in the following the following instructions.
127+
if (!EmitAsyncCFI && !(MFnI.branchProtectionPAuthLR())) {
128+
// Reduce the size of the generated call frame information for synchronous
129+
// CFI by bundling the new CFI instruction with others in the prolog, so
130+
// that no additional DW_CFA_advance_loc is needed.
131+
for (auto I = MBBI; I != MBB.end(); ++I) {
132+
if (I->getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
133+
I->getFlag(MachineInstr::FrameSetup)) {
134+
MBBI = I;
135+
break;
136+
}
137+
}
138+
}
139+
140+
unsigned CFIIndex = MF.addFrameInst(CFIInst);
141+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
142+
.addCFIIndex(CFIIndex)
143+
.setMIFlags(Flags);
144+
}
145+
98146
void AArch64PointerAuth::signLR(MachineFunction &MF,
99147
MachineBasicBlock::iterator MBBI) const {
100148
auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
101149
bool UseBKey = MFnI.shouldSignWithBKey();
102150
bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF);
103-
bool EmitAsyncCFI = MFnI.needsAsyncDwarfUnwindInfo(MF);
104151
bool NeedsWinCFI = MF.hasWinCFI();
105152

106153
MachineBasicBlock &MBB = *MBBI->getParent();
@@ -128,34 +175,18 @@ void AArch64PointerAuth::signLR(MachineFunction &MF,
128175
: AArch64::PACIASPPC))
129176
.setMIFlag(MachineInstr::FrameSetup)
130177
->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
178+
emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI);
131179
} else {
132180
BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup);
133181
BuildMI(MBB, MBBI, DL,
134182
TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSP
135183
: AArch64::PACIASP))
136184
.setMIFlag(MachineInstr::FrameSetup)
137185
->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
186+
emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameSetup, EmitCFI);
138187
}
139188

140-
if (EmitCFI) {
141-
if (!EmitAsyncCFI) {
142-
// Reduce the size of the generated call frame information for synchronous
143-
// CFI by bundling the new CFI instruction with others in the prolog, so
144-
// that no additional DW_CFA_advance_loc is needed.
145-
for (auto I = MBBI; I != MBB.end(); ++I) {
146-
if (I->getOpcode() == TargetOpcode::CFI_INSTRUCTION &&
147-
I->getFlag(MachineInstr::FrameSetup)) {
148-
MBBI = I;
149-
break;
150-
}
151-
}
152-
}
153-
unsigned CFIIndex =
154-
MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
155-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
156-
.addCFIIndex(CFIIndex)
157-
.setMIFlags(MachineInstr::FrameSetup);
158-
} else if (NeedsWinCFI) {
189+
if (!EmitCFI && NeedsWinCFI) {
159190
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
160191
.setMIFlag(MachineInstr::FrameSetup);
161192
}
@@ -190,6 +221,7 @@ void AArch64PointerAuth::authenticateLR(
190221
!MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
191222
if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
192223
assert(PACSym && "No PAC instruction to refer to");
224+
emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
193225
BuildMI(MBB, TI, DL,
194226
TII->get(UseBKey ? AArch64::RETABSPPCi : AArch64::RETAASPPCi))
195227
.addSym(PACSym)
@@ -205,24 +237,20 @@ void AArch64PointerAuth::authenticateLR(
205237
} else {
206238
if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
207239
assert(PACSym && "No PAC instruction to refer to");
240+
emitPACSymOffsetIntoX16(*TII, MBB, MBBI, DL, PACSym);
208241
BuildMI(MBB, MBBI, DL,
209242
TII->get(UseBKey ? AArch64::AUTIBSPPCi : AArch64::AUTIASPPCi))
210243
.addSym(PACSym)
211244
.setMIFlag(MachineInstr::FrameDestroy);
245+
emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, EmitAsyncCFI);
212246
} else {
213247
BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, PACSym);
214248
BuildMI(MBB, MBBI, DL,
215249
TII->get(UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP))
216250
.setMIFlag(MachineInstr::FrameDestroy);
251+
emitPACCFI(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, EmitAsyncCFI);
217252
}
218253

219-
if (EmitAsyncCFI) {
220-
unsigned CFIIndex =
221-
MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
222-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
223-
.addCFIIndex(CFIIndex)
224-
.setMIFlags(MachineInstr::FrameDestroy);
225-
}
226254
if (NeedsWinCFI) {
227255
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
228256
.setMIFlag(MachineInstr::FrameDestroy);

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
195195
bool parseDirectiveReq(StringRef Name, SMLoc L);
196196
bool parseDirectiveUnreq(SMLoc L);
197197
bool parseDirectiveCFINegateRAState();
198+
bool parseDirectiveCFINegateRAStateWithPC();
198199
bool parseDirectiveCFIBKeyFrame();
199200
bool parseDirectiveCFIMTETaggedFrame();
200201

@@ -6821,6 +6822,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
68216822
parseDirectiveInst(Loc);
68226823
else if (IDVal == ".cfi_negate_ra_state")
68236824
parseDirectiveCFINegateRAState();
6825+
else if (IDVal == ".cfi_negate_ra_state_with_pc")
6826+
parseDirectiveCFINegateRAStateWithPC();
68246827
else if (IDVal == ".cfi_b_key_frame")
68256828
parseDirectiveCFIBKeyFrame();
68266829
else if (IDVal == ".cfi_mte_tagged_frame")
@@ -7271,6 +7274,13 @@ bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
72717274
return false;
72727275
}
72737276

7277+
bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7278+
if (parseEOL())
7279+
return true;
7280+
getStreamer().emitCFINegateRAStateWithPC();
7281+
return false;
7282+
}
7283+
72747284
/// parseDirectiveCFIBKeyFrame
72757285
/// ::= .cfi_b_key
72767286
bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {

0 commit comments

Comments
 (0)