OLD | NEW |
(Empty) | |
| 1 //===- SubstituteUndefs.cpp - Replace undefs with deterministic constants -===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // PNaCl bitcode may contain undefined values inside function bodies, i.e. as |
| 11 // a placeholder for numerical constants and constant vectors. Their actual |
| 12 // value at runtime will most likely be the current value from one of the |
| 13 // registers or from the native stack. |
| 14 // |
| 15 // Using undefined values, the sandboxed code could obtain protected values, |
| 16 // such as the base address of the address subspace or a value from another |
| 17 // protection domain left in the register file. Additionally, undefined values |
| 18 // may introduce undesirable non-determinism. |
| 19 // |
| 20 // This pass therefore substitutes all undefined expressions with predefined |
| 21 // constants. |
| 22 // |
| 23 //===----------------------------------------------------------------------===// |
| 24 |
| 25 #include "llvm/Pass.h" |
| 26 #include "llvm/IR/Constants.h" |
| 27 #include "llvm/IR/Function.h" |
| 28 #include "llvm/Transforms/MinSFI.h" |
| 29 |
| 30 using namespace llvm; |
| 31 |
| 32 static const uint64_t SubstInt = 0xBAADF00DCAFEBABE; |
| 33 static const double SubstFloat = 3.14159265359; |
| 34 |
| 35 namespace { |
| 36 class SubstituteUndefs : public FunctionPass { |
| 37 public: |
| 38 static char ID; |
| 39 SubstituteUndefs() : FunctionPass(ID) { |
| 40 initializeSubstituteUndefsPass(*PassRegistry::getPassRegistry()); |
| 41 } |
| 42 |
| 43 virtual bool runOnFunction(Function &Func); |
| 44 }; |
| 45 } // namespace |
| 46 |
| 47 static inline bool isScalarOrVectorInteger(Type *T) { |
| 48 if (T->isIntegerTy()) |
| 49 return true; |
| 50 else if (T->isVectorTy() && T->getVectorElementType()->isIntegerTy()) |
| 51 return true; |
| 52 else |
| 53 return false; |
| 54 } |
| 55 |
| 56 static inline bool isScalarOrVectorFloatingPoint(Type *T) { |
| 57 if (T->isFloatingPointTy()) |
| 58 return true; |
| 59 else if (T->isVectorTy() && T->getVectorElementType()->isFloatingPointTy()) |
| 60 return true; |
| 61 else |
| 62 return false; |
| 63 } |
| 64 |
| 65 bool SubstituteUndefs::runOnFunction(Function &Func) { |
| 66 bool HadUndefs = false; |
| 67 for (Function::iterator BB = Func.begin(), E = Func.end(); BB != E; ++BB) { |
| 68 for (BasicBlock::iterator Inst = BB->begin(), E = BB->end(); Inst != E; |
| 69 ++Inst) { |
| 70 for (int Index = 0, NumOps = Inst->getNumOperands(); Index < NumOps; |
| 71 ++Index) { |
| 72 Value *Operand = Inst->getOperand(Index); |
| 73 if (isa<UndefValue>(Operand)) { |
| 74 HadUndefs = true; |
| 75 Type *OpType = Operand->getType(); |
| 76 if (isScalarOrVectorInteger(OpType)) |
| 77 Inst->setOperand(Index, ConstantInt::get(OpType, SubstInt)); |
| 78 else if (isScalarOrVectorFloatingPoint(OpType)) |
| 79 Inst->setOperand(Index, ConstantFP::get(OpType, SubstFloat)); |
| 80 else |
| 81 assert(false && "Type of undef not permitted by the PNaCl ABI"); |
| 82 } |
| 83 } |
| 84 } |
| 85 } |
| 86 return HadUndefs; |
| 87 } |
| 88 |
| 89 char SubstituteUndefs::ID = 0; |
| 90 INITIALIZE_PASS(SubstituteUndefs, "minsfi-substitute-undefs", |
| 91 "Replace undef values with deterministic constants", |
| 92 false, false) |
| 93 |
| 94 FunctionPass *llvm::createSubstituteUndefsPass() { |
| 95 return new SubstituteUndefs(); |
| 96 } |
OLD | NEW |