blob: 5062f710f62c88951f9eeb2b469e4f57ab958472 (
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
|
//===- 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/ADT/Twine.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/NaCl.h"
using namespace llvm;
namespace {
// This pass should not touch function bodies, to stay streaming-friendly
struct PNaClABIVerifyModule : public ModulePass {
static char ID;
PNaClABIVerifyModule() : ModulePass(ID) {}
bool runOnModule(Module &M);
// For now, this print method exists to allow us to run the pass with
// opt -analyze to avoid dumping the result to stdout, to make testing
// simpler. In the future we will probably want to make it do something
// useful.
virtual void print(llvm::raw_ostream &O, const Module *M) const {};
};
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
bool PNaClABIVerifyModule::runOnModule(Module &M) {
// Check GV linkage types
for (Module::const_global_iterator MI = M.global_begin(), ME = M.global_end();
MI != ME; ++MI) {
switch(MI->getLinkage()) {
case GlobalValue::ExternalLinkage:
case GlobalValue::AvailableExternallyLinkage:
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
break;
default:
errs() << (Twine("Variable ") + MI->getName() +
" has disallowed linkage type: " +
LinkageName(MI->getLinkage()) + "\n");
}
}
return false;
}
char PNaClABIVerifyModule::ID = 0;
static RegisterPass<PNaClABIVerifyModule> X("verify-pnaclabi-module",
"Verify module for PNaCl", false, false);
ModulePass *llvm::createPNaClABIVerifyModulePass() {
return new PNaClABIVerifyModule();
}
|