From 355af01d71d1d902b028a93098f3df57b3e76633 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Thu, 11 Apr 2024 13:24:34 +0200 Subject: [PATCH 1/4] Add ctor to LLVMBasedICFG that allows injecting a CG resolver --- .../PhasarLLVM/ControlFlow/LLVMBasedICFG.h | 10 ++++ lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 54 +++++++++++++------ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h index 12bc784930..92e964e142 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h +++ b/include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h @@ -42,6 +42,7 @@ namespace psr { class LLVMTypeHierarchy; class LLVMProjectIRDB; +class Resolver; class LLVMBasedICFG; template <> struct CFGTraits : CFGTraits {}; @@ -87,6 +88,11 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { LLVMAliasInfoRef PT = nullptr, Soundness S = Soundness::Soundy, bool IncludeGlobals = true); + explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver, + llvm::ArrayRef EntryPoints = {}, + LLVMTypeHierarchy *TH = nullptr, + Soundness S = Soundness::Soundy, + bool IncludeGlobals = true); /// Creates an ICFG with an already given call-graph explicit LLVMBasedICFG(CallGraph CG, LLVMProjectIRDB *IRDB, @@ -157,6 +163,10 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase { [[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel( llvm::Module &M, llvm::ArrayRef UserEntryPoints); + void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, + llvm::ArrayRef EntryPoints, + LLVMTypeHierarchy *TH, Soundness S, bool IncludeGlobals); + // --- CallGraph CG; diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 87b2279f28..eb7e8a0f66 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -40,11 +40,11 @@ namespace psr { struct LLVMBasedICFG::Builder { LLVMProjectIRDB *IRDB = nullptr; - LLVMAliasInfoRef PT{}; + // LLVMAliasInfoRef PT{}; LLVMTypeHierarchy *TH{}; + Resolver *Res = nullptr; CallGraphBuilder CGBuilder{}; - std::unique_ptr Res = nullptr; llvm::DenseSet VisitedFunctions{}; llvm::SmallVector UserEntryPoints{}; @@ -321,6 +321,28 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) { return NewTargetsFound; } +void LLVMBasedICFG::initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver, + llvm::ArrayRef EntryPoints, + LLVMTypeHierarchy *TH, Soundness S, + bool IncludeGlobals) { + Builder B{IRDB, this->TH.get(), &CGResolver}; + + B.initEntryPoints(EntryPoints); + B.initGlobalsAndWorkList(this, IncludeGlobals); + + PHASAR_LOG_LEVEL_CAT( + INFO, "LLVMBasedICFG", + "Starting ICFG construction " + << std::chrono::steady_clock::now().time_since_epoch().count()); + + this->CG = B.buildCallGraph(S); + + PHASAR_LOG_LEVEL_CAT( + INFO, "LLVMBasedICFG", + "Finished ICFG construction " + << std::chrono::steady_clock::now().time_since_epoch().count()); +} + LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, CallGraphAnalysisType CGType, llvm::ArrayRef EntryPoints, @@ -333,29 +355,29 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, this->TH = std::make_unique(*IRDB); } - Builder B{IRDB, PT, this->TH.get()}; LLVMAliasInfo PTOwn; if (!PT && CGType == CallGraphAnalysisType::OTF) { PTOwn = std::make_unique(IRDB); - B.PT = PTOwn.asRef(); + PT = PTOwn.asRef(); } - B.Res = Resolver::create(CGType, IRDB, this->TH.get(), this, B.PT); - B.initEntryPoints(EntryPoints); - B.initGlobalsAndWorkList(this, IncludeGlobals); + auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), this, PT); + initialize(IRDB, *CGRes, EntryPoints, TH, S, IncludeGlobals); +} - PHASAR_LOG_LEVEL_CAT( - INFO, "LLVMBasedICFG", - "Starting ICFG construction " - << std::chrono::steady_clock::now().time_since_epoch().count()); +LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver, + llvm::ArrayRef EntryPoints, + LLVMTypeHierarchy *TH, Soundness S, + bool IncludeGlobals) + : IRDB(IRDB), TH(TH) { + assert(IRDB != nullptr); - this->CG = B.buildCallGraph(S); + if (!TH) { + this->TH = std::make_unique(*IRDB); + } - PHASAR_LOG_LEVEL_CAT( - INFO, "LLVMBasedICFG", - "Finished ICFG construction " - << std::chrono::steady_clock::now().time_since_epoch().count()); + initialize(IRDB, CGResolver, EntryPoints, TH, S, IncludeGlobals); } LLVMBasedICFG::LLVMBasedICFG(CallGraph CG, LLVMProjectIRDB *IRDB, From f5e3ecb7bf9dda1ed8cfd09758c20871571685c3 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sat, 20 Apr 2024 14:34:37 +0200 Subject: [PATCH 2/4] Low-hanging fruits in resolvers --- .../phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h | 4 +--- include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h | 8 ++++---- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 2 +- lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp | 6 +++--- lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp | 5 +---- lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp | 6 ++---- 6 files changed, 12 insertions(+), 19 deletions(-) diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h index 5755c52072..13c75d8f34 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h @@ -35,16 +35,14 @@ class Value; namespace psr { -class LLVMBasedICFG; class LLVMTypeHierarchy; class OTFResolver : public Resolver { protected: - LLVMBasedICFG &ICF; LLVMAliasInfoRef PT; public: - OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, LLVMBasedICFG &ICF, + OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, LLVMAliasInfoRef PT); ~OTFResolver() override = default; diff --git a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h index 58671342f5..73adbd37e8 100644 --- a/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h +++ b/include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h @@ -36,7 +36,6 @@ namespace psr { class LLVMProjectIRDB; class LLVMTypeHierarchy; enum class CallGraphAnalysisType; -class LLVMBasedICFG; class LLVMPointsToInfo; [[nodiscard]] std::optional @@ -83,9 +82,10 @@ class Resolver { [[nodiscard]] virtual std::string str() const = 0; - static std::unique_ptr - create(CallGraphAnalysisType Ty, LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH, - LLVMBasedICFG *ICF = nullptr, LLVMAliasInfoRef PT = nullptr); + static std::unique_ptr create(CallGraphAnalysisType Ty, + LLVMProjectIRDB *IRDB, + LLVMTypeHierarchy *TH, + LLVMAliasInfoRef PT = nullptr); }; } // namespace psr diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index eb7e8a0f66..c9c6cbfaeb 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -362,7 +362,7 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, PT = PTOwn.asRef(); } - auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), this, PT); + auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), PT); initialize(IRDB, *CGRes, EntryPoints, TH, S, IncludeGlobals); } diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp index 3473997168..3e9112add8 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp @@ -36,8 +36,8 @@ using namespace psr; OTFResolver::OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, - LLVMBasedICFG &ICF, LLVMAliasInfoRef PT) - : Resolver(IRDB, TH), ICF(ICF), PT(PT) {} + LLVMAliasInfoRef PT) + : Resolver(IRDB, TH), PT(PT) {} void OTFResolver::preCall(const llvm::Instruction *Inst) {} @@ -60,7 +60,7 @@ void OTFResolver::handlePossibleTargets(const llvm::CallBase *CallSite, } // handle return value if (CalleeTarget->getReturnType()->isPointerTy()) { - for (const auto &ExitPoint : ICF.getExitPointsOf(CalleeTarget)) { + for (const auto &ExitPoint : psr::getAllExitPoints(CalleeTarget)) { // get the function's return value if (const auto *Ret = llvm::dyn_cast(ExitPoint)) { // introduce alias to the returned value diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp index 2f0b883e1c..817f9a209c 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp @@ -99,8 +99,6 @@ void RTAResolver::resolveAllocatedStructTypes() { } llvm::DenseSet AllocatedStructTypes; - const llvm::StringSet<> MemAllocatingFunctions = {"_Znwm", "_Znam", "malloc", - "calloc", "realloc"}; for (const auto *Fun : IRDB.getAllFunctions()) { for (const auto &Inst : llvm::instructions(Fun)) { @@ -114,8 +112,7 @@ void RTAResolver::resolveAllocatedStructTypes() { // check if an instance of a user-defined type is allocated on the // heap - if (!MemAllocatingFunctions.contains( - CallSite->getCalledFunction()->getName())) { + if (!isHeapAllocatingFunction(CallSite->getCalledFunction())) { continue; } /// TODO: Does this iteration over the users make sense? diff --git a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp index fbb08a957a..0beb6d1747 100644 --- a/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp +++ b/lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp @@ -145,7 +145,7 @@ auto Resolver::resolveFunctionPointer(const llvm::CallBase *CallSite) FunctionSetTy CalleeTargets; for (const auto *F : IRDB.getAllFunctions()) { - if (isConsistentCall(CallSite, F)) { + if (F->hasAddressTaken() && isConsistentCall(CallSite, F)) { CalleeTargets.insert(F); } } @@ -158,7 +158,6 @@ void Resolver::otherInst(const llvm::Instruction *Inst) {} std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH, - LLVMBasedICFG *ICF, LLVMAliasInfoRef PT) { assert(IRDB != nullptr); @@ -179,9 +178,8 @@ std::unique_ptr Resolver::create(CallGraphAnalysisType Ty, "The VTA callgraph algorithm is not implemented yet"); case CallGraphAnalysisType::OTF: assert(TH != nullptr); - assert(ICF != nullptr); assert(PT); - return std::make_unique(*IRDB, *TH, *ICF, PT); + return std::make_unique(*IRDB, *TH, PT); case CallGraphAnalysisType::Invalid: llvm::report_fatal_error("Invalid callgraph algorithm specified"); } From 04d214affd4463516ec7be844e1ac6ad1f7e1bc5 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Thu, 25 Apr 2024 18:14:59 +0200 Subject: [PATCH 3/4] Remove out-commented code + unnecessary includes --- lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index c9c6cbfaeb..eadc987db1 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -9,7 +9,6 @@ #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" -#include "phasar/Config/Configuration.h" #include "phasar/ControlFlow/CallGraph.h" #include "phasar/ControlFlow/CallGraphAnalysisType.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h" @@ -24,23 +23,18 @@ #include "phasar/Utils/MaybeUniquePtr.h" #include "phasar/Utils/PAMMMacros.h" #include "phasar/Utils/Soundness.h" -#include "phasar/Utils/TypeTraits.h" -#include "phasar/Utils/Utilities.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" #include "llvm/Support/ErrorHandling.h" -#include #include namespace psr { struct LLVMBasedICFG::Builder { LLVMProjectIRDB *IRDB = nullptr; - // LLVMAliasInfoRef PT{}; LLVMTypeHierarchy *TH{}; Resolver *Res = nullptr; CallGraphBuilder From aa206e30ce1ed81da3390935b9ae030285722e90 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel <52407375+fabianbs96@users.noreply.github.com> Date: Thu, 25 Apr 2024 18:53:53 +0200 Subject: [PATCH 4/4] Make the docker push pipeline work again --- utils/InstallAptDependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/InstallAptDependencies.sh b/utils/InstallAptDependencies.sh index f8d4f3a0ac..8dba455bc0 100755 --- a/utils/InstallAptDependencies.sh +++ b/utils/InstallAptDependencies.sh @@ -3,4 +3,4 @@ set -e sudo apt-get update sudo apt-get install git -y -sudo apt-get install zlib1g-dev python3 g++ ninja-build cmake -y +sudo apt-get install zlib1g-dev python3 python3-pip g++ ninja-build cmake -y