Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions src/fuzztest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,23 @@ using namespace ccc;
extern "C" int LLVMFuzzerTestOneInput(const u8* data, size_t size)
{
std::vector<u8> image(data, data + size);
Result<std::unique_ptr<SymbolFile>> symbol_file =
parse_symbol_file(std::move(image), "totallyrealvideogame.elf");
Result<std::unique_ptr<SymbolFile>> symbol_file = parse_symbol_file(std::move(image), "totallyrealvideogame.elf");
if (!symbol_file.success()) {
return 0;
}

Result<std::vector<std::unique_ptr<SymbolTable>>> symbol_tables =
(*symbol_file)->get_all_symbol_tables();

Result<std::vector<std::unique_ptr<SymbolTable>>> symbol_tables = (*symbol_file)->get_all_symbol_tables();
if (!symbol_tables.success()) {
return 0;
}

SymbolDatabase database;

DemanglerFunctions demangler; // Don't fuzz the demangler.

Result<ModuleHandle> module_handle = import_symbol_tables(
database,
*symbol_tables,
(*symbol_file)->name(),
Address(),
NO_IMPORTER_FLAGS,
demangler,
nullptr);
database, *symbol_tables, (*symbol_file)->name(), Address(), NO_IMPORTER_FLAGS, demangler, nullptr);
static_cast<void>(module_handle);

return 0;
}
19 changes: 11 additions & 8 deletions src/mips/insn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,23 @@

#include "tables.h"

#define OPCODE_MASK 0b11111100000000000000000000000000
#define RS_MASK 0b00000011111000000000000000000000
#define RT_MASK 0b00000000000111110000000000000000
#define RD_MASK 0b00000000000000001111100000000000
#define SA_MASK 0b00000000000000000000011111000000
#define FUNCTION_MASK 0b00000000000000000000000000111111
#define OPCODE_MASK 0b11111100000000000000000000000000
#define RS_MASK 0b00000011111000000000000000000000
#define RT_MASK 0b00000000000111110000000000000000
#define RD_MASK 0b00000000000000001111100000000000
#define SA_MASK 0b00000000000000000000011111000000
#define FUNCTION_MASK 0b00000000000000000000000000111111
#define IMMEDIATE_MASK 0b00000000000000001111111111111111
#define TARGET_MASK 0b00000011111111111111111111111111
#define TARGET_MASK 0b00000011111111111111111111111111

namespace ccc::mips {

Insn::Insn() {}

Insn::Insn(u32 val) : value(val) {}
Insn::Insn(u32 val)
: value(val)
{
}

InsnClass Insn::iclass() const
{
Expand Down
71 changes: 48 additions & 23 deletions src/mips/insn.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

namespace ccc::mips {

enum InsnClass {
enum InsnClass
{
INSN_CLASS_MIPS = 0,
INSN_CLASS_MIPS_SPECIAL = 1,
INSN_CLASS_MIPS_REGIMM = 2,
Expand All @@ -30,7 +31,8 @@ enum InsnClass {
MAX_INSN_CLASS = 16
};

enum InsnFormat {
enum InsnFormat
{
INSN_FORMAT_IMM,
INSN_FORMAT_JMP,
INSN_FORMAT_REG,
Expand All @@ -50,7 +52,8 @@ enum InsnFormat {
INSN_FORMAT_BAD
};

enum class InsnField {
enum class InsnField
{
NONE,
RS,
RT,
Expand All @@ -61,67 +64,89 @@ enum class InsnField {
FUNC
};

enum class FlowDirection {
enum class FlowDirection
{
NONE = 0,
IN,
OUT,
INOUT
};

enum class FlowType {
enum class FlowType
{
IMMED,
REG,
FIXED_REG
};

struct FlowInfo {
struct FlowInfo
{
FlowInfo()
: direction(FlowDirection::NONE) {}
: direction(FlowDirection::NONE)
{
}
FlowInfo(FlowDirection d, FlowType t, InsnField f, RegisterClass c, s32 i)
: direction(d), type(t), field(f), reg_class(c), reg_index(i) {}
: direction(d)
, type(t)
, field(f)
, reg_class(c)
, reg_index(i)
{
}
FlowInfo(FlowDirection d, FlowType t, InsnField f)
: FlowInfo(d, t, f, RegisterClass::INVALID, -1) {}
: FlowInfo(d, t, f, RegisterClass::INVALID, -1)
{
}
// REG
FlowInfo(FlowDirection d, RegisterClass c, InsnField f)
: FlowInfo(d, FlowType::REG, f, c, -1) {}
: FlowInfo(d, FlowType::REG, f, c, -1)
{
}
// FIXED_REG
FlowInfo(FlowDirection d, GPR gpr)
: FlowInfo(d, FlowType::FIXED_REG, InsnField::NONE, RegisterClass::GPR, (s32) gpr) {}
: FlowInfo(d, FlowType::FIXED_REG, InsnField::NONE, RegisterClass::GPR, (s32) gpr)
{
}
FlowInfo(FlowDirection d, SpecialGPR sgpr)
: FlowInfo(d, FlowType::FIXED_REG, InsnField::NONE, RegisterClass::SPECIAL_GPR, (s32) sgpr) {}

: FlowInfo(d, FlowType::FIXED_REG, InsnField::NONE, RegisterClass::SPECIAL_GPR, (s32) sgpr)
{
}

FlowDirection direction;
FlowType type;
InsnField field;
RegisterClass reg_class;
s32 reg_index;

bool is_past_end() const { return direction == FlowDirection::NONE; }
};

enum class InsnType {
enum class InsnType
{
INVALD,
BRANCH, // branches, jumps
CALL, // calls, syscalls
ARTMTC, // moves, integer arithmetic, floating point maths
LOADFM, // memory loads
STOREM, // memory stores
SYSTEM // cache, pref
SYSTEM // cache, pref
};

struct InsnInfo {
struct InsnInfo
{
const char* mnemonic;
InsnType type;
FlowInfo data_flows[10];
};

struct Insn {
struct Insn
{
Insn();
Insn(u32 val);

InsnClass iclass() const;
const InsnInfo& info() const;

u32 opcode() const;
u32 rs() const;
u32 rt() const;
Expand All @@ -131,13 +156,13 @@ struct Insn {
u32 immed() const;
u32 target_insns() const;
u32 target_bytes() const;

u32 field(InsnField field) const;

static Insn create_i_type(u32 op, u32 rs, u32 rt, u32 immediate);
static Insn create_j_type(u32 op, u32 target);
static Insn create_r_type(u32 op, u32 rs, u32 rt, u32 rd, u32 sa, u32 function);

u32 value;
};

Expand Down
2 changes: 2 additions & 0 deletions src/mips/opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace ccc::mips {

// clang-format off
enum OpCode {
OPCODE_SPECIAL = 0b000000,
OPCODE_REGIMM = 0b000001,
Expand Down Expand Up @@ -736,5 +737,6 @@ enum W {
W_UNDEF_63 = 0b111111,
MAX_W = 64
};
// clang-format on

}
4 changes: 3 additions & 1 deletion src/mips/tables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const InsnInfo* INSN_TABLES[MAX_INSN_CLASS] = {
COP1_TABLE,
COP1_BC1_TABLE,
COP1_S_TABLE,
COP1_W_TABLE
COP1_W_TABLE,
};

using IT = InsnType;
Expand All @@ -29,6 +29,7 @@ using FT = FlowType;
using IF = InsnField;
using RC = RegisterClass;

// clang-format off
extern const InsnInfo MIPS_OPCODE_TABLE[MAX_OPCODE] = {
{"special" , IT::INVALD},
{"regimm" , IT::INVALD},
Expand Down Expand Up @@ -745,5 +746,6 @@ extern const InsnInfo COP1_W_TABLE[MAX_W] = {
{"undef_62", IT::INVALD},
{"undef_63", IT::INVALD}
};
// clang-format on

}
18 changes: 9 additions & 9 deletions src/objdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@ using namespace ccc;
int main(int argc, char** argv)
{
CCC_EXIT_IF_FALSE(argc == 2, "Incorrect number of arguments.");

fs::path input_path(argv[1]);
Result<std::vector<u8>> image = platform::read_binary_file(input_path);
CCC_EXIT_IF_ERROR(image);

Result<ElfFile> elf = ElfFile::parse(std::move(*image));
CCC_EXIT_IF_ERROR(elf);

const ElfSection* text = elf->lookup_section(".text");
CCC_EXIT_IF_FALSE(text, "ELF contains no .text section!");

std::optional<u32> text_address = elf->file_offset_to_virtual_address(text->header.offset);
CCC_EXIT_IF_FALSE(text_address.has_value(), "Failed to translate file offset to virtual address.");
std::optional<std::span<const mips::Insn>> insns =
elf->get_array_virtual<mips::Insn>(*text_address, text->header.size / 4);

std::optional<std::span<const mips::Insn>> insns = elf->get_array_virtual<mips::Insn>(
*text_address, text->header.size / 4);
CCC_EXIT_IF_FALSE(insns.has_value(), "Failed to read .text section.");

for (u32 i = 0; i < text->header.size / 4; i++) {
mips::Insn insn = (*insns)[i];
const mips::InsnInfo& info = insn.info();
u32 insn_address = *text_address + i;

printf("%08x:\t\t%08x %s ", insn_address, insn.value, info.mnemonic);
for (s32 i = 0; i < 16 - (s32) strlen(info.mnemonic); i++) {
printf(" ");
Expand Down
Loading
Loading