| Index: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
|
| diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
|
| index cd3ede4b5872bc35a979aa18fbd9cec9f0eb8348..fc1b5821c6e71b6918282d90fd126bc4d33ee21f 100644
|
| --- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
|
| +++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
|
| @@ -17,6 +17,7 @@
|
| #include "llvm/Analysis/NaCl.h"
|
| #include "llvm/IR/Function.h"
|
| #include "llvm/IR/Instructions.h"
|
| +#include "llvm/IR/LLVMContext.h"
|
| #include "llvm/IR/Metadata.h"
|
| #include "llvm/Support/raw_ostream.h"
|
|
|
| @@ -33,13 +34,16 @@ class PNaClABIVerifyFunctions : public FunctionPass {
|
| PNaClABIVerifyFunctions() :
|
| FunctionPass(ID),
|
| Reporter(new PNaClABIErrorReporter),
|
| - ReporterIsOwned(true) {
|
| + ReporterIsOwned(true),
|
| + AllowDebugMetadata(false) {
|
| initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry());
|
| }
|
| - explicit PNaClABIVerifyFunctions(PNaClABIErrorReporter *Reporter_) :
|
| + PNaClABIVerifyFunctions(PNaClABIErrorReporter *Reporter_,
|
| + bool AllowDebugMetadata_) :
|
| FunctionPass(ID),
|
| Reporter(Reporter_),
|
| - ReporterIsOwned(false) {
|
| + ReporterIsOwned(false),
|
| + AllowDebugMetadata(AllowDebugMetadata_) {
|
| initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry());
|
| }
|
| ~PNaClABIVerifyFunctions() {
|
| @@ -49,13 +53,28 @@ class PNaClABIVerifyFunctions : public FunctionPass {
|
| bool runOnFunction(Function &F);
|
| virtual void print(raw_ostream &O, const Module *M) const;
|
| private:
|
| + bool IsWhiteListedMetadata(unsigned MDKind);
|
| PNaClABITypeChecker TC;
|
| PNaClABIErrorReporter *Reporter;
|
| bool ReporterIsOwned;
|
| + bool AllowDebugMetadata;
|
| };
|
|
|
| +// There's no built-in way to get the name of an MDNode, so use a
|
| +// string ostream to print it.
|
| +std::string getMDNodeString(const MDNode *MD) {
|
| + std::string s;
|
| + raw_string_ostream N(s);
|
| + MD->print(N);
|
| + return N.str();
|
| +}
|
| +
|
| } // and anonymous namespace
|
|
|
| +bool PNaClABIVerifyFunctions::IsWhiteListedMetadata(unsigned MDKind) {
|
| + return MDKind == LLVMContext::MD_dbg && AllowDebugMetadata;
|
| +}
|
| +
|
| bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
|
| // TODO: only report one error per instruction?
|
| for (Function::const_iterator FI = F.begin(), FE = F.end();
|
| @@ -181,15 +200,25 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
|
| }
|
| }
|
|
|
| - // Get types hiding in metadata attached to the instruction
|
| + // Check instruction attachment metadata.
|
| SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
|
| - BBI->getAllMetadataOtherThanDebugLoc(MDForInst);
|
| + BBI->getAllMetadata(MDForInst);
|
| +
|
| for (unsigned i = 0, e = MDForInst.size(); i != e; i++) {
|
| - Type *T = TC.checkTypesInMDNode(MDForInst[i].second);
|
| - if (T) {
|
| - Reporter->addError() << "Function " << F.getName() <<
|
| - " has instruction metadata containing disallowed type: " <<
|
| - PNaClABITypeChecker::getTypeName(T) << "\n";
|
| + if (!IsWhiteListedMetadata(MDForInst[i].first)) {
|
| + Reporter->addError()
|
| + << "Function " << F.getName()
|
| + << " has disallowed instruction metadata: "
|
| + << getMDNodeString(MDForInst[i].second) << "\n";
|
| + } else {
|
| + // If allowed, check the types hiding in the metadata.
|
| + Type *T = TC.checkTypesInMDNode(MDForInst[i].second);
|
| + if (T) {
|
| + Reporter->addError()
|
| + << "Function " << F.getName()
|
| + << " has instruction metadata containing disallowed type: "
|
| + << PNaClABITypeChecker::getTypeName(T) << "\n";
|
| + }
|
| }
|
| }
|
| }
|
| @@ -213,6 +242,7 @@ INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions",
|
| "Verify functions for PNaCl", false, true)
|
|
|
| FunctionPass *llvm::createPNaClABIVerifyFunctionsPass(
|
| - PNaClABIErrorReporter *Reporter) {
|
| - return new PNaClABIVerifyFunctions(Reporter);
|
| + PNaClABIErrorReporter *Reporter,
|
| + bool AllowDebugMetadata) {
|
| + return new PNaClABIVerifyFunctions(Reporter, AllowDebugMetadata);
|
| }
|
|
|