Add decompiler IR, basic operations, all-types file (#57)

* framework for basic op

* started IR framework

* check in type info file

* add some basic operations to the first pass ir conversion

* use a single condition system

* add more basic op decoding

* more ir
This commit is contained in:
water111
2020-09-29 20:24:15 -04:00
committed by GitHub
parent c9b53d51ff
commit 376c273845
37 changed files with 10346 additions and 392 deletions
+27 -10
View File
@@ -18,6 +18,7 @@
#include "common/util/Timer.h"
#include "common/util/FileUtil.h"
#include "decompiler/Function/BasicBlocks.h"
#include "decompiler/IR/BasicOpBuilder.h"
/*!
* Get a unique name for this object file.
@@ -64,6 +65,8 @@ ObjectFileData& ObjectFileDB::lookup_record(ObjectFileRecord rec) {
*/
ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos) {
Timer timer;
printf("- Loading Types...\n");
dts.parse_type_defs({"decompiler", "config", "all-types.gc"});
printf("- Initializing ObjectFileDB...\n");
for (auto& dgo : _dgos) {
@@ -71,7 +74,7 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos) {
}
printf("ObjectFileDB Initialized:\n");
printf(" total dgos: %lld\n", _dgos.size());
printf(" total dgos: %d\n", int(_dgos.size()));
printf(" total data: %d bytes\n", stats.total_dgo_bytes);
printf(" total objs: %d\n", stats.total_obj_files);
printf(" unique objs: %d\n", stats.unique_obj_files);
@@ -356,7 +359,7 @@ void ObjectFileDB::process_link_data() {
LinkedObjectFile::Stats combined_stats;
for_each_obj([&](ObjectFileData& obj) {
obj.linked_data = to_linked_object_file(obj.data, obj.record.name);
obj.linked_data = to_linked_object_file(obj.data, obj.record.name, dts);
combined_stats.add(obj.linked_data.stats);
});
@@ -543,7 +546,7 @@ void ObjectFileDB::analyze_functions() {
auto& func = data.linked_data.functions_by_seg.at(2).front();
assert(func.guessed_name.empty());
func.guessed_name.set_as_top_level();
func.find_global_function_defs(data.linked_data);
func.find_global_function_defs(data.linked_data, dts);
func.find_method_defs(data.linked_data);
}
});
@@ -591,6 +594,8 @@ void ObjectFileDB::analyze_functions() {
int total_nontrivial_functions = 0;
int total_resolved_nontrivial_functions = 0;
int total_named_functions = 0;
int total_basic_ops = 0;
int total_failed_basic_ops = 0;
std::map<int, std::vector<std::string>> unresolved_by_length;
if (get_config().find_basic_blocks) {
@@ -601,10 +606,18 @@ void ObjectFileDB::analyze_functions() {
total_basic_blocks += blocks.size();
func.basic_blocks = blocks;
total_functions++;
if (!func.suspected_asm) {
func.analyze_prologue(data.linked_data);
func.cfg = build_cfg(data.linked_data, segment_id, func);
total_functions++;
for (auto& block : func.basic_blocks) {
if (block.end_word > block.start_word) {
add_basic_ops_to_block(&func, block, &data.linked_data);
}
}
total_basic_ops += func.get_basic_op_count();
total_failed_basic_ops += func.get_failed_basic_op_count();
if (func.cfg->is_fully_resolved()) {
resolved_cfg_functions++;
}
@@ -640,11 +653,15 @@ void ObjectFileDB::analyze_functions() {
total_nontrivial_functions,
100.f * float(total_resolved_nontrivial_functions) / float(total_nontrivial_functions));
for (auto& kv : unresolved_by_length) {
printf("LEN %d\n", kv.first);
for (auto& x : kv.second) {
printf(" %s\n", x.c_str());
}
}
int successful_basic_ops = total_basic_ops - total_failed_basic_ops;
printf(" %d/%d basic ops converted successfully (%.2f%%)\n", successful_basic_ops,
total_basic_ops, 100.f * float(successful_basic_ops) / float(total_basic_ops));
// for (auto& kv : unresolved_by_length) {
// printf("LEN %d\n", kv.first);
// for (auto& x : kv.second) {
// printf(" %s\n", x.c_str());
// }
// }
}
}