#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
namespace {
class StackProtector : public FunctionPass {
+ const TargetMachine *TM;
+
/// TLI - Keep a pointer of a TargetLowering to consult for determining
/// target type sizes.
const TargetLoweringBase *TLI;
+ const Triple Trip;
Function *F;
Module *M;
bool RequiresStackProtector();
public:
static char ID; // Pass identification, replacement for typeid.
- StackProtector() : FunctionPass(ID), TLI(0) {
+ StackProtector() : FunctionPass(ID), TM(0), TLI(0) {
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
}
- StackProtector(const TargetLoweringBase *tli)
- : FunctionPass(ID), TLI(tli) {
+ StackProtector(const TargetMachine *TM)
+ : FunctionPass(ID), TM(TM), TLI(0), Trip(TM->getTargetTriple()) {
initializeStackProtectorPass(*PassRegistry::getPassRegistry());
}
INITIALIZE_PASS(StackProtector, "stack-protector",
"Insert stack protectors", false, false)
-FunctionPass *llvm::createStackProtectorPass(const TargetLoweringBase *tli) {
- return new StackProtector(tli);
+FunctionPass *llvm::createStackProtectorPass(const TargetMachine *TM) {
+ return new StackProtector(TM);
}
bool StackProtector::runOnFunction(Function &Fn) {
F = &Fn;
M = F->getParent();
DT = getAnalysisIfAvailable<DominatorTree>();
+ TLI = TM->getTargetLowering();
if (!RequiresStackProtector()) return false;
return true;
const TargetMachine &TM = TLI->getTargetMachine();
if (!AT->getElementType()->isIntegerTy(8)) {
- Triple Trip(TM.getTargetTriple());
-
// If we're on a non-Darwin platform or we're inside of a structure, don't
// add stack protectors unless the array is a character array.
if (InStruct || !Trip.isOSDarwin())
StackGuardVar = ConstantExpr::getIntToPtr(OffsetVal,
PointerType::get(PtrTy, AddressSpace));
+ } else if (Trip.getOS() == llvm::Triple::OpenBSD) {
+ StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
+ cast<GlobalValue>(StackGuardVar)
+ ->setVisibility(GlobalValue::HiddenVisibility);
} else {
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
}
/// CreateFailBB - Create a basic block to jump to when the stack protector
/// check fails.
BasicBlock *StackProtector::CreateFailBB() {
- BasicBlock *FailBB = BasicBlock::Create(F->getContext(),
- "CallStackCheckFailBlk", F);
- Constant *StackChkFail =
- M->getOrInsertFunction("__stack_chk_fail",
- Type::getVoidTy(F->getContext()), NULL);
- CallInst::Create(StackChkFail, "", FailBB);
- new UnreachableInst(F->getContext(), FailBB);
+ LLVMContext &Context = F->getContext();
+ BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
+ if (Trip.getOS() == llvm::Triple::OpenBSD) {
+ Constant *StackChkFail = M->getOrInsertFunction(
+ "__stack_smash_handler", Type::getVoidTy(Context),
+ Type::getInt8PtrTy(Context), NULL);
+
+ Constant *NameStr = ConstantDataArray::getString(Context, F->getName());
+ Constant *FuncName =
+ new GlobalVariable(*M, NameStr->getType(), true,
+ GlobalVariable::PrivateLinkage, NameStr, "SSH");
+
+ SmallVector<Constant *, 2> IdxList;
+ IdxList.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0));
+ IdxList.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0));
+
+ SmallVector<Value *, 1> Args;
+ Args.push_back(ConstantExpr::getGetElementPtr(FuncName, IdxList));
+
+ CallInst::Create(StackChkFail, Args, "", FailBB);
+ } else {
+ Constant *StackChkFail = M->getOrInsertFunction(
+ "__stack_chk_fail", Type::getVoidTy(Context), NULL);
+ CallInst::Create(StackChkFail, "", FailBB);
+ }
+ new UnreachableInst(Context, FailBB);
return FailBB;
}