From 284709802020e7ecd45e56886ec4e99e41c9595d Mon Sep 17 00:00:00 2001 From: Lukas Cone Date: Mon, 28 Feb 2022 00:07:04 +0100 Subject: [PATCH] patterns: Added bitfield_order pragma (#457) --- .../pattern_language/ast/ast_node_bitfield.hpp | 8 ++++---- .../include/hex/pattern_language/evaluator.hpp | 15 +++++++++++++++ .../source/pattern_language/pattern_language.cpp | 12 ++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/libimhex/include/hex/pattern_language/ast/ast_node_bitfield.hpp b/lib/libimhex/include/hex/pattern_language/ast/ast_node_bitfield.hpp index 07ceffa67..0ce0a7238 100644 --- a/lib/libimhex/include/hex/pattern_language/ast/ast_node_bitfield.hpp +++ b/lib/libimhex/include/hex/pattern_language/ast/ast_node_bitfield.hpp @@ -30,17 +30,17 @@ namespace hex::pl { size_t bitOffset = 0; std::vector> fields; - bool isLeftToRight = false; + BitfieldOrder order = evaluator->getBitfieldOrder(); if (this->hasAttribute("left_to_right", false)) - isLeftToRight = true; + order = BitfieldOrder::LeftToRight; else if (this->hasAttribute("right_to_left", false)) - isLeftToRight = false; + order = BitfieldOrder::RightToLeft; std::vector> entries; for (const auto &[name, entry] : this->m_entries) entries.push_back({ name, entry.get() }); - if (isLeftToRight) + if (order == BitfieldOrder::LeftToRight) std::reverse(entries.begin(), entries.end()); evaluator->pushScope(pattern.get(), fields); diff --git a/lib/libimhex/include/hex/pattern_language/evaluator.hpp b/lib/libimhex/include/hex/pattern_language/evaluator.hpp index d29701c94..0103c944a 100644 --- a/lib/libimhex/include/hex/pattern_language/evaluator.hpp +++ b/lib/libimhex/include/hex/pattern_language/evaluator.hpp @@ -34,6 +34,12 @@ namespace hex::pl { Return }; + enum class BitfieldOrder + { + RightToLeft, + LeftToRight + }; + class Pattern; class PatternCreationLimiter; class ASTNode; @@ -161,6 +167,14 @@ namespace hex::pl { return this->m_loopLimit; } + void setBitfieldOrder(BitfieldOrder order) { + this->m_bitfieldOrder = order; + } + + [[nodiscard]] BitfieldOrder getBitfieldOrder() { + return this->m_bitfieldOrder; + } + u64 &dataOffset() { return this->m_currOffset; } bool addCustomFunction(const std::string &name, u32 numParams, const ContentRegistry::PatternLanguage::Callback &function) { @@ -270,6 +284,7 @@ namespace hex::pl { std::atomic m_dangerousFunctionCalled = false; std::atomic m_allowDangerousFunctions = DangerousFunctionPermission::Ask; ControlFlowStatement m_currControlFlowStatement; + BitfieldOrder m_bitfieldOrder = BitfieldOrder::RightToLeft; friend class PatternCreationLimiter; }; diff --git a/lib/libimhex/source/pattern_language/pattern_language.cpp b/lib/libimhex/source/pattern_language/pattern_language.cpp index f6ba4d21e..7e6db842a 100644 --- a/lib/libimhex/source/pattern_language/pattern_language.cpp +++ b/lib/libimhex/source/pattern_language/pattern_language.cpp @@ -83,6 +83,18 @@ namespace hex::pl { ImHexApi::Provider::get()->setBaseAddress(baseAddress); return true; }); + + this->m_preprocessor->addPragmaHandler("bitfield_order", [this](const std::string &value) { + if (value == "left_to_right") { + this->m_evaluator->setBitfieldOrder(BitfieldOrder::LeftToRight); + return true; + } else if (value == "right_to_left") { + this->m_evaluator->setBitfieldOrder(BitfieldOrder::RightToLeft); + return true; + } else { + return false; + } + }); } PatternLanguage::~PatternLanguage() {