blob: bf6be5189278d6a38bf9968102090582cce7c88e [file] [log] [blame]
//===-- EntryPointAnalysis.cpp - Entry point Finding Pass -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a general way of finding entry points in a system. Simple programs
// will use the main version. Libraries and OS kernels can have more
// specialized versions. This is done as an analysis group to allow more
// convinient opt invocations.
//
//===----------------------------------------------------------------------===//
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Debug.h"
#include <fstream>
#include <set>
#include "dsa/EntryPointAnalysis.h"
using namespace llvm;
static cl::opt<std::string> epaFile("epa-file",
cl::desc("File with entry point names")); //, cl::ReallyHidden);
static void readNames(std::set<std::string>& names) {
std::ifstream msf(epaFile.c_str(), std::ifstream::in);
if (!msf.good())
errs() << "Failed to open file: " << epaFile << " (continuing anyway)\n";
while (msf.good()) {
std::string n;
msf >> n;
if (n.size()) {
names.insert(n);
// errs() << "Read " << n << "\n";
}
}
}
EntryPointAnalysis::EntryPointAnalysis() :ModulePass(&ID), haveNames(false) {
}
EntryPointAnalysis::~EntryPointAnalysis() {}
void EntryPointAnalysis::findEntryPoints(const Module& M,
std::vector<const Function*>& dest) const {
for (Module::const_iterator ii = M.begin(), ee = M.end(); ii != ee; ++ii)
if (isEntryPoint(ii))
dest.push_back(ii);
}
void EntryPointAnalysis::print(llvm::raw_ostream& O, const Module* M) const {
std::vector<const Function*> d;
findEntryPoints(*M, d);
O << "EntryPoints: ";
bool prev = false;
for (std::vector<const Function*>::iterator ii = d.begin(), ee = d.end();
ii != ee; ++ii) {
O << (prev ? ", " : "") << (*ii)->getNameStr();
prev = true;
}
O << "\n";
}
bool EntryPointAnalysis::runOnModule(llvm::Module& M) {
if (epaFile.size()) {
haveNames = true;
readNames(names);
}
return false;
}
void EntryPointAnalysis::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool EntryPointAnalysis::isEntryPoint(const llvm::Function* F) const {
if (haveNames) {
return !F->isDeclaration()
&& F->hasExternalLinkage()
&& F->hasName()
&& names.find(F->getNameStr()) != names.end();
} else {
return !F->isDeclaration()
&& F->hasExternalLinkage()
&& F->hasName() && F->getName() == "main";
}
}
char EntryPointAnalysis::ID;
static RegisterPass<EntryPointAnalysis> A("epa", "Identify EntryPoints");