diff --git a/BreakingChanges.md b/BreakingChanges.md index 2afe3d276..f9b008ecf 100644 --- a/BreakingChanges.md +++ b/BreakingChanges.md @@ -4,6 +4,7 @@ - The `DTAResolver` and the cli option `--call-graph-analysis=dta` do not work anymore (due to opaque pointers) and will be removed for the next release. Please use the `OTF` or `RTA` resolver instead. - The default type-hierarchy implementation has been changed from `LLVMTypeHierarchy` to `DIBasedTypeHierarchy`. This also requires all affected analyses to be performed on LLVM IR that contains debug information. +- Removed the phasar-library `phasar_controller`. It is now part of the tool `phasar-cli`. - The API of the `TypeHierarchy` interface (and thus the `LLVMTypeHierarchy` and `DIBasedTypeHierarchy` as well) has changed: - No handling of the super-type relation (only sub-types) - No VTable handling anymore -- has been out-sourced into `LLVMVFTableProvider` diff --git a/Config.cmake.in b/Config.cmake.in index f160d869b..adc1a9a6c 100644 --- a/Config.cmake.in +++ b/Config.cmake.in @@ -37,7 +37,6 @@ set(PHASAR_COMPONENTS llvm llvm_ifdside analysis_strategy - controller ) list(REMOVE_DUPLICATES phasar_FIND_COMPONENTS) diff --git a/include/phasar.h b/include/phasar.h index 0444cf20f..397cbba0f 100644 --- a/include/phasar.h +++ b/include/phasar.h @@ -13,7 +13,6 @@ #include "phasar/AnalysisStrategy.h" #include "phasar/Config.h" #include "phasar/ControlFlow.h" -#include "phasar/Controller.h" #include "phasar/DB.h" #include "phasar/DataFlow.h" #include "phasar/Domain.h" diff --git a/include/phasar/Controller.h b/include/phasar/Controller.h deleted file mode 100644 index 92d4c2202..000000000 --- a/include/phasar/Controller.h +++ /dev/null @@ -1,16 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2023 Fabian Schiebel. - * All rights reserved. This program and the accompanying materials are made - * available under the terms of LICENSE.txt. - * - * Contributors: - * Fabian Schiebel and others - *****************************************************************************/ - -#ifndef PHASAR_CONTROLLER_H -#define PHASAR_CONTROLLER_H - -#include "phasar/Controller/AnalysisController.h" -#include "phasar/Controller/AnalysisControllerEmitterOptions.h" - -#endif // PHASAR_CONTROLLER_H diff --git a/include/phasar/Utils/InitPhasar.h b/include/phasar/Utils/InitPhasar.h new file mode 100644 index 000000000..57bb37e5a --- /dev/null +++ b/include/phasar/Utils/InitPhasar.h @@ -0,0 +1,22 @@ +/****************************************************************************** + * Copyright (c) 2024 Fabian Schiebel. + * All rights reserved. This program and the accompanying materials are made + * available under the terms of LICENSE.txt. + * + * Contributors: + * Fabian Schiebel and others + *****************************************************************************/ + +#include "llvm/Support/InitLLVM.h" + +namespace psr { +class InitPhasar : llvm::InitLLVM { +public: + InitPhasar(int &Argc, const char **&Argv) noexcept; + InitPhasar(int &Argc, char **&Argv) noexcept + : InitPhasar(Argc, (const char **&)Argv) {} +}; +} // namespace psr + +#define PSR_INITIALIZER(argc, argv) \ + const ::psr::InitPhasar PsrInitializerVar((argc), (argv)) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 3c2ab5fdf..86d4c048d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,7 +4,6 @@ add_subdirectory(PhasarPass) add_subdirectory(DB) add_subdirectory(Config) add_subdirectory(Utils) -add_subdirectory(Controller) add_subdirectory(Pointer) add_subdirectory(ControlFlow) if(BUILD_PHASAR_CLANG) @@ -36,7 +35,6 @@ set(PHASAR_LINK_LIBS phasar_llvm phasar_llvm_ifdside phasar_analysis_strategy - phasar_controller ) if(SQLite3_FOUND) list(APPEND PHASAR_LINK_LIBS phasar_db) diff --git a/lib/Controller/CMakeLists.txt b/lib/Controller/CMakeLists.txt deleted file mode 100644 index b5fe95c5b..000000000 --- a/lib/Controller/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -file(GLOB_RECURSE CONTROLLER_SRC *.h *.cpp) - -add_phasar_library(phasar_controller - FILES - ${CONTROLLER_SRC} - - LINKS - phasar_llvm_ifdside - phasar_mono - phasar_llvm_db - phasar_llvm_pointer - phasar_llvm_typehierarchy - phasar_llvm_controlflow - phasar_llvm_utils - phasar_utils - phasar_analysis_strategy - phasar_taintconfig - phasar_passes - - LLVM_LINK_COMPONENTS - Core - Support - Demangle - - LINK_PRIVATE - ${PHASAR_STD_FILESYSTEM} -) diff --git a/lib/Utils/InitPhasar.cpp b/lib/Utils/InitPhasar.cpp new file mode 100644 index 000000000..fc58a8458 --- /dev/null +++ b/lib/Utils/InitPhasar.cpp @@ -0,0 +1,45 @@ +#include "phasar/Utils/InitPhasar.h" + +#include "phasar/Utils/Logger.h" + +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/raw_ostream.h" + +using namespace psr; + +#define PSR_ISSUE_TRACKER_URL \ + "https://github.com/secure-software-engineering/phasar/issues" + +InitPhasar::InitPhasar(int &Argc, const char **&Argv) noexcept + : llvm::InitLLVM(Argc, Argv) { + static std::nullptr_t InitGlobals = [] { + // Replace LLVM's bug report URL with ours + llvm::setBugReportMsg("PLEASE create a bug report at " PSR_ISSUE_TRACKER_URL + " and include the crash backtrace.\n "); + + // Install custom error handlers, such that fatal errors do not start with + // "LLVM ERROR" + auto FatalErrorHandler = [](void * /*HandlerData*/, const char *Reason, + bool /*GenCrashDiag*/) { + // Prevent recursion in case our error handler itself fails + llvm::remove_fatal_error_handler(); + llvm::remove_bad_alloc_error_handler(); + + // Write the actual error message + Logger::addLinePrefix(llvm::errs(), SeverityLevel::CRITICAL, + std::nullopt); + llvm::errs() << Reason << '\n'; + llvm::errs().flush(); + }; + + // NOTE: Install the bad_alloc handler before the fatal_error handler due to + // a bug in LLVM + // https://github.com/llvm/llvm-project/issues/83040 + llvm::install_bad_alloc_error_handler(FatalErrorHandler, nullptr); + llvm::install_fatal_error_handler(FatalErrorHandler, nullptr); + // llvm::install_out_of_memory_new_handler() is already done by InitLLVM + return nullptr; + }(); + (void)InitGlobals; +} diff --git a/tools/phasar-cli/CMakeLists.txt b/tools/phasar-cli/CMakeLists.txt index a8276c347..f25ce28f7 100644 --- a/tools/phasar-cli/CMakeLists.txt +++ b/tools/phasar-cli/CMakeLists.txt @@ -20,38 +20,14 @@ else() ) endif() -# Warning! There is a another listing of libraries inside cmake/phasar_macros.cmake. -# If this list is altered the other one should be altered accordingly. +add_subdirectory(Controller) + target_link_libraries(phasar-cli PRIVATE - phasar_config - phasar_controller - phasar_llvm_controlflow - phasar_llvm_utils - phasar_analysis_strategy - phasar_llvm_ifdside - phasar_utils - phasar_mono - phasar_llvm_db - phasar_passes - phasar_llvm_pointer - phasar_llvm - phasar_llvm_typehierarchy - phasar_taintconfig - + phasar ${PHASAR_STD_FILESYSTEM} ) if (NOT PHASAR_IN_TREE) - if(USE_LLVM_FAT_LIB) - llvm_config(phasar-cli USE_SHARED ${LLVM_LINK_COMPONENTS}) - else() - llvm_config(phasar-cli ${LLVM_LINK_COMPONENTS}) - endif() - - install(TARGETS phasar-cli - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - ) + install(TARGETS phasar-cli) endif() diff --git a/lib/Controller/AnalysisController.cpp b/tools/phasar-cli/Controller/AnalysisController.cpp similarity index 76% rename from lib/Controller/AnalysisController.cpp rename to tools/phasar-cli/Controller/AnalysisController.cpp index 32922b2c9..a3013aa3e 100644 --- a/lib/Controller/AnalysisController.cpp +++ b/tools/phasar-cli/Controller/AnalysisController.cpp @@ -7,7 +7,7 @@ * Philipp Schubert and others *****************************************************************************/ -#include "phasar/Controller/AnalysisController.h" +#include "AnalysisController.h" #include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h" #include "phasar/PhasarLLVM/TypeHierarchy/DIBasedTypeHierarchy.h" @@ -17,9 +17,8 @@ namespace psr { -static void -emitRequestedHelperAnalysisResults(AnalysisController::ControllerData &Data) { - auto WithResultFileOrStdout = [&ResultDirectory = Data.ResultDirectory]( +void AnalysisController::emitRequestedHelperAnalysisResults() { + auto WithResultFileOrStdout = [&ResultDirectory = this->ResultDirectory]( const auto &FileName, auto Callback) { if (!ResultDirectory.empty()) { if (auto OFS = openFileStream(ResultDirectory.string() + FileName)) { @@ -30,8 +29,8 @@ emitRequestedHelperAnalysisResults(AnalysisController::ControllerData &Data) { } }; - auto EmitterOptions = Data.EmitterOptions; - auto &HA = *Data.HA; + auto EmitterOptions = this->EmitterOptions; + auto &HA = *this->HA; if (EmitterOptions & AnalysisControllerEmitterOptions::EmitIR) { WithResultFileOrStdout("/psr-preprocess-ir.ll", [&HA](auto &OS) { @@ -96,24 +95,24 @@ emitRequestedHelperAnalysisResults(AnalysisController::ControllerData &Data) { } } -static void executeDemandDriven(AnalysisController::ControllerData & /*Data*/) { +static void executeDemandDriven(AnalysisController & /*Data*/) { llvm::report_fatal_error( "AnalysisStrategy 'demand-driven' not supported, yet!"); } -static void executeIncremental(AnalysisController::ControllerData & /*Data*/) { +static void executeIncremental(AnalysisController & /*Data*/) { llvm::report_fatal_error( "AnalysisStrategy 'incremental' not supported, yet!"); } -static void executeModuleWise(AnalysisController::ControllerData & /*Data*/) { +static void executeModuleWise(AnalysisController & /*Data*/) { llvm::report_fatal_error( "AnalysisStrategy 'module-wise' not supported, yet!"); } -static void executeVariational(AnalysisController::ControllerData & /*Data*/) { +static void executeVariational(AnalysisController & /*Data*/) { llvm::report_fatal_error( "AnalysisStrategy 'variational' not supported, yet!"); } -static void executeWholeProgram(AnalysisController::ControllerData &Data) { +static void executeWholeProgram(AnalysisController &Data) { for (auto DataFlowAnalysis : Data.DataFlowAnalyses) { using namespace controller; switch (DataFlowAnalysis) { @@ -171,60 +170,31 @@ static void executeWholeProgram(AnalysisController::ControllerData &Data) { } } -static void executeAs(AnalysisController::ControllerData &Data, - AnalysisStrategy Strategy) { +void AnalysisController::run() { switch (Strategy) { case AnalysisStrategy::None: return; case AnalysisStrategy::DemandDriven: - executeDemandDriven(Data); + executeDemandDriven(*this); return; case AnalysisStrategy::Incremental: - executeIncremental(Data); + executeIncremental(*this); return; case AnalysisStrategy::ModuleWise: - executeModuleWise(Data); + executeModuleWise(*this); return; case AnalysisStrategy::Variational: - executeVariational(Data); + executeVariational(*this); return; case AnalysisStrategy::WholeProgram: - executeWholeProgram(Data); + executeWholeProgram(*this); return; } llvm_unreachable( "All AnalysisStrategy variants should be handled in the switch above!"); } -AnalysisController::AnalysisController( - HelperAnalyses &HA, std::vector DataFlowAnalyses, - std::vector AnalysisConfigs, - std::vector EntryPoints, AnalysisStrategy Strategy, - AnalysisControllerEmitterOptions EmitterOptions, - IFDSIDESolverConfig SolverConfig, std::string ProjectID, - std::string OutDirectory) - : Data{ - &HA, - std::move(DataFlowAnalyses), - std::move(AnalysisConfigs), - std::move(EntryPoints), - Strategy, - EmitterOptions, - std::move(ProjectID), - std::move(OutDirectory), - SolverConfig, - } { - if (!Data.ResultDirectory.empty()) { - // create directory for results - Data.ResultDirectory /= Data.ProjectID + "-" + createTimeStamp(); - std::filesystem::create_directory(Data.ResultDirectory); - } - emitRequestedHelperAnalysisResults(Data); - executeAs(Data, Strategy); -} - -LLVMTaintConfig -controller::makeTaintConfig(AnalysisController::ControllerData &Data) { +LLVMTaintConfig controller::makeTaintConfig(AnalysisController &Data) { std::string AnalysisConfigPath = !Data.AnalysisConfigs.empty() ? Data.AnalysisConfigs[0] : ""; return !AnalysisConfigPath.empty() diff --git a/include/phasar/Controller/AnalysisController.h b/tools/phasar-cli/Controller/AnalysisController.h similarity index 51% rename from include/phasar/Controller/AnalysisController.h rename to tools/phasar-cli/Controller/AnalysisController.h index 7b9e132c4..b2757b0b8 100644 --- a/include/phasar/Controller/AnalysisController.h +++ b/tools/phasar-cli/Controller/AnalysisController.h @@ -11,37 +11,26 @@ #define PHASAR_CONTROLLER_ANALYSISCONTROLLER_H #include "phasar/AnalysisStrategy/Strategies.h" -#include "phasar/Controller/AnalysisControllerEmitterOptions.h" #include "phasar/DataFlow/IfdsIde/IFDSIDESolverConfig.h" #include "phasar/PhasarLLVM/HelperAnalyses.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" +#include "AnalysisControllerEmitterOptions.h" + #include namespace psr { -class AnalysisController { -public: - struct ControllerData { - HelperAnalyses *HA{}; - std::vector DataFlowAnalyses; - std::vector AnalysisConfigs; - std::vector EntryPoints; - [[maybe_unused]] AnalysisStrategy Strategy; - AnalysisControllerEmitterOptions EmitterOptions = - AnalysisControllerEmitterOptions::None; - std::string ProjectID; - std::filesystem::path ResultDirectory; - IFDSIDESolverConfig SolverConfig{}; - }; - - explicit AnalysisController( - HelperAnalyses &HA, std::vector DataFlowAnalyses, - std::vector AnalysisConfigs, - std::vector EntryPoints, AnalysisStrategy Strategy, - AnalysisControllerEmitterOptions EmitterOptions, - IFDSIDESolverConfig SolverConfig, - std::string ProjectID = "default-phasar-project", - std::string OutDirectory = ""); +struct AnalysisController { + 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; static constexpr bool needsToEmitPTA(AnalysisControllerEmitterOptions EmitterOptions) { @@ -50,8 +39,8 @@ class AnalysisController { (EmitterOptions & AnalysisControllerEmitterOptions::EmitPTAAsText); } -private: - ControllerData Data; + void emitRequestedHelperAnalysisResults(); + void run(); }; } // namespace psr diff --git a/include/phasar/Controller/AnalysisControllerEmitterOptions.h b/tools/phasar-cli/Controller/AnalysisControllerEmitterOptions.h similarity index 100% rename from include/phasar/Controller/AnalysisControllerEmitterOptions.h rename to tools/phasar-cli/Controller/AnalysisControllerEmitterOptions.h diff --git a/lib/Controller/AnalysisControllerInternal.h b/tools/phasar-cli/Controller/AnalysisControllerInternal.h similarity index 65% rename from lib/Controller/AnalysisControllerInternal.h rename to tools/phasar-cli/Controller/AnalysisControllerInternal.h index 8a736e3a1..1246518fb 100644 --- a/lib/Controller/AnalysisControllerInternal.h +++ b/tools/phasar-cli/Controller/AnalysisControllerInternal.h @@ -10,7 +10,6 @@ #ifndef PHASAR_CONTROLLER_ANALYSISCONTROLLERINTERNAL_H #define PHASAR_CONTROLLER_ANALYSISCONTROLLERINTERNAL_H -#include "phasar/Controller/AnalysisController.h" #include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h" @@ -22,44 +21,34 @@ #include "llvm/Support/Compiler.h" +#include "AnalysisController.h" + namespace psr { template class IDESolver; } // namespace psr namespace psr::controller { -LLVM_LIBRARY_VISIBILITY void -executeIFDSUninitVar(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIFDSConst(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIFDSTaint(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIFDSType(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIFDSSolverTest(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIFDSFieldSensTaint(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDEXTaint(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDEOpenSSLTS(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDECSTDIOTS(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDELinearConst(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDESolverTest(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIDEIIA(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIntraMonoFullConstant(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeIntraMonoSolverTest(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeInterMonoSolverTest(AnalysisController::ControllerData &Data); -LLVM_LIBRARY_VISIBILITY void -executeInterMonoTaint(AnalysisController::ControllerData &Data); +LLVM_LIBRARY_VISIBILITY void executeIFDSUninitVar(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIFDSConst(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIFDSTaint(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIFDSType(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIFDSSolverTest(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void +executeIFDSFieldSensTaint(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDEXTaint(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDEOpenSSLTS(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDECSTDIOTS(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDELinearConst(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDESolverTest(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeIDEIIA(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void +executeIntraMonoFullConstant(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void +executeIntraMonoSolverTest(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void +executeInterMonoSolverTest(AnalysisController &Data); +LLVM_LIBRARY_VISIBILITY void executeInterMonoTaint(AnalysisController &Data); /// /// \brief The maximum length of the CallStrings used in the InterMonoSolver @@ -67,7 +56,7 @@ executeInterMonoTaint(AnalysisController::ControllerData &Data); static constexpr unsigned K = 3; [[nodiscard]] LLVM_LIBRARY_VISIBILITY LLVMTaintConfig -makeTaintConfig(AnalysisController::ControllerData &Data); +makeTaintConfig(AnalysisController &Data); template static void statsEmitter(llvm::raw_ostream & /*OS*/, const T & /*Solver*/) {} @@ -75,9 +64,7 @@ template static void statsEmitter(llvm::raw_ostream &OS, const IDESolver &Solver); template -static void -emitRequestedDataFlowResults(AnalysisController::ControllerData &Data, - T &Solver) { +static void emitRequestedDataFlowResults(AnalysisController &Data, T &Solver) { auto EmitterOptions = Data.EmitterOptions; const auto &ResultDirectory = Data.ResultDirectory; diff --git a/lib/Controller/AnalysisControllerInternalIDE.h b/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h similarity index 82% rename from lib/Controller/AnalysisControllerInternalIDE.h rename to tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h index fa758bbb6..645c055a7 100644 --- a/lib/Controller/AnalysisControllerInternalIDE.h +++ b/tools/phasar-cli/Controller/AnalysisControllerInternalIDE.h @@ -24,8 +24,7 @@ static void statsEmitter(llvm::raw_ostream &OS, const IDESolver &Solver) { } template -static void executeIfdsIdeAnalysis(AnalysisController::ControllerData &Data, - ArgTys &&...Args) { +static void executeIfdsIdeAnalysis(AnalysisController &Data, ArgTys &&...Args) { auto Problem = createAnalysisProblem(*Data.HA, std::forward(Args)...); SolverTy Solver(Problem, &Data.HA->getICFG()); @@ -44,15 +43,13 @@ static void executeIfdsIdeAnalysis(AnalysisController::ControllerData &Data, } template -static void executeIFDSAnalysis(AnalysisController::ControllerData &Data, - ArgTys &&...Args) { +static void executeIFDSAnalysis(AnalysisController &Data, ArgTys &&...Args) { executeIfdsIdeAnalysis, ProblemTy>( Data, std::forward(Args)...); } template -static void executeIDEAnalysis(AnalysisController::ControllerData &Data, - ArgTys &&...Args) { +static void executeIDEAnalysis(AnalysisController &Data, ArgTys &&...Args) { executeIfdsIdeAnalysis, ProblemTy>( Data, std::forward(Args)...); } diff --git a/lib/Controller/AnalysisControllerInternalMono.h b/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h similarity index 83% rename from lib/Controller/AnalysisControllerInternalMono.h rename to tools/phasar-cli/Controller/AnalysisControllerInternalMono.h index e68878931..8bd649ca7 100644 --- a/lib/Controller/AnalysisControllerInternalMono.h +++ b/tools/phasar-cli/Controller/AnalysisControllerInternalMono.h @@ -18,8 +18,7 @@ namespace psr::controller { template -static void executeMonoAnalysis(AnalysisController::ControllerData &Data, - ArgTys &&...Args) { +static void executeMonoAnalysis(AnalysisController &Data, ArgTys &&...Args) { auto Problem = createAnalysisProblem(*Data.HA, std::forward(Args)...); SolverTy Solver(Problem); @@ -28,14 +27,14 @@ static void executeMonoAnalysis(AnalysisController::ControllerData &Data, } template -static void executeIntraMonoAnalysis(AnalysisController::ControllerData &Data, +static void executeIntraMonoAnalysis(AnalysisController &Data, ArgTys &&...Args) { executeMonoAnalysis, ProblemTy>( Data, std::forward(Args)...); } template -static void executeInterMonoAnalysis(AnalysisController::ControllerData &Data, +static void executeInterMonoAnalysis(AnalysisController &Data, ArgTys &&...Args) { executeMonoAnalysis, ProblemTy>( Data, std::forward(Args)...); diff --git a/lib/Controller/AnalysisControllerXIDECSTDIOTS.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp similarity index 90% rename from lib/Controller/AnalysisControllerXIDECSTDIOTS.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp index f6c268ae8..11f81a349 100644 --- a/lib/Controller/AnalysisControllerXIDECSTDIOTS.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDECSTDIOTS.cpp @@ -14,7 +14,7 @@ using namespace psr; -void controller::executeIDECSTDIOTS(AnalysisController::ControllerData &Data) { +void controller::executeIDECSTDIOTS(AnalysisController &Data) { CSTDFILEIOTypeStateDescription TSDesc; executeIDEAnalysis>( Data, &TSDesc, Data.EntryPoints); diff --git a/lib/Controller/AnalysisControllerXIDEIIA.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp similarity index 95% rename from lib/Controller/AnalysisControllerXIDEIIA.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp index e44f08422..e16390901 100644 --- a/lib/Controller/AnalysisControllerXIDEIIA.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEIIA.cpp @@ -17,7 +17,7 @@ using namespace psr; -void controller::executeIDEIIA(AnalysisController::ControllerData &Data) { +void controller::executeIDEIIA(AnalysisController &Data) { // use Phasar's instruction ids as testing labels auto Generator = [](std::variant diff --git a/lib/Controller/AnalysisControllerXIDELinearConst.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp similarity index 87% rename from lib/Controller/AnalysisControllerXIDELinearConst.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp index 1e794814f..fc4e95ef5 100644 --- a/lib/Controller/AnalysisControllerXIDELinearConst.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDELinearConst.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeIDELinearConst( - AnalysisController::ControllerData &Data) { +void controller::executeIDELinearConst(AnalysisController &Data) { executeIDEAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIDEOpenSSLTS.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp similarity index 90% rename from lib/Controller/AnalysisControllerXIDEOpenSSLTS.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp index f45029770..9f65b2082 100644 --- a/lib/Controller/AnalysisControllerXIDEOpenSSLTS.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEOpenSSLTS.cpp @@ -14,7 +14,7 @@ using namespace psr; -void controller::executeIDEOpenSSLTS(AnalysisController::ControllerData &Data) { +void controller::executeIDEOpenSSLTS(AnalysisController &Data) { OpenSSLEVPKDFDescription TSDesc; executeIDEAnalysis>( Data, &TSDesc, Data.EntryPoints); diff --git a/lib/Controller/AnalysisControllerXIDESolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp similarity index 86% rename from lib/Controller/AnalysisControllerXIDESolverTest.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp index 719207aa3..baa3a27d2 100644 --- a/lib/Controller/AnalysisControllerXIDESolverTest.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDESolverTest.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeIDESolverTest( - AnalysisController::ControllerData &Data) { +void controller::executeIDESolverTest(AnalysisController &Data) { executeIDEAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIDEXTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp similarity index 89% rename from lib/Controller/AnalysisControllerXIDEXTaint.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp index 892939457..dc03bda7f 100644 --- a/lib/Controller/AnalysisControllerXIDEXTaint.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIDEXTaint.cpp @@ -13,7 +13,7 @@ using namespace psr; -void controller::executeIDEXTaint(AnalysisController::ControllerData &Data) { +void controller::executeIDEXTaint(AnalysisController &Data) { auto Config = makeTaintConfig(Data); executeIDEAnalysis>(Data, Config, Data.EntryPoints); diff --git a/lib/Controller/AnalysisControllerXIFDSConst.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp similarity index 88% rename from lib/Controller/AnalysisControllerXIFDSConst.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp index 0393c2950..55a3600d4 100644 --- a/lib/Controller/AnalysisControllerXIFDSConst.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSConst.cpp @@ -13,6 +13,6 @@ using namespace psr; -void controller::executeIFDSConst(AnalysisController::ControllerData &Data) { +void controller::executeIFDSConst(AnalysisController &Data) { executeIFDSAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIFDSSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp similarity index 86% rename from lib/Controller/AnalysisControllerXIFDSSolverTest.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp index 08f8c2689..c8b37c574 100644 --- a/lib/Controller/AnalysisControllerXIFDSSolverTest.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSSolverTest.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeIFDSSolverTest( - AnalysisController::ControllerData &Data) { +void controller::executeIFDSSolverTest(AnalysisController &Data) { executeIFDSAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIFDSTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp similarity index 88% rename from lib/Controller/AnalysisControllerXIFDSTaint.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp index a94abca60..0d410ccbc 100644 --- a/lib/Controller/AnalysisControllerXIFDSTaint.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp @@ -13,7 +13,7 @@ using namespace psr; -void controller::executeIFDSTaint(AnalysisController::ControllerData &Data) { +void controller::executeIFDSTaint(AnalysisController &Data) { auto Config = makeTaintConfig(Data); executeIFDSAnalysis(Data, &Config, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIFDSType.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp similarity index 88% rename from lib/Controller/AnalysisControllerXIFDSType.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp index e5a56d531..8c8410e99 100644 --- a/lib/Controller/AnalysisControllerXIFDSType.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSType.cpp @@ -13,6 +13,6 @@ using namespace psr; -void controller::executeIFDSType(AnalysisController::ControllerData &Data) { +void controller::executeIFDSType(AnalysisController &Data) { executeIFDSAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIFDSUninit.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp similarity index 87% rename from lib/Controller/AnalysisControllerXIFDSUninit.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp index db66cfef1..7e4789808 100644 --- a/lib/Controller/AnalysisControllerXIFDSUninit.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSUninit.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeIFDSUninitVar( - AnalysisController::ControllerData &Data) { +void controller::executeIFDSUninitVar(AnalysisController &Data) { executeIFDSAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXInterMonoSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp similarity index 86% rename from lib/Controller/AnalysisControllerXInterMonoSolverTest.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp index 17ad61168..3b2b8e78a 100644 --- a/lib/Controller/AnalysisControllerXInterMonoSolverTest.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoSolverTest.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeInterMonoSolverTest( - AnalysisController::ControllerData &Data) { +void controller::executeInterMonoSolverTest(AnalysisController &Data) { executeInterMonoAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXInterMonoTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp similarity index 88% rename from lib/Controller/AnalysisControllerXInterMonoTaint.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp index cc24440e1..dbbb19d2a 100644 --- a/lib/Controller/AnalysisControllerXInterMonoTaint.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXInterMonoTaint.cpp @@ -13,8 +13,7 @@ using namespace psr; -void controller::executeInterMonoTaint( - AnalysisController::ControllerData &Data) { +void controller::executeInterMonoTaint(AnalysisController &Data) { auto Config = makeTaintConfig(Data); executeInterMonoAnalysis(Data, Config, Data.EntryPoints); diff --git a/lib/Controller/AnalysisControllerXIntraMonoFullConstant.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp similarity index 87% rename from lib/Controller/AnalysisControllerXIntraMonoFullConstant.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp index 65a95b338..8c17bbb9f 100644 --- a/lib/Controller/AnalysisControllerXIntraMonoFullConstant.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoFullConstant.cpp @@ -13,8 +13,7 @@ using namespace psr; -void controller::executeIntraMonoFullConstant( - AnalysisController::ControllerData &Data) { +void controller::executeIntraMonoFullConstant(AnalysisController &Data) { executeIntraMonoAnalysis(Data, Data.EntryPoints); } diff --git a/lib/Controller/AnalysisControllerXIntraMonoSolverTest.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp similarity index 86% rename from lib/Controller/AnalysisControllerXIntraMonoSolverTest.cpp rename to tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp index 557d5899d..c1043a6f1 100644 --- a/lib/Controller/AnalysisControllerXIntraMonoSolverTest.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIntraMonoSolverTest.cpp @@ -13,7 +13,6 @@ using namespace psr; -void controller::executeIntraMonoSolverTest( - AnalysisController::ControllerData &Data) { +void controller::executeIntraMonoSolverTest(AnalysisController &Data) { executeIntraMonoAnalysis(Data, Data.EntryPoints); } diff --git a/tools/phasar-cli/Controller/CMakeLists.txt b/tools/phasar-cli/Controller/CMakeLists.txt new file mode 100644 index 000000000..5977a5aef --- /dev/null +++ b/tools/phasar-cli/Controller/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB_RECURSE CONTROLLER_SRC *.h *.cpp) + +target_sources(phasar-cli PRIVATE ${CONTROLLER_SRC}) diff --git a/tools/phasar-cli/phasar-cli.cpp b/tools/phasar-cli/phasar-cli.cpp index 301e9c704..c3addbb99 100644 --- a/tools/phasar-cli/phasar-cli.cpp +++ b/tools/phasar-cli/phasar-cli.cpp @@ -10,25 +10,25 @@ #include "phasar/AnalysisStrategy/Strategies.h" #include "phasar/Config/Configuration.h" #include "phasar/ControlFlow/CallGraphAnalysisType.h" -#include "phasar/Controller/AnalysisController.h" -#include "phasar/Controller/AnalysisControllerEmitterOptions.h" #include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h" #include "phasar/PhasarLLVM/HelperAnalyses.h" -#include "phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h" #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.h" #include "phasar/Pointer/AliasAnalysisType.h" #include "phasar/Utils/IO.h" +#include "phasar/Utils/InitPhasar.h" #include "phasar/Utils/Logger.h" #include "phasar/Utils/Soundness.h" +#include "phasar/Utils/Utilities.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" -#include "nlohmann/json.hpp" +#include "Controller/AnalysisController.h" +#include "Controller/AnalysisControllerEmitterOptions.h" #include #include -#include +#include #include #include @@ -40,6 +40,10 @@ namespace { cl::OptionCategory PsrCat("PhASAR"); +static auto values(std::initializer_list IList) { + return cl::ValuesClass(IList); +} + #define PSR_OPTION_FLAG(NAME, CMDFLAG, DESC, ...) \ cl::opt NAME(CMDFLAG, cl::desc(DESC), cl::cat(PsrCat), ##__VA_ARGS__) @@ -70,27 +74,28 @@ PSR_SHORTLONG_OPTION_TYPE( "Set the entry point(s) to be used; use '__ALL__' to specify all available " "function definitions as entry points"); -cl::list DataFlowAnalysisOpt( - "data-flow-analysis", cl::desc("Set the analyses to be run"), - cl::values( +cl::list + DataFlowAnalysisOpt("data-flow-analysis", + cl::desc("Set the analyses to be run"), + values({ #define DATA_FLOW_ANALYSIS_TYPES(NAME, CMDFLAG, DESC) \ clEnumValN(DataFlowAnalysisType::NAME, CMDFLAG, DESC), #include "phasar/PhasarLLVM/Utils/DataFlowAnalysisType.def" - clEnumValN(DataFlowAnalysisType::None, "none", "No-op")), - cl::cat(PsrCat)); + }), + cl::cat(PsrCat)); cl::alias DataFlowAnalysisAlias("D", cl::aliasopt(DataFlowAnalysisOpt), cl::desc("Alias for --data-flow-analysis"), cl::cat(PsrCat)); -cl::opt - StrategyOpt("analysis-strategy", cl::desc("The analysis strategy"), - cl::values( +cl::opt StrategyOpt("analysis-strategy", + cl::desc("The analysis strategy"), + values({ #define ANALYSIS_STRATEGY_TYPES(NAME, CMDFLAG, DESC) \ clEnumValN(AnalysisStrategy::NAME, CMDFLAG, DESC), #include "phasar/AnalysisStrategy/Strategies.def" - clEnumValN(AnalysisStrategy::None, "none", "none")), - cl::init(AnalysisStrategy::WholeProgram), cl::cat(PsrCat), - cl::Hidden); + }), + cl::init(AnalysisStrategy::WholeProgram), + cl::cat(PsrCat), cl::Hidden); cl::opt AnalysisConfigOpt( "analysis-config", @@ -102,36 +107,38 @@ cl::opt AliasTypeOpt( cl::desc("Set the alias analysis to be used (CFLSteens, " "CFLAnders). CFLSteens is ~O(N) but inaccurate while " "CFLAnders O(N^3) but more accurate."), - cl::values( + values({ #define ALIAS_ANALYSIS_TYPE(NAME, CMDFLAG, DESC) \ clEnumValN(AliasAnalysisType::NAME, CMDFLAG, DESC), #include "phasar/Pointer/AliasAnalysisType.def" - clEnumValN(AliasAnalysisType::Invalid, "invalid", "invalid")), + }), cl::init(AliasAnalysisType::CFLAnders), cl::cat(PsrCat)); cl::alias AliasTypeAlias("P", cl::aliasopt(AliasTypeOpt), cl::desc("Alias for --alias-analysis"), cl::cat(PsrCat)); -cl::opt CGTypeOpt( - "call-graph-analysis", cl::desc("Set the call-graph algorithm to be used"), - cl::values( +cl::opt + CGTypeOpt("call-graph-analysis", + cl::desc("Set the call-graph algorithm to be used"), + values({ #define CALL_GRAPH_ANALYSIS_TYPE(NAME, CMDFLAG, DESC) \ clEnumValN(CallGraphAnalysisType::NAME, CMDFLAG, DESC), #include "phasar/ControlFlow/CallGraphAnalysisType.def" - clEnumValN(CallGraphAnalysisType::Invalid, "invalid", "invalid")), - cl::init(CallGraphAnalysisType::OTF), cl::cat(PsrCat)); + }), + cl::init(CallGraphAnalysisType::OTF), cl::cat(PsrCat)); cl::alias CGTypeAlias("C", cl::aliasopt(CGTypeOpt), cl::desc("Alias for --call-graph-analysis"), cl::cat(PsrCat)); -cl::opt - SoundnessOpt("soundness", cl::desc("Set the soundiness level to be used"), - cl::values( +cl::opt SoundnessOpt("soundness", + cl::desc("Set the soundiness level to be used"), + values({ #define SOUNDNESS_FLAG_TYPE(NAME, CMDFLAG, DESC) \ clEnumValN(Soundness::NAME, CMDFLAG, DESC), #include "phasar/Utils/Soundness.def" - clEnumValN(Soundness::Invalid, "invalid", "invalid")), - cl::init(Soundness::Soundy), cl::cat(PsrCat), cl::Hidden); + }), + cl::init(Soundness::Soundy), cl::cat(PsrCat), + cl::Hidden); PSR_OPTION_FLAG(AutoGlobalsOpt, "auto-globals", "Enable automated support for global initializers", cl::init(true)); @@ -149,10 +156,10 @@ cl::opt LogSeverityOpt( "printed. Has no effect if logging is disabled. You can enable " "logging with --log/-L or by specifying at least one --log-cat."), cl::cat(PsrCat), - cl::values( + values({ #define SEVERITY_LEVEL(NAME, TYPE) clEnumValN(SeverityLevel::TYPE, NAME, NAME), #include "phasar/Utils/SeverityLevel.def" - clEnumValN(SeverityLevel::INVALID, "INVALID", "INVALID")), + }), cl::init(SeverityLevel::DEBUG)); cl::list @@ -319,6 +326,8 @@ void validatePTAJsonFile() { } // anonymous namespace int main(int Argc, const char **Argv) { + PSR_INITIALIZER(Argc, Argv); + cl::SetVersionPrinter([](llvm::raw_ostream &OS) { OS << "PhASAR " << PhasarConfig::PhasarVersion() << '\n'; }); @@ -460,8 +469,25 @@ int main(int Argc, const char **Argv) { return 1; } - AnalysisController Controller( - HA, DataFlowAnalysisOpt, {AnalysisConfigOpt.getValue()}, EntryOpt, - StrategyOpt, EmitterOptions, SolverConfig, ProjectIdOpt, OutDirOpt); + AnalysisController Controller{ + &HA, + DataFlowAnalysisOpt, + {AnalysisConfigOpt.getValue()}, + EntryOpt, + StrategyOpt, + EmitterOptions, + SolverConfig, + ProjectIdOpt.getValue(), + OutDirOpt.getValue(), + }; + if (!OutDirOpt.empty()) { + // create directory for results + Controller.ResultDirectory /= + Controller.ProjectID + "-" + createTimeStamp(); + std::filesystem::create_directory(Controller.ResultDirectory); + } + + Controller.emitRequestedHelperAnalysisResults(); + Controller.run(); return 0; }