Permalink
Browse files

Added changes to llvm

  • Loading branch information...
1 parent 87c1e27 commit 5c025d2ea78053df0cdba1fd064d03a759df23ad @martintrojer committed Nov 10, 2011
View
4 README
@@ -3,3 +3,7 @@ Alterations to LLVM and KLEE for practical "false positive pruning" defect findi
Copyright Martin Trojer <martin.trojer@gmail.com>
For more information see
+
+llvm-2.6 contains the update to LLVM, mainly the "CallPaths" LLVM analysis pass.
+This uses Boost Graph Library to generate a set of potential paths from a
+root basic block to the taket basic-block(s).
@@ -0,0 +1,77 @@
+/* include/llvm/ADT/iterator.h. Generated from iterator.h.in by configure. */
+//==-- llvm/ADT/iterator.h - Portable wrapper around <iterator> --*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <iterator> header file.
+// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
+// friends), instead of the standard iterator class. In GCC 3.1, the
+// bidirectional_iterator class got moved out and the new, standards compliant,
+// iterator<> class was added. Because there is nothing that we can do to get
+// correct behavior on both compilers, we have this header with #ifdef's. Gross
+// huh?
+//
+// By #includ'ing this file, you get the contents of <iterator> plus the
+// following classes in the global namespace:
+//
+// 1. bidirectional_iterator
+// 2. forward_iterator
+//
+// The #if directives' expressions are filled in by Autoconf.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_H
+#define LLVM_ADT_ITERATOR_H
+
+#include <iterator>
+
+#define HAVE_BI_ITERATOR 0
+#define HAVE_STD_ITERATOR 1
+#define HAVE_FWD_ITERATOR 0
+
+#ifdef _MSC_VER
+# define HAVE_BI_ITERATOR 0
+# define HAVE_STD_ITERATOR 1
+# define HAVE_FWD_ITERATOR 0
+#endif
+
+#if !HAVE_BI_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the bidirectional iterator is not defined, we attempt to define it in
+/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
+/// statement.
+///
+template<class Ty, class PtrDiffTy>
+struct bidirectional_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define bidirectional iterator!"
+# endif
+#else
+using std::bidirectional_iterator;
+#endif
+
+#if !HAVE_FWD_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the forward iterator is not defined, attempt to define it in terms of
+/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
+///
+template<class Ty, class PtrDiffTy>
+struct forward_iterator
+ : public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define forward iterator!"
+# endif
+#else
+using std::forward_iterator;
+#endif
+
+#endif // LLVM_ADT_ITERATOR_H
@@ -0,0 +1,38 @@
+#ifndef LLVM_ANALYSIS_CALLGRAPHCFG_H
+#define LLVM_ANALYSIS_CALLGRAPHCFG_H
+
+#include <vector>
+#include "llvm/Pass.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+#include "llvm/Analysis/CallGraph.h"
+
+namespace llvm {
+
+ class CallGraphCFG : public ModulePass {
+ public:
+ typedef std::map<std::string, std::vector<int> > defectList;
+
+ public:
+ std::vector<std::vector<BasicBlock*> > *bbpaths;
+ std::string defectFile;
+ static char ID;
+ defectList dl;
+
+ CallGraphCFG();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual bool runOnModule(Module &M);
+
+ private:
+ // At function level now, should rellay be at BB level
+ bool findLineInBB(BasicBlock *BB, std::string srcFile, int srcLine);
+ bool findLineInFunction(Function *F, BasicBlock **BB, std::string srcFile, int srcLine);
+ bool findBBPath(CallGraphNode *n, std::vector<BasicBlock*> &path, std::string srcFile, int srcLine);
+
+ void getDefectList(std::string docname, defectList *res);
+ };
+
+ ModulePass *createCallGraphCFGPass(std::vector<std::vector<BasicBlock*> > *_bbpaths, std::string _filename);
+}
+
+#endif
@@ -0,0 +1,199 @@
+#ifndef LLVM_ANALYSIS_CALLPATHS_H
+#define LLVM_ANALYSIS_CALLPATHS_H
+
+#include <vector>
+#include "llvm/Pass.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+#include "llvm/Analysis/CallGraph.h"
+
+#include <boost/config.hpp>
+#include <boost/utility.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/graphviz.hpp>
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/depth_first_search.hpp>
+
+using namespace boost;
+
+namespace llvm {
+
+ // -------(BGL)---------------------------
+ // typedef adjacency_list<setS, vecS, directedS, no_property, property<edge_weight_t, int> > Graph;
+ typedef adjacency_list<setS, vecS, bidirectionalS, no_property, property<edge_weight_t, int> > Graph;
+ typedef graph_traits<Graph>::vertex_descriptor Vertex;
+ typedef graph_traits<Graph>::edge_descriptor Edge;
+ typedef color_traits<default_color_type> Color;
+ typedef std::vector<default_color_type> ColorVec;
+
+ class my_dfs_visitor;
+
+ ModulePass *createCallPathsPass(std::vector<std::vector<BasicBlock*> > *_bbpaths, std::string _filename);
+
+ class CallPaths : public ModulePass {
+ friend class my_dfs_visitor;
+ public:
+ // Do not create (createCallPathsPass is the object Factory)
+ CallPaths();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual bool runOnModule(Module &_M);
+
+ public:
+ // createCallPathsPass Input : All BB paths found
+ std::vector<std::vector<BasicBlock*> > *bbpaths;
+ // createCallPathsPass Input : filename to defect xml file
+ std::string defectFile;
+
+ // Stored pointer to the module (gotten fron runOnModule)
+ Module *M;
+ // LLVM Pass ID
+ static char ID;
+
+ private:
+ // Set of filenames and line numbers pointing to areas of interest
+ typedef std::map<std::string, std::vector<int> > defectList;
+ defectList dl;
+ // Parse defectFile and build the defectList (dl) map
+ void getDefectList(std::string docname, defectList *res);
+
+ //Return a Function* given a filename/srcline - used by DFS funcGraph
+ Function *getFunction(std::string srcFile, int srcLine);
+ //Return a BB* given a filename/srcline -- used by DFS bbGraph
+ BasicBlock *getBB(std::string srcFile, int srcLine);
+
+ // Checks wether a BB contains the code found in a file/line compination
+ bool findLineInBB(BasicBlock *BB, std::string srcFile, int srcLine);
+ // Checks wether a Function contains the code found in a file/line compination
+ // (uses findLineInBB)
+ bool findLineInFunction(Function *F, BasicBlock **BB, std::string srcFile, int srcLine);
+
+ // -------(BGL)---------------------------
+ private:
+ Graph funcG, bbG;
+ std::map<Function*, Vertex> funcMap; // Map functions to vertices
+ std::map<BasicBlock*, Vertex> bbMap;
+
+ private:
+ //Return a BB* given a Vertex -- used by Dijkstra
+ BasicBlock *getBB(Vertex v);
+ // Given a BB, add edges to all it's successors
+ void addBBEdges(BasicBlock *BB);
+ // Reset the entire weightmap.
+ // FIX; no need for the BuildGraph to worry about the weightmap?
+ void resetWeightMap(void);
+
+ // Get the name of Function given a vertex (relies on the funcMap)
+ std::string getName(Vertex v);
+ // Get the name of BB given a vertex (relies on the bbMap)
+ std::string getBBName(Vertex v);
+
+ // Given a CallGraph (result of the CallGraph LLVM Pass) builds the
+ // funcG and bbG
+ void buildGraph(CallGraph *CG);
+ // check wether a given paths already exists in *paths
+ bool duplicate(std::vector<std::vector<Vertex> >*paths, std::vector<Vertex> p);
+ // Runs Dijkstra's algortihm and find the shortest path between root and target
+ void findSinglePath(std::vector<Vertex> *path,
+ Vertex root,
+ Vertex target);
+ // Tries to find a maximum of 'number' unique paths and put them in *paths
+ // Runs multiple Dijsktra's and tinkers with the weightmap to find new paths
+ void findPaths(std::vector<std::vector<Vertex> >*paths,
+ BasicBlock *rootBB,
+ BasicBlock *targetBB,
+ int number);
+
+ // Helper functor used to write nice labels for functions in GraphViz dot files
+ private:
+ struct my_func_label_writer {
+ CallPaths *CP;
+ my_func_label_writer(CallPaths *_CP) : CP(_CP) { }
+ template <class VertexOrEdge>
+ void operator()(std::ostream& out, const VertexOrEdge& v) const {
+ out << "[label=\"" << CP->getName(v) << "\"]";
+ }
+ };
+
+ // Helper functor used to write nice labels for BBs in GraphViz dot files
+ struct my_bb_label_writer {
+ CallPaths *CP;
+ my_bb_label_writer(CallPaths *_CP) : CP(_CP) { }
+ template <class VertexOrEdge>
+ void operator()(std::ostream& out, const VertexOrEdge& v) const {
+ out << "[label=\"" << CP->getBBName(v) << "\"]";
+ }
+ };
+
+ // --- Obsolete -----
+ private:
+ // This is the old loop to try generating paths, doesn't work properly
+ bool findBBPath(CallGraphNode *n, std::vector<BasicBlock*> &path, std::string srcFile, int srcLine);
+ // BGL; find out if a BB is a pred of another (gets stuck in loops)
+ bool isBBPred(BasicBlock *BB, BasicBlock *succBB);
+ };
+
+ // DFS Visitor class (used by the brute force DFS path builders)
+ class my_dfs_visitor:public default_dfs_visitor {
+ private:
+ CallPaths *CP;
+ Vertex target, root;
+ std::vector<std::vector<Vertex> >*paths;
+ std::vector<Vertex> tpath;
+ std::vector<default_color_type> &colmap;
+ long long ctr;
+ public:
+ my_dfs_visitor(CallPaths *_CP, Vertex _target, Vertex _root,
+ std::vector<std::vector<Vertex> >*_paths,
+ std::vector<default_color_type> &_colmap) :
+ CP(_CP), target(_target), root(_root), paths(_paths), colmap(_colmap), ctr(0) { }
+ bool duplicate(std::vector<Vertex> p)
+ {
+ for (std::vector<std::vector<Vertex> >::iterator it=paths->begin(); it != paths->end(); ++it) {
+ std::vector<Vertex> cpath = *it;
+ if (cpath.size() != p.size())
+ continue;
+ unsigned int i;
+ for (i=0; i<cpath.size(); ++i) {
+ if (p[i] != cpath[i])
+ break;
+ }
+ if (i==cpath.size())
+ return true;
+ }
+ return false;
+ }
+ void newPath(void)
+ {
+ if (tpath.size() > 0)
+ if (tpath.front() == root)
+ if (!duplicate(tpath))
+ paths->push_back(tpath);
+
+ std::cerr << "newPath " << paths->size() << " : " << tpath.size() << "\n";
+ }
+ void discover_vertex(Vertex u, const Graph & g)
+ {
+ // std::cerr << "discover " << CP->getName(u) << "\n";
+
+ ctr++;
+
+ if ((ctr%1000000)==0)
+ std::cerr << "visited " << ctr << " vertices -- tpath size "
+ << tpath.size() << "\n";
+
+ tpath.push_back(u);
+ if (u == target) {
+ newPath();
+ }
+ }
+ void finish_vertex(Vertex u, const Graph & g)
+ {
+ // std::cerr << "finish " << CP->getName(u) << " : " << colmap[u] <<"\n";
+
+ tpath.pop_back();
+ colmap[u] = Color::white();
+ }
+ };
+}
+
+#endif
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmParsers.def - LLVM Assembly Parsers -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language parsers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PARSER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly parsers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PARSER
+# error Please define the macro LLVM_ASM_PARSER(TargetName)
+#endif
+
+LLVM_ASM_PARSER(X86)
+
+#undef LLVM_ASM_PARSER
@@ -0,0 +1,29 @@
+//===- llvm/Config/AsmPrinters.def - LLVM Assembly Printers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file enumerates all of the assembly-language printers
+// supported by this build of LLVM. Clients of this file should define
+// the LLVM_ASM_PRINTER macro to be a function-like macro with a
+// single parameter (the name of the target whose assembly can be
+// generated); including this file will then enumerate all of the
+// targets with assembly printers.
+//
+// The set of targets supported by LLVM is generated at configuration
+// time, at which point this header is generated. Do not modify this
+// header directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASM_PRINTER
+# error Please define the macro LLVM_ASM_PRINTER(TargetName)
+#endif
+
+LLVM_ASM_PRINTER(Blackfin) LLVM_ASM_PRINTER(SystemZ) LLVM_ASM_PRINTER(MSP430) LLVM_ASM_PRINTER(XCore) LLVM_ASM_PRINTER(PIC16) LLVM_ASM_PRINTER(CellSPU) LLVM_ASM_PRINTER(Mips) LLVM_ASM_PRINTER(ARM) LLVM_ASM_PRINTER(Alpha) LLVM_ASM_PRINTER(PowerPC) LLVM_ASM_PRINTER(Sparc) LLVM_ASM_PRINTER(X86)
+
+#undef LLVM_ASM_PRINTER
Oops, something went wrong.

0 comments on commit 5c025d2

Please sign in to comment.