Basic disassembler

This commit is contained in:
Dani Messerman 2015-04-27 22:53:27 +03:00
parent 927e20fb6e
commit 26ff6094e2
5 changed files with 209 additions and 0 deletions

View File

@ -2,10 +2,14 @@ set(SRCS
main.cpp
CodeGen.cpp
ModuleGen.cpp
Disassembler.cpp
Instruction.cpp
)
set(HEADERS
CodeGen.h
ModuleGen.h
Disassembler.h
Instruction.h
)
create_directory_groups(${SRCS} ${HEADERS})

View File

@ -0,0 +1,23 @@
#include "Disassembler.h"
#include "Instruction.h"
#include <vector>
std::vector<RegisterInstructionBase::CreateFunctionType> g_read_functions;
RegisterInstructionBase::RegisterInstructionBase(CreateFunctionType create_function)
{
g_read_functions.push_back(create_function);
}
std::unique_ptr<Instruction> Disassmbler::Disassemble(u32 instruction, u32 address)
{
for (auto read_function : g_read_functions)
{
auto result = read_function(instruction, address);
if (result != nullptr)
{
return std::unique_ptr<Instruction>(result);
}
}
return nullptr;
}

View File

@ -0,0 +1,43 @@
#include "common/common_types.h"
#include <memory>
class Instruction;
class Disassmbler
{
public:
/*
* Returns the instruction at address or null if unknown or not translatable
* address is used for PC relative operations
*/
static std::unique_ptr<Instruction> Disassemble(u32 instruction, u32 address);
};
class RegisterInstructionBase
{
public:
typedef Instruction *(*CreateFunctionType)(u32 instruction, u32 address);
RegisterInstructionBase(CreateFunctionType create_function);
};
/*
* Instantiate this class in a source file to register instruction in the disassembler
*/
template<typename DerivedInstruction>
class RegisterInstruction : RegisterInstructionBase
{
public:
RegisterInstruction() : RegisterInstructionBase(&RegisterInstruction::Create) {}
private:
static Instruction *Create(u32 instruction, u32 address)
{
auto result = new DerivedInstruction(instruction, address);
if (!result->Read())
{
delete result;
return nullptr;
}
return result;
}
};

View File

@ -0,0 +1,52 @@
#include "Instruction.h"
#include <cassert>
Instruction::Instruction(u32 instruction, u32 address) : instruction(instruction), address(address)
{
}
Instruction::~Instruction()
{
}
bool Instruction::ReadFields(const std::initializer_list<FieldDefObject> &fields)
{
size_t total_bit_count = 0;
auto current_instruction = instruction;
for (auto &field : fields)
{
total_bit_count += field.BitCount();
// Read the upper bits
auto value = current_instruction >> (32 - field.BitCount());
if (!field.Read(value)) return false;
// Remove the upper bits
current_instruction <<= field.BitCount();
}
assert(total_bit_count == 32);
return true;
}
Instruction::FieldDefObject::FieldDefObject(u32 bit_count, u32 const_value)
: bit_count(bit_count), const_value(const_value), constant(true)
{
}
Instruction::FieldDefObject::FieldDefObject(u32 bit_count, void* field_address, WriteFunctionType write_function)
: bit_count(bit_count), field_address(field_address), write_function(write_function), constant(false)
{
}
bool Instruction::FieldDefObject::Read(u32 value) const
{
if (constant)
{
return value == const_value;
}
else
{
write_function(value, field_address);
return true;
}
}

View File

@ -0,0 +1,87 @@
#pragma once
#include "common/common_types.h"
#include <initializer_list>
class Instruction
{
protected:
class FieldDefObject;
public:
Instruction(u32 instruction, u32 address);
virtual ~Instruction();
/*
* Reads the instruction.
* Returns true on success, or false otherwise
*/
virtual bool Read() = 0;
protected:
/*
* Reads fields from the instruction
* The fields come most significant first
*/
bool ReadFields(const std::initializer_list<FieldDefObject> &fields);
/*
* Creates a field definition for a constant
*/
template<size_t BitCount>
static FieldDefObject FieldDef(u32 value);
/*
* Creates a field definition for a field
*/
template<size_t BitCount, typename Type>
static FieldDefObject FieldDef(Type *field);
private:
/*
* Function used by FieldDefObject to write to a field
*/
template<typename Type>
static void WriteFunction(u32 value, void *field_address);
// Instruction value
u32 instruction;
// Instruction address
u32 address;
};
/*
* Object produced by FieldDef
*/
class Instruction::FieldDefObject
{
public:
typedef void(*WriteFunctionType)(u32 value, void *field_address);
public:
// Constant
FieldDefObject(u32 bit_count, u32 const_value);
// Field
FieldDefObject(u32 bit_count, void *field_address, WriteFunctionType write_function);
bool Read(u32 value) const;
u32 BitCount() const { return bit_count; }
private:
u32 bit_count;
u32 const_value;
void *field_address;
WriteFunctionType write_function;
bool constant;
};
template <size_t BitCount>
Instruction::FieldDefObject Instruction::FieldDef(u32 value)
{
return FieldDefObject(BitCount, value);
}
template <size_t BitCount, typename Type>
Instruction::FieldDefObject Instruction::FieldDef(Type* field)
{
return FieldDefObject(BitCount, field, &Instruction::WriteFunction<Type>);
}
template <typename Type>
void Instruction::WriteFunction(u32 value, void *field_address)
{
*static_cast<Type *>(field_address) = static_cast<Type>(value);
}