Basic disassembler

This commit is contained in:
Dani Messerman 2015-04-28 00:56:52 +03:00
parent 26ff6094e2
commit a91f373f36
10 changed files with 112 additions and 10 deletions

View File

@ -3,17 +3,23 @@ set(SRCS
CodeGen.cpp CodeGen.cpp
ModuleGen.cpp ModuleGen.cpp
Disassembler.cpp Disassembler.cpp
Instruction.cpp
Instructions/Instruction.cpp
Instructions/DataProcessing.cpp
) )
set(HEADERS set(HEADERS
CodeGen.h CodeGen.h
ModuleGen.h ModuleGen.h
Disassembler.h Disassembler.h
Instruction.h
Instructions/Types.h
Instructions/Instruction.h
Instructions/DataProcessing.h
) )
create_directory_groups(${SRCS} ${HEADERS}) create_directory_groups(${SRCS} ${HEADERS})
include_directories(.)
add_executable(binary_translate ${SRCS} ${HEADERS}) add_executable(binary_translate ${SRCS} ${HEADERS})
target_link_libraries(binary_translate ${llvm_libs}) target_link_libraries(binary_translate ${llvm_libs})
target_link_libraries(binary_translate core common video_core) target_link_libraries(binary_translate core common video_core)

View File

@ -1,5 +1,5 @@
#include "Disassembler.h" #include "Disassembler.h"
#include "Instruction.h" #include "Instructions/Instruction.h"
#include <vector> #include <vector>
std::vector<RegisterInstructionBase::CreateFunctionType> g_read_functions; std::vector<RegisterInstructionBase::CreateFunctionType> g_read_functions;
@ -9,7 +9,7 @@ RegisterInstructionBase::RegisterInstructionBase(CreateFunctionType create_funct
g_read_functions.push_back(create_function); g_read_functions.push_back(create_function);
} }
std::unique_ptr<Instruction> Disassmbler::Disassemble(u32 instruction, u32 address) std::unique_ptr<Instruction> Disassembler::Disassemble(u32 instruction, u32 address)
{ {
for (auto read_function : g_read_functions) for (auto read_function : g_read_functions)
{ {

View File

@ -3,7 +3,7 @@
class Instruction; class Instruction;
class Disassmbler class Disassembler
{ {
public: public:
/* /*
@ -32,8 +32,8 @@ public:
private: private:
static Instruction *Create(u32 instruction, u32 address) static Instruction *Create(u32 instruction, u32 address)
{ {
auto result = new DerivedInstruction(instruction, address); auto result = new DerivedInstruction();
if (!result->Read()) if (!result->Read(instruction, address))
{ {
delete result; delete result;
return nullptr; return nullptr;

View File

@ -0,0 +1,15 @@
#include "DataProcessing.h"
#include "Disassembler.h"
static RegisterInstruction<DataProcessing> register_instruction;
bool DataProcessing::Decode()
{
if (ReadFields({ FieldDef<4>(&cond), FieldDef<3>(1), FieldDef<4>(&short_op), FieldDef<1>(&s), FieldDef<4>(&rn),
FieldDef<4>(&rd), FieldDef<12>(&imm12) }))
{
form = Form::Immediate;
return true;
}
return false;
}

View File

@ -0,0 +1,36 @@
#include "Instruction.h"
#include "Types.h"
/*
* Data processing instructions
* ARMv7-A 5.2.1 (register), 5.2.2 (register-shifted register, 5.2.3 (immediate)
*/
class DataProcessing : public Instruction
{
public:
/*
* The 4 bit op types (1 = 0001x: BitwiseXor, etc...)
*/
enum class ShortOpType
{
BitwiseAnd = 0, BitwiseXor, Subtract, RevSubtract, Add, AddWithCarry, SubtractWithCarry, ReverseSubtractWithCarry,
// Compare, Test, Misc
BitwiseOr = 12, Move, BitwiseBitClear, BitwiseNot
};
enum class Form
{
Register, RegisterShiftedRegister, Immediate
};
public:
virtual bool Decode() override;
private:
Form form;
Condition cond;
ShortOpType short_op;
bool s;
Register rn;
Register rd;
u32 imm12;
};

View File

@ -1,7 +1,7 @@
#include "Instruction.h" #include "Instruction.h"
#include <cassert> #include <cassert>
Instruction::Instruction(u32 instruction, u32 address) : instruction(instruction), address(address) Instruction::Instruction()
{ {
} }
@ -9,6 +9,14 @@ Instruction::~Instruction()
{ {
} }
bool Instruction::Read(u32 instruction, u32 address)
{
this->instruction = instruction;
this->address = address;
// Call the read of derived class
return Decode();
}
bool Instruction::ReadFields(const std::initializer_list<FieldDefObject> &fields) bool Instruction::ReadFields(const std::initializer_list<FieldDefObject> &fields)
{ {
size_t total_bit_count = 0; size_t total_bit_count = 0;

View File

@ -7,15 +7,19 @@ class Instruction
protected: protected:
class FieldDefObject; class FieldDefObject;
public: public:
Instruction(u32 instruction, u32 address); Instruction();
virtual ~Instruction(); virtual ~Instruction();
/* /*
* Reads the instruction. * Reads the instruction.
* Returns true on success, or false otherwise * Returns true on success, or false otherwise
*/ */
virtual bool Read() = 0; bool Read(u32 instruction, u32 address);
protected: protected:
/*
* Derived classes should override this, and implement it by calling ReadFields
*/
virtual bool Decode() = 0;
/* /*
* Reads fields from the instruction * Reads fields from the instruction
* The fields come most significant first * The fields come most significant first

View File

@ -0,0 +1,14 @@
/*
* A register in a broad sense: R0-R15, and flags
*/
enum class Register
{
R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, SP, LR, PC,
N, Z, C, V
};
enum class Condition
{
EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, Invalid
};

View File

@ -1,4 +1,8 @@
#include "ModuleGen.h" #include "ModuleGen.h"
#include "Disassembler.h"
#include "core/loader/loader.h"
#include "core/mem_map.h"
#include "Instructions/Instruction.h"
#include <llvm/IR/Function.h> #include <llvm/IR/Function.h>
#include <llvm/IR/GlobalVariable.h> #include <llvm/IR/GlobalVariable.h>
@ -19,6 +23,8 @@ void ModuleGen::Run()
GenerateGlobals(); GenerateGlobals();
GenerateCanRunFunction(); GenerateCanRunFunction();
GenerateRunFunction(); GenerateRunFunction();
GenerateBlocks();
} }
void ModuleGen::GenerateGlobals() void ModuleGen::GenerateGlobals()
@ -49,4 +55,16 @@ void ModuleGen::GenerateRunFunction()
ir_builder->SetInsertPoint(basic_block); ir_builder->SetInsertPoint(basic_block);
ir_builder->CreateRetVoid(); ir_builder->CreateRetVoid();
}
void ModuleGen::GenerateBlocks()
{
for (auto i = Loader::ROMCodeStart; i <= Loader::ROMCodeStart + Loader::ROMCodeSize - 4; i += 4)
{
auto instruction = Disassembler::Disassemble(Memory::Read32(i), i);
if (instruction != nullptr)
{
LOG_DEBUG(BinaryTranslator, "Instruction at %08x", i);
}
}
} }

View File

@ -15,6 +15,7 @@ public:
void GenerateGlobals(); void GenerateGlobals();
void GenerateCanRunFunction(); void GenerateCanRunFunction();
void GenerateRunFunction(); void GenerateRunFunction();
void GenerateBlocks();
private: private:
std::unique_ptr<llvm::IRBuilder<>> ir_builder; std::unique_ptr<llvm::IRBuilder<>> ir_builder;
llvm::Module *module; llvm::Module *module;