From 4754ed018d3a1b19142104eb31ded1ab327af7ae Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 18 Jan 2016 23:47:49 +0100 Subject: [PATCH] Add expression function evaluation, and endianness() function to retrieve endianness of current platform --- Archs/Architecture.cpp | 1 + CMakeLists.txt | 2 ++ Core/Expression.cpp | 47 ++++++++++++++++++++++++++++++++++++ Core/Expression.h | 1 + Core/ExpressionFunctions.cpp | 28 +++++++++++++++++++++ Core/ExpressionFunctions.h | 15 ++++++++++++ Core/FileManager.h | 1 + libarmips.vcxproj | 2 ++ libarmips.vcxproj.filters | 6 +++++ 9 files changed, 103 insertions(+) create mode 100644 Core/ExpressionFunctions.cpp create mode 100644 Core/ExpressionFunctions.h diff --git a/Archs/Architecture.cpp b/Archs/Architecture.cpp index 110fe2ab..b7c73280 100644 --- a/Archs/Architecture.cpp +++ b/Archs/Architecture.cpp @@ -14,6 +14,7 @@ ArchitectureCommand::ArchitectureCommand(const std::wstring& tempText, const std bool ArchitectureCommand::Validate() { position = g_fileManager->getVirtualAddress(); + g_fileManager->setEndianness(endianness); return false; } diff --git a/CMakeLists.txt b/CMakeLists.txt index 73273f71..753139fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,8 @@ add_executable(armips Core/Common.h Core/Expression.cpp Core/Expression.h + Core/ExpressionFunctions.cpp + Core/ExpressionFunctions.h Core/FileManager.cpp Core/FileManager.h Core/Misc.cpp diff --git a/Core/Expression.cpp b/Core/Expression.cpp index f97924dc..c03ca43a 100644 --- a/Core/Expression.cpp +++ b/Core/Expression.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Expression.h" #include "Common.h" +#include "ExpressionFunctions.h" enum class ExpressionValueCombination { @@ -513,6 +514,50 @@ void ExpressionInternal::replaceMemoryPos(const std::wstring& identifierName) } } +ExpressionValue ExpressionInternal::executeFunctionCall() +{ + ExpressionValue invalid; + + // find function, check parameter counts + auto it = expressionFunctions.find(strValue); + if (it == expressionFunctions.end()) + { + Logger::queueError(Logger::Error,L"Unknown function \"%s\"",strValue); + return invalid; + } + + if (it->second.minParams > childrenCount) + { + Logger::queueError(Logger::Error,L"Not enough parameters for \"%s\" (min %d)",strValue,it->second.minParams); + return invalid; + } + + if (it->second.maxParams < childrenCount) + { + Logger::queueError(Logger::Error,L"Too many parameters for \"%s\" (min %d)",strValue,it->second.maxParams); + return invalid; + } + + // evaluate parameters + std::vector params; + params.reserve(childrenCount); + + for (size_t i = 0; i < childrenCount; i++) + { + ExpressionValue result = children[i]->evaluate(); + if (result.isValid() == false) + { + Logger::queueError(Logger::Error,L"Invalid expression"); + return result; + } + + params.push_back(result); + } + + // execute + return it->second.function(params); +} + ExpressionValue ExpressionInternal::evaluate() { ExpressionValue val; @@ -620,6 +665,8 @@ ExpressionValue ExpressionInternal::evaluate() return children[2]->evaluate(); else return children[1]->evaluate(); + case OperatorType::FunctionCall: + return executeFunctionCall(); default: return val; } diff --git a/Core/Expression.h b/Core/Expression.h index 293e2ad1..5eea5ca7 100644 --- a/Core/Expression.h +++ b/Core/Expression.h @@ -128,6 +128,7 @@ class ExpressionInternal void allocate(size_t count); void deallocate(); std::wstring formatFunctionCall(); + ExpressionValue executeFunctionCall(); OperatorType type; ExpressionInternal** children; diff --git a/Core/ExpressionFunctions.cpp b/Core/ExpressionFunctions.cpp new file mode 100644 index 00000000..2103d0ac --- /dev/null +++ b/Core/ExpressionFunctions.cpp @@ -0,0 +1,28 @@ +#include "stdafx.h" +#include "ExpressionFunctions.h" +#include "Misc.h" +#include "Common.h" + +ExpressionValue expressionFunctionEndianness(const std::vector& parameters) +{ + Endianness endianness = g_fileManager->getEndianness(); + + ExpressionValue result; + result.type = ExpressionValueType::String; + + switch (endianness) + { + case Endianness::Little: + result.strValue = L"little"; + break; + case Endianness::Big: + result.strValue = L"big"; + break; + } + + return result; +} + +const ExpressionFunctionMap expressionFunctions = { + { L"endianness", { &expressionFunctionEndianness, 0, 0 } }, +}; diff --git a/Core/ExpressionFunctions.h b/Core/ExpressionFunctions.h new file mode 100644 index 00000000..52e85bd8 --- /dev/null +++ b/Core/ExpressionFunctions.h @@ -0,0 +1,15 @@ +#pragma once +#include "Expression.h" +#include + +typedef ExpressionValue (*ExpressionFunction)(const std::vector&); + +struct ExpressionFunctionEntry { + ExpressionFunction function; + size_t minParams; + size_t maxParams; +}; + +typedef std::map ExpressionFunctionMap; + +extern const ExpressionFunctionMap expressionFunctions; diff --git a/Core/FileManager.h b/Core/FileManager.h index 52270372..7de1282e 100644 --- a/Core/FileManager.h +++ b/Core/FileManager.h @@ -77,6 +77,7 @@ class FileManager bool advanceMemory(size_t bytes); AssemblerFile* getOpenFile() { return activeFile; }; void setEndianness(Endianness endianness) { this->endianness = endianness; }; + Endianness getEndianness() { return endianness; } private: bool checkActiveFile(); std::vector files; diff --git a/libarmips.vcxproj b/libarmips.vcxproj index ca99b3c6..88915804 100644 --- a/libarmips.vcxproj +++ b/libarmips.vcxproj @@ -244,6 +244,7 @@ + @@ -297,6 +298,7 @@ + diff --git a/libarmips.vcxproj.filters b/libarmips.vcxproj.filters index 6f0a723b..6d30e433 100644 --- a/libarmips.vcxproj.filters +++ b/libarmips.vcxproj.filters @@ -160,6 +160,9 @@ Archs\MIPS + + Core + @@ -295,5 +298,8 @@ Archs\MIPS + + Core + \ No newline at end of file