Skip to content

Commit 63eb7ff

Browse files
committed
[ARM] Implement PAC return address signing mechanism for PACBTI-M
This patch implements PAC return address signing for armv8-m. This patch roughly accomplishes the following things: - PAC and AUT instructions are generated. - They're part of the stack frame setup, so that shrink-wrapping can move them inwards to cover only part of a function - The auth code generated by PAC is saved across subroutine calls so that AUT can find it again to check - PAC is emitted before stacking registers (so that the SP it signs is the one on function entry). - The new pseudo-register ra_auth_code is mentioned in the DWARF frame data - With CMSE also in use: PAC is emitted before stacking FPCXTNS, and AUT validates the corresponding value of SP - Emit correct unwind information when PAC is replaced by PACBTI - Handle tail calls correctly Some notes: We make the assembler accept the `.save {ra_auth_code}` directive that is emitted by the compiler when it saves a register that contains a return address authentication code. For EHABI we need to have the `FrameSetup` flag on the instruction and handle the `t2PACBTI` opcode (identically to `t2PAC`), so we can emit `.save {ra_auth_code}`, instead of `.save {r12}`. For PACBTI-M, the instruction which computes return address PAC should use SP value before adjustment for the argument registers save are (used for variadic functions and when a parameter is is split between stack and register), but at the same it should be after the instruction that saves FPCXT when compiling a CMSE entry function. This patch moves the varargs SP adjustment after the FPCXT save (they are never enabled at the same time), so in a following patch handling of the `PAC` instruction can be placed between them. Epilogue emission code adjusted in a similar manner. PACBTI-M code generation should not emit any instructions for architectures v6-m, v8-m.base, and for A- and R-class cores. Diagnostic message for such cases is handled separately by a future ticket. note on tail calls: If the called function has four arguments that occupy registers `r0`-`r3`, the only option for holding the function pointer itself is `r12`, but this register is used to keep the PAC during function/prologue epilogue and clobbers the function pointer. When we do the tail call we need the five registers (`r0`-`r3` and `r12`) to keep six values - the four function arguments, the function pointer and the PAC, which is obviously impossible. One option would be to authenticate the return address before all callee-saved registers are restored, so we have a scratch register to temporarily keep the value of `r12`. The issue with this approach is that it violates a fundamental invariant that PAC is computed using CFA as a modifier. It would also mean using separate instructions to pop `lr` and the rest of the callee-saved registers, which would offset the advantages of doing a tail call. Instead, this patch disables indirect tail calls when the called function take four or more arguments and the return address sign and authentication is enabled for the caller function, conservatively assuming the caller function would spill LR. This patch is part of a series that adds support for the PACBTI-M extension of the Armv8.1-M architecture, as detailed here: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension The PACBTI-M specification can be found in the Armv8-M Architecture Reference Manual: https://developer.arm.com/documentation/ddi0553/latest The following people contributed to this patch: - Momchil Velikov - Ties Stuij Reviewed By: danielkiss Differential Revision: https://reviews.llvm.org/D112429
1 parent db490ad commit 63eb7ff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1918
-212
lines changed

llvm/include/llvm/Support/ARMEHABI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ namespace EHABI {
7171
// Purpose: finish
7272
UNWIND_OPCODE_FINISH = 0xb0,
7373

74+
// Format: 10110100
75+
// Purpose: Pop Return Address Authetication Code
76+
UNWIND_OPCODE_POP_RA_AUTH_CODE = 0xb4,
77+
7478
// Format: 10110001 0000xxxx
7579
// Purpose: pop r[3:0]
7680
// Constraint: x != 0

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,8 +1153,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
11531153
unsigned StartOp = 2 + 2;
11541154
// Use all the operands.
11551155
unsigned NumOffset = 0;
1156-
// Amount of SP adjustment folded into a push.
1157-
unsigned Pad = 0;
1156+
// Amount of SP adjustment folded into a push, before the
1157+
// registers are stored (pad at higher addresses).
1158+
unsigned PadBefore = 0;
1159+
// Amount of SP adjustment folded into a push, after the
1160+
// registers are stored (pad at lower addresses).
1161+
unsigned PadAfter = 0;
11581162

11591163
switch (Opc) {
11601164
default:
@@ -1185,7 +1189,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
11851189
"Pad registers must come before restored ones");
11861190
unsigned Width =
11871191
TargetRegInfo->getRegSizeInBits(MO.getReg(), MachineRegInfo) / 8;
1188-
Pad += Width;
1192+
PadAfter += Width;
11891193
continue;
11901194
}
11911195
// Check for registers that are remapped (for a Thumb1 prologue that
@@ -1201,14 +1205,32 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
12011205
case ARM::t2STR_PRE:
12021206
assert(MI->getOperand(2).getReg() == ARM::SP &&
12031207
"Only stack pointer as a source reg is supported");
1208+
if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1209+
SrcReg = RemappedReg;
1210+
1211+
RegList.push_back(SrcReg);
1212+
break;
1213+
case ARM::t2STRD_PRE:
1214+
assert(MI->getOperand(3).getReg() == ARM::SP &&
1215+
"Only stack pointer as a source reg is supported");
1216+
SrcReg = MI->getOperand(1).getReg();
1217+
if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1218+
SrcReg = RemappedReg;
1219+
RegList.push_back(SrcReg);
1220+
SrcReg = MI->getOperand(2).getReg();
1221+
if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(SrcReg))
1222+
SrcReg = RemappedReg;
12041223
RegList.push_back(SrcReg);
1224+
PadBefore = -MI->getOperand(4).getImm() - 8;
12051225
break;
12061226
}
12071227
if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) {
1228+
if (PadBefore)
1229+
ATS.emitPad(PadBefore);
12081230
ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
12091231
// Account for the SP adjustment, folded into the push.
1210-
if (Pad)
1211-
ATS.emitPad(Pad);
1232+
if (PadAfter)
1233+
ATS.emitPad(PadAfter);
12121234
}
12131235
} else {
12141236
// Changes of stack / frame pointer.
@@ -1300,6 +1322,10 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
13001322
Offset = MI->getOperand(2).getImm();
13011323
AFI->EHPrologueOffsetInRegs[DstReg] |= (Offset << 16);
13021324
break;
1325+
case ARM::t2PAC:
1326+
case ARM::t2PACBTI:
1327+
AFI->EHPrologueRemappedRegs[ARM::R12] = ARM::RA_AUTH_CODE;
1328+
break;
13031329
default:
13041330
MI->print(errs());
13051331
llvm_unreachable("Unsupported opcode for unwinding information");

llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp

Lines changed: 153 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5678,7 +5678,7 @@ bool llvm::HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2,
56785678
/// | | Thumb2 | ARM |
56795679
/// +-------------------------+--------+-----+
56805680
/// | Call overhead in Bytes | 4 | 4 |
5681-
/// | Frame overhead in Bytes | 4 | 4 |
5681+
/// | Frame overhead in Bytes | 2 | 4 |
56825682
/// | Stack fixup required | No | No |
56835683
/// +-------------------------+--------+-----+
56845684
///
@@ -5755,7 +5755,7 @@ struct OutlinerCosts {
57555755
CallThunk(target.isThumb() ? 4 : 4),
57565756
FrameThunk(target.isThumb() ? 0 : 0),
57575757
CallNoLRSave(target.isThumb() ? 4 : 4),
5758-
FrameNoLRSave(target.isThumb() ? 4 : 4),
5758+
FrameNoLRSave(target.isThumb() ? 2 : 4),
57595759
CallRegSave(target.isThumb() ? 8 : 12),
57605760
FrameRegSave(target.isThumb() ? 2 : 4),
57615761
CallDefault(target.isThumb() ? 8 : 12),
@@ -5868,11 +5868,17 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
58685868
return outliner::OutlinedFunction();
58695869
}
58705870

5871+
// We expect the majority of the outlining candidates to be in consensus with
5872+
// regard to return address sign and authentication, and branch target
5873+
// enforcement, in other words, partitioning according to all the four
5874+
// possible combinations of PAC-RET and BTI is going to yield one big subset
5875+
// and three small (likely empty) subsets. That allows us to cull incompatible
5876+
// candidates separately for PAC-RET and BTI.
5877+
58715878
// Partition the candidates in two sets: one with BTI enabled and one with BTI
5872-
// disabled. Remove the candidates from the smaller set. We expect the
5873-
// majority of the candidates to be in consensus with regard to branch target
5874-
// enforcement with just a few oddballs, but if they are the same number
5875-
// prefer the non-BTI ones for outlining, since they have less overhead.
5879+
// disabled. Remove the candidates from the smaller set. If they are the same
5880+
// number prefer the non-BTI ones for outlining, since they have less
5881+
// overhead.
58765882
auto NoBTI =
58775883
llvm::partition(RepeatedSequenceLocs, [](const outliner::Candidate &C) {
58785884
const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
@@ -5883,6 +5889,24 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
58835889
RepeatedSequenceLocs.erase(NoBTI, RepeatedSequenceLocs.end());
58845890
else
58855891
RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoBTI);
5892+
5893+
if (RepeatedSequenceLocs.size() < 2)
5894+
return outliner::OutlinedFunction();
5895+
5896+
// Likewise, partition the candidates according to PAC-RET enablement.
5897+
auto NoPAC =
5898+
llvm::partition(RepeatedSequenceLocs, [](const outliner::Candidate &C) {
5899+
const ARMFunctionInfo &AFI = *C.getMF()->getInfo<ARMFunctionInfo>();
5900+
// If the function happens to not spill the LR, do not disqualify it
5901+
// from the outlining.
5902+
return AFI.shouldSignReturnAddress(true);
5903+
});
5904+
if (std::distance(RepeatedSequenceLocs.begin(), NoPAC) >
5905+
std::distance(NoPAC, RepeatedSequenceLocs.end()))
5906+
RepeatedSequenceLocs.erase(NoPAC, RepeatedSequenceLocs.end());
5907+
else
5908+
RepeatedSequenceLocs.erase(RepeatedSequenceLocs.begin(), NoPAC);
5909+
58865910
if (RepeatedSequenceLocs.size() < 2)
58875911
return outliner::OutlinedFunction();
58885912

@@ -5899,6 +5923,7 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
58995923
};
59005924

59015925
OutlinerCosts Costs(Subtarget);
5926+
59025927
const auto &SomeMFI =
59035928
*RepeatedSequenceLocs.front().getMF()->getInfo<ARMFunctionInfo>();
59045929
// Adjust costs to account for the BTI instructions.
@@ -5909,6 +5934,13 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
59095934
Costs.FrameTailCall += 4;
59105935
Costs.FrameThunk += 4;
59115936
}
5937+
5938+
// Adjust costs to account for sign and authentication instructions.
5939+
if (SomeMFI.shouldSignReturnAddress(true)) {
5940+
Costs.CallDefault += 8; // +PAC instr, +AUT instr
5941+
Costs.SaveRestoreLROnStack += 8; // +PAC instr, +AUT instr
5942+
}
5943+
59125944
unsigned FrameID = MachineOutlinerDefault;
59135945
unsigned NumBytesToCreateFrame = Costs.FrameDefault;
59145946

@@ -6325,6 +6357,11 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
63256357
// * LR is available in the range (No save/restore around call)
63266358
// * The range doesn't include calls (No save/restore in outlined frame)
63276359
// are true.
6360+
// These conditions also ensure correctness of the return address
6361+
// authentication - we insert sign and authentication instructions only if
6362+
// we save/restore LR on stack, but then this condition ensures that the
6363+
// outlined range does not modify the SP, therefore the SP value used for
6364+
// signing is the same as the one used for authentication.
63286365
// FIXME: This is very restrictive; the flags check the whole block,
63296366
// not just the bit we will try to outline.
63306367
bool MightNeedStackFixUp =
@@ -6369,23 +6406,39 @@ void ARMBaseInstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
63696406
}
63706407

63716408
void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
6372-
MachineBasicBlock::iterator It) const {
6373-
unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
6374-
int Align = -Subtarget.getStackAlignment().value();
6375-
BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
6376-
.addReg(ARM::LR, RegState::Kill)
6377-
.addReg(ARM::SP)
6378-
.addImm(Align)
6379-
.add(predOps(ARMCC::AL));
6380-
}
6409+
MachineBasicBlock::iterator It, bool CFI,
6410+
bool Auth) const {
6411+
int Align = std::max(Subtarget.getStackAlignment().value(), uint64_t(8));
6412+
assert(Align >= 8 && Align <= 256);
6413+
if (Auth) {
6414+
assert(Subtarget.isThumb2());
6415+
// Compute PAC in R12. Outlining ensures R12 is dead across the outlined
6416+
// sequence.
6417+
BuildMI(MBB, It, DebugLoc(), get(ARM::t2PAC))
6418+
.setMIFlags(MachineInstr::FrameSetup);
6419+
BuildMI(MBB, It, DebugLoc(), get(ARM::t2STRD_PRE), ARM::SP)
6420+
.addReg(ARM::R12, RegState::Kill)
6421+
.addReg(ARM::LR, RegState::Kill)
6422+
.addReg(ARM::SP)
6423+
.addImm(-Align)
6424+
.add(predOps(ARMCC::AL))
6425+
.setMIFlags(MachineInstr::FrameSetup);
6426+
} else {
6427+
unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
6428+
BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
6429+
.addReg(ARM::LR, RegState::Kill)
6430+
.addReg(ARM::SP)
6431+
.addImm(-Align)
6432+
.add(predOps(ARMCC::AL))
6433+
.setMIFlags(MachineInstr::FrameSetup);
6434+
}
6435+
6436+
if (!CFI)
6437+
return;
63816438

6382-
void ARMBaseInstrInfo::emitCFIForLRSaveOnStack(
6383-
MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
63846439
MachineFunction &MF = *MBB.getParent();
6385-
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
6386-
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
6387-
int Align = Subtarget.getStackAlignment().value();
6388-
// Add a CFI saying the stack was moved down.
6440+
6441+
// Add a CFI, saying CFA is offset by Align bytes from SP.
63896442
int64_t StackPosEntry =
63906443
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Align));
63916444
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
@@ -6394,11 +6447,23 @@ void ARMBaseInstrInfo::emitCFIForLRSaveOnStack(
63946447

63956448
// Add a CFI saying that the LR that we want to find is now higher than
63966449
// before.
6397-
int64_t LRPosEntry =
6398-
MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfLR, -Align));
6450+
int LROffset = Auth ? Align - 4 : Align;
6451+
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
6452+
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
6453+
int64_t LRPosEntry = MF.addFrameInst(
6454+
MCCFIInstruction::createOffset(nullptr, DwarfLR, -LROffset));
63996455
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
64006456
.addCFIIndex(LRPosEntry)
64016457
.setMIFlags(MachineInstr::FrameSetup);
6458+
if (Auth) {
6459+
// Add a CFI for the location of the return adddress PAC.
6460+
unsigned DwarfRAC = MRI->getDwarfRegNum(ARM::RA_AUTH_CODE, true);
6461+
int64_t RACPosEntry = MF.addFrameInst(
6462+
MCCFIInstruction::createOffset(nullptr, DwarfRAC, -Align));
6463+
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6464+
.addCFIIndex(RACPosEntry)
6465+
.setMIFlags(MachineInstr::FrameSetup);
6466+
}
64026467
}
64036468

64046469
void ARMBaseInstrInfo::emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
@@ -6416,35 +6481,64 @@ void ARMBaseInstrInfo::emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
64166481
.setMIFlags(MachineInstr::FrameSetup);
64176482
}
64186483

6419-
void ARMBaseInstrInfo::restoreLRFromStack(
6420-
MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
6421-
unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
6422-
MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
6423-
.addReg(ARM::SP, RegState::Define)
6424-
.addReg(ARM::SP);
6425-
if (!Subtarget.isThumb())
6426-
MIB.addReg(0);
6427-
MIB.addImm(Subtarget.getStackAlignment().value()).add(predOps(ARMCC::AL));
6428-
}
6484+
void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
6485+
MachineBasicBlock::iterator It,
6486+
bool CFI, bool Auth) const {
6487+
int Align = Subtarget.getStackAlignment().value();
6488+
if (Auth) {
6489+
assert(Subtarget.isThumb2());
6490+
// Restore return address PAC and LR.
6491+
BuildMI(MBB, It, DebugLoc(), get(ARM::t2LDRD_POST))
6492+
.addReg(ARM::R12, RegState::Define)
6493+
.addReg(ARM::LR, RegState::Define)
6494+
.addReg(ARM::SP, RegState::Define)
6495+
.addReg(ARM::SP)
6496+
.addImm(Align)
6497+
.add(predOps(ARMCC::AL))
6498+
.setMIFlags(MachineInstr::FrameDestroy);
6499+
// LR authentication is after the CFI instructions, below.
6500+
} else {
6501+
unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
6502+
MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
6503+
.addReg(ARM::SP, RegState::Define)
6504+
.addReg(ARM::SP);
6505+
if (!Subtarget.isThumb())
6506+
MIB.addReg(0);
6507+
MIB.addImm(Subtarget.getStackAlignment().value())
6508+
.add(predOps(ARMCC::AL))
6509+
.setMIFlags(MachineInstr::FrameDestroy);
6510+
}
64296511

6430-
void ARMBaseInstrInfo::emitCFIForLRRestoreFromStack(
6431-
MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
6432-
// Now stack has moved back up...
6433-
MachineFunction &MF = *MBB.getParent();
6434-
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
6435-
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
6436-
int64_t StackPosEntry =
6437-
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
6438-
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6439-
.addCFIIndex(StackPosEntry)
6440-
.setMIFlags(MachineInstr::FrameDestroy);
6512+
if (CFI) {
6513+
// Now stack has moved back up...
6514+
MachineFunction &MF = *MBB.getParent();
6515+
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
6516+
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
6517+
int64_t StackPosEntry =
6518+
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
6519+
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6520+
.addCFIIndex(StackPosEntry)
6521+
.setMIFlags(MachineInstr::FrameDestroy);
6522+
6523+
// ... and we have restored LR.
6524+
int64_t LRPosEntry =
6525+
MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
6526+
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6527+
.addCFIIndex(LRPosEntry)
6528+
.setMIFlags(MachineInstr::FrameDestroy);
6529+
6530+
if (Auth) {
6531+
unsigned DwarfRAC = MRI->getDwarfRegNum(ARM::RA_AUTH_CODE, true);
6532+
int64_t Entry =
6533+
MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, DwarfRAC));
6534+
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6535+
.addCFIIndex(Entry)
6536+
.setMIFlags(MachineInstr::FrameDestroy);
6537+
}
6538+
}
64416539

6442-
// ... and we have restored LR.
6443-
int64_t LRPosEntry =
6444-
MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
6445-
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
6446-
.addCFIIndex(LRPosEntry)
6447-
.setMIFlags(MachineInstr::FrameDestroy);
6540+
if (Auth)
6541+
BuildMI(MBB, It, DebugLoc(), get(ARM::t2AUT));
64486542
}
64496543

64506544
void ARMBaseInstrInfo::emitCFIForLRRestoreFromReg(
@@ -6500,8 +6594,11 @@ void ARMBaseInstrInfo::buildOutlinedFrame(
65006594
MBB.addLiveIn(ARM::LR);
65016595

65026596
// Insert a save before the outlined region
6503-
saveLROnStack(MBB, It);
6504-
emitCFIForLRSaveOnStack(MBB, It);
6597+
bool Auth = OF.Candidates.front()
6598+
.getMF()
6599+
->getInfo<ARMFunctionInfo>()
6600+
->shouldSignReturnAddress(true);
6601+
saveLROnStack(MBB, It, true, Auth);
65056602

65066603
// Fix up the instructions in the range, since we're going to modify the
65076604
// stack.
@@ -6510,8 +6607,7 @@ void ARMBaseInstrInfo::buildOutlinedFrame(
65106607
fixupPostOutline(MBB);
65116608

65126609
// Insert a restore before the terminator for the function. Restore LR.
6513-
restoreLRFromStack(MBB, Et);
6514-
emitCFIForLRRestoreFromStack(MBB, Et);
6610+
restoreLRFromStack(MBB, Et, true, Auth);
65156611
}
65166612

65176613
// If this is a tail call outlined function, then there's already a return.
@@ -6590,13 +6686,10 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
65906686
// We have the default case. Save and restore from SP.
65916687
if (!MBB.isLiveIn(ARM::LR))
65926688
MBB.addLiveIn(ARM::LR);
6593-
saveLROnStack(MBB, It);
6594-
if (!AFI.isLRSpilled())
6595-
emitCFIForLRSaveOnStack(MBB, It);
6689+
bool Auth = !AFI.isLRSpilled() && AFI.shouldSignReturnAddress(true);
6690+
saveLROnStack(MBB, It, !AFI.isLRSpilled(), Auth);
65966691
CallPt = MBB.insert(It, CallMIB);
6597-
restoreLRFromStack(MBB, It);
6598-
if (!AFI.isLRSpilled())
6599-
emitCFIForLRRestoreFromStack(MBB, It);
6692+
restoreLRFromStack(MBB, It, !AFI.isLRSpilled(), Auth);
66006693
It--;
66016694
return CallPt;
66026695
}

0 commit comments

Comments
 (0)