blob: afe42434e7dc6cc65c18bbfd91c4806f1c3347d2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
//===- PNaClABIVerifyModule.cpp - Verify PNaCl ABI rules --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Verify module-level PNaCl ABI requirements (specifically those that do not
// require looking at the function bodies)
//
//
//===----------------------------------------------------------------------===//
#include "llvm/Pass.h"
#include "llvm/Analysis/NaCl.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "CheckTypes.h"
using namespace llvm;
namespace {
// This pass should not touch function bodies, to stay streaming-friendly
class PNaClABIVerifyModule : public ModulePass {
public:
static char ID;
PNaClABIVerifyModule();
bool runOnModule(Module &M);
virtual void print(llvm::raw_ostream &O, const Module *M) const;
private:
TypeChecker TC;
std::string ErrorsString;
llvm::raw_string_ostream Errors;
};
static const char *linkageName(GlobalValue::LinkageTypes LT) {
// This logic is taken from PrintLinkage in lib/VMCore/AsmWriter.cpp
switch (LT) {
case GlobalValue::ExternalLinkage: return "external";
case GlobalValue::PrivateLinkage: return "private ";
case GlobalValue::LinkerPrivateLinkage: return "linker_private ";
case GlobalValue::LinkerPrivateWeakLinkage: return "linker_private_weak ";
case GlobalValue::InternalLinkage: return "internal ";
case GlobalValue::LinkOnceAnyLinkage: return "linkonce ";
case GlobalValue::LinkOnceODRLinkage: return "linkonce_odr ";
case GlobalValue::LinkOnceODRAutoHideLinkage:
return "linkonce_odr_auto_hide ";
case GlobalValue::WeakAnyLinkage: return "weak ";
case GlobalValue::WeakODRLinkage: return "weak_odr ";
case GlobalValue::CommonLinkage: return "common ";
case GlobalValue::AppendingLinkage: return "appending ";
case GlobalValue::DLLImportLinkage: return "dllimport ";
case GlobalValue::DLLExportLinkage: return "dllexport ";
case GlobalValue::ExternalWeakLinkage: return "extern_weak ";
case GlobalValue::AvailableExternallyLinkage:
return "available_externally ";
default:
return "unknown";
}
}
} // end anonymous namespace
PNaClABIVerifyModule::PNaClABIVerifyModule() : ModulePass(ID),
Errors(ErrorsString) {}
bool PNaClABIVerifyModule::runOnModule(Module &M) {
for (Module::const_global_iterator MI = M.global_begin(), ME = M.global_end();
MI != ME; ++MI) {
// Check types of global variables and their initializers
if (!TC.isValidType(MI->getType())) {
// GVs are pointers, so print the pointed-to type for clarity
Errors << "Variable " + MI->getName() +
" has disallowed type: " +
TypeChecker::getTypeName(MI->getType()->getContainedType(0)) + "\n";
} else if (MI->hasInitializer()) {
// If the type of the global is bad, no point in checking its initializer
Type *T = TC.checkTypesInValue(MI->getInitializer());
if (T)
Errors << "Initializer for " + MI->getName() +
" has disallowed type: " +
TypeChecker::getTypeName(T) + "\n";
}
// Check GV linkage types
switch (MI->getLinkage()) {
case GlobalValue::ExternalLinkage:
case GlobalValue::AvailableExternallyLinkage:
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
break;
default:
Errors << "Variable " + MI->getName() +
" has disallowed linkage type: " +
linkageName(MI->getLinkage()) + "\n";
}
}
// No aliases allowed for now.
for (Module::alias_iterator MI = M.alias_begin(),
E = M.alias_end(); MI != E; ++MI)
Errors << "Variable " + MI->getName() + " is an alias (disallowed)\n";
Errors.flush();
return false;
}
void PNaClABIVerifyModule::print(llvm::raw_ostream &O, const Module *M) const {
O << ErrorsString;
}
char PNaClABIVerifyModule::ID = 0;
static RegisterPass<PNaClABIVerifyModule> X("verify-pnaclabi-module",
"Verify module for PNaCl", false, false);
ModulePass *llvm::createPNaClABIVerifyModulePass() {
return new PNaClABIVerifyModule();
}
|