[FEAT] Decompiler
[BUG] Several address calculation errors
This commit is contained in:
10
decompiled.txt
Normal file
10
decompiled.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
NOP
|
||||||
|
NOP
|
||||||
|
PUSH 4
|
||||||
|
LD 72
|
||||||
|
LD 60
|
||||||
|
MUL
|
||||||
|
SUB
|
||||||
|
ST 144
|
||||||
|
STL 4
|
||||||
|
STL 0
|
||||||
59
decompiler.cpp
Normal file
59
decompiler.cpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "decompiler.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#define SIMPLE(X) f << X << std::endl; pos++; break
|
||||||
|
// [RZC 05/05/2021] To solve alignment problems on ARM architectures we have to first copy the 4 bytes to an aligned byte array, then cast it to float
|
||||||
|
#define FVAR(X) memcpy(data, &code[pos+1], 4); f << X << " " << *((float*)data) << std::endl; pos += 5; break
|
||||||
|
#define IVAR(X) memcpy(data, &code[pos+1], 4); f << X << " " << *((uint32_t*)data) << std::endl; pos += 5; break
|
||||||
|
|
||||||
|
void decompiler_save(const uint8_t *code, const int size) {
|
||||||
|
uint8_t data[4];
|
||||||
|
int pos = 0;
|
||||||
|
float fval = 0;
|
||||||
|
uint32_t ival = 0;
|
||||||
|
std::ofstream f("decompiled.txt");
|
||||||
|
if (f.is_open()) {
|
||||||
|
while (pos < size) {
|
||||||
|
switch (code[pos]) {
|
||||||
|
case OP_NOP: SIMPLE("NOP");
|
||||||
|
case OP_PUSH: FVAR("PUSH");
|
||||||
|
case OP_POP: SIMPLE("POP");
|
||||||
|
case OP_DUP: SIMPLE("DUP");
|
||||||
|
case OP_SWAP: SIMPLE("SWAP");
|
||||||
|
case OP_LD: IVAR("LD");
|
||||||
|
case OP_ST: IVAR("ST");
|
||||||
|
case OP_LDL: IVAR("LDL");
|
||||||
|
case OP_STL: IVAR("STL");
|
||||||
|
case OP_JMP: IVAR("JMP");
|
||||||
|
case OP_JNT: IVAR("JNT");
|
||||||
|
case OP_JTR: IVAR("JTR");
|
||||||
|
case OP_RET: SIMPLE("RET");
|
||||||
|
case OP_CALL: IVAR("CALL");
|
||||||
|
case OP_CALLEX: IVAR("CALLEX");
|
||||||
|
case OP_ADD: SIMPLE("ADD");
|
||||||
|
case OP_SUB: SIMPLE("SUB");
|
||||||
|
case OP_MUL: SIMPLE("MUL");
|
||||||
|
case OP_DIV: SIMPLE("DIV");
|
||||||
|
case OP_MOD: SIMPLE("MOD");
|
||||||
|
case OP_AND: SIMPLE("AND");
|
||||||
|
case OP_OR: SIMPLE("OR");
|
||||||
|
case OP_NOT: SIMPLE("NOT");
|
||||||
|
case OP_NEG: SIMPLE("NEG");
|
||||||
|
case OP_INC: SIMPLE("INC");
|
||||||
|
case OP_DEC: SIMPLE("DEC");
|
||||||
|
case OP_CONCAT: SIMPLE("CONCAT");
|
||||||
|
case OP_EQ: SIMPLE("EQ");
|
||||||
|
case OP_NEQ: SIMPLE("NEQ");
|
||||||
|
case OP_LT: SIMPLE("LT");
|
||||||
|
case OP_GT: SIMPLE("GT");
|
||||||
|
case OP_LEQ: SIMPLE("LEQ");
|
||||||
|
case OP_GEQ: SIMPLE("GEQ");
|
||||||
|
case OP_SLEEP: SIMPLE("SLEEP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
4
decompiler.h
Normal file
4
decompiler.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void decompiler_save(const uint8_t *code, const int size);
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include "decompiler.h"
|
||||||
|
|
||||||
#define MAX_CODE_SIZE 65536
|
#define MAX_CODE_SIZE 65536
|
||||||
#define MAX_LABELS 256
|
#define MAX_LABELS 256
|
||||||
@@ -326,7 +327,7 @@ static void parse_expr_atom() {
|
|||||||
const int address = get_variable_address();
|
const int address = get_variable_address();
|
||||||
if (address == -1) return;
|
if (address == -1) return;
|
||||||
emmit(scope_is_local() ? OP_LDL : OP_LD);
|
emmit(scope_is_local() ? OP_LDL : OP_LD);
|
||||||
emmit(address);
|
emmit_dw(address);
|
||||||
tkn_next();
|
tkn_next();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@@ -890,7 +891,9 @@ void parser_parse(const char* buffer, byte* mem) {
|
|||||||
//codepos = 0xA000;
|
//codepos = 0xA000;
|
||||||
//emmit(OP_JMP);
|
//emmit(OP_JMP);
|
||||||
//emmit_w(0xA000);
|
//emmit_w(0xA000);
|
||||||
}
|
} else {
|
||||||
|
decompiler_save(code, codepos);
|
||||||
|
}
|
||||||
|
|
||||||
//FILE *f = fopen("test.bin", "wb");
|
//FILE *f = fopen("test.bin", "wb");
|
||||||
//fwrite(mem, codepos, 1, f);
|
//fwrite(mem, codepos, 1, f);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const int scope_declare_variable(const std::string name, const uint32_t type, co
|
|||||||
const uint32_t address = scope.total_size;
|
const uint32_t address = scope.total_size;
|
||||||
const t_variable var {name, type, length, address};
|
const t_variable var {name, type, length, address};
|
||||||
scope.variables.push_back(var);
|
scope.variables.push_back(var);
|
||||||
scope.total_size += types_get_length(type) + (length == 0 ? 1 : length);
|
scope.total_size += types_get_length(type) * (length == 0 ? 1 : length);
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const int types_add_member(const uint32_t type, const std::string name, const ui
|
|||||||
for (auto m : types[type].members) if (m.name == name) return -1;
|
for (auto m : types[type].members) if (m.name == name) return -1;
|
||||||
const t_variable new_var {name, var_type, length, types[type].size};
|
const t_variable new_var {name, var_type, length, types[type].size};
|
||||||
types[type].members.push_back(new_var);
|
types[type].members.push_back(new_var);
|
||||||
types[type].size += types_get_length(var_type) + length;
|
types[type].size += types_get_length(var_type) * length;
|
||||||
return types[type].members.size()-1;
|
return types[type].members.size()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user