Skip to content

Commit 0733e1f

Browse files
authored
Merge pull request #420 from secure-software-engineering/f-InsertBackwardRets
insert dummy return instructions in each function in the backward ICFG to get consistency w.r.t. forward ICFG
2 parents eec7fcf + f8e0996 commit 0733e1f

2 files changed

Lines changed: 88 additions & 19 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.h

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <unordered_set>
1919
#include <vector>
2020

21+
#include "llvm/IR/LLVMContext.h"
22+
2123
#include "phasar/PhasarLLVM/ControlFlow/ICFG.h"
2224
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
2325
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
@@ -42,17 +44,28 @@ class LLVMBasedBackwardsICFG
4244
: public ICFG<const llvm::Instruction *, const llvm::Function *>,
4345
public virtual LLVMBasedBackwardCFG {
4446
private:
45-
LLVMBasedICFG ForwardICFG;
47+
LLVMBasedICFG &ForwardICFG;
48+
static inline const std::unique_ptr<llvm::LLVMContext> LLVMBackwardRetCTX =
49+
std::make_unique<llvm::LLVMContext>();
50+
51+
class LLVMBackwardRet {
52+
private:
53+
const llvm::ReturnInst *Instance;
54+
55+
public:
56+
LLVMBackwardRet()
57+
: Instance(llvm::ReturnInst::Create(*LLVMBackwardRetCTX)){};
58+
[[nodiscard]] const llvm::ReturnInst *getInstance() const {
59+
return Instance;
60+
}
61+
};
62+
std::unordered_map<const llvm::Function *, LLVMBackwardRet> BackwardRets;
63+
llvm::DenseMap<const llvm::Instruction *, const llvm::Function *>
64+
BackwardRetToFunction;
4665

4766
public:
4867
LLVMBasedBackwardsICFG(LLVMBasedICFG &ICFG);
4968

50-
LLVMBasedBackwardsICFG(ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
51-
const std::set<std::string> &EntryPoints = {},
52-
LLVMTypeHierarchy *TH = nullptr,
53-
LLVMPointsToInfo *PT = nullptr,
54-
Soundness S = Soundness::Soundy);
55-
5669
~LLVMBasedBackwardsICFG() override = default;
5770

5871
std::set<const llvm::Function *> getAllFunctions() const override;
@@ -77,6 +90,20 @@ class LLVMBasedBackwardsICFG
7790

7891
std::set<const llvm::Instruction *> allNonCallStartNodes() const override;
7992

93+
[[nodiscard]] const llvm::Function *
94+
getFunctionOf(const llvm::Instruction *Stmt) const override;
95+
96+
[[nodiscard]] std::vector<const llvm::Instruction *>
97+
getPredsOf(const llvm::Instruction *Stmt) const override;
98+
99+
[[nodiscard]] std::vector<const llvm::Instruction *>
100+
getSuccsOf(const llvm::Instruction *Stmt) const override;
101+
102+
[[nodiscard]] std::set<const llvm::Instruction *>
103+
getExitPointsOf(const llvm::Function *Fun) const override;
104+
105+
[[nodiscard]] bool isExitInst(const llvm::Instruction *Stmt) const override;
106+
80107
void mergeWith(const LLVMBasedBackwardsICFG &other);
81108

82109
using LLVMBasedBackwardCFG::print; // tell the compiler we wish to have both
@@ -95,6 +122,9 @@ class LLVMBasedBackwardsICFG
95122

96123
std::vector<const llvm::Function *> getDependencyOrderedFunctions();
97124

125+
private:
126+
void createBackwardRets();
127+
98128
protected:
99129
void collectGlobalCtors() override;
100130

lib/PhasarLLVM/ControlFlow/LLVMBasedBackwardICFG.cpp

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ LLVMBasedBackwardsICFG::LLVMBasedBackwardsICFG(LLVMBasedICFG &ICFG)
3838
: ForwardICFG(ICFG) {
3939
auto CgCopy = ForwardICFG.CallGraph;
4040
boost::copy_graph(boost::make_reverse_graph(CgCopy), ForwardICFG.CallGraph);
41+
createBackwardRets();
4142
}
4243

43-
LLVMBasedBackwardsICFG::LLVMBasedBackwardsICFG(
44-
ProjectIRDB &IRDB, CallGraphAnalysisType CGType,
45-
const std::set<std::string> &EntryPoints, LLVMTypeHierarchy *TH,
46-
LLVMPointsToInfo *PT, Soundness S)
47-
: ForwardICFG(IRDB, CGType, EntryPoints, TH, PT, S) {
48-
auto CgCopy = ForwardICFG.CallGraph;
49-
boost::copy_graph(boost::make_reverse_graph(CgCopy), ForwardICFG.CallGraph);
44+
void LLVMBasedBackwardsICFG::createBackwardRets() {
45+
for (const auto *Function : getAllFunctions()) {
46+
BackwardRetToFunction[BackwardRets[Function].getInstance()] = Function;
47+
}
5048
}
5149

5250
bool LLVMBasedBackwardsICFG::isIndirectFunctionCall(
@@ -88,15 +86,11 @@ std::set<const llvm::Instruction *>
8886
LLVMBasedBackwardsICFG::getReturnSitesOfCallAt(
8987
const llvm::Instruction *N) const {
9088
std::set<const llvm::Instruction *> ReturnSites;
91-
if (const auto *Call = llvm::dyn_cast<llvm::CallInst>(N)) {
89+
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(N)) {
9290
for (const auto *Succ : this->getSuccsOf(Call)) {
9391
ReturnSites.insert(Succ);
9492
}
9593
}
96-
if (const auto *Invoke = llvm::dyn_cast<llvm::InvokeInst>(N)) {
97-
ReturnSites.insert(&Invoke->getNormalDest()->back());
98-
ReturnSites.insert(&Invoke->getUnwindDest()->back());
99-
}
10094
return ReturnSites;
10195
}
10296

@@ -105,6 +99,51 @@ LLVMBasedBackwardsICFG::allNonCallStartNodes() const {
10599
return ForwardICFG.allNonCallStartNodes();
106100
}
107101

102+
const llvm::Function *
103+
LLVMBasedBackwardsICFG::getFunctionOf(const llvm::Instruction *Stmt) const {
104+
auto BackwardRetIt = BackwardRetToFunction.find(Stmt);
105+
if (BackwardRetIt != BackwardRetToFunction.end()) {
106+
return BackwardRetIt->second;
107+
}
108+
return Stmt->getFunction();
109+
}
110+
111+
std::vector<const llvm::Instruction *>
112+
LLVMBasedBackwardsICFG::getPredsOf(const llvm::Instruction *Stmt) const {
113+
auto BackwardRetIt = BackwardRetToFunction.find(Stmt);
114+
if (BackwardRetIt == BackwardRetToFunction.end()) {
115+
return LLVMBasedBackwardCFG::getPredsOf(Stmt);
116+
}
117+
auto ExitPoints =
118+
LLVMBasedBackwardCFG::getExitPointsOf(BackwardRetIt->second);
119+
return {ExitPoints.begin(), ExitPoints.end()};
120+
}
121+
122+
std::vector<const llvm::Instruction *>
123+
LLVMBasedBackwardsICFG::getSuccsOf(const llvm::Instruction *Stmt) const {
124+
if (isExitInst(Stmt)) {
125+
return {};
126+
}
127+
std::vector<const llvm::Instruction *> Succs =
128+
LLVMBasedBackwardCFG::getSuccsOf(Stmt);
129+
if (Succs.size() == 0) {
130+
assert(Stmt->getParent()->getParent() && "Could not find parent of stmt's parent ");
131+
Succs.push_back(
132+
BackwardRets.at(Stmt->getParent()->getParent()).getInstance());
133+
}
134+
return Succs;
135+
}
136+
137+
bool LLVMBasedBackwardsICFG::isExitInst(const llvm::Instruction *Stmt) const {
138+
return (Stmt->getParent() == nullptr &&
139+
BackwardRetToFunction.count(Stmt) > 0);
140+
}
141+
142+
std::set<const llvm::Instruction *>
143+
LLVMBasedBackwardsICFG::getExitPointsOf(const llvm::Function *Fun) const {
144+
return {BackwardRets.at(Fun).getInstance()};
145+
}
146+
108147
void LLVMBasedBackwardsICFG::mergeWith(const LLVMBasedBackwardsICFG &Other) {
109148
ForwardICFG.mergeWith(Other.ForwardICFG);
110149
}

0 commit comments

Comments
 (0)