mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 01:42:09 +00:00
- Modify the stack protector algorithm so that the stack slot is allocated in
LLVM IR code and not in the selection DAG ISel. This is a cleaner solution. - Fix the heuristic for determining if protectors are necessary. The previous one wasn't checking the proper type size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58824 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
848693c254
commit
b7c6ebcb47
@ -179,9 +179,10 @@ def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
|
||||
// Stack Protector Intrinsics - The stackprotector_create writes the stack guard
|
||||
// to the correct place on the stack frame. The stackprotector_check reads back
|
||||
// the stack guard that the stackprotector_create stored.
|
||||
def int_stackprotector_create : Intrinsic<[llvm_void_ty, llvm_ptr_ty],
|
||||
[IntrWriteMem]>;
|
||||
def int_stackprotector_check : Intrinsic<[llvm_ptr_ty], [IntrReadMem]>;
|
||||
def int_stackprotector_create : Intrinsic<[llvm_void_ty, llvm_ptr_ty,
|
||||
llvm_ptrptr_ty], [IntrWriteMem]>;
|
||||
def int_stackprotector_check : Intrinsic<[llvm_ptr_ty, llvm_ptrptr_ty],
|
||||
[IntrReadMem]>;
|
||||
|
||||
//===------------------- Standard C Library Intrinsics --------------------===//
|
||||
//
|
||||
|
@ -3801,14 +3801,10 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MVT PtrTy = TLI.getPointerTy();
|
||||
|
||||
// Retrieve the stack protector guard's value.
|
||||
SDValue Src = getValue(I.getOperand(1));
|
||||
SDValue Src = getValue(I.getOperand(1)); // The guard's value.
|
||||
AllocaInst *Slot = cast<AllocaInst>(I.getOperand(2));
|
||||
|
||||
// Create a slot on the stack for the stack protector. It should go first
|
||||
// before local variables are allocated.
|
||||
unsigned Align =
|
||||
TLI.getTargetData()->getPrefTypeAlignment(PtrTy.getTypeForMVT());
|
||||
int FI = MFI->CreateStackObject(PtrTy.getSizeInBits() / 8, Align);
|
||||
int FI = FuncInfo.StaticAllocaMap[Slot];
|
||||
MFI->setStackProtectorIndex(FI);
|
||||
|
||||
SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
|
||||
|
@ -97,9 +97,6 @@ bool StackProtector::runOnFunction(Function &Fn) {
|
||||
/// - The epilogue checks the value stored in the prologue against the original
|
||||
/// value. It calls __stack_chk_fail if they differ.
|
||||
bool StackProtector::InsertStackProtectors() {
|
||||
Constant *StackGuardVar = 0; // The global variable for the stack guard.
|
||||
BasicBlock *FailBB = 0; // The basic block to jump to if check fails.
|
||||
|
||||
// Loop through the basic blocks that have return instructions. Convert this:
|
||||
//
|
||||
// return:
|
||||
@ -122,18 +119,34 @@ bool StackProtector::InsertStackProtectors() {
|
||||
// call void @__stack_chk_fail()
|
||||
// unreachable
|
||||
//
|
||||
BasicBlock *FailBB = 0; // The basic block to jump to if check fails.
|
||||
AllocaInst *AI = 0; // Place on stack that stores the stack guard.
|
||||
Constant *StackGuardVar = 0; // The stack guard variable.
|
||||
|
||||
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
|
||||
BasicBlock *BB = I;
|
||||
|
||||
if (isa<ReturnInst>(BB->getTerminator())) {
|
||||
// Create the basic block to jump to when the guard check fails.
|
||||
if (!FailBB)
|
||||
if (!FailBB) {
|
||||
// Create the basic block to jump to when the guard check fails.
|
||||
FailBB = CreateFailBB();
|
||||
|
||||
if (!StackGuardVar)
|
||||
StackGuardVar =
|
||||
M->getOrInsertGlobal("__stack_chk_guard",
|
||||
PointerType::getUnqual(Type::Int8Ty));
|
||||
// Insert code into the entry block that stores the __stack_chk_guard
|
||||
// variable onto the stack.
|
||||
PointerType *PtrTy = PointerType::getUnqual(Type::Int8Ty);
|
||||
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
|
||||
|
||||
BasicBlock &Entry = F->getEntryBlock();
|
||||
Instruction *InsPt = &Entry.front();
|
||||
|
||||
AI = new AllocaInst(PtrTy, "StackGuardSlot", InsPt);
|
||||
LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsPt);
|
||||
|
||||
Value *Args[] = { LI, AI };
|
||||
CallInst::
|
||||
Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create),
|
||||
&Args[0], array_endof(Args), "", InsPt);
|
||||
}
|
||||
|
||||
ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());
|
||||
Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
|
||||
@ -151,7 +164,7 @@ bool StackProtector::InsertStackProtectors() {
|
||||
LoadInst *LI1 = new LoadInst(StackGuardVar, "", false, BB);
|
||||
CallInst *CI = CallInst::
|
||||
Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_check),
|
||||
"", BB);
|
||||
AI, "", BB);
|
||||
ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, CI, LI1, "", BB);
|
||||
BranchInst::Create(NewBB, FailBB, Cmp, BB);
|
||||
}
|
||||
@ -161,16 +174,6 @@ bool StackProtector::InsertStackProtectors() {
|
||||
// statements in the function.
|
||||
if (!FailBB) return false;
|
||||
|
||||
// Insert code into the entry block that stores the __stack_chk_guard variable
|
||||
// onto the stack.
|
||||
BasicBlock &Entry = F->getEntryBlock();
|
||||
Instruction *InsertPt = &Entry.front();
|
||||
|
||||
LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, InsertPt);
|
||||
CallInst::
|
||||
Create(Intrinsic::getDeclaration(M, Intrinsic::stackprotector_create),
|
||||
LI, "", InsertPt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -202,21 +205,16 @@ bool StackProtector::RequiresStackProtector() const {
|
||||
for (BasicBlock::iterator
|
||||
II = BB->begin(), IE = BB->end(); II != IE; ++II)
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
|
||||
if (!AI->isArrayAllocation()) continue; // Only care about arrays.
|
||||
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
|
||||
const Type *Ty = AI->getAllocatedType();
|
||||
uint64_t TySize = TD->getABITypeSize(Ty);
|
||||
if (AI->isArrayAllocation())
|
||||
// This is a call to alloca with a variable size. Emit stack
|
||||
// protectors.
|
||||
return true;
|
||||
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType()))
|
||||
// If an array has more than 8 bytes of allocated space, then we
|
||||
// emit stack protectors.
|
||||
if (SSPBufferSize <= TySize * CI->getZExtValue())
|
||||
if (SSPBufferSize <= TD->getABITypeSize(AT))
|
||||
return true;
|
||||
} else {
|
||||
// This is a call to alloca with a variable size. Default to adding
|
||||
// stack protectors.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user