diff --git a/docs/README.dox b/docs/README.dox
index 6ae3b786c0..eb2643421b 100644
--- a/docs/README.dox
+++ b/docs/README.dox
@@ -16,7 +16,7 @@ PhASAR is primarily developed and maintained by the [Secure Software Engineering
PhASAR was initially developed by Philipp Dominik Schubert (@pdschubert)().
\b Currently, PhASAR is maintained by
-- Fabian Schiebel (@fabianbs96)(fabian.schiebel@iem.fraunhofer.de)
+- Fabian Schiebel (@fabianbs96)(fabian.schiebel@uni-paderborn.de)
- Sriteja Kummita (@sritejakv)
- Lucas Briese (@jusito)
- Martin Mory (@MMory)(martin.mory@upb.de)
diff --git a/include/phasar/PhasarLLVM/HelperAnalyses.h b/include/phasar/PhasarLLVM/HelperAnalyses.h
index ec75980e46..8f82b85d8e 100644
--- a/include/phasar/PhasarLLVM/HelperAnalyses.h
+++ b/include/phasar/PhasarLLVM/HelperAnalyses.h
@@ -63,6 +63,9 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions)
explicit HelperAnalyses(std::unique_ptr IRModule,
std::vector EntryPoints,
HelperAnalysisConfig Config = {});
+ explicit HelperAnalyses(std::unique_ptr IRDB,
+ std::vector EntryPoints,
+ HelperAnalysisConfig Config = {});
~HelperAnalyses() noexcept;
[[nodiscard]] LLVMProjectIRDB &getProjectIRDB();
@@ -76,6 +79,10 @@ class HelperAnalyses { // NOLINT(cppcoreguidelines-special-member-functions)
[[nodiscard]] const SCCDependencyGraph &getCGSCCCallers();
[[nodiscard]] const UsedGlobalsHolder &
getUsedGlobals();
+ [[nodiscard]] const std::vector &
+ getEntryPoints() const noexcept {
+ return EntryPoints;
+ }
private:
std::unique_ptr IRDB;
diff --git a/lib/PhasarLLVM/HelperAnalyses.cpp b/lib/PhasarLLVM/HelperAnalyses.cpp
index 2ade892838..88dc1c47bb 100644
--- a/lib/PhasarLLVM/HelperAnalyses.cpp
+++ b/lib/PhasarLLVM/HelperAnalyses.cpp
@@ -75,6 +75,12 @@ HelperAnalyses::HelperAnalyses(std::unique_ptr IRModule,
this->IRDB = std::make_unique(
std::move(IRModule), Config.PreprocessExistingModule);
}
+HelperAnalyses::HelperAnalyses(std::unique_ptr IRDB,
+ std::vector EntryPoints,
+ HelperAnalysisConfig Config)
+ : HelperAnalyses(std::string(), std::move(EntryPoints), std::move(Config)) {
+ this->IRDB = std::move(IRDB);
+}
HelperAnalyses::~HelperAnalyses() noexcept = default;
diff --git a/tools/phasar-cli/Controller/AnalysisController.cpp b/tools/phasar-cli/Controller/AnalysisController.cpp
index 1f6feb5657..7e3e6a224d 100644
--- a/tools/phasar-cli/Controller/AnalysisController.cpp
+++ b/tools/phasar-cli/Controller/AnalysisController.cpp
@@ -9,6 +9,8 @@
#include "AnalysisController.h"
+#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
+#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
#include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h"
#include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h"
#include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h"
@@ -22,7 +24,7 @@ void AnalysisController::emitRequestedHelperAnalysisResults() {
auto WithResultFileOrStdout = [&ResultDirectory = this->ResultDirectory](
const auto &FileName, auto Callback) {
if (!ResultDirectory.empty()) {
- if (auto OFS = openFileStream(ResultDirectory.string() + FileName)) {
+ if (auto OFS = openFileStream(ResultDirectory + llvm::Twine(FileName))) {
Callback(*OFS);
}
} else {
@@ -31,7 +33,7 @@ void AnalysisController::emitRequestedHelperAnalysisResults() {
};
auto EmitterOptions = this->EmitterOptions;
- auto &HA = *this->HA;
+ auto &HA = this->HA;
if (EmitterOptions & AnalysisControllerEmitterOptions::EmitIR) {
WithResultFileOrStdout("/psr-preprocess-ir.ll", [&HA](auto &OS) {
@@ -211,9 +213,9 @@ LLVMTaintConfig controller::makeTaintConfig(AnalysisController &Data) {
std::string AnalysisConfigPath =
!Data.AnalysisConfigs.empty() ? Data.AnalysisConfigs[0] : "";
return !AnalysisConfigPath.empty()
- ? LLVMTaintConfig(Data.HA->getProjectIRDB(),
+ ? LLVMTaintConfig(Data.HA.getProjectIRDB(),
parseTaintConfig(AnalysisConfigPath))
- : LLVMTaintConfig(Data.HA->getProjectIRDB());
+ : LLVMTaintConfig(Data.HA.getProjectIRDB());
}
} // namespace psr
diff --git a/tools/phasar-cli/Controller/AnalysisController.h b/tools/phasar-cli/Controller/AnalysisController.h
index b2757b0b8e..3faca34057 100644
--- a/tools/phasar-cli/Controller/AnalysisController.h
+++ b/tools/phasar-cli/Controller/AnalysisController.h
@@ -15,22 +15,22 @@
#include "phasar/PhasarLLVM/HelperAnalyses.h"
#include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h"
+#include "llvm/ADT/SmallString.h"
+
#include "AnalysisControllerEmitterOptions.h"
-#include
namespace psr {
struct AnalysisController {
- HelperAnalyses *HA{};
+ HelperAnalyses HA;
std::vector DataFlowAnalyses;
std::vector AnalysisConfigs;
- std::vector EntryPoints;
[[maybe_unused]] AnalysisStrategy Strategy{};
AnalysisControllerEmitterOptions EmitterOptions =
AnalysisControllerEmitterOptions::None;
IFDSIDESolverConfig SolverConfig{};
- std::string ProjectID = "default-phasar-project";
- std::filesystem::path ResultDirectory;
+ llvm::SmallString<128> ProjectID;
+ llvm::SmallString<128> ResultDirectory;
static constexpr bool
needsToEmitPTA(AnalysisControllerEmitterOptions EmitterOptions) {
@@ -41,6 +41,10 @@ struct AnalysisController {
void emitRequestedHelperAnalysisResults();
void run();
+
+ [[nodiscard]] const auto &getEntryPoints() const noexcept {
+ return HA.getEntryPoints();
+ }
};
} // namespace psr
diff --git a/tools/phasar-cli/Controller/AnalysisControllerInternal.h b/tools/phasar-cli/Controller/AnalysisControllerInternal.h
index 78a35898c0..c9f06c2f05 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerInternal.h
+++ b/tools/phasar-cli/Controller/AnalysisControllerInternal.h
@@ -10,12 +10,9 @@
#ifndef PHASAR_CONTROLLER_ANALYSISCONTROLLERINTERNAL_H
#define PHASAR_CONTROLLER_ANALYSISCONTROLLERINTERNAL_H
-#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
-#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
-#include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h"
+#include "phasar/ControlFlow/ICFG.h"
#include "phasar/PhasarLLVM/SimpleAnalysisConstructor.h"
#include "phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h"
-#include "phasar/Utils/ChronoUtils.h"
#include "phasar/Utils/IO.h"
#include "phasar/Utils/Timer.h"
@@ -79,8 +76,7 @@ static void emitRequestedDataFlowResults(AnalysisController &Data, T &Solver) {
const auto PrintResult = [&ResultDirectory](llvm::StringRef Suffix,
auto WithStream) {
if (!ResultDirectory.empty()) {
- if (auto OFS =
- openFileStream(llvm::Twine(ResultDirectory.string()) + Suffix)) {
+ if (auto OFS = openFileStream(ResultDirectory + Suffix)) {
WithStream(*OFS);
}
} else {
diff --git a/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h b/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h
index c986ccc01a..527cefcd9e 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h
+++ b/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h
@@ -46,7 +46,7 @@ static void executeIfdsIdeAnalysisImpl(SolverTy &Solver,
template
static void executeSparseIfdsIdeAnalysis(AnalysisController &Data,
ArgTys &&...Args) {
- SparseLLVMBasedICFGView SVFG(&Data.HA->getICFG(), Data.HA->getAliasInfo());
+ SparseLLVMBasedICFGView SVFG(&Data.HA.getICFG(), Data.HA.getAliasInfo());
executeIfdsIdeAnalysisImpl(
Data, SVFG, std::forward(Args)...);
}
@@ -56,7 +56,7 @@ static void executeIFDSAnalysisWithICFG(AnalysisController &Data,
const ICFG auto &ICF,
ArgTys &&...Args) {
auto Problem =
- createAnalysisProblem(*Data.HA, std::forward(Args)...);
+ createAnalysisProblem(Data.HA, std::forward(Args)...);
IFDSSolver Solver(&Problem, &ICF);
executeIfdsIdeAnalysisImpl(Solver, Data);
}
@@ -64,34 +64,34 @@ template
static void executeIDEAnalysisWithICFG(AnalysisController &Data,
const ICFG auto &ICF, ArgTys &&...Args) {
auto Problem =
- createAnalysisProblem(*Data.HA, std::forward(Args)...);
+ createAnalysisProblem(Data.HA, std::forward(Args)...);
IDESolver Solver(&Problem, &ICF);
executeIfdsIdeAnalysisImpl(Solver, Data);
}
template
static void executeIFDSAnalysis(AnalysisController &Data, ArgTys &&...Args) {
- executeIFDSAnalysisWithICFG(Data, Data.HA->getICFG(),
+ executeIFDSAnalysisWithICFG(Data, Data.HA.getICFG(),
PSR_FWD(Args)...);
}
template
static void executeSparseIFDSAnalysis(AnalysisController &Data,
ArgTys &&...Args) {
- SparseLLVMBasedICFGView SVFG(&Data.HA->getICFG(), Data.HA->getAliasInfo());
+ SparseLLVMBasedICFGView SVFG(&Data.HA.getICFG(), Data.HA.getAliasInfo());
executeIFDSAnalysisWithICFG(Data, SVFG, PSR_FWD(Args)...);
}
template
static void executeIDEAnalysis(AnalysisController &Data, ArgTys &&...Args) {
- executeIDEAnalysisWithICFG(Data, Data.HA->getICFG(),
+ executeIDEAnalysisWithICFG(Data, Data.HA.getICFG(),
PSR_FWD(Args)...);
}
template
static void executeSparseIDEAnalysis(AnalysisController &Data,
ArgTys &&...Args) {
- SparseLLVMBasedICFGView SVFG(&Data.HA->getICFG(), Data.HA->getAliasInfo());
+ SparseLLVMBasedICFGView SVFG(&Data.HA.getICFG(), Data.HA.getAliasInfo());
executeIDEAnalysisWithICFG(Data, SVFG, PSR_FWD(Args)...);
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h b/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h
index 8bd649ca75..7b2a1334fc 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h
+++ b/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h
@@ -20,7 +20,7 @@ namespace psr::controller {
template
static void executeMonoAnalysis(AnalysisController &Data, ArgTys &&...Args) {
auto Problem =
- createAnalysisProblem(*Data.HA, std::forward(Args)...);
+ createAnalysisProblem(Data.HA, std::forward(Args)...);
SolverTy Solver(Problem);
Solver.solve();
emitRequestedDataFlowResults(Data, Solver);
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp
index 11f81a3498..ac485154c9 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp
@@ -17,5 +17,5 @@ using namespace psr;
void controller::executeIDECSTDIOTS(AnalysisController &Data) {
CSTDFILEIOTypeStateDescription TSDesc;
executeIDEAnalysis>(
- Data, &TSDesc, Data.EntryPoints);
+ Data, &TSDesc, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDEFIIA.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEFIIA.cpp
index 6bc04e31aa..8177577ad8 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDEFIIA.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEFIIA.cpp
@@ -39,6 +39,6 @@ void controller::executeIDEFIIA(AnalysisController &Data) {
Current);
};
- executeIDEAnalysis(Data, Data.EntryPoints,
+ executeIDEAnalysis(Data, Data.getEntryPoints(),
Generator);
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp
index e16390901a..8e5dc741e7 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp
@@ -39,6 +39,6 @@ void controller::executeIDEIIA(AnalysisController &Data) {
Current);
};
- executeIDEAnalysis(Data, Data.EntryPoints,
+ executeIDEAnalysis(Data, Data.getEntryPoints(),
Generator);
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp
index fc4e95ef56..f9d146d64f 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIDELinearConst(AnalysisController &Data) {
- executeIDEAnalysis(Data, Data.EntryPoints);
+ executeIDEAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp
index 9f65b2082a..fc1716bb46 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp
@@ -17,5 +17,5 @@ using namespace psr;
void controller::executeIDEOpenSSLTS(AnalysisController &Data) {
OpenSSLEVPKDFDescription TSDesc;
executeIDEAnalysis>(
- Data, &TSDesc, Data.EntryPoints);
+ Data, &TSDesc, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp
index baa3a27d25..07ba5b816d 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIDESolverTest(AnalysisController &Data) {
- executeIDEAnalysis(Data, Data.EntryPoints);
+ executeIDEAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp
index dc03bda7f0..7106b1c7b4 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp
@@ -16,5 +16,5 @@ using namespace psr;
void controller::executeIDEXTaint(AnalysisController &Data) {
auto Config = makeTaintConfig(Data);
executeIDEAnalysis>(Data, Config,
- Data.EntryPoints);
+ Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSCFLEnvTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSCFLEnvTaint.cpp
index c4ed6a7cf8..a320f2feff 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSCFLEnvTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSCFLEnvTaint.cpp
@@ -25,12 +25,12 @@ void controller::executeIFDSCFLEnvTaint(AnalysisController &Data) {
auto Config = makeTaintConfig(Data);
auto UserProblem = createAnalysisProblem(
- *Data.HA, &Config, Data.EntryPoints, /*TaintMainArgs*/ false,
+ Data.HA, &Config, Data.getEntryPoints(), /*TaintMainArgs*/ false,
/*EnableStrongUpdateStore*/ false);
auto Printer = UserProblem.consumePrinter();
auto FieldSensProblem = CFLFieldSensIFDSProblem(&UserProblem);
- IterativeIDESolver Solver(&FieldSensProblem, &Data.HA->getICFG());
+ IterativeIDESolver Solver(&FieldSensProblem, &Data.HA.getICFG());
SimpleTimer MeasureTime;
@@ -52,7 +52,7 @@ void controller::executeIFDSCFLEnvTaint(AnalysisController &Data) {
HasResultsDir = !Data.ResultDirectory.empty()](
const llvm::Twine &FileName, auto Handler) {
if (HasResultsDir) {
- if (auto OFS = openFileStream(Data.ResultDirectory.string() + FileName)) {
+ if (auto OFS = openFileStream(Data.ResultDirectory + FileName)) {
Handler(*OFS);
}
} else {
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp
index 55a3600d45..733e62a848 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIFDSConst(AnalysisController &Data) {
- executeIFDSAnalysis(Data, Data.EntryPoints);
+ executeIFDSAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp
index c8b37c5746..847740b632 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIFDSSolverTest(AnalysisController &Data) {
- executeIFDSAnalysis(Data, Data.EntryPoints);
+ executeIFDSAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp
index 9d91efd7d0..66898a4530 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp
@@ -17,6 +17,6 @@ void controller::executeIFDSTaint(AnalysisController &Data) {
auto Config = makeTaintConfig(Data);
// Note: Don't blindly generate argc and argv. Use a proper taint config
// instead
- executeIFDSAnalysis(Data, &Config, Data.EntryPoints,
+ executeIFDSAnalysis(Data, &Config, Data.getEntryPoints(),
false);
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp
index 8c8410e996..89e7b76586 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIFDSType(AnalysisController &Data) {
- executeIFDSAnalysis(Data, Data.EntryPoints);
+ executeIFDSAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp
index 7e47898081..1e111f96bf 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIFDSUninitVar(AnalysisController &Data) {
- executeIFDSAnalysis(Data, Data.EntryPoints);
+ executeIFDSAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp
index 3b2b8e78a7..d1d0a7f02f 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeInterMonoSolverTest(AnalysisController &Data) {
- executeInterMonoAnalysis(Data, Data.EntryPoints);
+ executeInterMonoAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp
index dbbb19d2aa..946f809de3 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp
@@ -16,5 +16,5 @@ using namespace psr;
void controller::executeInterMonoTaint(AnalysisController &Data) {
auto Config = makeTaintConfig(Data);
executeInterMonoAnalysis(Data, Config,
- Data.EntryPoints);
+ Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp
index 8c17bbb9ff..7e8f714617 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp
@@ -14,6 +14,6 @@
using namespace psr;
void controller::executeIntraMonoFullConstant(AnalysisController &Data) {
- executeIntraMonoAnalysis(Data,
- Data.EntryPoints);
+ executeIntraMonoAnalysis(
+ Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp
index c1043a6f1a..a4f143197f 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp
@@ -14,5 +14,5 @@
using namespace psr;
void controller::executeIntraMonoSolverTest(AnalysisController &Data) {
- executeIntraMonoAnalysis(Data, Data.EntryPoints);
+ executeIntraMonoAnalysis(Data, Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXMonoIFDSTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXMonoIFDSTaint.cpp
index 52d5138ead..eb170f7a93 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXMonoIFDSTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXMonoIFDSTaint.cpp
@@ -8,6 +8,7 @@
*****************************************************************************/
#include "phasar/DataFlow/MonoIfds/MonoIFDSSolver.h"
+#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
#include "phasar/PhasarLLVM/DataFlow/MonoIfds/Problems/MonoIFDSTaintAnalysis.h"
#include "phasar/PhasarLLVM/Pointer/FilteredLLVMAliasIterator.h"
@@ -18,17 +19,17 @@ using namespace psr;
void controller::executeMonoIFDSTaint(AnalysisController &Data) {
- FilteredLLVMAliasIterator FAI(Data.HA->getAliasInfo());
+ FilteredLLVMAliasIterator FAI(Data.HA.getAliasInfo());
auto Config = makeTaintConfig(Data);
- monoifds::TaintAnalysis TA(&Config, &Data.HA->getUsedGlobals(), &FAI);
+ monoifds::TaintAnalysis TA(&Config, &Data.HA.getUsedGlobals(), &FAI);
// monoifds::MonoIFDSSolver Solver(&TA, &Data.HA->getICFG());
// Solver //
// .setCGSCCs(&Data.HA->getCGSCCs())
// .setFunctionCompressor(&Data.HA->getCompressedFunctions());
- monoifds::MonoIFDSSolver Solver(&TA, *Data.HA);
+ monoifds::MonoIFDSSolver Solver(&TA, Data.HA);
{
std::optional MeasureTime;
diff --git a/tools/phasar-cli/Controller/AnalysisControllerXSparseIFDSTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXSparseIFDSTaint.cpp
index 4d3b8623b8..17097b8e30 100644
--- a/tools/phasar-cli/Controller/AnalysisControllerXSparseIFDSTaint.cpp
+++ b/tools/phasar-cli/Controller/AnalysisControllerXSparseIFDSTaint.cpp
@@ -15,5 +15,6 @@ using namespace psr;
void controller::executeSparseIFDSTaint(AnalysisController &Data) {
auto Config = makeTaintConfig(Data);
- executeSparseIFDSAnalysis(Data, &Config, Data.EntryPoints);
+ executeSparseIFDSAnalysis(Data, &Config,
+ Data.getEntryPoints());
}
diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp
index e5d5e90d6e..23a2b649c0 100644
--- a/tools/phasar-cli/phasar-cli.cpp
+++ b/tools/phasar-cli/phasar-cli.cpp
@@ -11,26 +11,33 @@
#include "phasar/Config/Configuration.h"
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/CallGraphData.h"
+#include "phasar/PhasarLLVM/ControlFlow/EntryFunctionUtils.h"
+#include "phasar/PhasarLLVM/ControlFlow/ExternCallbackModel.h"
+#include "phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h"
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
#include "phasar/PhasarLLVM/HelperAnalyses.h"
-#include "phasar/PhasarLLVM/HelperAnalysisConfig.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSetData.h"
#include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h"
#include "phasar/Pointer/AliasAnalysisType.h"
#include "phasar/Pointer/UnionFindAliasAnalysisType.h"
#include "phasar/Utils/InitPhasar.h"
+#include "phasar/Utils/Lazy.h"
#include "phasar/Utils/Logger.h"
#include "phasar/Utils/Soundness.h"
#include "phasar/Utils/Utilities.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/WithColor.h"
#include "Controller/AnalysisController.h"
#include "Controller/AnalysisControllerEmitterOptions.h"
#include
-#include
#include
#include
#include
@@ -70,7 +77,7 @@ cl::alias QuietAlias("quiet", cl::aliasopt(SilentOpt),
cl::desc("Alias for --silent"), cl::cat(PsrCat));
PSR_SHORTLONG_OPTION(ModuleOpt, std::string, "m", "module",
- "Path to the LLVM IR module under analysis");
+ "Path to the LLVM IR module under analysis", cl::Required);
PSR_SHORTLONG_OPTION_TYPE(
EntryOpt, cl::list, "E", "entry-points",
@@ -156,6 +163,12 @@ PSR_OPTION_FLAG(AutoGlobalsOpt, "auto-globals",
"Enable automated support for global initializers",
cl::init(true));
+PSR_OPTION_FLAG(ExternalCallsRewriteOpt, "rewrite-external-calls",
+ "Whether to rewrite calls-to known external functions, such as "
+ "pthread_create, s.t., their callback calls are not lost in "
+ "the call-graph",
+ cl::init(true));
+
PSR_SHORTLONG_OPTION(
StatisticsOpt, bool, "S", "emit-stats",
"Collect and emit statistics of the module(s) under analysis");
@@ -262,140 +275,74 @@ PSR_SHORTLONG_OPTION(PammOutOpt, std::string, "A", "pamm-out",
"Filename for PAMM's gathered data",
cl::init("PAMM_data.json"), cl::cat(PsrCat), cl::Hidden);
-// void validateParamConfigFile(const std::string &Config) {
-// if (!(std::filesystem::exists(Config) &&
-// !std::filesystem::is_directory(Config))) {
-// llvm::errs() << "PhASAR configuration '" << Config << "' does not
-// exist!\n"; exit(1);
-// }
-// }
-
void validateParamModule() {
- if (ModuleOpt.empty()) {
- llvm::errs() << "At least one LLVM target module is required!\n";
- exit(1);
- }
-
- std::filesystem::path ModulePath(ModuleOpt.getValue());
- if (!(std::filesystem::exists(ModulePath) &&
- !std::filesystem::is_directory(ModulePath) &&
- (ModulePath.extension() == ".ll" || ModulePath.extension() == ".bc"))) {
- llvm::errs() << "LLVM module '" << std::filesystem::canonical(ModulePath)
- << "' does not exist!\n";
+ if (!(llvm::sys::fs::exists(ModuleOpt) &&
+ !llvm::sys::fs::is_directory(ModuleOpt) &&
+ (llvm::is_contained(llvm::ArrayRef{".bc", ".ll"},
+ llvm::sys::path::extension(ModuleOpt))))) {
+ llvm::SmallString<256> RealModPath;
+ auto EC = llvm::sys::fs::real_path(ModuleOpt, RealModPath);
+ llvm::WithColor::error()
+ << "LLVM module '" << (EC ? ModuleOpt.getValue() : RealModPath.str())
+ << "' does not exist!\n";
exit(1);
}
}
void validateParamOutput() {
if (!OutDirOpt.empty() &&
- !std::filesystem::is_directory(OutDirOpt.getValue())) {
- llvm::errs() << '\'' << OutDirOpt
- << "' does not exist, a valid output directory is required!\n";
- exit(1);
- }
-}
-
-void validateParamPointerAnalysis() {
- if (AliasTypeOpt == AliasAnalysisType::Invalid) {
- llvm::errs() << "'Invalid' is not a valid pointer analysis!\n";
- exit(1);
- }
-}
-
-void validateParamCallGraphAnalysis() {
- if (CGTypeOpt == CallGraphAnalysisType::Invalid) {
- llvm::errs() << "'Invalid' is not a valid call-graph analysis!\n";
- exit(1);
- }
-}
-
-void validateSoundnessFlag() {
- if (SoundnessOpt == Soundness::Invalid) {
- llvm::errs() << "'Invalid' is not a valid soundness level!\n";
+ !llvm::sys::fs::is_directory(OutDirOpt.getValue())) {
+ llvm::WithColor::error()
+ << '\'' << OutDirOpt
+ << "' does not exist, a valid output directory is required!\n";
exit(1);
}
}
void validateParamAnalysisConfig() {
if (!AnalysisConfigOpt.empty() &&
- !(std::filesystem::exists(AnalysisConfigOpt.getValue()) &&
- !std::filesystem::is_directory(AnalysisConfigOpt.getValue()))) {
- llvm::errs() << "Analysis configuration '" << AnalysisConfigOpt
- << "' does not exist!\n";
+ !(llvm::sys::fs::exists(AnalysisConfigOpt.getValue()) &&
+ !llvm::sys::fs::is_directory(AnalysisConfigOpt.getValue()))) {
+ llvm::WithColor::error() << "Analysis configuration '" << AnalysisConfigOpt
+ << "' does not exist!\n";
exit(1);
}
}
void validatePTAJsonFile() {
if (!LoadPTAFromJsonOpt.empty() &&
- !(std::filesystem::exists(LoadPTAFromJsonOpt.getValue()) &&
- !std::filesystem::is_directory(LoadPTAFromJsonOpt.getValue()))) {
- llvm::errs() << "Points-to info file '" << LoadPTAFromJsonOpt
- << "' does not exist!\n";
+ !(llvm::sys::fs::exists(LoadPTAFromJsonOpt.getValue()) &&
+ !llvm::sys::fs::is_directory(LoadPTAFromJsonOpt.getValue()))) {
+ llvm::WithColor::error() << "Points-to info file '" << LoadPTAFromJsonOpt
+ << "' does not exist!\n";
exit(1);
}
}
-} // anonymous namespace
-
-int main(int Argc, const char **Argv) {
- PSR_INITIALIZER(Argc, Argv);
-
- cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
- OS << "PhASAR " << PhasarConfig::PhasarVersion() << '\n';
- });
- cl::HideUnrelatedOptions(PsrCat);
- cl::ParseCommandLineOptions(Argc, Argv);
-
-#ifdef DYNAMIC_LOG
- if (LogSeverityOpt == SeverityLevel::INVALID) {
- llvm::errs() << "Invalid log-severity\n";
- return 1;
- }
- if (LogOpt) {
- Logger::initializeStderrLogger(LogSeverityOpt);
- } else if (!SilentOpt) {
- Logger::initializeStderrLogger(SeverityLevel::ERROR);
- }
- for (const auto &LogCat : LogCategoriesOpt) {
- Logger::initializeStderrLogger(LogSeverityOpt, LogCat);
- }
-#endif
-
- // Vanity header
- if (!SilentOpt) {
- llvm::outs() << "PhASAR " << PhasarConfig::PhasarVersion()
- << "\nA LLVM-based static analysis framework\n\n";
- }
-
- if (StrategyOpt == AnalysisStrategy::None) {
- llvm::errs() << "Invalid analysis strategy!\n";
- return 1;
- }
-
- if (ProjectIdOpt.empty()) {
- ProjectIdOpt = std::filesystem::path(ModuleOpt.getValue())
- .filename()
- .replace_extension();
- if (ProjectIdOpt.empty()) {
- ProjectIdOpt = "default-phasar-project";
+std::vector setupIRAndEntrypoints(LLVMProjectIRDB &IRDB) {
+ std::vector EntryPoints = std::move(EntryOpt);
+ if (EntryPoints.empty()) {
+ EntryPoints = getDefaultEntryPoints(IRDB);
+ }
+ if (AutoGlobalsOpt) {
+ if (EntryPoints.size() == 1 && EntryPoints.front() == "main") {
+ GlobalCtorsDtorsModel::buildModel(IRDB, EntryPoints);
+ EntryPoints = {GlobalCtorsDtorsModel::ModelName.str()};
+ } else if (AutoGlobalsOpt.getNumOccurrences() > 0) {
+ llvm::WithColor::warning()
+ << "'--auto-globals' is currently not supported for libraries, only "
+ "for applications with 'main' as entry-point'\n";
}
}
+ if (ExternalCallsRewriteOpt) {
+ ExternCallbackModel::rewriteCalls(IRDB);
+ }
+ return EntryPoints;
+}
- validateParamModule();
- validateParamOutput();
- validateParamPointerAnalysis();
- validateParamCallGraphAnalysis();
- validateSoundnessFlag();
- validateParamAnalysisConfig();
- validatePTAJsonFile();
-
- [[maybe_unused]] auto &PConfig = PhasarConfig::getPhasarConfig();
-
- // setup the emitter options to display the computed analysis results
+[[nodiscard]] AnalysisControllerEmitterOptions setupEmitterOptions() {
auto EmitterOptions = AnalysisControllerEmitterOptions::None;
- IFDSIDESolverConfig SolverConfig{};
if (EmitIROpt) {
EmitterOptions |= AnalysisControllerEmitterOptions::EmitIR;
}
@@ -427,10 +374,11 @@ int main(int Argc, const char **Argv) {
EmitterOptions |= AnalysisControllerEmitterOptions::EmitCGAsJson;
}
if (EmitCGAsTextOpt) {
- llvm::errs()
- << "ERROR: emit-cg-as-text is currently not supported. Did you mean "
- "emit-cg-as-dot? For reversible serialization use emit-cg-as-json\n";
- return 1;
+ llvm::WithColor::error()
+ << "'--emit-cg-as-text' is currently not supported. Did you mean "
+ "'--emit-cg-as-dot'? For reversible serialization use "
+ "'--emit-cg-as-json'\n";
+ exit(1);
}
if (EmitPTAAsTextOpt) {
EmitterOptions |= AnalysisControllerEmitterOptions::EmitPTAAsText;
@@ -447,13 +395,57 @@ int main(int Argc, const char **Argv) {
if (EmitStatsAsJsonOpt) {
EmitterOptions |= AnalysisControllerEmitterOptions::EmitStatisticsAsJson;
}
+ return EmitterOptions;
+}
+[[nodiscard]] IFDSIDESolverConfig setupSolverConfig() {
+ IFDSIDESolverConfig SolverConfig{};
SolverConfig.setFollowReturnsPastSeeds(FollowReturnPastSeedsOpt);
SolverConfig.setAutoAddZero(AutoAddZeroOpt);
SolverConfig.setComputeValues(ComputeValuesOpt);
SolverConfig.setRecordEdges(RecordEdgesOpt || EmitESGAsDotOpt);
SolverConfig.setComputePersistedSummaries(PersistedSummariesOpt);
SolverConfig.setEmitESG(EmitESGAsDotOpt);
+ return SolverConfig;
+}
+
+} // anonymous namespace
+
+int main(int Argc, const char **Argv) {
+ PSR_INITIALIZER(Argc, Argv);
+
+ cl::SetVersionPrinter([](llvm::raw_ostream &OS) {
+ OS << "PhASAR " << PhasarConfig::PhasarVersion() << '\n';
+ });
+ cl::HideUnrelatedOptions(PsrCat);
+ cl::ParseCommandLineOptions(Argc, Argv);
+
+#ifdef DYNAMIC_LOG
+ if (LogOpt) {
+ Logger::initializeStderrLogger(LogSeverityOpt);
+ } else if (!SilentOpt) {
+ Logger::initializeStderrLogger(SeverityLevel::ERROR);
+ }
+ for (const auto &LogCat : LogCategoriesOpt) {
+ Logger::initializeStderrLogger(LogSeverityOpt, LogCat);
+ }
+#endif
+
+ // Vanity header
+ if (!SilentOpt) {
+ llvm::outs() << "PhASAR " << PhasarConfig::PhasarVersion()
+ << "\nA LLVM-based static analysis framework\n\n";
+ }
+
+ validateParamModule();
+ validateParamOutput();
+ validateParamAnalysisConfig();
+ validatePTAJsonFile();
+
+ [[maybe_unused]] auto &PConfig = PhasarConfig::getPhasarConfig();
+
+ // setup the emitter options to display the computed analysis results
+ auto EmitterOptions = setupEmitterOptions();
std::optional PrecomputedAliasSet;
if (!LoadPTAFromJsonOpt.empty()) {
@@ -467,43 +459,54 @@ int main(int Argc, const char **Argv) {
PrecomputedCallGraph = CallGraphData::deserializeJson(LoadCGFromJsonOpt);
}
- if (EntryOpt.empty()) {
- EntryOpt.push_back("main");
+ auto IRDB = std::make_unique(
+ PSR_LAZY(LLVMProjectIRDB::loadOrExit(ModuleOpt)));
+
+ auto EntryPoints = setupIRAndEntrypoints(*IRDB);
+
+ llvm::SmallString<128> ProjectId(llvm::sys::path::filename(ProjectIdOpt));
+ if (ProjectId.empty()) {
+ llvm::sys::path::replace_extension(ProjectId, {});
+ if (ProjectId.empty()) {
+ ProjectId = "default-phasar-project";
+ }
}
- HelperAnalysisConfig HAConfig{
- .PrecomputedCG = std::move(PrecomputedCallGraph),
- .PTATy = AliasTypeOpt,
- .UFAATy = UFAliasTypeOpt,
- .CGTy = CGTypeOpt,
- .SoundnessLevel = SoundnessOpt,
- .AutoGlobalSupport = AutoGlobalsOpt,
- .AllowLazyPTS = !AnalysisController::needsToEmitPTA(EmitterOptions),
- };
- HelperAnalyses HA(std::move(ModuleOpt.getValue()), EntryOpt,
- std::move(HAConfig));
- if (!HA.getProjectIRDB().isValid()) {
- // Note: Error message has already been printed
- return 1;
+ // create directory for results
+ llvm::SmallString<128> OutDir(OutDirOpt);
+ if (!OutDir.empty()) {
+ llvm::sys::path::append(OutDir,
+ ProjectId + llvm::Twine("-") + createTimeStamp());
+ auto EC = llvm::sys::fs::create_directory(OutDir);
+ if (EC) {
+ llvm::WithColor::error() << EC.message() << '\n';
+ return 1;
+ }
}
AnalysisController Controller{
- .HA = &HA,
+ .HA = HelperAnalyses(
+ std::move(IRDB), std::move(EntryPoints),
+ {
+ .PrecomputedPTS = std::move(PrecomputedAliasSet),
+ .PrecomputedCG = std::move(PrecomputedCallGraph),
+ .PTATy = AliasTypeOpt,
+ .UFAATy = UFAliasTypeOpt,
+ .CGTy = CGTypeOpt,
+ .SoundnessLevel = SoundnessOpt,
+ .AutoGlobalSupport =
+ false, // already handled in setupIRAndEntrypoints()
+ .AllowLazyPTS =
+ !AnalysisController::needsToEmitPTA(EmitterOptions),
+ }),
.DataFlowAnalyses = DataFlowAnalysisOpt,
.AnalysisConfigs = {AnalysisConfigOpt.getValue()},
- .EntryPoints = EntryOpt,
.Strategy = StrategyOpt,
.EmitterOptions = EmitterOptions,
- .SolverConfig = SolverConfig,
- .ProjectID = ProjectIdOpt.getValue(),
- .ResultDirectory = OutDirOpt.getValue(),
+ .SolverConfig = setupSolverConfig(),
+ .ProjectID = std::move(ProjectId),
+ .ResultDirectory = std::move(OutDir),
};
- if (!OutDirOpt.empty()) {
- // create directory for results
- Controller.ResultDirectory /=
- Controller.ProjectID + "-" + createTimeStamp();
- std::filesystem::create_directory(Controller.ResultDirectory);
- }
Controller.emitRequestedHelperAnalysisResults();
Controller.run();