Removed the "Disassembler" namespace

Added experimental Clang compiler support
This commit is contained in:
flobernd 2014-11-03 15:15:48 +01:00
parent 11cb62c1ed
commit 319fe310e6
18 changed files with 197 additions and 380 deletions

View File

@ -30,99 +30,9 @@
**************************************************************************************************/
#include <tchar.h>
#include <iostream>
#include <iomanip>
#include "VXDisassembler.h"
#include <Windows.h>
using namespace Verteron;
using namespace Disassembler;
void testDecodingAndFormatting(uintptr_t baseAddress, PIMAGE_NT_HEADERS ntHeaders)
{
uint32_t sizeTotal = 0;
VXInstructionInfo info;
VXInstructionDecoder decoder;
VXIntelInstructionFormatter formatter;
#ifdef _M_X64
decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT);
#else
decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT);
#endif
while (sizeTotal < 1024 * 1024 * 50)
{
PIMAGE_SECTION_HEADER sectionHeader =
reinterpret_cast<PIMAGE_SECTION_HEADER>(
reinterpret_cast<uintptr_t>(ntHeaders) + sizeof(IMAGE_NT_HEADERS)
+ ntHeaders->FileHeader.SizeOfOptionalHeader - sizeof(IMAGE_OPTIONAL_HEADER));
// Decode and format all code sections
for (unsigned int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
{
if (sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE)
{
VXMemoryDataSource input(reinterpret_cast<const void*>(
baseAddress + sectionHeader->VirtualAddress), sectionHeader->SizeOfRawData);
decoder.setDataSource(&input);
decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress);
while (decoder.decodeInstruction(info))
{
formatter.formatInstruction(info);
}
sizeTotal += sectionHeader->SizeOfRawData;
}
sectionHeader++;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// Find kernel32.dll in memory
void *ntdllBase = GetModuleHandle(L"kernel32.dll");
PIMAGE_DOS_HEADER dosHeader = static_cast<PIMAGE_DOS_HEADER>(ntdllBase);
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
std::cout << "Error: kernel32.dll is corrupted.";
return 1;
}
PIMAGE_NT_HEADERS ntHeaders =
reinterpret_cast<PIMAGE_NT_HEADERS>(
reinterpret_cast<uintptr_t>(dosHeader) + dosHeader->e_lfanew);
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
{
std::cout << "Error: kernel32.dll is corrupted.";
return 1;
}
double pcFrequency;
uint64_t pcStart;
LARGE_INTEGER li;
// Start the performance counter
if (!QueryPerformanceFrequency(&li))
{
std::cout << "Error: QueryPerformanceFrequency failed.";
return 1;
}
pcFrequency = static_cast<double>(li.QuadPart) / 1000.0;
if (!QueryPerformanceCounter(&li))
{
std::cout << "Error: QueryPerformanceCounter failed.";
return 1;
}
pcStart = li.QuadPart;
// Perform decoding test
testDecodingAndFormatting(reinterpret_cast<uintptr_t>(ntdllBase), ntHeaders);
// Stop the performance counter
if (!QueryPerformanceCounter(&li))
{
std::cout << "Error: QueryPerformanceCounter failed.";
return 1;
}
std::cout << "Time: " << static_cast<double>(li.QuadPart - pcStart) / pcFrequency
<< std::endl;
std::cin.get();
// TODO:
return 0;
}

View File

@ -36,7 +36,6 @@
#include "VXDisassembler.h"
using namespace Verteron;
using namespace Disassembler;
int _tmain(int argc, _TCHAR* argv[])
{

View File

@ -37,7 +37,6 @@
#include <Windows.h>
using namespace Verteron;
using namespace Disassembler;
int _tmain(int argc, _TCHAR* argv[])
{
@ -61,7 +60,11 @@ int _tmain(int argc, _TCHAR* argv[])
VXInstructionDecoder decoder;
VXExactSymbolResolver resolver;
VXIntelInstructionFormatter formatter;
#ifdef _M_X64
decoder.setDisassemblerMode(VXDisassemblerMode::M64BIT);
#else
decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT);
#endif
formatter.setSymbolResolver(&resolver);
// Initialize output stream
std::ofstream out;
@ -83,7 +86,7 @@ int _tmain(int argc, _TCHAR* argv[])
decoder.setInstructionPointer(baseAddress + sectionHeader->VirtualAddress);
while (decoder.decodeInstruction(info))
{
// Skip invalid instructions and non-relative instructions
// Skip invalid and non-relative instructions
if ((info.flags & IF_ERROR_MASK) || !(info.flags & IF_RELATIVE))
{
continue;

View File

@ -11,13 +11,43 @@ Fast and lightweight x86/x86-64 disassembler library.
- SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES,
- AMD-V, INTEL-VMX, SMX
- Optimized for high performance
- Decoding and formatting of 50MiB takes about 1 second on a Intel Core i7 3930k @ 3.2GHz CPU
- Very small overhead compared to other common disassembler libraries
- Only 44.00 KiB (64 bit: 47.00 KiB) for the decoder and 62.00 KiB (64 bit: 69.50 KiB) with the optional formatting functionality
- Very small overhead compared to other common disassembler libraries (about 60KiB)
- Abstract formatter and symbol-resolver classes for custom syntax implementations.
- Intel syntax is implemented by default
- Complete doxygen documentation
## Quick Example ##
The following example program uses VDE to disassemble a given memory buffer and prints the output to the console.
```C++
#include <tchar.h>
#include <iostream>
#include <stdint.h>
#include "VXDisassembler.h"
using namespace Verteron;
int _tmain(int argc, _TCHAR* argv[])
{
uint8_t data[] =
{
0x90, 0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3
};
VXMemoryDataSource input(&data[0], sizeof(data));
VXInstructionInfo info;
VXInstructionDecoder decoder;
decoder.setDisassemblerMode(VXDisassemblerMode::M32BIT);
decoder.setDataSource(&input);
decoder.setInstructionPointer(0);
VXIntelInstructionFormatter formatter;
while (decoder.decodeInstruction(info))
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
```
## Compilation ##
- While VDE supports other compilers in theory, compilation has not been tested with any compiler other than MSVC12 (Visual Studio 2013)

View File

@ -34,5 +34,4 @@
#include "VXDisassemblerTypes.h"
#include "VXInstructionDecoder.h"
#include "VXInstructionFormatter.h"
#include "VXSymbolResolver.h"
#include "VXDisassemblerUtils.h"

View File

@ -37,9 +37,6 @@
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Values that represent additional flags of a decoded instruction.
*/
@ -530,5 +527,3 @@ struct VXInstructionInfo
};
}
}

View File

@ -30,13 +30,11 @@
**************************************************************************************************/
#include "VXDisassemblerUtils.h"
#include <assert.h>
namespace Verteron
{
namespace Disassembler
{
uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInfo &operand)
{
assert((operand.type == VXOperandType::REL_IMMEDIATE) ||
@ -74,5 +72,3 @@ uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInf
}
}
}

View File

@ -37,9 +37,6 @@
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Calculates the absolute target address of a relative instruction operand.
* @param info The instruction info.
@ -49,5 +46,3 @@ namespace Disassembler
uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInfo &operand);
}
}

View File

@ -35,9 +35,6 @@
namespace Verteron
{
namespace Disassembler
{
bool VXInstructionDecoder::decodeRegisterOperand(VXInstructionInfo &info, VXOperandInfo &operand,
RegisterClass registerClass, uint8_t registerId, VXDefinedOperandSize operandSize) const
{
@ -1304,5 +1301,3 @@ DecodeError:
}
}
}

View File

@ -38,9 +38,6 @@
namespace Verteron
{
namespace Disassembler
{
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
@ -195,7 +192,7 @@ inline uint8_t VXBaseDataSource::inputCurrent() const
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Implements a memory buffer based data source.
* @brief A memory-buffer based data source for the @c VXInstructionDecoder class.
*/
class VXMemoryDataSource : public VXBaseDataSource
{
@ -275,7 +272,7 @@ inline bool VXMemoryDataSource::setPosition(uint64_t position)
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Implements a stream based data source.
* @brief A stream based data source for the @c VXInstructionDecoder class.
*/
class VXStreamDataSource : public VXBaseDataSource
{
@ -719,5 +716,3 @@ inline void VXInstructionDecoder::setInstructionPointer(uint64_t instructionPoin
///////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -37,9 +37,21 @@
namespace Verteron
{
namespace Disassembler
///////////////////////////////////////////////////////////////////////////////////////////////////
VXBaseSymbolResolver::~VXBaseSymbolResolver()
{
}
const char* VXBaseSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
const char* VXBaseInstructionFormatter::m_registerStrings[] =
{
/* 8 bit general purpose registers */
@ -104,7 +116,7 @@ void VXBaseInstructionFormatter::internalFormatInstruction(const VXInstructionIn
VXBaseInstructionFormatter::VXBaseInstructionFormatter()
: m_symbolResolver(nullptr)
, m_outputStringLen(0)
, m_uppercase(false)
, m_outputUppercase(false)
{
}
@ -112,7 +124,7 @@ VXBaseInstructionFormatter::VXBaseInstructionFormatter()
VXBaseInstructionFormatter::VXBaseInstructionFormatter(VXBaseSymbolResolver *symbolResolver)
: m_symbolResolver(symbolResolver)
, m_outputStringLen(0)
, m_uppercase(false)
, m_outputUppercase(false)
{
}
@ -167,7 +179,7 @@ char const* VXBaseInstructionFormatter::outputString()
// Increase the string length
m_outputStringLen = offset + strLen;
// Convert to uppercase
if (m_uppercase)
if (m_outputUppercase)
{
for (size_t i = offset; i < m_outputStringLen - 1; ++i)
{
@ -208,7 +220,7 @@ char const* VXBaseInstructionFormatter::outputString()
// Increase the string length
m_outputStringLen = offset + strLen + 1;
// Convert to uppercase
if (m_uppercase)
if (m_outputUppercase)
{
for (size_t i = offset; i < m_outputStringLen - 1; ++i)
{
@ -318,7 +330,7 @@ void VXBaseInstructionFormatter::outputAppendDisplacement(const VXInstructionInf
const VXOperandInfo &operand)
{
assert(operand.offset > 0);
if (operand.base == VXRegister::NONE && operand.index == VXRegister::NONE)
if ((operand.base == VXRegister::NONE) && (operand.index == VXRegister::NONE))
{
// Assume the displacement value is unsigned
assert(operand.scale == 0);
@ -598,6 +610,46 @@ VXIntelInstructionFormatter::~VXIntelInstructionFormatter()
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
VXExactSymbolResolver::~VXExactSymbolResolver()
{
}
const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
if (iterator != m_symbolMap.end())
{
offset = 0;
return iterator->second.c_str();
}
return nullptr;
}
bool VXExactSymbolResolver::containsSymbol(uint64_t address) const
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
return (iterator != m_symbolMap.end());
}
void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name)
{
m_symbolMap[address].assign(name);
}
void VXExactSymbolResolver::removeSymbol(uint64_t address)
{
m_symbolMap.erase(address);
}
void VXExactSymbolResolver::clear()
{
m_symbolMap.clear();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -32,14 +32,38 @@
#pragma once
#include <vector>
#include <unordered_map>
#include "VXDisassemblerTypes.h"
#include "VXSymbolResolver.h"
namespace Verteron
{
namespace Disassembler
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Base class for all symbol resolver implementations.
*/
class VXBaseSymbolResolver
{
public:
/**
* @brief Destructor.
*/
virtual ~VXBaseSymbolResolver();
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
virtual const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Base class for all instruction formatter implementations.
@ -51,7 +75,7 @@ private:
VXBaseSymbolResolver *m_symbolResolver;
std::vector<char> m_outputBuffer;
size_t m_outputStringLen;
bool m_uppercase;
bool m_outputUppercase;
protected:
/**
* @brief Clears the output string buffer.
@ -164,7 +188,7 @@ public:
inline void VXBaseInstructionFormatter::outputSetUppercase(bool uppercase)
{
m_uppercase = uppercase;
m_outputUppercase = uppercase;
}
inline char const* VXBaseInstructionFormatter::registerToString(VXRegister reg) const
@ -240,6 +264,56 @@ public:
~VXIntelInstructionFormatter() override;
};
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Simple symbol resolver that only matches exact addresses.
*/
class VXExactSymbolResolver : public VXBaseSymbolResolver
{
private:
std::unordered_map<uint64_t, std::string> m_symbolMap;
public:
/**
* @brief Destructor.
*/
~VXExactSymbolResolver() override;
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset) override;
public:
/**
* @brief Query if the given address is a known symbol.
* @param address The address.
* @return True if the address is known, false if not.
*/
bool containsSymbol(uint64_t address) const;
/**
* @brief Adds or changes a symbol.
* @param address The address.
* @param name The symbol name.
*/
void setSymbol(uint64_t address, const char* name);
/**
* @brief Removes the symbol described by address. This will invalidate all char pointers
* to the specific symbol name.
* @param address The address.
*/
void removeSymbol(uint64_t address);
/**
* @brief Clears the symbol tree.
*/
void clear();
};
///////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -34,16 +34,13 @@
namespace Verteron
{
namespace Disassembler
{
namespace Internal
{
#define INVALID 0
#define NODE(type, n) (static_cast<VXOpcodeTreeNode>(type) << 12 | (n))
static const VXOpcodeTreeNode optreeTable[][256] =
const VXOpcodeTreeNode optreeTable[][256] =
{
{
/* 00 */ 0x0015,
@ -2627,7 +2624,7 @@ static const VXOpcodeTreeNode optreeTable[][256] =
},
};
static const VXOpcodeTreeNode optreeModrmMod[][2] =
const VXOpcodeTreeNode optreeModrmMod[][2] =
{
{
/* 00 */ NODE(VXOpcodeTreeNodeType::MANDATORY, 0x0001),
@ -2747,7 +2744,7 @@ static const VXOpcodeTreeNode optreeModrmMod[][2] =
},
};
static const VXOpcodeTreeNode optreeModrmReg[][8] =
const VXOpcodeTreeNode optreeModrmReg[][8] =
{
{
/* 00 */ 0x0531,
@ -3231,7 +3228,7 @@ static const VXOpcodeTreeNode optreeModrmReg[][8] =
},
};
static const VXOpcodeTreeNode optreeModrmRm[][8] =
const VXOpcodeTreeNode optreeModrmRm[][8] =
{
{
/* 00 */ INVALID,
@ -3375,7 +3372,7 @@ static const VXOpcodeTreeNode optreeModrmRm[][8] =
},
};
static const VXOpcodeTreeNode optreeMandatory[][4] =
const VXOpcodeTreeNode optreeMandatory[][4] =
{
{
/* 00 */ NODE(VXOpcodeTreeNodeType::MODRM_REG, 0x0000),
@ -5293,7 +5290,7 @@ static const VXOpcodeTreeNode optreeMandatory[][4] =
},
};
static const VXOpcodeTreeNode optreeX87[][64] =
const VXOpcodeTreeNode optreeX87[][64] =
{
{
/* 00 */ 0x00BC,
@ -5825,7 +5822,7 @@ static const VXOpcodeTreeNode optreeX87[][64] =
},
};
static const VXOpcodeTreeNode optreeAddressSize[][3] =
const VXOpcodeTreeNode optreeAddressSize[][3] =
{
{
/* 00 */ 0x02CD,
@ -5834,7 +5831,7 @@ static const VXOpcodeTreeNode optreeAddressSize[][3] =
},
};
static const VXOpcodeTreeNode optreeOperandSize[][3] =
const VXOpcodeTreeNode optreeOperandSize[][3] =
{
{
/* 00 */ 0x03E0,
@ -5958,7 +5955,7 @@ static const VXOpcodeTreeNode optreeOperandSize[][3] =
},
};
static const VXOpcodeTreeNode optreeMode[][2] =
const VXOpcodeTreeNode optreeMode[][2] =
{
{
/* 00 */ 0x04AA,
@ -6142,7 +6139,7 @@ static const VXOpcodeTreeNode optreeMode[][2] =
},
};
static const VXOpcodeTreeNode optreeVendor[][2] =
const VXOpcodeTreeNode optreeVendor[][2] =
{
{
/* 00 */ INVALID,
@ -6246,7 +6243,7 @@ static const VXOpcodeTreeNode optreeVendor[][2] =
},
};
static const VXOpcodeTreeNode optree3dnow[][256] =
const VXOpcodeTreeNode optree3dnow[][256] =
{
{
/* 00 */ INVALID,
@ -6508,7 +6505,7 @@ static const VXOpcodeTreeNode optree3dnow[][256] =
},
};
static const VXOpcodeTreeNode optreeVex[][16] =
const VXOpcodeTreeNode optreeVex[][16] =
{
{
/* 00 */ NODE(VXOpcodeTreeNodeType::MODE, 0x0024),
@ -6548,7 +6545,7 @@ static const VXOpcodeTreeNode optreeVex[][16] =
},
};
static const VXOpcodeTreeNode optreeVexW[][2] =
const VXOpcodeTreeNode optreeVexW[][2] =
{
{
/* 00 */ 0x061D,
@ -6652,7 +6649,7 @@ static const VXOpcodeTreeNode optreeVexW[][2] =
},
};
static const VXOpcodeTreeNode optreeVexL[][2] =
const VXOpcodeTreeNode optreeVexL[][2] =
{
{
/* 00 */ 0x069C,
@ -6865,7 +6862,7 @@ static const VXOpcodeTreeNode optreeVexL[][2] =
#define OPI_sIb { VXDefinedOperandType::sI, VXDefinedOperandSize::B }
#define OPI_sIz { VXDefinedOperandType::sI, VXDefinedOperandSize::Z }
static const VXInstructionDefinition instrDefinitions[] =
const VXInstructionDefinition instrDefinitions[] =
{
/* 000 */ { VXInstructionMnemonic::INVALID, { OPI_NONE, OPI_NONE, OPI_NONE, OPI_NONE }, 0 },
/* 001 */ { VXInstructionMnemonic::AAA, { OPI_NONE, OPI_NONE, OPI_NONE, OPI_NONE }, 0 },
@ -9656,5 +9653,3 @@ const char* instrMnemonicStrings[] =
}
}
}

View File

@ -37,9 +37,6 @@
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Values that represent an instruction mnemonic.
*/
@ -1754,5 +1751,3 @@ inline VXDefinedOperandSize VDEGetComplexOperandRegSize(VXDefinedOperandSize ope
}
}
}

View File

@ -1,93 +0,0 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 29. October 2014
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**************************************************************************************************/
#include "VXSymbolResolver.h"
namespace Verteron
{
namespace Disassembler
{
VXBaseSymbolResolver::~VXBaseSymbolResolver()
{
}
const char* VXBaseSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
VXExactSymbolResolver::~VXExactSymbolResolver()
{
}
const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
if (iterator != m_symbolMap.end())
{
offset = 0;
return iterator->second.c_str();
}
return nullptr;
}
bool VXExactSymbolResolver::containsSymbol(uint64_t address) const
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
return (iterator != m_symbolMap.end());
}
void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name)
{
m_symbolMap[address].assign(name);
}
void VXExactSymbolResolver::removeSymbol(uint64_t address)
{
m_symbolMap.erase(address);
}
void VXExactSymbolResolver::clear()
{
m_symbolMap.clear();
}
}
}

View File

@ -1,119 +0,0 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 29. October 2014
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**************************************************************************************************/
#pragma once
#include <string>
#include <unordered_map>
#include "VXDisassemblerTypes.h"
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Base class for all symbol resolver implementations.
*/
class VXBaseSymbolResolver
{
public:
/**
* @brief Destructor.
*/
virtual ~VXBaseSymbolResolver();
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
virtual const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Simple symbol resolver that only matches exact addresses.
*/
class VXExactSymbolResolver : public VXBaseSymbolResolver
{
private:
std::unordered_map<uint64_t, std::string> m_symbolMap;
public:
/**
* @brief Destructor.
*/
~VXExactSymbolResolver() override;
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset) override;
public:
/**
* @brief Query if the given address is a known symbol.
* @param address The address.
* @return True if the address is known, false if not.
*/
bool containsSymbol(uint64_t address) const;
/**
* @brief Adds or changes a symbol.
* @param address The address.
* @param name The symbol name.
*/
void setSymbol(uint64_t address, const char* name);
/**
* @brief Removes the symbol described by address. This will invalidate all char pointers
* to the specific symbol name.
* @param address The address.
*/
void removeSymbol(uint64_t address);
/**
* @brief Clears the symbol tree.
*/
void clear();
};
}
}

View File

@ -25,14 +25,12 @@
<ClInclude Include="VXInstructionDecoder.h" />
<ClInclude Include="VXInstructionFormatter.h" />
<ClInclude Include="VXOpcodeTable.h" />
<ClInclude Include="VXSymbolResolver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="VXDisassemblerUtils.cpp" />
<ClCompile Include="VXInstructionDecoder.cpp" />
<ClCompile Include="VXInstructionFormatter.cpp" />
<ClCompile Include="VXOpcodeTable.cpp" />
<ClCompile Include="VXSymbolResolver.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F5C6F0A7-F75D-42BD-A8AB-A2D1D5F67099}</ProjectGuid>

View File

@ -3,17 +3,15 @@
<ItemGroup>
<ClInclude Include="VXDisassembler.h" />
<ClInclude Include="VXDisassemblerTypes.h" />
<ClInclude Include="VXDisassemblerUtils.h" />
<ClInclude Include="VXInstructionDecoder.h" />
<ClInclude Include="VXInstructionFormatter.h" />
<ClInclude Include="VXOpcodeTable.h" />
<ClInclude Include="VXSymbolResolver.h" />
<ClInclude Include="VXDisassemblerUtils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="VXDisassemblerUtils.cpp" />
<ClCompile Include="VXInstructionDecoder.cpp" />
<ClCompile Include="VXInstructionFormatter.cpp" />
<ClCompile Include="VXOpcodeTable.cpp" />
<ClCompile Include="VXSymbolResolver.cpp" />
<ClCompile Include="VXDisassemblerUtils.cpp" />
</ItemGroup>
</Project>