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

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

Issue 17777004: Concurrency support for PNaCl ABI (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Simplify overloading and function verification. Created 7 years, 5 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 //===- PNaClABIVerifyModule.cpp - Verify PNaCl ABI rules ------------------===// 1 //===- PNaClABIVerifyModule.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 module-level PNaCl ABI requirements (specifically those that do not 10 // Verify module-level PNaCl ABI requirements (specifically those that do not
11 // require looking at the function bodies) 11 // require looking at the function bodies)
12 // 12 //
13 // 13 //
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "llvm/Pass.h"
17 #include "llvm/ADT/Twine.h" 16 #include "llvm/ADT/Twine.h"
18 #include "llvm/Analysis/NaCl.h" 17 #include "llvm/Analysis/NaCl.h"
19 #include "llvm/IR/Constants.h" 18 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/NaClIntrinsics.h"
21 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/Intrinsics.h" 22 #include "llvm/IR/Intrinsics.h"
22 #include "llvm/IR/Module.h" 23 #include "llvm/IR/Module.h"
24 #include "llvm/Pass.h"
23 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/raw_ostream.h" 26 #include "llvm/Support/raw_ostream.h"
25 27
26 #include "PNaClABITypeChecker.h" 28 #include "PNaClABITypeChecker.h"
27 using namespace llvm; 29 using namespace llvm;
28 30
29 namespace llvm { 31 namespace llvm {
30 cl::opt<bool> 32 cl::opt<bool>
31 PNaClABIAllowDebugMetadata("pnaclabi-allow-debug-metadata", 33 PNaClABIAllowDebugMetadata("pnaclabi-allow-debug-metadata",
32 cl::desc("Allow debug metadata during PNaCl ABI verification."), 34 cl::desc("Allow debug metadata during PNaCl ABI verification."),
(...skipping 26 matching lines...) Expand all
59 initializePNaClABIVerifyModulePass(*PassRegistry::getPassRegistry()); 61 initializePNaClABIVerifyModulePass(*PassRegistry::getPassRegistry());
60 } 62 }
61 ~PNaClABIVerifyModule() { 63 ~PNaClABIVerifyModule() {
62 if (ReporterIsOwned) 64 if (ReporterIsOwned)
63 delete Reporter; 65 delete Reporter;
64 } 66 }
65 bool runOnModule(Module &M); 67 bool runOnModule(Module &M);
66 virtual void print(raw_ostream &O, const Module *M) const; 68 virtual void print(raw_ostream &O, const Module *M) const;
67 private: 69 private:
68 void checkGlobalValueCommon(const GlobalValue *GV); 70 void checkGlobalValueCommon(const GlobalValue *GV);
69 bool isWhitelistedIntrinsic(const Function *F, unsigned ID); 71 bool isWhitelistedIntrinsic(const NaCl::AtomicIntrinsics *AI,
72 const Function *F, Intrinsic::ID ID);
70 bool isWhitelistedMetadata(const NamedMDNode *MD); 73 bool isWhitelistedMetadata(const NamedMDNode *MD);
71 void checkGlobalIsFlattened(const GlobalVariable *GV); 74 void checkGlobalIsFlattened(const GlobalVariable *GV);
72 PNaClABIErrorReporter *Reporter; 75 PNaClABIErrorReporter *Reporter;
73 bool ReporterIsOwned; 76 bool ReporterIsOwned;
74 bool StreamingMode; 77 bool StreamingMode;
75 }; 78 };
76 79
77 static const char *linkageName(GlobalValue::LinkageTypes LT) { 80 static const char *linkageName(GlobalValue::LinkageTypes LT) {
78 // This logic is taken from PrintLinkage in lib/VMCore/AsmWriter.cpp 81 // This logic is taken from PrintLinkage in lib/VMCore/AsmWriter.cpp
79 switch (LT) { 82 switch (LT) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 if (FT->getNumParams() != 1) 166 if (FT->getNumParams() != 1)
164 return false; 167 return false;
165 Type *ParamType = FT->getParamType(0); 168 Type *ParamType = FT->getParamType(0);
166 LLVMContext &C = F->getContext(); 169 LLVMContext &C = F->getContext();
167 Type *AcceptableTypes[] = { Type::getInt16Ty(C), 170 Type *AcceptableTypes[] = { Type::getInt16Ty(C),
168 Type::getInt32Ty(C), 171 Type::getInt32Ty(C),
169 Type::getInt64Ty(C) }; 172 Type::getInt64Ty(C) };
170 return TypeAcceptable(ParamType, AcceptableTypes); 173 return TypeAcceptable(ParamType, AcceptableTypes);
171 } 174 }
172 175
176 static bool isWhitelistedAtomic(const NaCl::AtomicIntrinsics *AI,
177 const Function *F, Intrinsic::ID ID) {
178 FunctionType *FT = F->getFunctionType();
179 for (NaCl::AtomicIntrinsics::const_iterator I = AI->begin(ID),
180 E = AI->end(ID);
181 I != E; ++I) {
182 bool Match = true;
183 for (size_t P = 0; P != I->NumParams; ++P)
Mark Seaborn 2013/07/02 19:16:02 Start a "{" block here since the body is multi-lin
JF 2013/07/02 23:14:54 Done.
184 if (I->Parameter(P) != FT->getParamType(P))
185 Match = false;
186 if (Match)
187 return true;
188 }
189 return false;
190 }
191
173 // We accept cttz, ctlz, and ctpop for a limited set of types (i32, i64). 192 // We accept cttz, ctlz, and ctpop for a limited set of types (i32, i64).
174 static bool isWhitelistedCountBits(const Function *F, unsigned num_params) { 193 static bool isWhitelistedCountBits(const Function *F, unsigned num_params) {
175 FunctionType *FT = F->getFunctionType(); 194 FunctionType *FT = F->getFunctionType();
176 if (FT->getNumParams() != num_params) 195 if (FT->getNumParams() != num_params)
177 return false; 196 return false;
178 Type *ParamType = FT->getParamType(0); 197 Type *ParamType = FT->getParamType(0);
179 LLVMContext &C = F->getContext(); 198 LLVMContext &C = F->getContext();
180 Type *AcceptableTypes[] = { Type::getInt32Ty(C), Type::getInt64Ty(C) }; 199 Type *AcceptableTypes[] = { Type::getInt32Ty(C), Type::getInt64Ty(C) };
181 return TypeAcceptable(ParamType, AcceptableTypes); 200 return TypeAcceptable(ParamType, AcceptableTypes);
182 } 201 }
183 202
184 bool PNaClABIVerifyModule::isWhitelistedIntrinsic(const Function *F, 203 bool PNaClABIVerifyModule::isWhitelistedIntrinsic(const NaCl::AtomicIntrinsics * AI,
Mark Seaborn 2013/07/02 19:16:02 Line is >80 chars
JF 2013/07/02 23:14:54 Done.
185 unsigned ID) { 204 const Function *F,
205 Intrinsic::ID ID) {
186 // Keep 3 categories of intrinsics for now. 206 // Keep 3 categories of intrinsics for now.
187 // (1) Allowed always 207 // (1) Allowed.
188 // (2) Never allowed 208 // (2) Never allowed.
189 // (3) "Dev" intrinsics, which may or may not be allowed. 209 // (3) "Dev" intrinsics, which may or may not be allowed.
190 // "Dev" intrinsics are controlled by the PNaClABIAllowDevIntrinsics flag. 210 // "Dev" intrinsics are controlled by the PNaClABIAllowDevIntrinsics flag.
191 // Please keep these sorted or grouped in a sensible way, within 211 // Please keep these sorted or grouped in a sensible way, within
192 // each category. 212 // each category.
193 switch(ID) { 213 switch(ID) {
194 // Disallow by default. 214 // Disallow by default.
195 default: return false; 215 default: return false;
196 // (1) Always allowed. 216 // (1) Allowed.
217 case Intrinsic::memcpy:
Mark Seaborn 2013/07/02 19:16:02 You'll need to rebase this on top of recent change
218 case Intrinsic::memmove:
219 case Intrinsic::memset:
220 case Intrinsic::nacl_setjmp:
221 case Intrinsic::nacl_longjmp:
222 case Intrinsic::nacl_read_tp:
223 case Intrinsic::trap:
224 return true;
225 case Intrinsic::nacl_atomic_load:
226 case Intrinsic::nacl_atomic_store:
227 case Intrinsic::nacl_atomic_rmw:
228 case Intrinsic::nacl_atomic_cmpxchg:
229 case Intrinsic::nacl_atomic_fence:
230 return isWhitelistedAtomic(AI, F, ID);
197 case Intrinsic::bswap: return isWhitelistedBswap(F); 231 case Intrinsic::bswap: return isWhitelistedBswap(F);
198 case Intrinsic::ctlz: 232 case Intrinsic::ctlz:
199 case Intrinsic::cttz: return isWhitelistedCountBits(F, 2); 233 case Intrinsic::cttz: return isWhitelistedCountBits(F, 2);
200 case Intrinsic::ctpop: return isWhitelistedCountBits(F, 1); 234 case Intrinsic::ctpop: return isWhitelistedCountBits(F, 1);
201 case Intrinsic::memcpy:
202 case Intrinsic::memmove:
203 case Intrinsic::memset:
204 case Intrinsic::nacl_read_tp:
205 case Intrinsic::nacl_setjmp:
206 case Intrinsic::nacl_longjmp:
207 case Intrinsic::trap:
208 return true;
209 235
210 // (2) Known to be never allowed. 236 // (2) Known to be never allowed.
211 case Intrinsic::not_intrinsic: 237 case Intrinsic::not_intrinsic:
212 // Trampolines depend on a target-specific-sized/aligned buffer. 238 // Trampolines depend on a target-specific-sized/aligned buffer.
213 case Intrinsic::adjust_trampoline: 239 case Intrinsic::adjust_trampoline:
214 case Intrinsic::init_trampoline: 240 case Intrinsic::init_trampoline:
215 // CXX exception handling is not stable. 241 // CXX exception handling is not stable.
216 case Intrinsic::eh_dwarf_cfa: 242 case Intrinsic::eh_dwarf_cfa:
217 case Intrinsic::eh_return_i32: 243 case Intrinsic::eh_return_i32:
218 case Intrinsic::eh_return_i64: 244 case Intrinsic::eh_return_i64:
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 413 }
388 } 414 }
389 415
390 // No aliases allowed for now. 416 // No aliases allowed for now.
391 for (Module::alias_iterator MI = M.alias_begin(), 417 for (Module::alias_iterator MI = M.alias_begin(),
392 E = M.alias_end(); MI != E; ++MI) { 418 E = M.alias_end(); MI != E; ++MI) {
393 Reporter->addError() << "Variable " << MI->getName() << 419 Reporter->addError() << "Variable " << MI->getName() <<
394 " is an alias (disallowed)\n"; 420 " is an alias (disallowed)\n";
395 } 421 }
396 422
423 NaCl::AtomicIntrinsics AI(M.getContext());
397 for (Module::const_iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { 424 for (Module::const_iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
398 if (MI->isIntrinsic()) { 425 if (MI->isIntrinsic()) {
399 // Check intrinsics. 426 // Check intrinsics.
400 if (!isWhitelistedIntrinsic(MI, MI->getIntrinsicID())) { 427 Intrinsic::ID ID = (Intrinsic::ID) MI->getIntrinsicID();
428 if (!isWhitelistedIntrinsic(&AI, MI, ID)) {
401 Reporter->addError() << "Function " << MI->getName() 429 Reporter->addError() << "Function " << MI->getName()
402 << " is a disallowed LLVM intrinsic\n"; 430 << " is a disallowed LLVM intrinsic\n";
403 } 431 }
404 } else { 432 } else {
405 // Check types of functions and their arguments. Not necessary 433 // Check types of functions and their arguments. Not necessary
406 // for intrinsics, whose types are fixed anyway, and which have 434 // for intrinsics, whose types are fixed anyway, and which have
407 // argument types that we disallow such as i8. 435 // argument types that we disallow such as i8.
408 if (!PNaClABITypeChecker::isValidFunctionType(MI->getFunctionType())) { 436 if (!PNaClABITypeChecker::isValidFunctionType(MI->getFunctionType())) {
409 Reporter->addError() << "Function " << MI->getName() 437 Reporter->addError() << "Function " << MI->getName()
410 << " has disallowed type: " 438 << " has disallowed type: "
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } 499 }
472 500
473 char PNaClABIVerifyModule::ID = 0; 501 char PNaClABIVerifyModule::ID = 0;
474 INITIALIZE_PASS(PNaClABIVerifyModule, "verify-pnaclabi-module", 502 INITIALIZE_PASS(PNaClABIVerifyModule, "verify-pnaclabi-module",
475 "Verify module for PNaCl", false, true) 503 "Verify module for PNaCl", false, true)
476 504
477 ModulePass *llvm::createPNaClABIVerifyModulePass( 505 ModulePass *llvm::createPNaClABIVerifyModulePass(
478 PNaClABIErrorReporter *Reporter, bool StreamingMode) { 506 PNaClABIErrorReporter *Reporter, bool StreamingMode) {
479 return new PNaClABIVerifyModule(Reporter, StreamingMode); 507 return new PNaClABIVerifyModule(Reporter, StreamingMode);
480 } 508 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698