| Index: lib/Transforms/MinSFI/SubstituteUndefs.cpp
|
| diff --git a/lib/Transforms/MinSFI/SubstituteUndefs.cpp b/lib/Transforms/MinSFI/SubstituteUndefs.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..352193bc09bfc29244a360a6df699c32073889a0
|
| --- /dev/null
|
| +++ b/lib/Transforms/MinSFI/SubstituteUndefs.cpp
|
| @@ -0,0 +1,96 @@
|
| +//===- SubstituteUndefs.cpp - Replace undefs with deterministic constants -===//
|
| +//
|
| +// The LLVM Compiler Infrastructure
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// PNaCl bitcode may contain undefined values inside function bodies, i.e. as
|
| +// a placeholder for numerical constants and constant vectors. Their actual
|
| +// value at runtime will most likely be the current value from one of the
|
| +// registers or from the native stack.
|
| +//
|
| +// Using undefined values, the sandboxed code could obtain protected values,
|
| +// such as the base address of the address subspace or a value from another
|
| +// protection domain left in the register file. Additionally, undefined values
|
| +// may introduce undesirable non-determinism.
|
| +//
|
| +// This pass therefore substitutes all undefined expressions with predefined
|
| +// constants.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "llvm/Pass.h"
|
| +#include "llvm/IR/Constants.h"
|
| +#include "llvm/IR/Function.h"
|
| +#include "llvm/Transforms/MinSFI.h"
|
| +
|
| +using namespace llvm;
|
| +
|
| +static const uint64_t SubstInt = 0xBAADF00DCAFEBABE;
|
| +static const double SubstFloat = 3.14159265359;
|
| +
|
| +namespace {
|
| +class SubstituteUndefs : public FunctionPass {
|
| + public:
|
| + static char ID;
|
| + SubstituteUndefs() : FunctionPass(ID) {
|
| + initializeSubstituteUndefsPass(*PassRegistry::getPassRegistry());
|
| + }
|
| +
|
| + virtual bool runOnFunction(Function &Func);
|
| +};
|
| +} // namespace
|
| +
|
| +static inline bool isScalarOrVectorInteger(Type *T) {
|
| + if (T->isIntegerTy())
|
| + return true;
|
| + else if (T->isVectorTy() && T->getVectorElementType()->isIntegerTy())
|
| + return true;
|
| + else
|
| + return false;
|
| +}
|
| +
|
| +static inline bool isScalarOrVectorFloatingPoint(Type *T) {
|
| + if (T->isFloatingPointTy())
|
| + return true;
|
| + else if (T->isVectorTy() && T->getVectorElementType()->isFloatingPointTy())
|
| + return true;
|
| + else
|
| + return false;
|
| +}
|
| +
|
| +bool SubstituteUndefs::runOnFunction(Function &Func) {
|
| + bool HadUndefs = false;
|
| + for (Function::iterator BB = Func.begin(), E = Func.end(); BB != E; ++BB) {
|
| + for (BasicBlock::iterator Inst = BB->begin(), E = BB->end(); Inst != E;
|
| + ++Inst) {
|
| + for (int Index = 0, NumOps = Inst->getNumOperands(); Index < NumOps;
|
| + ++Index) {
|
| + Value *Operand = Inst->getOperand(Index);
|
| + if (isa<UndefValue>(Operand)) {
|
| + HadUndefs = true;
|
| + Type *OpType = Operand->getType();
|
| + if (isScalarOrVectorInteger(OpType))
|
| + Inst->setOperand(Index, ConstantInt::get(OpType, SubstInt));
|
| + else if (isScalarOrVectorFloatingPoint(OpType))
|
| + Inst->setOperand(Index, ConstantFP::get(OpType, SubstFloat));
|
| + else
|
| + assert(false && "Type of undef not permitted by the PNaCl ABI");
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return HadUndefs;
|
| +}
|
| +
|
| +char SubstituteUndefs::ID = 0;
|
| +INITIALIZE_PASS(SubstituteUndefs, "minsfi-substitute-undefs",
|
| + "Replace undef values with deterministic constants",
|
| + false, false)
|
| +
|
| +FunctionPass *llvm::createSubstituteUndefsPass() {
|
| + return new SubstituteUndefs();
|
| +}
|
|
|