Skip to content

Commit 4bb4ad4

Browse files
authored
[AArch64][PAC] Use enum to describe LR signing condition (NFC) (#168548)
Express the condition of signing the return address in a function using an `enum class` instead of a pair of `bool`s. Define `enum class SignReturnAddress` with the values corresponding to the three possible modes that can be requested via "sign-return-address" function attribute. Previously, there were two overloads of `shouldSignReturnAddress` accepting either `const MachineFunction &` or `bool` argument. Due to pointer-to-bool conversion, when `shouldSignReturnAddress` was incorrectly called with `const MachineFunction *` argument, the latter overload was used instead of reporting a compile-time error.
1 parent e085082 commit 4bb4ad4

File tree

4 files changed

+52
-38
lines changed

4 files changed

+52
-38
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,8 +973,7 @@ bool AArch64FrameLowering::shouldSignReturnAddressEverywhere(
973973
if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI())
974974
return false;
975975
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
976-
bool SignReturnAddressAll = AFI->shouldSignReturnAddress(/*SpillsLR=*/false);
977-
return SignReturnAddressAll;
976+
return AFI->getSignReturnAddressCondition() == SignReturnAddress::All;
978977
}
979978

980979
// Given a load or a store instruction, generate an appropriate unwinding SEH

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9796,8 +9796,8 @@ outliningCandidatesSigningScopeConsensus(const outliner::Candidate &a,
97969796
const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>();
97979797
const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>();
97989798

9799-
return MFIa->shouldSignReturnAddress(false) == MFIb->shouldSignReturnAddress(false) &&
9800-
MFIa->shouldSignReturnAddress(true) == MFIb->shouldSignReturnAddress(true);
9799+
return MFIa->getSignReturnAddressCondition() ==
9800+
MFIb->getSignReturnAddressCondition();
98019801
}
98029802

98039803
static bool
@@ -9888,10 +9888,11 @@ AArch64InstrInfo::getOutliningCandidateInfo(
98889888
// Performing a tail call may require extra checks when PAuth is enabled.
98899889
// If PAuth is disabled, set it to zero for uniformity.
98909890
unsigned NumBytesToCheckLRInTCEpilogue = 0;
9891-
if (RepeatedSequenceLocs[0]
9892-
.getMF()
9893-
->getInfo<AArch64FunctionInfo>()
9894-
->shouldSignReturnAddress(true)) {
9891+
const auto RASignCondition = RepeatedSequenceLocs[0]
9892+
.getMF()
9893+
->getInfo<AArch64FunctionInfo>()
9894+
->getSignReturnAddressCondition();
9895+
if (RASignCondition != SignReturnAddress::None) {
98959896
// One PAC and one AUT instructions
98969897
NumBytesToCreateFrame += 8;
98979898

@@ -10695,7 +10696,9 @@ void AArch64InstrInfo::buildOutlinedFrame(
1069510696
Et = MBB.insert(Et, LDRXpost);
1069610697
}
1069710698

10698-
bool ShouldSignReturnAddr = FI->shouldSignReturnAddress(!IsLeafFunction);
10699+
auto RASignCondition = FI->getSignReturnAddressCondition();
10700+
bool ShouldSignReturnAddr = AArch64FunctionInfo::shouldSignReturnAddress(
10701+
RASignCondition, !IsLeafFunction);
1069910702

1070010703
// If this is a tail call outlined function, then there's already a return.
1070110704
if (OF.FrameConstructionID == MachineOutlinerTailCall ||

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "AArch64MachineFunctionInfo.h"
1717
#include "AArch64InstrInfo.h"
1818
#include "AArch64Subtarget.h"
19+
#include "llvm/ADT/StringSwitch.h"
1920
#include "llvm/IR/Constants.h"
2021
#include "llvm/IR/Metadata.h"
2122
#include "llvm/IR/Module.h"
@@ -63,24 +64,21 @@ void AArch64FunctionInfo::initializeBaseYamlFields(
6364
setHasStreamingModeChanges(*YamlMFI.HasStreamingModeChanges);
6465
}
6566

66-
static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
67+
static SignReturnAddress GetSignReturnAddress(const Function &F) {
6768
if (F.hasFnAttribute("ptrauth-returns"))
68-
return {true, false}; // non-leaf
69+
return SignReturnAddress::NonLeaf;
70+
6971
// The function should be signed in the following situations:
7072
// - sign-return-address=all
7173
// - sign-return-address=non-leaf and the functions spills the LR
7274
if (!F.hasFnAttribute("sign-return-address"))
73-
return {false, false};
75+
return SignReturnAddress::None;
7476

7577
StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
76-
if (Scope == "none")
77-
return {false, false};
78-
79-
if (Scope == "all")
80-
return {true, true};
81-
82-
assert(Scope == "non-leaf");
83-
return {true, false};
78+
return StringSwitch<SignReturnAddress>(Scope)
79+
.Case("none", SignReturnAddress::None)
80+
.Case("non-leaf", SignReturnAddress::NonLeaf)
81+
.Case("all", SignReturnAddress::All);
8482
}
8583

8684
static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
@@ -116,7 +114,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
116114
// HasRedZone here.
117115
if (F.hasFnAttribute(Attribute::NoRedZone))
118116
HasRedZone = false;
119-
std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
117+
SignCondition = GetSignReturnAddress(F);
120118
SignWithBKey = ShouldSignWithBKey(F, *STI);
121119
HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
122120
// TODO: skip functions that have no instrumented allocas for optimization
@@ -169,23 +167,27 @@ MachineFunctionInfo *AArch64FunctionInfo::clone(
169167
return DestMF.cloneInfo<AArch64FunctionInfo>(*this);
170168
}
171169

172-
bool AArch64FunctionInfo::shouldSignReturnAddress(bool SpillsLR) const {
173-
if (!SignReturnAddress)
174-
return false;
175-
if (SignReturnAddressAll)
176-
return true;
177-
return SpillsLR;
178-
}
179-
180170
static bool isLRSpilled(const MachineFunction &MF) {
181171
return llvm::any_of(
182172
MF.getFrameInfo().getCalleeSavedInfo(),
183173
[](const auto &Info) { return Info.getReg() == AArch64::LR; });
184174
}
185175

176+
bool AArch64FunctionInfo::shouldSignReturnAddress(SignReturnAddress Condition,
177+
bool IsLRSpilled) {
178+
switch (Condition) {
179+
case SignReturnAddress::None:
180+
return false;
181+
case SignReturnAddress::NonLeaf:
182+
return IsLRSpilled;
183+
case SignReturnAddress::All:
184+
return true;
185+
}
186+
}
187+
186188
bool AArch64FunctionInfo::shouldSignReturnAddress(
187189
const MachineFunction &MF) const {
188-
return shouldSignReturnAddress(isLRSpilled(MF));
190+
return shouldSignReturnAddress(SignCondition, isLRSpilled(MF));
189191
}
190192

191193
bool AArch64FunctionInfo::needsShadowCallStackPrologueEpilogue(

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ struct TPIDR2Object {
4242
unsigned Uses = 0;
4343
};
4444

45+
/// Condition of signing the return address in a function.
46+
///
47+
/// Corresponds to possible values of "sign-return-address" function attribute.
48+
enum class SignReturnAddress {
49+
None,
50+
NonLeaf,
51+
All,
52+
};
53+
4554
/// AArch64FunctionInfo - This class is derived from MachineFunctionInfo and
4655
/// contains private AArch64-specific information for each MachineFunction.
4756
class AArch64FunctionInfo final : public MachineFunctionInfo {
@@ -170,13 +179,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
170179
// CalleeSavedStackSize) to the address of the frame record.
171180
int CalleeSaveBaseToFrameRecordOffset = 0;
172181

173-
/// SignReturnAddress is true if PAC-RET is enabled for the function with
174-
/// defaults being sign non-leaf functions only, with the B key.
175-
bool SignReturnAddress = false;
176-
177-
/// SignReturnAddressAll modifies the default PAC-RET mode to signing leaf
178-
/// functions as well.
179-
bool SignReturnAddressAll = false;
182+
/// SignCondition controls when PAC-RET protection should be used.
183+
SignReturnAddress SignCondition = SignReturnAddress::None;
180184

181185
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
182186
bool SignWithBKey = false;
@@ -591,8 +595,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
591595
CalleeSaveBaseToFrameRecordOffset = Offset;
592596
}
593597

598+
static bool shouldSignReturnAddress(SignReturnAddress Condition,
599+
bool IsLRSpilled);
600+
594601
bool shouldSignReturnAddress(const MachineFunction &MF) const;
595-
bool shouldSignReturnAddress(bool SpillsLR) const;
602+
603+
SignReturnAddress getSignReturnAddressCondition() const {
604+
return SignCondition;
605+
}
596606

597607
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const;
598608

0 commit comments

Comments
 (0)