[llvm] 79b3f08 - StackProtector: expose RequiresStackProtector publicly. NFC.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 16 04:34:33 PDT 2023
Author: Tim Northover
Date: 2023-03-16T11:32:45Z
New Revision: 79b3f0823e562fc652c3272b2ccfb99174445fa6
URL: https://github.com/llvm/llvm-project/commit/79b3f0823e562fc652c3272b2ccfb99174445fa6
DIFF: https://github.com/llvm/llvm-project/commit/79b3f0823e562fc652c3272b2ccfb99174445fa6.diff
LOG: StackProtector: expose RequiresStackProtector publicly. NFC.
Added:
Modified:
llvm/include/llvm/CodeGen/StackProtector.h
llvm/lib/CodeGen/StackProtector.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/StackProtector.h b/llvm/include/llvm/CodeGen/StackProtector.h
index a5a95c421b2e..6bbdae69666f 100644
--- a/llvm/include/llvm/CodeGen/StackProtector.h
+++ b/llvm/include/llvm/CodeGen/StackProtector.h
@@ -63,12 +63,6 @@ class StackProtector : public FunctionPass {
/// protection when -fstack-protection is used.
unsigned SSPBufferSize = DefaultSSPBufferSize;
- /// VisitedPHIs - The set of PHI nodes visited when determining
- /// if a variable's reference has been taken. This set
- /// is maintained to ensure we don't visit the same PHI node multiple
- /// times.
- SmallPtrSet<const PHINode *, 16> VisitedPHIs;
-
// A prologue is generated.
bool HasPrologue = false;
@@ -87,22 +81,6 @@ class StackProtector : public FunctionPass {
/// check fails.
BasicBlock *CreateFailBB();
- /// ContainsProtectableArray - Check whether the type either is an array or
- /// contains an array of sufficient size so that we need stack protectors
- /// for it.
- /// \param [out] IsLarge is set to true if a protectable array is found and
- /// it is "large" ( >= ssp-buffer-size). In the case of a structure with
- /// multiple arrays, this gets set if any of them is large.
- bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
- bool InStruct = false) const;
-
- /// Check whether a stack allocation has its address taken.
- bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize);
-
- /// RequiresStackProtector - Check whether or not this function needs a
- /// stack protector based upon the stack protector level.
- bool RequiresStackProtector();
-
public:
static char ID; // Pass identification, replacement for typeid.
@@ -116,6 +94,11 @@ class StackProtector : public FunctionPass {
bool runOnFunction(Function &Fn) override;
void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
+
+ /// Check whether or not \p F needs a stack protector based upon the stack
+ /// protector level.
+ static bool requiresStackProtector(Function *F, SSPLayoutMap *Layout = nullptr);
+
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 52336cc1d609..aa92dcb38656 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -96,7 +96,7 @@ bool StackProtector::runOnFunction(Function &Fn) {
SSPBufferSize = Fn.getFnAttributeAsParsedInteger(
"stack-protector-buffer-size", DefaultSSPBufferSize);
- if (!RequiresStackProtector())
+ if (!requiresStackProtector(F, &Layout))
return false;
// TODO(etienneb): Functions with funclets are not correctly supported now.
@@ -121,9 +121,9 @@ bool StackProtector::runOnFunction(Function &Fn) {
/// \param [out] IsLarge is set to true if a protectable array is found and
/// it is "large" ( >= ssp-buffer-size). In the case of a structure with
/// multiple arrays, this gets set if any of them is large.
-bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
- bool Strong,
- bool InStruct) const {
+static bool ContainsProtectableArray(Type *Ty, Module *M, unsigned SSPBufferSize,
+ bool &IsLarge, bool Strong,
+ bool InStruct) {
if (!Ty)
return false;
if (ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
@@ -132,7 +132,7 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
// add stack protectors unless the array is a character array.
// However, in strong mode any array, regardless of type and size,
// triggers a protector.
- if (!Strong && (InStruct || !Trip.isOSDarwin()))
+ if (!Strong && (InStruct || !Triple(M->getTargetTriple()).isOSDarwin()))
return false;
}
@@ -154,7 +154,7 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
bool NeedsProtector = false;
for (Type *ET : ST->elements())
- if (ContainsProtectableArray(ET, IsLarge, Strong, true)) {
+ if (ContainsProtectableArray(ET, M, SSPBufferSize, IsLarge, Strong, true)) {
// If the element is a protectable array and is large (>= SSPBufferSize)
// then we are done. If the protectable array is not large, then
// keep looking in case a subsequent element is a large array.
@@ -166,8 +166,10 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
return NeedsProtector;
}
-bool StackProtector::HasAddressTaken(const Instruction *AI,
- TypeSize AllocSize) {
+/// Check whether a stack allocation has its address taken.
+static bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize,
+ Module *M,
+ SmallPtrSet<const PHINode *, 16> &VisitedPHIs) {
const DataLayout &DL = M->getDataLayout();
for (const User *U : AI->users()) {
const auto *I = cast<Instruction>(U);
@@ -221,14 +223,14 @@ bool StackProtector::HasAddressTaken(const Instruction *AI,
// assume the scalable value is of minimum size.
TypeSize NewAllocSize =
TypeSize::Fixed(AllocSize.getKnownMinValue()) - OffsetSize;
- if (HasAddressTaken(I, NewAllocSize))
+ if (HasAddressTaken(I, NewAllocSize, M, VisitedPHIs))
return true;
break;
}
case Instruction::BitCast:
case Instruction::Select:
case Instruction::AddrSpaceCast:
- if (HasAddressTaken(I, AllocSize))
+ if (HasAddressTaken(I, AllocSize, M, VisitedPHIs))
return true;
break;
case Instruction::PHI: {
@@ -236,7 +238,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI,
// they are only visited once.
const auto *PN = cast<PHINode>(I);
if (VisitedPHIs.insert(PN).second)
- if (HasAddressTaken(PN, AllocSize))
+ if (HasAddressTaken(PN, AllocSize, M, VisitedPHIs))
return true;
break;
}
@@ -282,10 +284,19 @@ static const CallInst *findStackProtectorIntrinsic(Function &F) {
/// functions with aggregates that contain any buffer regardless of type and
/// size, and functions that contain stack-based variables that have had their
/// address taken.
-bool StackProtector::RequiresStackProtector() {
+bool StackProtector::requiresStackProtector(Function *F, SSPLayoutMap *Layout) {
+ Module *M = F->getParent();
bool Strong = false;
bool NeedsProtector = false;
+ // The set of PHI nodes visited when determining if a variable's reference has
+ // been taken. This set is maintained to ensure we don't visit the same PHI
+ // node multiple times.
+ SmallPtrSet<const PHINode *, 16> VisitedPHIs;
+
+ unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger(
+ "stack-protector-buffer-size", DefaultSSPBufferSize);
+
if (F->hasFnAttribute(Attribute::SafeStack))
return false;
@@ -295,6 +306,8 @@ bool StackProtector::RequiresStackProtector() {
OptimizationRemarkEmitter ORE(F);
if (F->hasFnAttribute(Attribute::StackProtectReq)) {
+ if (!Layout)
+ return true;
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorRequested", F)
<< "Stack protection applied to function "
@@ -324,21 +337,27 @@ bool StackProtector::RequiresStackProtector() {
if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
// A call to alloca with size >= SSPBufferSize requires
// stack protectors.
- Layout.insert(std::make_pair(AI,
- MachineFrameInfo::SSPLK_LargeArray));
+ if (!Layout)
+ return true;
+ Layout->insert(
+ std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
ORE.emit(RemarkBuilder);
NeedsProtector = true;
} else if (Strong) {
// Require protectors for all alloca calls in strong mode.
- Layout.insert(std::make_pair(AI,
- MachineFrameInfo::SSPLK_SmallArray));
+ if (!Layout)
+ return true;
+ Layout->insert(
+ std::make_pair(AI, MachineFrameInfo::SSPLK_SmallArray));
ORE.emit(RemarkBuilder);
NeedsProtector = true;
}
} else {
// A call to alloca with a variable size requires protectors.
- Layout.insert(std::make_pair(AI,
- MachineFrameInfo::SSPLK_LargeArray));
+ if (!Layout)
+ return true;
+ Layout->insert(
+ std::make_pair(AI, MachineFrameInfo::SSPLK_LargeArray));
ORE.emit(RemarkBuilder);
NeedsProtector = true;
}
@@ -346,10 +365,13 @@ bool StackProtector::RequiresStackProtector() {
}
bool IsLarge = false;
- if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
- Layout.insert(std::make_pair(AI, IsLarge
- ? MachineFrameInfo::SSPLK_LargeArray
- : MachineFrameInfo::SSPLK_SmallArray));
+ if (ContainsProtectableArray(AI->getAllocatedType(), M, SSPBufferSize,
+ IsLarge, Strong, false)) {
+ if (!Layout)
+ return true;
+ Layout->insert(std::make_pair(
+ AI, IsLarge ? MachineFrameInfo::SSPLK_LargeArray
+ : MachineFrameInfo::SSPLK_SmallArray));
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorBuffer", &I)
<< "Stack protection applied to function "
@@ -361,10 +383,14 @@ bool StackProtector::RequiresStackProtector() {
continue;
}
- if (Strong && HasAddressTaken(AI, M->getDataLayout().getTypeAllocSize(
- AI->getAllocatedType()))) {
+ if (Strong &&
+ HasAddressTaken(
+ AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),
+ M, VisitedPHIs)) {
++NumAddrTaken;
- Layout.insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
+ if (!Layout)
+ return true;
+ Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
ORE.emit([&]() {
return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
&I)
More information about the llvm-commits
mailing list