Add prototype decompiler GUI (#93)

* json output for basic ops

* add prototype gui

* add some more fields and layout the gui a little bit nicer
This commit is contained in:
water111
2020-10-23 17:20:04 -04:00
committed by GitHub
parent fc1a8f37c6
commit 0bc2466f86
5 changed files with 424 additions and 4 deletions
@@ -11,6 +11,7 @@
#include "LinkedObjectFile.h"
#include "decompiler/Disasm/InstructionDecode.h"
#include "decompiler/config.h"
#include "third-party/json.hpp"
/*!
* Set the number of segments in this object file.
@@ -504,6 +505,70 @@ void LinkedObjectFile::process_fp_relative_links() {
}
}
std::string LinkedObjectFile::to_asm_json() {
nlohmann::json data;
std::vector<nlohmann::json::object_t> functions;
std::unordered_map<std::string, int> functions_seen;
for (int seg = segments; seg-- > 0;) {
for (size_t fi = functions_by_seg.at(seg).size(); fi--;) {
auto& func = functions_by_seg.at(seg).at(fi);
auto fname = func.guessed_name.to_string();
if (functions_seen.find(fname) != functions_seen.end()) {
printf("duplicated %s\n", fname.c_str()); // todo - this needs fixing
functions_seen[fname]++;
fname += "-v" + std::to_string(functions_seen[fname]);
} else {
functions_seen[fname] = 0;
}
nlohmann::json::object_t f;
f["name"] = fname;
f["type"] = func.type.print();
f["segment"] = seg;
f["warnings"] = func.warnings;
std::vector<nlohmann::json::object_t> ops;
for (int i = 1; i < func.end_word - func.start_word; i++) {
nlohmann::json::object_t op;
auto label_id = get_label_at(seg, (func.start_word + i) * 4);
if (label_id != -1) {
op["label"] = labels.at(label_id).name;
}
auto& instr = func.instructions.at(i);
op["id"] = i;
op["asm_op"] = instr.to_string(*this);
if (func.has_basic_ops() && func.instr_starts_basic_op(i)) {
op["basic_op"] = func.get_basic_op_at_instr(i)->print(*this);
if (func.has_typemaps()) {
auto& tm = func.get_typemap_by_instr_idx(i);
auto& json_type_map = op["type_map"];
for (auto& kv : tm) {
json_type_map[kv.first.to_charp()] = kv.second.print();
}
}
}
for (int iidx = 0; iidx < instr.n_src; iidx++) {
if (instr.get_src(iidx).is_label()) {
auto lab = labels.at(instr.get_src(iidx).get_label());
if (is_string(lab.target_segment, lab.offset)) {
op["referenced_string"] = get_goal_string(lab.target_segment, lab.offset / 4 - 1);
}
}
}
ops.push_back(op);
}
f["asm"] = ops;
functions.push_back(f);
}
}
data["functions"] = functions;
return data.dump();
}
/*!
* Print disassembled functions and data segments.
*/