Permalink
Browse files

Merge pull request #130 from sp1187/exprfunc

Implement support for arch-specific expression functions
  • Loading branch information...
Kingcom committed Jan 13, 2018
2 parents c082e18 + 830ffa8 commit e2610fe1c654c4b78e966d824d6d3189cb6acaac
@@ -3,6 +3,7 @@
#include "Core/Common.h"
#include "ArmRelocator.h"
#include "ArmParser.h"
#include "ArmExpressionFunctions.h"

CArmArchitecture Arm;

@@ -33,6 +34,11 @@ CAssemblerCommand* CArmArchitecture::parseOpcode(Parser& parser)
return armParser.parseArmOpcode(parser);
}

const ExpressionFunctionMap& CArmArchitecture::getExpressionFunctions()
{
return armExpressionFunctions;
}

void CArmArchitecture::clear()
{
currentPoolContent.clear();
@@ -1,8 +1,5 @@
#pragma once
#include "Archs/Architecture.h"
#include "Pool.h"
#include "Core/Expression.h"
#include "Parser/Tokenizer.h"

#define ARM_SHIFT_LSL 0x00
#define ARM_SHIFT_LSR 0x01
@@ -40,6 +37,7 @@ class CArmArchitecture: public CArchitecture

virtual CAssemblerCommand* parseDirective(Parser& parser);
virtual CAssemblerCommand* parseOpcode(Parser& parser);
virtual const ExpressionFunctionMap& getExpressionFunctions();
virtual void NextSection();
virtual void Pass2();
virtual void Revalidate();
@@ -0,0 +1,26 @@
#include "stdafx.h"
#include "Core/ExpressionFunctions.h"
#include "Core/Common.h"
#include "ArmExpressionFunctions.h"
#include "Arm.h"

#define GET_PARAM(params,index,dest) \
if (getExpFuncParameter(params,index,dest,funcName,false) == false) \
return ExpressionValue();

ExpressionValue expFuncIsArm(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
bool isArm = Arch == &Arm && Arm.GetThumbMode() == false;
return ExpressionValue(isArm ? INT64_C(1) : INT64_C(0));
}

ExpressionValue expFuncIsThumb(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
bool isThumb = Arm.GetThumbMode() == true;
return ExpressionValue(isThumb ? INT64_C(1) : INT64_C(0));
}

const ExpressionFunctionMap armExpressionFunctions = {
{ L"isarm", { &expFuncIsArm, 0, 0, ExpFuncSafety::Safe } },
{ L"isthumb", { &expFuncIsThumb, 0, 0, ExpFuncSafety::Safe } },
};
@@ -0,0 +1,3 @@
#pragma once

extern const ExpressionFunctionMap armExpressionFunctions;
@@ -22,4 +22,4 @@ class ArmElfRelocator: public IElfRelocator
virtual CAssemblerCommand* generateCtorStub(std::vector<ElfRelocatorCtor>& ctors);
private:
bool arm9;
};
};
@@ -1,5 +1,6 @@
#pragma once
#include "../Commands/CAssemblerCommand.h"
#include "../Core/ExpressionFunctions.h"
#include "../Core/FileManager.h"

class IElfRelocator;
@@ -9,13 +10,16 @@ class Parser;
class CArchitecture
{
public:
virtual CAssemblerCommand* parseDirective(Parser& parserr) { return nullptr; };
virtual CAssemblerCommand* parseOpcode(Parser& parser) { return nullptr; };
virtual CAssemblerCommand* parseDirective(Parser& parser) { return nullptr; }
virtual CAssemblerCommand* parseOpcode(Parser& parser) { return nullptr; }
virtual const ExpressionFunctionMap& getExpressionFunctions() { return emptyMap; }
virtual void NextSection() = 0;
virtual void Pass2() = 0;
virtual void Revalidate() = 0;
virtual IElfRelocator* getElfRelocator() = 0;
virtual Endianness getEndianness() = 0;
private:
const ExpressionFunctionMap emptyMap = {};
};

class ArchitectureCommand: public CAssemblerCommand
@@ -1,14 +1,8 @@
#include "stdafx.h"
#include "Mips.h"
#include "CMipsInstruction.h"
#include "Core/Common.h"
#include "MipsMacros.h"
#include "Core/FileManager.h"
#include "MipsElfFile.h"
#include "Commands/CDirectiveFile.h"
#include "PsxRelocator.h"
#include "MipsParser.h"
#include "Parser/Parser.h"
#include "MipsExpressionFunctions.h"

CMipsArchitecture Mips;

@@ -24,7 +18,7 @@ bool MipsElfRelocator::relocateOpcode(int type, RelocationData& data)
break;
case R_MIPS_32:
op += (int) data.relocationBase;
break;
break;
case R_MIPS_HI16:
p = (op & 0xFFFF) + (int) data.relocationBase;
op = (op&0xffff0000) | (((p >> 16) + ((p & 0x8000) != 0)) & 0xFFFF);
@@ -132,6 +126,11 @@ CAssemblerCommand* CMipsArchitecture::parseOpcode(Parser& parser)
return mipsParser.parseOpcode(parser);
}

const ExpressionFunctionMap& CMipsArchitecture::getExpressionFunctions()
{
return mipsExpressionFunctions;
}

void CMipsArchitecture::NextSection()
{
LoadDelay = false;
@@ -1,6 +1,5 @@
#pragma once
#include "Archs/Architecture.h"
#include "Core/Expression.h"
#include "Core/ELF/ElfRelocator.h"

enum MipsArchType { MARCH_PSX = 0, MARCH_N64, MARCH_PS2, MARCH_PSP, MARCH_RSP, MARCH_INVALID };
@@ -27,6 +26,7 @@ class CMipsArchitecture: public CArchitecture
CMipsArchitecture();
virtual CAssemblerCommand* parseDirective(Parser& parser);
virtual CAssemblerCommand* parseOpcode(Parser& parser);
virtual const ExpressionFunctionMap& getExpressionFunctions();
virtual void NextSection();
virtual void Pass2() { return; };
virtual void Revalidate();
@@ -0,0 +1,30 @@
#include "stdafx.h"
#include "Core/ExpressionFunctions.h"
#include "MipsExpressionFunctions.h"

#define GET_PARAM(params,index,dest) \
if (getExpFuncParameter(params,index,dest,funcName,false) == false) \
return ExpressionValue();

ExpressionValue expFuncHi(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
int64_t value;

GET_PARAM(parameters,0,value);

return ExpressionValue((int64_t)((value >> 16) + ((value & 0x8000) != 0)) & 0xFFFF);
}

ExpressionValue expFuncLo(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
int64_t value;

GET_PARAM(parameters,0,value);

return ExpressionValue((int64_t)(int16_t)(value & 0xFFFF));
}

const ExpressionFunctionMap mipsExpressionFunctions = {
{ L"lo", { &expFuncLo, 1, 1, ExpFuncSafety::Safe } },
{ L"hi", { &expFuncHi, 1, 1, ExpFuncSafety::Safe } },
};
@@ -0,0 +1,3 @@
#pragma once

extern const ExpressionFunctionMap mipsExpressionFunctions;
@@ -26,6 +26,8 @@ add_library(armips STATIC

Archs/ARM/Arm.cpp
Archs/ARM/Arm.h
Archs/ARM/ArmExpressionFunctions.cpp
Archs/ARM/ArmExpressionFunctions.h
Archs/ARM/ArmOpcodes.cpp
Archs/ARM/ArmOpcodes.h
Archs/ARM/ArmParser.cpp
@@ -47,6 +49,8 @@ add_library(armips STATIC
Archs/MIPS/Mips.h
Archs/MIPS/MipsElfFile.cpp
Archs/MIPS/MipsElfFile.h
Archs/MIPS/MipsExpressionFunctions.cpp
Archs/MIPS/MipsExpressionFunctions.h
Archs/MIPS/MipsMacros.cpp
Archs/MIPS/MipsMacros.h
Archs/MIPS/MipsOpcodes.cpp
@@ -541,8 +541,13 @@ ExpressionValue ExpressionInternal::executeFunctionCall()
auto it = expressionFunctions.find(strValue);
if (it == expressionFunctions.end())
{
Logger::queueError(Logger::Error,L"Unknown function \"%s\"",strValue);
return invalid;
auto archExpressionFunctions = Arch->getExpressionFunctions();
it = archExpressionFunctions.find(strValue);
if (it == archExpressionFunctions.end())
{
Logger::queueError(Logger::Error,L"Unknown function \"%s\"",strValue);
return invalid;
}
}

if (checkParameterCount(it->second.minParams,it->second.maxParams) == false)
@@ -5,7 +5,6 @@
#if ARMIPS_REGEXP
#include <regex>
#endif
#include "../Archs/ARM/Arm.h"

bool getExpFuncParameter(const std::vector<ExpressionValue>& parameters, size_t index, int64_t& dest,
const std::wstring& funcName, bool optional)
@@ -487,35 +486,7 @@ ExpressionValue expFuncDefined(ExpressionInternal* exp)
return ExpressionValue(label->isDefined() ? INT64_C(1) : INT64_C(0));
}

ExpressionValue expFuncIsArm(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
bool isArm = Arch == &Arm && Arm.GetThumbMode() == false;
return ExpressionValue(isArm ? INT64_C(1) : INT64_C(0));
}

ExpressionValue expFuncIsThumb(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
bool isThumb = Arch == &Arm && Arm.GetThumbMode() == true;
return ExpressionValue(isThumb ? INT64_C(1) : INT64_C(0));
}

ExpressionValue expFuncHi(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
int64_t value;

GET_PARAM(parameters,0,value);

return ExpressionValue((int64_t)((value >> 16) + ((value & 0x8000) != 0)) & 0xFFFF);
}

ExpressionValue expFuncLo(const std::wstring& funcName, const std::vector<ExpressionValue>& parameters)
{
int64_t value;

GET_PARAM(parameters,0,value);

return ExpressionValue((int64_t)(int16_t)(value & 0xFFFF));
}

const ExpressionFunctionMap expressionFunctions = {
{ L"version", { &expFuncVersion, 0, 0, ExpFuncSafety::Safe } },
@@ -555,10 +526,4 @@ const ExpressionFunctionMap expressionFunctions = {
{ L"reads32", { &expFuncRead<int32_t>, 1, 2, ExpFuncSafety::ConditionalUnsafe } },
{ L"reads64", { &expFuncRead<int64_t>, 1, 2, ExpFuncSafety::ConditionalUnsafe } },
{ L"readascii", { &expFuncReadAscii, 1, 3, ExpFuncSafety::ConditionalUnsafe } },

{ L"lo", { &expFuncLo, 1, 1, ExpFuncSafety::Safe } },
{ L"hi", { &expFuncHi, 1, 1, ExpFuncSafety::Safe } },

{ L"isarm", { &expFuncIsArm, 0, 0, ExpFuncSafety::Safe } },
{ L"isthumb", { &expFuncIsThumb, 0, 0, ExpFuncSafety::Safe } },
};
@@ -2,7 +2,13 @@
#include "Expression.h"
#include <map>

typedef ExpressionValue (*ExpressionFunction)(const std::wstring& funcName, const std::vector<ExpressionValue>&);
bool getExpFuncParameter(const std::vector<ExpressionValue>& parameters, size_t index, int64_t& dest,
const std::wstring& funcName, bool optional);

bool getExpFuncParameter(const std::vector<ExpressionValue>& parameters, size_t index, const std::wstring*& dest,
const std::wstring& funcName, bool optional);

using ExpressionFunction = ExpressionValue (*)(const std::wstring& funcName, const std::vector<ExpressionValue>&);

enum class ExpFuncSafety
{
@@ -22,8 +28,9 @@ struct ExpressionFunctionEntry
ExpFuncSafety safety;
};

typedef std::map<std::wstring, const ExpressionFunctionEntry> ExpressionFunctionMap;
using ExpressionFunctionMap = std::map<std::wstring, const ExpressionFunctionEntry>;;

extern const ExpressionFunctionMap expressionFunctions;

ExpressionValue expFuncDefined(ExpressionInternal* exp);

@@ -1,4 +1,4 @@
.psx
.nds
.create "output.bin", 0

label:
@@ -29,9 +29,10 @@ label:
.byte 31h
.endif

.thumb

; test .ifndef and .ifarm
; expected: 42h

.ifndef label
.byte 40h
.else
@@ -42,9 +43,6 @@ label:
.endif
.endif

.nds
.thumb

; test nested ifs and .ifthumb
; expected: 50h
.if 5 < 6
@@ -61,4 +59,4 @@ label:
.byte 53h
.endif

.close
.close
@@ -217,6 +217,7 @@
<ItemGroup>
<ClCompile Include="Archs\Architecture.cpp" />
<ClCompile Include="Archs\ARM\Arm.cpp" />
<ClCompile Include="Archs\ARM\ArmExpressionFunctions.cpp" />
<ClCompile Include="Archs\ARM\ArmOpcodes.cpp" />
<ClCompile Include="Archs\ARM\ArmParser.cpp" />
<ClCompile Include="Archs\ARM\ArmRelocator.cpp" />
@@ -227,6 +228,7 @@
<ClCompile Include="Archs\MIPS\CMipsInstruction.cpp" />
<ClCompile Include="Archs\MIPS\Mips.cpp" />
<ClCompile Include="Archs\MIPS\MipsElfFile.cpp" />
<ClCompile Include="Archs\MIPS\MipsExpressionFunctions.cpp" />
<ClCompile Include="Archs\MIPS\MipsMacros.cpp" />
<ClCompile Include="Archs\MIPS\MipsOpcodes.cpp" />
<ClCompile Include="Archs\MIPS\MipsParser.cpp" />
@@ -270,6 +272,7 @@
<ItemGroup>
<ClInclude Include="Archs\Architecture.h" />
<ClInclude Include="Archs\ARM\Arm.h" />
<ClInclude Include="Archs\ARM\ArmExpressionFunctions.h" />
<ClInclude Include="Archs\ARM\ArmOpcodes.h" />
<ClInclude Include="Archs\ARM\ArmParser.h" />
<ClInclude Include="Archs\ARM\ArmRelocator.h" />
@@ -280,6 +283,7 @@
<ClInclude Include="Archs\MIPS\CMipsInstruction.h" />
<ClInclude Include="Archs\MIPS\Mips.h" />
<ClInclude Include="Archs\MIPS\MipsElfFile.h" />
<ClInclude Include="Archs\MIPS\MipsExpressionFunctions.h" />
<ClInclude Include="Archs\MIPS\MipsMacros.h" />
<ClInclude Include="Archs\MIPS\MipsOpcodes.h" />
<ClInclude Include="Archs\MIPS\MipsParser.h" />
@@ -318,4 +322,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
Oops, something went wrong.

0 comments on commit e2610fe

Please sign in to comment.