Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp

Issue 12449014: ABI verifier: Add standalone tool pnacl-abicheck (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules --------===// 1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules --------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // Verify function-level PNaCl ABI requirements. 10 // Verify function-level PNaCl ABI requirements.
(...skipping 12 matching lines...) Expand all
23 #include "PNaClABITypeChecker.h" 23 #include "PNaClABITypeChecker.h"
24 using namespace llvm; 24 using namespace llvm;
25 25
26 namespace { 26 namespace {
27 27
28 // Checks that examine anything in the function body should be in 28 // Checks that examine anything in the function body should be in
29 // FunctionPasses to make them streaming-friendly 29 // FunctionPasses to make them streaming-friendly
30 class PNaClABIVerifyFunctions : public FunctionPass { 30 class PNaClABIVerifyFunctions : public FunctionPass {
31 public: 31 public:
32 static char ID; 32 static char ID;
33 PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString) {} 33 PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString),
34 Strict(false), ErrorCount(0) {}
34 bool runOnFunction(Function &F); 35 bool runOnFunction(Function &F);
35 virtual void print(raw_ostream &O, const Module *M) const; 36 virtual void print(raw_ostream &O, const Module *M) const;
37 virtual void setStrict(bool Strict_) { Strict = Strict_; }
38 virtual int getErrorCount() { return ErrorCount; }
36 private: 39 private:
37 PNaClABITypeChecker TC; 40 PNaClABITypeChecker TC;
38 std::string ErrorsString; 41 std::string ErrorsString;
39 raw_string_ostream Errors; 42 raw_string_ostream Errors;
43 bool Strict;
44 int ErrorCount;
40 }; 45 };
41 46
42 } // and anonymous namespace 47 } // and anonymous namespace
43 48
44 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { 49 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
45 // For now just start with new errors on each function; this may change 50 // For now just start with new errors on each function; this may change
46 // once we want to do something with them other than just calling print() 51 // once we want to do something with them other than just calling print()
47 ErrorsString.clear(); 52 ErrorsString.clear();
53 ErrorCount = 0;
48 // TODO: only report one error per instruction 54 // TODO: only report one error per instruction
49 for (Function::const_iterator FI = F.begin(), FE = F.end(); 55 for (Function::const_iterator FI = F.begin(), FE = F.end();
50 FI != FE; ++FI) { 56 FI != FE; ++FI) {
51 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); 57 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end();
52 BBI != BBE; ++BBI) { 58 BBI != BBE; ++BBI) {
53 switch (BBI->getOpcode()) { 59 switch (BBI->getOpcode()) {
54 // Disallowed instructions. Default is to disallow. 60 // Disallowed instructions. Default is to disallow.
55 default: 61 default:
56 // indirectbr may interfere with streaming 62 // indirectbr may interfere with streaming
57 case Instruction::IndirectBr: 63 case Instruction::IndirectBr:
58 // No vector instructions yet 64 // No vector instructions yet
59 case Instruction::ExtractElement: 65 case Instruction::ExtractElement:
60 case Instruction::InsertElement: 66 case Instruction::InsertElement:
61 case Instruction::ShuffleVector: 67 case Instruction::ShuffleVector:
62 Errors << "Function " + F.getName() + 68 Errors << "Function " + F.getName() +
63 " has disallowed instruction: " + 69 " has disallowed instruction: " +
64 BBI->getOpcodeName() + "\n"; 70 BBI->getOpcodeName() + "\n";
71 ErrorCount++;
65 break; 72 break;
66 73
67 // Terminator instructions 74 // Terminator instructions
68 case Instruction::Ret: 75 case Instruction::Ret:
69 case Instruction::Br: 76 case Instruction::Br:
70 case Instruction::Switch: 77 case Instruction::Switch:
71 case Instruction::Resume: 78 case Instruction::Resume:
72 case Instruction::Unreachable: 79 case Instruction::Unreachable:
73 case Instruction::Invoke: 80 case Instruction::Invoke:
74 // Binary operations 81 // Binary operations
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 case Instruction::Call: 129 case Instruction::Call:
123 case Instruction::VAArg: 130 case Instruction::VAArg:
124 case Instruction::LandingPad: 131 case Instruction::LandingPad:
125 break; 132 break;
126 } 133 }
127 // Check the types. First check the type of the instruction. 134 // Check the types. First check the type of the instruction.
128 if (!TC.isValidType(BBI->getType())) { 135 if (!TC.isValidType(BBI->getType())) {
129 Errors << "Function " + F.getName() + 136 Errors << "Function " + F.getName() +
130 " has instruction with disallowed type: " + 137 " has instruction with disallowed type: " +
131 PNaClABITypeChecker::getTypeName(BBI->getType()) + "\n"; 138 PNaClABITypeChecker::getTypeName(BBI->getType()) + "\n";
139 ErrorCount++;
132 } 140 }
133 141
134 // Check the instruction operands. Operands which are Instructions will 142 // Check the instruction operands. Operands which are Instructions will
135 // be checked on their own here, and GlobalValues will be checked by the 143 // be checked on their own here, and GlobalValues will be checked by the
136 // Module verifier. That leaves Constants. 144 // Module verifier. That leaves Constants.
137 // Switches are implemented in the in-memory IR with vectors, so don't 145 // Switches are implemented in the in-memory IR with vectors, so don't
138 // check them. 146 // check them.
139 if (!isa<SwitchInst>(*BBI)) 147 if (!isa<SwitchInst>(*BBI))
140 for (User::const_op_iterator OI = BBI->op_begin(), OE = BBI->op_end(); 148 for (User::const_op_iterator OI = BBI->op_begin(), OE = BBI->op_end();
141 OI != OE; OI++) { 149 OI != OE; OI++) {
142 if (isa<Constant>(OI) && !isa<GlobalValue>(OI)) { 150 if (isa<Constant>(OI) && !isa<GlobalValue>(OI)) {
143 Type *T = TC.checkTypesInConstant(cast<Constant>(*OI)); 151 Type *T = TC.checkTypesInConstant(cast<Constant>(*OI));
144 if (T) 152 if (T) {
145 Errors << "Function " + F.getName() + 153 Errors << "Function " + F.getName() +
146 " has instruction operand with disallowed type: " + 154 " has instruction operand with disallowed type: " +
147 PNaClABITypeChecker::getTypeName(T) + "\n"; 155 PNaClABITypeChecker::getTypeName(T) + "\n";
156 ErrorCount++;
157 }
148 } 158 }
149 } 159 }
150 160
151 // Get types hiding in metadata attached to the instruction 161 // Get types hiding in metadata attached to the instruction
152 SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst; 162 SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
153 BBI->getAllMetadataOtherThanDebugLoc(MDForInst); 163 BBI->getAllMetadataOtherThanDebugLoc(MDForInst);
154 for (unsigned i = 0, e = MDForInst.size(); i != e; i++) { 164 for (unsigned i = 0, e = MDForInst.size(); i != e; i++) {
155 Type *T = TC.checkTypesInMDNode(MDForInst[i].second); 165 Type *T = TC.checkTypesInMDNode(MDForInst[i].second);
156 if (T) 166 if (T) {
157 Errors << "Function " + F.getName() + 167 Errors << "Function " + F.getName() +
158 " has instruction metadata containing disallowed type: " + 168 " has instruction metadata containing disallowed type: " +
159 PNaClABITypeChecker::getTypeName(T) + "\n"; 169 PNaClABITypeChecker::getTypeName(T) + "\n";
170 ErrorCount++;
171 }
160 } 172 }
161 } 173 }
162 } 174 }
163 175
164 Errors.flush(); 176 Errors.flush();
177 if (Strict && ErrorCount > 0) {
178 report_fatal_error("Function " + F.getName() +
179 " is not valid PNaCl bitcode:\n" + ErrorsString);
180 }
165 return false; 181 return false;
166 } 182 }
167 183
168 void PNaClABIVerifyFunctions::print(llvm::raw_ostream &O, const Module *M) 184 void PNaClABIVerifyFunctions::print(llvm::raw_ostream &O, const Module *M)
169 const { 185 const {
170 O << ErrorsString; 186 O << ErrorsString;
171 } 187 }
172 188
173 char PNaClABIVerifyFunctions::ID = 0; 189 char PNaClABIVerifyFunctions::ID = 0;
174 190
175 static RegisterPass<PNaClABIVerifyFunctions> X("verify-pnaclabi-functions", 191 static RegisterPass<PNaClABIVerifyFunctions> X("verify-pnaclabi-functions",
176 "Verify functions for PNaCl", false, false); 192 "Verify functions for PNaCl", false, false);
177 193
178 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass() { 194 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass(bool Strict) {
179 return new PNaClABIVerifyFunctions(); 195 PNaClABIVerifyFunctions *P = new PNaClABIVerifyFunctions();
196 P->setStrict(Strict);
197 return P;
180 } 198 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698