From 2dbfbe70afb8fb62cb839f870b8b87a5d2c52abb Mon Sep 17 00:00:00 2001 From: WerWolv Date: Thu, 7 Jan 2021 01:56:15 +0100 Subject: [PATCH] Fixed rvalue value evaluation --- plugins/libimhex/include/helpers/utils.hpp | 5 ++++ source/lang/evaluator.cpp | 33 ++++++++++++---------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/plugins/libimhex/include/helpers/utils.hpp b/plugins/libimhex/include/helpers/utils.hpp index b281de1ef..79b2a55cc 100644 --- a/plugins/libimhex/include/helpers/utils.hpp +++ b/plugins/libimhex/include/helpers/utils.hpp @@ -135,6 +135,11 @@ namespace hex { return __builtin_bswap32(value); else if (size == 8) return __builtin_bswap64(value); + else if (size == 16) { + u64 parts[2]; + memcpy(parts, &value, size); + return u128(parts[1]) << 64 | u128(parts[0]); + } else throw std::invalid_argument("Invalid value size!"); } diff --git a/source/lang/evaluator.cpp b/source/lang/evaluator.cpp index 828a9323a..28a915619 100644 --- a/source/lang/evaluator.cpp +++ b/source/lang/evaluator.cpp @@ -1,6 +1,7 @@ #include "lang/evaluator.hpp" #include "lang/token.hpp" +#include "helpers/utils.hpp" #include #include @@ -60,11 +61,11 @@ namespace hex::lang { this->m_provider->read(unsignedPattern->getOffset(), value, unsignedPattern->getSize()); switch (unsignedPattern->getSize()) { - case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, *reinterpret_cast(value) }); - case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned16Bit, *reinterpret_cast(value) }); - case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned32Bit, *reinterpret_cast(value) }); - case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned64Bit, *reinterpret_cast(value) }); - case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned128Bit, *reinterpret_cast(value) }); + case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, hex::changeEndianess(*reinterpret_cast(value), 1, this->getCurrentEndian()) }); + case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned16Bit, hex::changeEndianess(*reinterpret_cast(value), 2, this->getCurrentEndian()) }); + case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned32Bit, hex::changeEndianess(*reinterpret_cast(value), 4, this->getCurrentEndian()) }); + case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned64Bit, hex::changeEndianess(*reinterpret_cast(value), 8, this->getCurrentEndian()) }); + case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned128Bit, hex::changeEndianess(*reinterpret_cast(value), 16, this->getCurrentEndian()) }); default: throwEvaluateError("invalid rvalue size", node->getLineNumber()); } } else if (auto signedPattern = dynamic_cast(currPattern); signedPattern != nullptr) { @@ -72,23 +73,25 @@ namespace hex::lang { this->m_provider->read(signedPattern->getOffset(), value, signedPattern->getSize()); switch (unsignedPattern->getSize()) { - case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed8Bit, *reinterpret_cast(value) }); - case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed16Bit, *reinterpret_cast(value) }); - case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed32Bit, *reinterpret_cast(value) }); - case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed64Bit, *reinterpret_cast(value) }); - case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed128Bit, *reinterpret_cast(value) }); + case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed8Bit, hex::changeEndianess(*reinterpret_cast(value), 1, this->getCurrentEndian()) }); + case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed16Bit, hex::changeEndianess(*reinterpret_cast(value), 2, this->getCurrentEndian()) }); + case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed32Bit, hex::changeEndianess(*reinterpret_cast(value), 4, this->getCurrentEndian()) }); + case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed64Bit, hex::changeEndianess(*reinterpret_cast(value), 8, this->getCurrentEndian()) }); + case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed128Bit, hex::changeEndianess(*reinterpret_cast(value), 16, this->getCurrentEndian()) }); default: throwEvaluateError("invalid rvalue size", node->getLineNumber()); } } else if (auto enumPattern = dynamic_cast(currPattern); enumPattern != nullptr) { u8 value[enumPattern->getSize()]; this->m_provider->read(enumPattern->getOffset(), value, enumPattern->getSize()); + + switch (enumPattern->getSize()) { - case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed8Bit, *reinterpret_cast(value) }); - case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed16Bit, *reinterpret_cast(value) }); - case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed32Bit, *reinterpret_cast(value) }); - case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed64Bit, *reinterpret_cast(value) }); - case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Signed128Bit, *reinterpret_cast(value) }); + case 1: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, hex::changeEndianess(*reinterpret_cast(value), 1, this->getCurrentEndian()) }); + case 2: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned16Bit, hex::changeEndianess(*reinterpret_cast(value), 2, this->getCurrentEndian()) }); + case 4: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned32Bit, hex::changeEndianess(*reinterpret_cast(value), 4, this->getCurrentEndian()) }); + case 8: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned64Bit, hex::changeEndianess(*reinterpret_cast(value), 8, this->getCurrentEndian()) }); + case 16: return new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned128Bit, hex::changeEndianess(*reinterpret_cast(value), 16, this->getCurrentEndian()) }); default: throwEvaluateError("invalid rvalue size", node->getLineNumber()); } } else