From a0fa9497700ec2e4ad6093164f84d5e87ef736a8 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Fri, 13 May 2022 14:18:34 +0200 Subject: [PATCH 1/2] Add support for compiling maat with MSVC --- cmake/variables.cmake | 3 +++ src/arch/register_aliases.cpp | 2 +- src/env/env_linux.cpp | 18 ++++++++--------- src/expression/value_set.cpp | 22 +++++++++++++++++++-- src/include/maat/cpu.hpp | 18 ++++++++--------- src/include/maat/event.hpp | 8 ++++---- src/include/maat/expression.hpp | 2 +- src/include/maat/serializer.hpp | 1 + src/include/maat/types.hpp | 7 +++++++ src/serialization/serialization_helpers.cpp | 4 ++-- src/serialization/serializer.cpp | 1 + 11 files changed, 57 insertions(+), 29 deletions(-) diff --git a/cmake/variables.cmake b/cmake/variables.cmake index 87433255..4cefd5c7 100644 --- a/cmake/variables.cmake +++ b/cmake/variables.cmake @@ -12,6 +12,9 @@ if(PROJECT_IS_TOP_LEVEL) option(maat_DEVELOPER_MODE "Enable developer mode" OFF) option(maat_RUN_PYTHON_TESTS "Enable running the Python tests" ON) option(BUILD_SHARED_LIBS "Build shared libs." OFF) + + # Enable folder support + set_property(GLOBAL PROPERTY USE_FOLDERS ON) endif() # These variables correspond to the dependencies that maat doesn't diff --git a/src/arch/register_aliases.cpp b/src/arch/register_aliases.cpp index 607eb608..2b8572b9 100644 --- a/src/arch/register_aliases.cpp +++ b/src/arch/register_aliases.cpp @@ -4,7 +4,7 @@ namespace maat{ namespace ir{ -inline void __attribute__((always_inline)) _set_flag_from_bit( +inline ALWAYS_INLINE void _set_flag_from_bit( CPUContext& ctx, ir::reg_t reg, const Value& val, diff --git a/src/env/env_linux.cpp b/src/env/env_linux.cpp index f9bd5b3e..f3731456 100644 --- a/src/env/env_linux.cpp +++ b/src/env/env_linux.cpp @@ -44,16 +44,16 @@ void LinuxEmulator::add_running_process(const ProcessInfo& pinfo, const std::str fs.create_symlink("/proc/self/exe", pinfo.binary_path, true); // Create stdin,stdout,stderr, for this process - std::string stdin = fs.get_stdin_for_pid(pinfo.pid); - std::string stdout = fs.get_stdout_for_pid(pinfo.pid); - std::string stderr = fs.get_stderr_for_pid(pinfo.pid); + std::string stdin_ = fs.get_stdin_for_pid(pinfo.pid); + std::string stdout_ = fs.get_stdout_for_pid(pinfo.pid); + std::string stderr_ = fs.get_stderr_for_pid(pinfo.pid); - fs.create_file(stdin); - fs.create_file(stdout); - fs.create_file(stderr); - fs._new_fa(stdin, 0); - fs._new_fa(stdout, 1); - fs._new_fa(stderr, 2); + fs.create_file(stdin_); + fs.create_file(stdout_); + fs.create_file(stderr_); + fs._new_fa(stdin_, 0); + fs._new_fa(stdout_, 1); + fs._new_fa(stderr_, 2); fs.get_file_by_handle(1)->flush_stream = std::ref(std::cout); fs.get_file_by_handle(2)->flush_stream = std::ref(std::cerr); } diff --git a/src/expression/value_set.cpp b/src/expression/value_set.cpp index 6a8d80bc..357ad0e0 100644 --- a/src/expression/value_set.cpp +++ b/src/expression/value_set.cpp @@ -344,11 +344,29 @@ void ValueSet::set_mul(ValueSet& vs1, ValueSet& vs2) } } +#ifdef _MSC_VER +#include +#include + +static ucst_t mulhshr(ucst_t x, ucst_t y, int shift) +{ + assert(shift > 0); + unsigned __int64 hi; + unsigned __int64 lo = _umul128(x, y, &hi); + return (ucst_t)((hi << (64 - shift)) | ((lo >> (shift - 1)) >> 1)); +} +#else +static ucst_t mulhshr(ucst_t x, ucst_t y, int shift) +{ + return (ucst_t)(((__uint128_t)x * (__uint128_t)y) >> shift); +} +#endif // _MSC_VER + void ValueSet::set_mulh(ValueSet& vs1, ValueSet& vs2) { // Simlar to MUL but there can not be an overflow on this one :) - ucst_t new_min = (ucst_t)(((__uint128_t)vs1.min * (__uint128_t)vs2.min) >> size ); - ucst_t new_max = (ucst_t)(((__uint128_t)vs1.max * (__uint128_t)vs2.max) >> size ); + ucst_t new_min = mulhshr(vs1.min, vs2.min, size); + ucst_t new_max = mulhshr(vs1.max, vs2.max, size); set(new_min, new_max, 1); } diff --git a/src/include/maat/cpu.hpp b/src/include/maat/cpu.hpp index 45494239..b1b1e3f5 100644 --- a/src/include/maat/cpu.hpp +++ b/src/include/maat/cpu.hpp @@ -76,9 +76,9 @@ class CPUContext: public serial::Serializable private: // Internal method that handles setting register aliases - inline void _set_aliased_reg(ir::reg_t reg, const Value& val) __attribute__((always_inline)); + inline ALWAYS_INLINE void _set_aliased_reg(ir::reg_t reg, const Value& val); // Internal method to check if a register is an alias - inline bool _is_alias(ir::reg_t reg) const __attribute__((always_inline)); + inline ALWAYS_INLINE bool _is_alias(ir::reg_t reg) const; public: /// Print the CPU context to a stream @@ -147,35 +147,33 @@ class CPU: public serial::Serializable /** \brief Extracts bit field (high_bit and low_bit included) from 'expr'. If * the extract extracts the whole expression, then simply returns 'expr' * without performing the extract */ - inline Expr _extract_abstract_if_needed(Expr expr, size_t high_bit, size_t low_bit) - __attribute__((always_inline)); + inline ALWAYS_INLINE Expr _extract_abstract_if_needed(Expr expr, size_t high_bit, size_t low_bit); /** \brief Extracts bit field (high_bit and low_bit included) from 'val'. 'val' is modified * **in place**. * Returns a reference to 'val' */ - inline Value _extract_value_bits(const Value& val, size_t high_bit, size_t low_bit) - __attribute__((always_inline)); + inline ALWAYS_INLINE Value _extract_value_bits(const Value& val, size_t high_bit, size_t low_bit); /** \brief Get value of parameter 'param' (extract bits if needed). * get_full_register is set to true, the function doesn't truncate the * expression if the parameter is a register */ - inline event::Action _get_param_value( + inline ALWAYS_INLINE event::Action _get_param_value( ProcessedInst::Param& dest, const ir::Param& param, MaatEngine& engine, bool get_full_register = false, bool trigger_events = true - ) __attribute__((always_inline)); + ); /** \brief Compute value to be assigned to the output parameter * for instruction 'inst' (with bit extract/concat if overwriting * only a subset of the output current value). Set value to 'dest'. */ - inline void _compute_res_value( + inline ALWAYS_INLINE void _compute_res_value( Value& dest, const ir::Inst& inst, ProcessedInst& pinst - ) __attribute__((always_inline)); + ); public: /** \brief Compute the values of the various parameters of the diff --git a/src/include/maat/event.hpp b/src/include/maat/event.hpp index 5f5d35e0..23126dd2 100644 --- a/src/include/maat/event.hpp +++ b/src/include/maat/event.hpp @@ -361,16 +361,16 @@ class EventManager private: /// Raises a event_exception if a hook with name 'name' already exists void _check_unique_name(const std::string& str); - inline Action _trigger_hooks( + inline ALWAYS_INLINE Action _trigger_hooks( const std::vector& events, When when, MaatEngine& engine - ) __attribute__((always_inline)); - inline Action _trigger_hooks( + ); + inline ALWAYS_INLINE Action _trigger_hooks( Event event, When when, MaatEngine& engine - ) __attribute__((always_inline)); + ); public: bool has_hooks( const std::vector& events, diff --git a/src/include/maat/expression.hpp b/src/include/maat/expression.hpp index 96e8cad9..758f4026 100644 --- a/src/include/maat/expression.hpp +++ b/src/include/maat/expression.hpp @@ -672,7 +672,7 @@ bool ite_evaluate(Expr left, ITECond cond, Expr right, const VarContext* ctx = n * to *higher_bit-new_expr.size()+1* with the expression 'new_expr'. **WARNING**: * 'new_expr' is expected to be small enough to overwrite 'old_expr' from the * specified bit, no check for potential overflow is performed */ -inline Expr __attribute__((always_inline)) overwrite_expr_bits(Expr old_expr, Expr new_expr, size_t higher_bit) +inline Expr ALWAYS_INLINE overwrite_expr_bits(Expr old_expr, Expr new_expr, size_t higher_bit) { if (new_expr->size >= old_expr->size) return new_expr; diff --git a/src/include/maat/serializer.hpp b/src/include/maat/serializer.hpp index e2d2b504..ea651be8 100644 --- a/src/include/maat/serializer.hpp +++ b/src/include/maat/serializer.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "maat/exception.hpp" namespace maat{ diff --git a/src/include/maat/types.hpp b/src/include/maat/types.hpp index 21a2eee8..ff0596e6 100644 --- a/src/include/maat/types.hpp +++ b/src/include/maat/types.hpp @@ -2,6 +2,13 @@ #define TYPES_H #include +#include + +#ifdef _MSC_VER +#define ALWAYS_INLINE __forceinline +#else +#define ALWAYS_INLINE __attribute__((always_inline)) +#endif // _MSC_VER /// Main namespace for Maat's API namespace maat diff --git a/src/serialization/serialization_helpers.cpp b/src/serialization/serialization_helpers.cpp index 3632b860..b146276c 100644 --- a/src/serialization/serialization_helpers.cpp +++ b/src/serialization/serialization_helpers.cpp @@ -30,7 +30,7 @@ bool SimpleStateManager::dequeue_state(MaatEngine& engine) if (pending_states.empty()) return false; - std::string filename = pending_states.front(); + std::filesystem::path filename = pending_states.front(); pending_states.pop(); std::ifstream in(filename, std::ios_base::binary); @@ -39,7 +39,7 @@ bool SimpleStateManager::dequeue_state(MaatEngine& engine) in.close(); if (delete_on_load) - remove(filename.c_str()); + remove(filename.string().c_str()); return true; } diff --git a/src/serialization/serializer.cpp b/src/serialization/serializer.cpp index 2294dc1b..f2c693e9 100644 --- a/src/serialization/serializer.cpp +++ b/src/serialization/serializer.cpp @@ -1,5 +1,6 @@ #include "maat/serializer.hpp" #include "maat/exception.hpp" +#include "maat/types.hpp" namespace maat{ namespace serial{ From 2ec208c1010903f153c6889c1c4512a4fca3cdb8 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Fri, 13 May 2022 14:19:18 +0200 Subject: [PATCH 2/2] Fix compilation errors in sleigh with MSVC Reference: https://developercommunity.visualstudio.com/t/error-c2872-byte-ambiguous-symbol/93889 The reason is that the Ghidra developers for some reason decided to put "using namespace std;" in their header files. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb9ec025..7681bd34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,10 @@ if(maat_USE_EXTERNAL_SLEIGH) find_package(sleigh REQUIRED) else() set(sleigh_ENABLE_TESTS OFF CACHE BOOL "") + # See: https://developercommunity.visualstudio.com/t/error-c2872-byte-ambiguous-symbol/93889 + if(MSVC) + add_compile_definitions(_HAS_STD_BYTE=0) + endif() add_subdirectory(src/third-party/sleigh/sleigh-cmake sleigh EXCLUDE_FROM_ALL) endif()