diff --git a/tools/revng-lift/ProgramCounterHandler.h b/include/revng/Support/ProgramCounterHandler.h similarity index 91% rename from tools/revng-lift/ProgramCounterHandler.h rename to include/revng/Support/ProgramCounterHandler.h index cf36a5cff..be922817a 100644 --- a/tools/revng-lift/ProgramCounterHandler.h +++ b/include/revng/Support/ProgramCounterHandler.h @@ -10,8 +10,6 @@ #include "revng/BasicAnalyses/GeneratedCodeBasicInfo.h" #include "revng/Support/IRHelpers.h" -#include "PTCInterface.h" - inline llvm::IntegerType *getCSVType(llvm::GlobalVariable *CSV) { using namespace llvm; return cast(CSV->getType()->getPointerElementType()); @@ -23,8 +21,22 @@ enum Values { Unique, Multiple, Helper }; }; -using CSVFactory = std::function; +namespace PCAffectingCSV { + +enum Values { PC, IsThumb }; + +}; + +namespace detail { + +using namespace llvm; + +using CSVFactory = std::function; + +}; // namespace detail + +using CSVFactory = detail::CSVFactory; class ProgramCounterHandler { protected: @@ -59,7 +71,6 @@ public: static std::unique_ptr create(llvm::Triple::ArchType Architecture, llvm::Module *M, - PTCInterface *PTC, const CSVFactory &Factory); public: @@ -206,6 +217,17 @@ protected: TypeCSV = createType(M); } +public: + void setMissingVariables(llvm::Module *M) { + AddressCSV = M->getGlobalVariable(AddressName); + EpochCSV = M->getGlobalVariable(EpochName); + AddressSpaceCSV = M->getGlobalVariable(AddressSpaceName); + TypeCSV = M->getGlobalVariable(TypeName); + + revng_assert(AddressCSV != nullptr and EpochCSV != nullptr + and AddressSpaceCSV != nullptr and TypeCSV != nullptr); + } + private: bool isPCAffectingHelper(llvm::Instruction *I) const; diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 647db6f7c..265f0ea03 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -11,6 +11,7 @@ revng_add_library_internal(revngSupport SHARED IRHelpers.cpp MetaAddress.cpp PathList.cpp + ProgramCounterHandler.cpp ResourceFinder.cpp Statistics.cpp) diff --git a/tools/revng-lift/ProgramCounterHandler.cpp b/lib/Support/ProgramCounterHandler.cpp similarity index 94% rename from tools/revng-lift/ProgramCounterHandler.cpp rename to lib/Support/ProgramCounterHandler.cpp index b68c8ad54..cb3a408ba 100644 --- a/tools/revng-lift/ProgramCounterHandler.cpp +++ b/lib/Support/ProgramCounterHandler.cpp @@ -8,21 +8,25 @@ #include "llvm/ADT/SmallSet.h" #include "revng/BasicAnalyses/GeneratedCodeBasicInfo.h" - -#include "ProgramCounterHandler.h" +#include "revng/Support/ProgramCounterHandler.h" using namespace llvm; using PCH = ProgramCounterHandler; class PCOnlyProgramCounterHandler : public ProgramCounterHandler { public: - PCOnlyProgramCounterHandler(Module *M, - PTCInterface *PTC, - const CSVFactory &Factory) { - AddressCSV = Factory(PTC->pc, "pc"); - CSVsAffectingPC.insert(AddressCSV); + static std::unique_ptr + create(Module *M, const CSVFactory &Factory) { + auto Result = std::make_unique(); - createMissingVariables(M); + // Create and register the pc CSV + Result->AddressCSV = Factory(PCAffectingCSV::PC, AddressName); + Result->CSVsAffectingPC.insert(Result->AddressCSV); + + // Create the other variables (non-CSV) + Result->createMissingVariables(M); + + return Result; } public: @@ -47,19 +51,27 @@ protected: }; class ARMProgramCounterHandler : public ProgramCounterHandler { +private: + static constexpr const char *IsThumbName = "is_thumb"; + private: GlobalVariable *IsThumb; public: - ARMProgramCounterHandler(Module *M, - PTCInterface *PTC, - const CSVFactory &Factory) { - AddressCSV = Factory(PTC->pc, AddressName); - IsThumb = Factory(PTC->is_thumb, "is_thumb"); - CSVsAffectingPC.insert(AddressCSV); - CSVsAffectingPC.insert(IsThumb); + static std::unique_ptr + create(Module *M, const CSVFactory &Factory) { + auto Result = std::make_unique(); - createMissingVariables(M); + // Create and register the pc and is_thumb CSV + Result->AddressCSV = Factory(PCAffectingCSV::PC, AddressName); + Result->CSVsAffectingPC.insert(Result->AddressCSV); + + Result->IsThumb = Factory(PCAffectingCSV::IsThumb, IsThumbName); + Result->CSVsAffectingPC.insert(Result->IsThumb); + + Result->createMissingVariables(M); + + return Result; } private: @@ -681,11 +693,10 @@ PCH::buildDispatcher(DispatcherTargets &Targets, std::unique_ptr PCH::create(Triple::ArchType Architecture, Module *M, - PTCInterface *PTC, const CSVFactory &Factory) { switch (Architecture) { case Triple::arm: - return std::make_unique(M, PTC, Factory); + return ARMProgramCounterHandler::create(M, Factory); case Triple::x86_64: case Triple::mips: @@ -693,7 +704,7 @@ PCH::create(Triple::ArchType Architecture, case Triple::aarch64: case Triple::systemz: case Triple::x86: - return std::make_unique(M, PTC, Factory); + return PCOnlyProgramCounterHandler::create(M, Factory); default: revng_abort("Unsupported architecture"); diff --git a/tools/revng-lift/CMakeLists.txt b/tools/revng-lift/CMakeLists.txt index aa093ed88..cf9fb96f1 100644 --- a/tools/revng-lift/CMakeLists.txt +++ b/tools/revng-lift/CMakeLists.txt @@ -12,7 +12,6 @@ revng_add_executable(revng-lift JumpTargetManager.cpp Main.cpp PTCDump.cpp - ProgramCounterHandler.cpp VariableManager.cpp) target_link_libraries(revng-lift diff --git a/tools/revng-lift/CodeGenerator.cpp b/tools/revng-lift/CodeGenerator.cpp index b94c4333b..045694a9f 100644 --- a/tools/revng-lift/CodeGenerator.cpp +++ b/tools/revng-lift/CodeGenerator.cpp @@ -42,6 +42,7 @@ #include "revng/Support/CommandLine.h" #include "revng/Support/Debug.h" #include "revng/Support/DebugHelper.h" +#include "revng/Support/ProgramCounterHandler.h" #include "revng/Support/revng.h" #include "CodeGenerator.h" @@ -50,7 +51,6 @@ #include "InstructionTranslator.h" #include "JumpTargetManager.h" #include "PTCInterface.h" -#include "ProgramCounterHandler.h" #include "VariableManager.h" using namespace llvm; @@ -877,13 +877,27 @@ void CodeGenerator::translate(Optional RawVirtualAddress) { GlobalVariable *SPReg = Variables.getByEnvOffset(ptc.sp, SPName).first; using PCHOwner = std::unique_ptr; - auto Factory = [&Variables](intptr_t Offset, + auto Factory = [&Variables](PCAffectingCSV::Values CSVID, llvm::StringRef Name) -> GlobalVariable * { + intptr_t Offset = 0; + + switch (CSVID) { + case PCAffectingCSV::PC: + Offset = ptc.pc; + break; + + case PCAffectingCSV::IsThumb: + Offset = ptc.is_thumb; + break; + + default: + revng_abort(); + } + return Variables.getByEnvOffset(Offset, Name).first; }; PCHOwner PCH = ProgramCounterHandler::create(Arch.type(), TheModule.get(), - &ptc, Factory); IRBuilder<> Builder(Context); diff --git a/tools/revng-lift/ExternalJumpsHandler.cpp b/tools/revng-lift/ExternalJumpsHandler.cpp index 9bc41396a..5db388334 100644 --- a/tools/revng-lift/ExternalJumpsHandler.cpp +++ b/tools/revng-lift/ExternalJumpsHandler.cpp @@ -20,11 +20,11 @@ #include "revng/BasicAnalyses/GeneratedCodeBasicInfo.h" #include "revng/Support/Debug.h" +#include "revng/Support/ProgramCounterHandler.h" #include "ExternalJumpsHandler.h" #include "BinaryFile.h" -#include "ProgramCounterHandler.h" using namespace llvm; using std::string; diff --git a/tools/revng-lift/InstructionTranslator.h b/tools/revng-lift/InstructionTranslator.h index d7a34ef72..c283e3a3d 100644 --- a/tools/revng-lift/InstructionTranslator.h +++ b/tools/revng-lift/InstructionTranslator.h @@ -13,11 +13,11 @@ #include "llvm/Pass.h" #include "llvm/Support/ErrorOr.h" +#include "revng/Support/ProgramCounterHandler.h" #include "revng/Support/revng.h" #include "JumpTargetManager.h" #include "PTCDump.h" -#include "ProgramCounterHandler.h" // Forward declarations namespace llvm { diff --git a/tools/revng-lift/JumpTargetManager.cpp b/tools/revng-lift/JumpTargetManager.cpp index c6c9d9a62..10a1ae04a 100644 --- a/tools/revng-lift/JumpTargetManager.cpp +++ b/tools/revng-lift/JumpTargetManager.cpp @@ -50,7 +50,6 @@ #include "AdvancedValueInfoPass.h" #include "CPUStateAccessAnalysisPass.h" #include "DropHelperCallsPass.h" -#include "ProgramCounterHandler.h" #include "SubGraph.h" using namespace llvm; diff --git a/tools/revng-lift/JumpTargetManager.h b/tools/revng-lift/JumpTargetManager.h index b31282959..bc7434f99 100644 --- a/tools/revng-lift/JumpTargetManager.h +++ b/tools/revng-lift/JumpTargetManager.h @@ -18,10 +18,11 @@ #include "revng/BasicAnalyses/MaterializedValue.h" #include "revng/Support/IRHelpers.h" +#include "revng/Support/ProgramCounterHandler.h" #include "revng/Support/revng.h" #include "BinaryFile.h" -#include "ProgramCounterHandler.h" + // Forward declarations namespace llvm { class BasicBlock;