aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-04-12 13:09:00 -0700
committerDerek Schuff <dschuff@chromium.org>2013-04-12 13:09:00 -0700
commit23da4c2957a29624ef0a759bf5a35516b4985f6f (patch)
tree5cea0039daa7a86782e51d5a1e0d040ca0a67b44 /lib
parent14551e67a9ac4e521b9dd5f7776bb1a4fdcd7998 (diff)
PNaCl: extend GlobalCleanup to null-out extern_weak function references, and extend the ABI checker to verify.
Also promote weak symbols to internal ones, which was required because the scons barebones tests define weak versions of memcpy/memset BUG= https://code.google.com/p/nativeclient/issues/detail?id=3339 TEST= llvm-regression (globalcleanup.ll), scons barebones tests Review URL: https://codereview.chromium.org/13989005
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyModule.cpp51
-rw-r--r--lib/Transforms/NaCl/GlobalCleanup.cpp9
2 files changed, 39 insertions, 21 deletions
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
index 857f6a24af..88914c85a8 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
@@ -47,6 +47,7 @@ class PNaClABIVerifyModule : public ModulePass {
bool runOnModule(Module &M);
virtual void print(raw_ostream &O, const Module *M) const;
private:
+ void CheckGlobalValueCommon(const GlobalValue *GV);
PNaClABITypeChecker TC;
PNaClABIErrorReporter *Reporter;
bool ReporterIsOwned;
@@ -80,6 +81,30 @@ static const char *linkageName(GlobalValue::LinkageTypes LT) {
} // end anonymous namespace
+// Check linkage type and section attributes, which are the same for
+// GlobalVariables and Functions.
+void PNaClABIVerifyModule::CheckGlobalValueCommon(const GlobalValue *GV) {
+ assert(!isa<GlobalAlias>(GV));
+ const char *GVTypeName = isa<GlobalVariable>(GV) ?
+ "Variable " : "Function ";
+ switch (GV->getLinkage()) {
+ // TODO(dschuff): Disallow external linkage
+ case GlobalValue::ExternalLinkage:
+ case GlobalValue::AvailableExternallyLinkage:
+ case GlobalValue::InternalLinkage:
+ case GlobalValue::PrivateLinkage:
+ break;
+ default:
+ Reporter->addError() << GVTypeName << GV->getName()
+ << " has disallowed linkage type: "
+ << linkageName(GV->getLinkage()) << "\n";
+ }
+ if (GV->hasSection()) {
+ Reporter->addError() << GVTypeName << GV->getName() <<
+ " has disallowed \"section\" attribute\n";
+ }
+}
+
bool PNaClABIVerifyModule::runOnModule(Module &M) {
for (Module::const_global_iterator MI = M.global_begin(), ME = M.global_end();
MI != ME; ++MI) {
@@ -100,28 +125,14 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
}
}
- // Check GV linkage types
- switch (MI->getLinkage()) {
- case GlobalValue::ExternalLinkage:
- case GlobalValue::AvailableExternallyLinkage:
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- Reporter->addError() << "Variable " << MI->getName() <<
- " has disallowed linkage type: " <<
- linkageName(MI->getLinkage()) << "\n";
- }
+ CheckGlobalValueCommon(MI);
- if (MI->hasSection()) {
- Reporter->addError() << "Variable " << MI->getName() <<
- " has disallowed \"section\" attribute\n";
- }
if (MI->isThreadLocal()) {
Reporter->addError() << "Variable " << MI->getName() <<
" has disallowed \"thread_local\" attribute\n";
}
}
+
// No aliases allowed for now.
for (Module::alias_iterator MI = M.alias_begin(),
E = M.alias_end(); MI != E; ++MI) {
@@ -129,7 +140,7 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
" is an alias (disallowed)\n";
}
- for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
+ for (Module::const_iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
// Check types of functions and their arguments
FunctionType *FT = MI->getFunctionType();
if (!TC.isValidType(FT->getReturnType())) {
@@ -152,10 +163,8 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
" is a variable-argument function (disallowed)\n";
}
- if (MI->hasSection()) {
- Reporter->addError() << "Function " << MI->getName() <<
- " has disallowed \"section\" attribute\n";
- }
+ CheckGlobalValueCommon(MI);
+
if (MI->hasGC()) {
Reporter->addError() << "Function " << MI->getName() <<
" has disallowed \"gc\" attribute\n";
diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp
index 9a28063af6..00e15b39a5 100644
--- a/lib/Transforms/NaCl/GlobalCleanup.cpp
+++ b/lib/Transforms/NaCl/GlobalCleanup.cpp
@@ -56,6 +56,10 @@ static bool CleanUpLinkage(GlobalValue *GV) {
GV->eraseFromParent();
return true;
}
+ case GlobalValue::WeakAnyLinkage: {
+ GV->setLinkage(GlobalValue::InternalLinkage);
+ return true;
+ }
default:
// default with fall through to avoid compiler warning
return false;
@@ -80,6 +84,11 @@ bool GlobalCleanup::runOnModule(Module &M) {
GlobalVariable *GV = I++;
Modified |= CleanUpLinkage(GV);
}
+
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
+ Function *F = I++;
+ Modified |= CleanUpLinkage(F);
+ }
return Modified;
}