| Index: lib/Transforms/NaCl/AddSFI.cpp
|
| diff --git a/lib/Transforms/NaCl/AddSFI.cpp b/lib/Transforms/NaCl/AddSFI.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..794909cc9b22e03ed240cfd69686ebfaa43e6d79
|
| --- /dev/null
|
| +++ b/lib/Transforms/NaCl/AddSFI.cpp
|
| @@ -0,0 +1,116 @@
|
| +//===- AddSFI.cpp - Apply SFI sandboxing-----------------------------------===//
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// XXX
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "llvm/IR/Constants.h"
|
| +#include "llvm/IR/Function.h"
|
| +#include "llvm/IR/Instructions.h"
|
| +// #include "llvm/IR/Intrinsics.h"
|
| +#include "llvm/IR/Module.h"
|
| +#include "llvm/Pass.h"
|
| +// #include "llvm/Support/raw_ostream.h"
|
| +#include "llvm/Transforms/NaCl.h"
|
| +
|
| +using namespace llvm;
|
| +
|
| +namespace {
|
| + // This is a ModulePass so that it can add global variables.
|
| + class ExpandAllocas : public ModulePass {
|
| + public:
|
| + static char ID; // Pass identification, replacement for typeid
|
| + ExpandAllocas() : ModulePass(ID) {
|
| + initializeExpandAllocasPass(*PassRegistry::getPassRegistry());
|
| + }
|
| +
|
| + virtual bool runOnModule(Module &M);
|
| + };
|
| +}
|
| +
|
| +char ExpandAllocas::ID = 0;
|
| +INITIALIZE_PASS(ExpandAllocas, "expand-allocas",
|
| + "Expand out alloca instructions",
|
| + false, false)
|
| +
|
| +static void expandAllocas(Function *Func, Type *IntPtrType, Value *StackPtr) {
|
| + // Skip function declarations.
|
| + if (Func->empty())
|
| + return;
|
| +
|
| + Type *I8Ptr = Type::getInt8PtrTy(Func->getContext());
|
| + Instruction *FrameTop = NULL;
|
| +
|
| + BasicBlock *EntryBB = &Func->getEntryBlock();
|
| + unsigned FrameOffset = 0;
|
| + for (BasicBlock::iterator Iter = EntryBB->begin(), E = EntryBB->end();
|
| + Iter != E; ) {
|
| + Instruction *Inst = Iter++;
|
| + if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) {
|
| + // XXX: error reporting
|
| + assert(Alloca->getType() == I8Ptr);
|
| + // XXX: error reporting
|
| + ConstantInt *CI = cast<ConstantInt>(Alloca->getArraySize());
|
| + // TODO: handle alignment
|
| + FrameOffset += CI->getZExtValue();
|
| +
|
| + if (!FrameTop) {
|
| + FrameTop = new LoadInst(StackPtr, "frame_top");
|
| + EntryBB->getInstList().push_front(FrameTop);
|
| + }
|
| + Value *Var = BinaryOperator::Create(
|
| + BinaryOperator::Add, FrameTop,
|
| + ConstantInt::get(IntPtrType, -FrameOffset), "", Alloca);
|
| + Var = new IntToPtrInst(Var, Alloca->getType(), "", Alloca);
|
| + Var->takeName(Alloca);
|
| + Alloca->replaceAllUsesWith(Var);
|
| + Alloca->eraseFromParent();
|
| + }
|
| + }
|
| + if (FrameTop) {
|
| + // Adjust stack pointer.
|
| + // TODO: Could omit this in leaf functions.
|
| + Instruction *FrameBottom = BinaryOperator::Create(
|
| + BinaryOperator::Add, FrameTop,
|
| + ConstantInt::get(IntPtrType, -FrameOffset), "frame_bottom");
|
| + FrameBottom->insertAfter(FrameTop);
|
| + (new StoreInst(FrameBottom, StackPtr))->insertAfter(FrameBottom);
|
| +
|
| + for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) {
|
| + for (BasicBlock::iterator Inst = BB->begin(), E = BB->end(); Inst != E;
|
| + ++Inst) {
|
| + if (isa<AllocaInst>(Inst)) {
|
| + report_fatal_error("TODO: handle dynamic alloca");
|
| + } else if (ReturnInst *Ret = dyn_cast<ReturnInst>(Inst)) {
|
| + // Restore stack pointer.
|
| + new StoreInst(FrameTop, StackPtr, Ret);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool ExpandAllocas::runOnModule(Module &M) {
|
| + Type *IntPtrType = Type::getInt32Ty(M.getContext()); // XXX
|
| + uint64_t InitialStackPtr = 0x40000000;
|
| + Value *StackPtr = new GlobalVariable(
|
| + M, IntPtrType, /*isConstant=*/false, GlobalVariable::InternalLinkage,
|
| + ConstantInt::get(IntPtrType, InitialStackPtr),
|
| + "__sfi_stack");
|
| +
|
| + for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) {
|
| + expandAllocas(Func, IntPtrType, StackPtr);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +ModulePass *llvm::createExpandAllocasPass() {
|
| + return new ExpandAllocas();
|
| +}
|
|
|