Skip to content

Commit 488da6a

Browse files
authored
Resolver Injection (#717)
* Add ctor to LLVMBasedICFG that allows injecting a CG resolver * Low-hanging fruits in resolvers * Remove out-commented code + unnecessary includes * Make the docker push pipeline work again
1 parent fc0147f commit 488da6a

8 files changed

Lines changed: 59 additions & 40 deletions

File tree

include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
namespace psr {
4343
class LLVMTypeHierarchy;
4444
class LLVMProjectIRDB;
45+
class Resolver;
4546

4647
class LLVMBasedICFG;
4748
template <> struct CFGTraits<LLVMBasedICFG> : CFGTraits<LLVMBasedCFG> {};
@@ -87,6 +88,11 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
8788
LLVMAliasInfoRef PT = nullptr,
8889
Soundness S = Soundness::Soundy,
8990
bool IncludeGlobals = true);
91+
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
92+
llvm::ArrayRef<std::string> EntryPoints = {},
93+
LLVMTypeHierarchy *TH = nullptr,
94+
Soundness S = Soundness::Soundy,
95+
bool IncludeGlobals = true);
9096

9197
/// Creates an ICFG with an already given call-graph
9298
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
@@ -157,6 +163,10 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
157163
[[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel(
158164
llvm::Module &M, llvm::ArrayRef<llvm::Function *> UserEntryPoints);
159165

166+
void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
167+
llvm::ArrayRef<std::string> EntryPoints,
168+
LLVMTypeHierarchy *TH, Soundness S, bool IncludeGlobals);
169+
160170
// ---
161171

162172
CallGraph<const llvm::Instruction *, const llvm::Function *> CG;

include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,14 @@ class Value;
3535

3636
namespace psr {
3737

38-
class LLVMBasedICFG;
3938
class LLVMTypeHierarchy;
4039

4140
class OTFResolver : public Resolver {
4241
protected:
43-
LLVMBasedICFG &ICF;
4442
LLVMAliasInfoRef PT;
4543

4644
public:
47-
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, LLVMBasedICFG &ICF,
45+
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
4846
LLVMAliasInfoRef PT);
4947

5048
~OTFResolver() override = default;

include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ namespace psr {
3636
class LLVMProjectIRDB;
3737
class LLVMTypeHierarchy;
3838
enum class CallGraphAnalysisType;
39-
class LLVMBasedICFG;
4039
class LLVMPointsToInfo;
4140

4241
[[nodiscard]] std::optional<unsigned>
@@ -83,9 +82,10 @@ class Resolver {
8382

8483
[[nodiscard]] virtual std::string str() const = 0;
8584

86-
static std::unique_ptr<Resolver>
87-
create(CallGraphAnalysisType Ty, LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH,
88-
LLVMBasedICFG *ICF = nullptr, LLVMAliasInfoRef PT = nullptr);
85+
static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
86+
LLVMProjectIRDB *IRDB,
87+
LLVMTypeHierarchy *TH,
88+
LLVMAliasInfoRef PT = nullptr);
8989
};
9090
} // namespace psr
9191

lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
1111

12-
#include "phasar/Config/Configuration.h"
1312
#include "phasar/ControlFlow/CallGraph.h"
1413
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
1514
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
@@ -24,27 +23,22 @@
2423
#include "phasar/Utils/MaybeUniquePtr.h"
2524
#include "phasar/Utils/PAMMMacros.h"
2625
#include "phasar/Utils/Soundness.h"
27-
#include "phasar/Utils/TypeTraits.h"
28-
#include "phasar/Utils/Utilities.h"
2926

30-
#include "llvm/ADT/STLExtras.h"
3127
#include "llvm/ADT/SmallVector.h"
3228
#include "llvm/ADT/StringSwitch.h"
3329
#include "llvm/IR/Function.h"
3430
#include "llvm/IR/Instruction.h"
3531
#include "llvm/Support/ErrorHandling.h"
3632

37-
#include <cstdint>
3833
#include <utility>
3934

4035
namespace psr {
4136
struct LLVMBasedICFG::Builder {
4237
LLVMProjectIRDB *IRDB = nullptr;
43-
LLVMAliasInfoRef PT{};
4438
LLVMTypeHierarchy *TH{};
39+
Resolver *Res = nullptr;
4540
CallGraphBuilder<const llvm::Instruction *, const llvm::Function *>
4641
CGBuilder{};
47-
std::unique_ptr<Resolver> Res = nullptr;
4842
llvm::DenseSet<const llvm::Function *> VisitedFunctions{};
4943
llvm::SmallVector<llvm::Function *, 1> UserEntryPoints{};
5044

@@ -321,6 +315,28 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) {
321315
return NewTargetsFound;
322316
}
323317

318+
void LLVMBasedICFG::initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
319+
llvm::ArrayRef<std::string> EntryPoints,
320+
LLVMTypeHierarchy *TH, Soundness S,
321+
bool IncludeGlobals) {
322+
Builder B{IRDB, this->TH.get(), &CGResolver};
323+
324+
B.initEntryPoints(EntryPoints);
325+
B.initGlobalsAndWorkList(this, IncludeGlobals);
326+
327+
PHASAR_LOG_LEVEL_CAT(
328+
INFO, "LLVMBasedICFG",
329+
"Starting ICFG construction "
330+
<< std::chrono::steady_clock::now().time_since_epoch().count());
331+
332+
this->CG = B.buildCallGraph(S);
333+
334+
PHASAR_LOG_LEVEL_CAT(
335+
INFO, "LLVMBasedICFG",
336+
"Finished ICFG construction "
337+
<< std::chrono::steady_clock::now().time_since_epoch().count());
338+
}
339+
324340
LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
325341
CallGraphAnalysisType CGType,
326342
llvm::ArrayRef<std::string> EntryPoints,
@@ -333,29 +349,29 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
333349
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
334350
}
335351

336-
Builder B{IRDB, PT, this->TH.get()};
337352
LLVMAliasInfo PTOwn;
338353

339354
if (!PT && CGType == CallGraphAnalysisType::OTF) {
340355
PTOwn = std::make_unique<LLVMAliasSet>(IRDB);
341-
B.PT = PTOwn.asRef();
356+
PT = PTOwn.asRef();
342357
}
343358

344-
B.Res = Resolver::create(CGType, IRDB, this->TH.get(), this, B.PT);
345-
B.initEntryPoints(EntryPoints);
346-
B.initGlobalsAndWorkList(this, IncludeGlobals);
359+
auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), PT);
360+
initialize(IRDB, *CGRes, EntryPoints, TH, S, IncludeGlobals);
361+
}
347362

348-
PHASAR_LOG_LEVEL_CAT(
349-
INFO, "LLVMBasedICFG",
350-
"Starting ICFG construction "
351-
<< std::chrono::steady_clock::now().time_since_epoch().count());
363+
LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
364+
llvm::ArrayRef<std::string> EntryPoints,
365+
LLVMTypeHierarchy *TH, Soundness S,
366+
bool IncludeGlobals)
367+
: IRDB(IRDB), TH(TH) {
368+
assert(IRDB != nullptr);
352369

353-
this->CG = B.buildCallGraph(S);
370+
if (!TH) {
371+
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
372+
}
354373

355-
PHASAR_LOG_LEVEL_CAT(
356-
INFO, "LLVMBasedICFG",
357-
"Finished ICFG construction "
358-
<< std::chrono::steady_clock::now().time_since_epoch().count());
374+
initialize(IRDB, CGResolver, EntryPoints, TH, S, IncludeGlobals);
359375
}
360376

361377
LLVMBasedICFG::LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,

lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
using namespace psr;
3232

3333
OTFResolver::OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
34-
LLVMBasedICFG &ICF, LLVMAliasInfoRef PT)
35-
: Resolver(IRDB, TH), ICF(ICF), PT(PT) {}
34+
LLVMAliasInfoRef PT)
35+
: Resolver(IRDB, TH), PT(PT) {}
3636

3737
void OTFResolver::preCall(const llvm::Instruction *Inst) {}
3838

@@ -55,7 +55,7 @@ void OTFResolver::handlePossibleTargets(const llvm::CallBase *CallSite,
5555
}
5656
// handle return value
5757
if (CalleeTarget->getReturnType()->isPointerTy()) {
58-
for (const auto &ExitPoint : ICF.getExitPointsOf(CalleeTarget)) {
58+
for (const auto &ExitPoint : psr::getAllExitPoints(CalleeTarget)) {
5959
// get the function's return value
6060
if (const auto *Ret = llvm::dyn_cast<llvm::ReturnInst>(ExitPoint)) {
6161
// introduce alias to the returned value

lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ void RTAResolver::resolveAllocatedStructTypes() {
9999
}
100100

101101
llvm::DenseSet<const llvm::StructType *> AllocatedStructTypes;
102-
const llvm::StringSet<> MemAllocatingFunctions = {"_Znwm", "_Znam", "malloc",
103-
"calloc", "realloc"};
104102

105103
for (const auto *Fun : IRDB.getAllFunctions()) {
106104
for (const auto &Inst : llvm::instructions(Fun)) {
@@ -114,8 +112,7 @@ void RTAResolver::resolveAllocatedStructTypes() {
114112
// check if an instance of a user-defined type is allocated on the
115113
// heap
116114

117-
if (!MemAllocatingFunctions.contains(
118-
CallSite->getCalledFunction()->getName())) {
115+
if (!isHeapAllocatingFunction(CallSite->getCalledFunction())) {
119116
continue;
120117
}
121118
/// TODO: Does this iteration over the users make sense?

lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ auto Resolver::resolveFunctionPointer(const llvm::CallBase *CallSite)
145145
FunctionSetTy CalleeTargets;
146146

147147
for (const auto *F : IRDB.getAllFunctions()) {
148-
if (isConsistentCall(CallSite, F)) {
148+
if (F->hasAddressTaken() && isConsistentCall(CallSite, F)) {
149149
CalleeTargets.insert(F);
150150
}
151151
}
@@ -158,7 +158,6 @@ void Resolver::otherInst(const llvm::Instruction *Inst) {}
158158
std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
159159
LLVMProjectIRDB *IRDB,
160160
LLVMTypeHierarchy *TH,
161-
LLVMBasedICFG *ICF,
162161
LLVMAliasInfoRef PT) {
163162
assert(IRDB != nullptr);
164163

@@ -179,9 +178,8 @@ std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
179178
"The VTA callgraph algorithm is not implemented yet");
180179
case CallGraphAnalysisType::OTF:
181180
assert(TH != nullptr);
182-
assert(ICF != nullptr);
183181
assert(PT);
184-
return std::make_unique<OTFResolver>(*IRDB, *TH, *ICF, PT);
182+
return std::make_unique<OTFResolver>(*IRDB, *TH, PT);
185183
case CallGraphAnalysisType::Invalid:
186184
llvm::report_fatal_error("Invalid callgraph algorithm specified");
187185
}

utils/InstallAptDependencies.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ set -e
33

44
sudo apt-get update
55
sudo apt-get install git -y
6-
sudo apt-get install zlib1g-dev python3 g++ ninja-build cmake -y
6+
sudo apt-get install zlib1g-dev python3 python3-pip g++ ninja-build cmake -y

0 commit comments

Comments
 (0)