Skip to content

Commit

Permalink
merged BackwardAnalysis into development
Browse files Browse the repository at this point in the history
  • Loading branch information
pdschubert committed Dec 3, 2018
2 parents ab3c28f + e7ecbdf commit 40a699b
Show file tree
Hide file tree
Showing 23 changed files with 657 additions and 460 deletions.
32 changes: 31 additions & 1 deletion README.md
Expand Up @@ -2,7 +2,10 @@

Phasar a LLVM-based Static Analysis Framework
=============================================
Version 1.1

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/c944f18c7960488798a0728db9380eb5)](https://app.codacy.com/app/pdschubert/phasar?utm_source=github.com&utm_medium=referral&utm_content=secure-software-engineering/phasar&utm_campaign=Badge_Grade_Dashboard)

Version 1218

Secure Software Engineering Group
---------------------------------
Expand Down Expand Up @@ -123,6 +126,33 @@ limit to 16 MB:
`$ ulimit -s 16777216`


Be careful when analyzing code that contains C-style variadic functions. Depending on your flow function
implementations PhASAR may crash. Observe the following example:
```C++
int sum(int n, ...) {
int s = 0;
va_list args;
va_start(args, n);
for (int i = 0; i < n; ++i) {
s += va_arg(args, int);
}
va_end(args);
return s;
}

int main() {
int s = sum(5 /* num args */, /* the actual args: */ 1, 2, 3, 4, 5);
printf("%d\n", s);
return 0;
}
```
The problem is that - if not handled carefully - the getCallFlowFunction() tries to map
more actual parameters into the callee than there are formal parameters (according to
LLVM sum has one formal parameter). Please have a look at our auto-mapping LLVM-based
flow function implementations `MapFactsToCallee` and `MapFactsToCaller` where we are using
a sound over-approximation. You may wish to use a similar treatment for your application.
Installation
------------
The installation of Phasar is not trivial, since it has some library
Expand Down
2 changes: 1 addition & 1 deletion include/phasar/PhasarLLVM/ControlFlow/CFG.h
Expand Up @@ -42,7 +42,7 @@ template <typename N, typename M> class CFG {
virtual bool isStartPoint(N stmt) = 0;

virtual bool isFieldLoad(N stmt) = 0;

virtual bool isFieldStore(N stmt) = 0;

virtual bool isFallThroughSuccessor(N stmt, N succ) = 0;
Expand Down
4 changes: 2 additions & 2 deletions include/phasar/PhasarLLVM/ControlFlow/ICFG.h
Expand Up @@ -28,7 +28,7 @@

namespace psr {

enum class CallGraphAnalysisType { CHA, RTA, DTA, VTA, OTF };
enum class CallGraphAnalysisType { CHA, RTA, DTA, OTF };

extern const std::map<std::string, CallGraphAnalysisType>
StringToCallGraphAnalysisType;
Expand All @@ -40,7 +40,7 @@ std::ostream &operator<<(std::ostream &os, const CallGraphAnalysisType &CGA);

using json = nlohmann::json;

template <typename N, typename M> class ICFG : public CFG<N, M> {
template <typename N, typename M> class ICFG : public virtual CFG<N, M> {
public:
virtual ~ICFG() = default;

Expand Down
40 changes: 24 additions & 16 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h
Expand Up @@ -22,6 +22,7 @@
#include <vector>

#include <phasar/PhasarLLVM/ControlFlow/CFG.h>
#include <phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h>

namespace llvm {
class Function;
Expand All @@ -31,39 +32,46 @@ class Instruction;
namespace psr {

class LLVMBasedBackwardCFG
: public CFG<const llvm::Instruction *, const llvm::Function *> {
: public virtual CFG<const llvm::Instruction *, const llvm::Function *> {
private:
LLVMBasedCFG ForwardCFG;

public:
LLVMBasedBackwardCFG();
LLVMBasedBackwardCFG() = default;

~LLVMBasedBackwardCFG() override = default;
virtual ~LLVMBasedBackwardCFG() = default;

const llvm::Function *
getMethodOf(const llvm::Instruction *stmt) override;
const llvm::Function *getMethodOf(const llvm::Instruction *stmt) override;

std::vector<const llvm::Instruction *>
std::vector<const llvm::Instruction *>
getPredsOf(const llvm::Instruction *stmt) override;

std::vector<const llvm::Instruction *>
std::vector<const llvm::Instruction *>
getSuccsOf(const llvm::Instruction *stmt) override;

std::vector<
std::pair<const llvm::Instruction *, const llvm::Instruction *>>
std::vector<std::pair<const llvm::Instruction *, const llvm::Instruction *>>
getAllControlFlowEdges(const llvm::Function *fun) override;

std::vector<const llvm::Instruction *>
std::vector<const llvm::Instruction *>
getAllInstructionsOf(const llvm::Function *fun) override;

bool isExitStmt(const llvm::Instruction *stmt) override;
bool isExitStmt(const llvm::Instruction *stmt) override;

bool isStartPoint(const llvm::Instruction *stmt) override;

bool isStartPoint(const llvm::Instruction *stmt) override;
bool isFieldLoad(const llvm::Instruction *stmt) override;

bool isFallThroughSuccessor(const llvm::Instruction *stmt,
const llvm::Instruction *succ) override;
bool isFieldStore(const llvm::Instruction *stmt) override;

bool isBranchTarget(const llvm::Instruction *stmt,
bool isFallThroughSuccessor(const llvm::Instruction *stmt,
const llvm::Instruction *succ) override;

std::string getMethodName(const llvm::Function *fun) override;
bool isBranchTarget(const llvm::Instruction *stmt,
const llvm::Instruction *succ) override;

std::string getMethodName(const llvm::Function *fun) override;

std::string getStatementId(const llvm::Instruction *stmt) override;
};
} // namespace psr

Expand Down
148 changes: 75 additions & 73 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h
Expand Up @@ -7,111 +7,113 @@
* Philipp Schubert and others
*****************************************************************************/

/*
*
* LLVMBasedBackwardsICFG.h
*
* Created on: 15.09.2016
* Author: pdschbrt
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDBACKWARDICFG_H_
#define PHASAR_PHASARLLVM_CONTROLFLOW_LLVMBASEDBACKWARDICFG_H_

#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <phasar/PhasarLLVM/ControFlow/BiDiICFG.h>
#include <set>
#include <functional>
#include <iosfwd>
#include <map>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

class LLVMBasedBackwardsICFG : public BiDiICFG<const llvm::Instruction*, const
llvm::Function*> {
private:
#include <boost/graph/adjacency_list.hpp>

#include <phasar/PhasarLLVM/ControlFlow/ICFG.h>
#include <phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h>
#include <phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h>
#include <phasar/PhasarLLVM/Pointer/PointsToGraph.h>

namespace llvm {
class Instruction;
class Function;
class Module;
class Instruction;
class BitCastInst;
} // namespace llvm

namespace psr {

class Resolver;
class ProjectIRDB;
class LLVMTypeHierarchy;

class LLVMBasedBackwardsICFG
: public ICFG<const llvm::Instruction *, const llvm::Function *>,
public virtual LLVMBasedBackwardCFG {
private:
public:
LLVMBasedBackwardsICFG();
LLVMBasedICFG ForwardICFG;
LLVMBasedBackwardsICFG(LLVMTypeHierarchy &STH, ProjectIRDB &IRDB);

LLVMBasedBackwardsICFG(LLVMTypeHierarchy &STH, ProjectIRDB &IRDB,
CallGraphAnalysisType CGType,
const std::vector<std::string> &EntryPoints = {
"main"});

LLVMBasedBackwardsICFG(LLVMTypeHierarchy &STH, ProjectIRDB &IRDB,
const llvm::Module &M, CallGraphAnalysisType CGType,
std::vector<std::string> EntryPoints = {});

virtual ~LLVMBasedBackwardsICFG();
virtual ~LLVMBasedBackwardsICFG() = default;

//swapped
std::vector<const llvm::Instruction*> getSuccsOf(const
llvm::Instruction* n) override;
std::set<const llvm::Function *> getAllMethods();

//swapped
std::set<const llvm::Instruction*> getStartPointsOf(const
llvm::Function* m) override;
bool isVirtualFunctionCall(llvm::ImmutableCallSite CS);

//swapped
std::set<const llvm::Instruction*> getReturnSitesOfCallAt(const
llvm::Instruction* n) override;
const llvm::Function *getMethod(const std::string &fun) override;

//swapped
bool isExitStmt(const llvm::Instruction* stmt) override;
std::set<const llvm::Function *>
getCalleesOfCallAt(const llvm::Instruction *n) override;

//swapped
bool isStartPoint(const llvm::Instruction* stmt) override;
std::set<const llvm::Instruction *>
getCallersOf(const llvm::Function *m) override;

//swapped
std::set<const llvm::Instruction*> allNonCallStartNodes() override;
std::set<const llvm::Instruction *>
getCallsFromWithin(const llvm::Function *m) override;

//swapped
std::vector<const llvm::Instruction*> getPredsOf(const
llvm::Instruction* u) override;
std::set<const llvm::Instruction *>
getStartPointsOf(const llvm::Function *m) override;

//swapped
std::set<const llvm::Instruction*> getEndPointsOf(const llvm::Function*
m) override;
std::set<const llvm::Instruction *>
getExitPointsOf(const llvm::Function *fun) override;

//swapped
std::vector<const llvm::Instruction*> getPredsOfCallAt(const
llvm::Instruction* u) override;
std::set<const llvm::Instruction *>
getReturnSitesOfCallAt(const llvm::Instruction *n) override;

//swapped
std::set<const llvm::Instruction*> allNonCallEndNodes() override;
bool isCallStmt(const llvm::Instruction *stmt) override;

//same
const llvm::Function* getMethodOf(const llvm::Instruction* n) override;
std::set<const llvm::Instruction *> allNonCallStartNodes() override;

//same
std::set<const llvm::Function*> getCalleesOfCallAt(const
llvm::Instruction* n) override;
const llvm::Instruction *getLastInstructionOf(const std::string &name);

//same
std::set<const llvm::Instruction*> getCallersOf(const llvm::Function* m)
override;
std::vector<const llvm::Instruction *>
getAllInstructionsOfFunction(const std::string &name);

//same
std::set<const llvm::Instruction*> getCallsFromWithin(const
llvm::Function* m) override;
void mergeWith(const LLVMBasedBackwardsICFG &other);

//same
bool isCallStmt(const llvm::Instruction* stmt) override;
bool isPrimitiveFunction(const std::string &name);

//same
//DirectedGraph<const llvm::Instruction*> getOrCreateUnitGraph(const
llvm::Function* m) override;
void print();

//same
std::vector<const llvm::Instruction*> getParameterRefs(const
llvm::Function* m) override;
void printAsDot(const std::string &filename);

bool isFallThroughSuccessor(const llvm::Instruction* stmt, const
llvm::Instruction* succ) override;
void printInternalPTGAsDot(const std::string &filename);

bool isBranchTarget(const llvm::Instruction* stmt, const
llvm::Instruction* succ) override;
json getAsJson() override;

//swapped
bool isReturnSite(const llvm::Instruction* n) override;
unsigned getNumOfVertices();

// same
bool isReachable(const llvm::Instruction* u) override;
unsigned getNumOfEdges();

void exportPATBCJSON();

PointsToGraph &getWholeModulePTG();

std::vector<std::string> getDependencyOrderedFunctions();
};

} // namespace psr

#endif
*/
20 changes: 10 additions & 10 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h
Expand Up @@ -26,30 +26,30 @@
namespace llvm {
class Function;
class Instruction;
} // namespace llvm
} // namespace llvm

namespace psr {

class LLVMBasedCFG
: public CFG<const llvm::Instruction *, const llvm::Function *> {
public:
: public virtual CFG<const llvm::Instruction *, const llvm::Function *> {
public:
LLVMBasedCFG() = default;

~LLVMBasedCFG() override = default;

const llvm::Function *getMethodOf(const llvm::Instruction *stmt) override;

std::vector<const llvm::Instruction *> getPredsOf(
const llvm::Instruction *stmt) override;
std::vector<const llvm::Instruction *>
getPredsOf(const llvm::Instruction *stmt) override;

std::vector<const llvm::Instruction *> getSuccsOf(
const llvm::Instruction *stmt) override;
std::vector<const llvm::Instruction *>
getSuccsOf(const llvm::Instruction *stmt) override;

std::vector<std::pair<const llvm::Instruction *, const llvm::Instruction *>>
getAllControlFlowEdges(const llvm::Function *fun) override;

std::vector<const llvm::Instruction *> getAllInstructionsOf(
const llvm::Function *fun) override;
std::vector<const llvm::Instruction *>
getAllInstructionsOf(const llvm::Function *fun) override;

bool isExitStmt(const llvm::Instruction *stmt) override;

Expand All @@ -70,6 +70,6 @@ class LLVMBasedCFG
std::string getMethodName(const llvm::Function *fun) override;
};

} // namespace psr
} // namespace psr

#endif

0 comments on commit 40a699b

Please sign in to comment.