aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp47
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyModule.cpp28
2 files changed, 63 insertions, 12 deletions
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
index cd3ede4b58..2c9a6a17b9 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"
@@ -49,14 +50,36 @@ 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;
};
+// There's no built-in way to get the name of an MDNode, so use a
+// string ostream to print it.
+std::string getMDNodeString(unsigned Kind,
+ const SmallVectorImpl<StringRef>& MDNames) {
+ std::string MDName;
+ raw_string_ostream N(MDName);
+ if (Kind < MDNames.size()) {
+ N << "!" << MDNames[Kind];
+ } else {
+ N << "!<unknown kind #" << Kind << ">";
+ }
+ return N.str();
+}
+
} // and anonymous namespace
+bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) {
+ return MDKind == LLVMContext::MD_dbg && PNaClABIAllowDebugMetadata;
+}
+
bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
+ SmallVector<StringRef, 8> MDNames;
+ F.getContext().getMDKindNames(MDNames);
+
// TODO: only report one error per instruction?
for (Function::const_iterator FI = F.begin(), FE = F.end();
FI != FE; ++FI) {
@@ -181,15 +204,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].first, MDNames) << "\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";
+ }
}
}
}
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
index 88914c85a8..efb40cf43a 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
@@ -23,6 +23,13 @@
#include "PNaClABITypeChecker.h"
using namespace llvm;
+namespace llvm {
+cl::opt<bool>
+PNaClABIAllowDebugMetadata("pnaclabi-allow-debug-metadata",
+ cl::desc("Allow debug metadata during PNaCl ABI verification."),
+ cl::init(false));
+}
+
namespace {
// This pass should not touch function bodies, to stay streaming-friendly
class PNaClABIVerifyModule : public ModulePass {
@@ -48,6 +55,7 @@ class PNaClABIVerifyModule : public ModulePass {
virtual void print(raw_ostream &O, const Module *M) const;
private:
void CheckGlobalValueCommon(const GlobalValue *GV);
+ bool IsWhitelistedMetadata(const NamedMDNode *MD);
PNaClABITypeChecker TC;
PNaClABIErrorReporter *Reporter;
bool ReporterIsOwned;
@@ -105,6 +113,10 @@ void PNaClABIVerifyModule::CheckGlobalValueCommon(const GlobalValue *GV) {
}
}
+bool PNaClABIVerifyModule::IsWhitelistedMetadata(const NamedMDNode* MD) {
+ return MD->getName().startswith("llvm.dbg.") && PNaClABIAllowDebugMetadata;
+}
+
bool PNaClABIVerifyModule::runOnModule(Module &M) {
for (Module::const_global_iterator MI = M.global_begin(), ME = M.global_end();
MI != ME; ++MI) {
@@ -174,11 +186,17 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
// Check named metadata nodes
for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
E = M.named_metadata_end(); I != E; ++I) {
- for (unsigned i = 0, e = I->getNumOperands(); i != e; i++) {
- if (Type *T = TC.checkTypesInMDNode(I->getOperand(i))) {
- Reporter->addError() << "Named metadata node " << I->getName() <<
- " refers to disallowed type: " <<
- PNaClABITypeChecker::getTypeName(T) << "\n";
+ if (!IsWhitelistedMetadata(I)) {
+ Reporter->addError() << "Named metadata node " << I->getName()
+ << " is disallowed\n";
+ } else {
+ // Check the types in the metadata.
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; i++) {
+ if (Type *T = TC.checkTypesInMDNode(I->getOperand(i))) {
+ Reporter->addError() << "Named metadata node " << I->getName()
+ << " refers to disallowed type: "
+ << PNaClABITypeChecker::getTypeName(T) << "\n";
+ }
}
}
}