Skip to content

Commit

Permalink
[decompiler] Clean up config more (#458)
Browse files Browse the repository at this point in the history
* remove global config

* fix dir
  • Loading branch information
water111 authored May 12, 2021
1 parent d7d5638 commit 0599d14
Show file tree
Hide file tree
Showing 17 changed files with 925 additions and 689 deletions.
6 changes: 3 additions & 3 deletions decompiler/Function/TypeInspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,8 @@ int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorRes
TypeInspectorResult inspect_inspect_method(Function& inspect,
const std::string& type_name,
DecompilerTypeSystem& dts,
LinkedObjectFile& file) {
LinkedObjectFile& file,
bool skip_fields) {
TypeInspectorResult result;
TypeFlags flags;
flags.flag = 0;
Expand All @@ -740,9 +741,8 @@ TypeInspectorResult inspect_inspect_method(Function& inspect,
result.type_heap_base = flags.heap_base;
assert(flags.pad == 0);

auto& bad_set = get_config().bad_inspect_types;
int idx = get_start_idx(inspect, file, &result, result.parent_type_name);
if (idx == 0 || bad_set.find(type_name) != bad_set.end()) {
if (idx == 0 || skip_fields) {
// printf("was weird: %s\n", result.warnings.c_str());
return result;
}
Expand Down
3 changes: 2 additions & 1 deletion decompiler/Function/TypeInspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ struct TypeInspectorResult {
TypeInspectorResult inspect_inspect_method(Function& inspect,
const std::string& type_name,
DecompilerTypeSystem& dts,
LinkedObjectFile& file);
LinkedObjectFile& file,
bool skip_fields);
} // namespace decompiler
3 changes: 1 addition & 2 deletions decompiler/ObjectFile/LinkedObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -680,8 +680,7 @@ std::string LinkedObjectFile::print_asm_function_disassembly(const std::string&
/*!
* Print disassembled functions and data segments.
*/
std::string LinkedObjectFile::print_disassembly() {
bool write_hex = get_config().write_hex_near_instructions;
std::string LinkedObjectFile::print_disassembly(bool write_hex) {
std::string result;

assert(segments <= 3);
Expand Down
2 changes: 1 addition & 1 deletion decompiler/ObjectFile/LinkedObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class LinkedObjectFile {
void disassemble_functions();
void process_fp_relative_links();
std::string print_scripts();
std::string print_disassembly();
std::string print_disassembly(bool write_hex);
bool has_any_functions();
void append_word_to_string(std::string& dest, const LinkedWord& word) const;
std::string print_function_disassembly(Function& func,
Expand Down
12 changes: 7 additions & 5 deletions decompiler/ObjectFile/LinkedObjectFileCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,8 @@ static void link_v5(LinkedObjectFile& f,
static void link_v3(LinkedObjectFile& f,
const std::vector<uint8_t>& data,
const std::string& name,
DecompilerTypeSystem& dts) {
DecompilerTypeSystem& dts,
int game_version) {
auto header = (const LinkHeaderV3*)(&data.at(0));
assert(name == header->name);
assert(header->segments == 3);
Expand Down Expand Up @@ -656,11 +657,11 @@ static void link_v3(LinkedObjectFile& f,
// HACK!
// why is this a thing?
// HACK!
if (get_config().game_version == 1 && name == "level-h" && seg_id == 0) {
if (game_version == 1 && name == "level-h" && seg_id == 0) {
segment_size++;
}

if (get_config().game_version == 2) {
if (game_version == 2) {
bool adjusted = false;
while (segment_size % 4) {
segment_size++;
Expand Down Expand Up @@ -800,14 +801,15 @@ static void link_v3(LinkedObjectFile& f,
*/
LinkedObjectFile to_linked_object_file(const std::vector<uint8_t>& data,
const std::string& name,
DecompilerTypeSystem& dts) {
DecompilerTypeSystem& dts,
int game_version) {
LinkedObjectFile result;
const auto* header = (const LinkHeaderCommon*)&data.at(0);

// use appropriate linker
if (header->version == 3) {
assert(header->type_tag == 0);
link_v3(result, data, name, dts);
link_v3(result, data, name, dts, game_version);
} else if (header->version == 4 || header->version == 2) {
assert(header->type_tag == 0xffffffff);
link_v2_or_v4(result, data, name, dts);
Expand Down
8 changes: 2 additions & 6 deletions decompiler/ObjectFile/LinkedObjectFileCreation.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@
* This implements a decoder for the GOAL linking format.
*/

#ifndef NEXT_LINKEDOBJECTFILECREATION_H
#define NEXT_LINKEDOBJECTFILECREATION_H

#include "LinkedObjectFile.h"

namespace decompiler {
class DecompilerTypeSystem;
LinkedObjectFile to_linked_object_file(const std::vector<uint8_t>& data,
const std::string& name,
DecompilerTypeSystem& dts);
DecompilerTypeSystem& dts,
int game_version);
} // namespace decompiler

#endif // NEXT_LINKEDOBJECTFILECREATION_H
42 changes: 24 additions & 18 deletions decompiler/ObjectFile/ObjectFileDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ ObjectFileData& ObjectFileDB::lookup_record(const ObjectFileRecord& rec) {
ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
const std::string& obj_file_name_map_file,
const std::vector<std::string>& object_files,
const std::vector<std::string>& str_files) {
const std::vector<std::string>& str_files,
const Config& config) {
Timer timer;

lg::info("-Loading types...");
Expand All @@ -128,14 +129,14 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,

lg::info("-Loading {} DGOs...", _dgos.size());
for (auto& dgo : _dgos) {
get_objs_from_dgo(dgo);
get_objs_from_dgo(dgo, config);
}

lg::info("-Loading {} plain object files...", object_files.size());
for (auto& obj : object_files) {
auto data = file_util::read_binary_file(obj);
auto name = obj_filename_to_name(obj);
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO");
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO", config);
}

lg::info("-Loading {} streaming object files...", str_files.size());
Expand All @@ -149,7 +150,7 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
// append the chunk ID to the full name
std::string name = obj_name + fmt::format("+{}", i);
auto& data = reader.get_chunk(i);
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO");
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO", config);
}
}

Expand Down Expand Up @@ -190,7 +191,7 @@ constexpr int MAX_CHUNK_SIZE = 0x8000;
/*!
* Load the objects stored in the given DGO into the ObjectFileDB
*/
void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {
void ObjectFileDB::get_objs_from_dgo(const std::string& filename, const Config& config) {
auto dgo_data = file_util::read_binary_file(filename);
stats.total_dgo_bytes += dgo_data.size();

Expand Down Expand Up @@ -221,7 +222,8 @@ void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {

auto name = get_object_file_name(obj_header.name, reader.here(), obj_header.object_count);

add_obj_from_dgo(name, obj_header.name, reader.here(), obj_header.object_count, dgo_base_name);
add_obj_from_dgo(name, obj_header.name, reader.here(), obj_header.object_count, dgo_base_name,
config);
reader.ffwd(obj_header.object_count);
}

Expand All @@ -236,8 +238,8 @@ void ObjectFileDB::add_obj_from_dgo(const std::string& obj_name,
const std::string& name_in_dgo,
const uint8_t* obj_data,
uint32_t obj_size,
const std::string& dgo_name) {
const auto& config = get_config();
const std::string& dgo_name,
const Config& config) {
if (!config.allowed_objects.empty()) {
if (config.allowed_objects.find(obj_name) == config.allowed_objects.end()) {
return;
Expand Down Expand Up @@ -390,14 +392,14 @@ std::string ObjectFileDB::generate_obj_listing() {
/*!
* Process all of the linking data of all objects.
*/
void ObjectFileDB::process_link_data() {
void ObjectFileDB::process_link_data(const Config& config) {
lg::info("Processing Link Data...");
Timer process_link_timer;

LinkedObjectFile::Stats combined_stats;

for_each_obj([&](ObjectFileData& obj) {
obj.linked_data = to_linked_object_file(obj.data, obj.record.name, dts);
obj.linked_data = to_linked_object_file(obj.data, obj.record.name, dts, config.game_version);
combined_stats.add(obj.linked_data.stats);
});

Expand Down Expand Up @@ -454,7 +456,8 @@ void ObjectFileDB::write_object_file_words(const std::string& output_dir,
*/
void ObjectFileDB::write_disassembly(const std::string& output_dir,
bool disassemble_data,
bool disassemble_code) {
bool disassemble_code,
bool print_hex) {
lg::info("- Writing functions...");
Timer timer;
uint32_t total_bytes = 0, total_files = 0;
Expand All @@ -463,7 +466,7 @@ void ObjectFileDB::write_disassembly(const std::string& output_dir,

for_each_obj([&](ObjectFileData& obj) {
if ((obj.obj_version == 3 && disassemble_code) || (obj.obj_version != 3 && disassemble_data)) {
auto file_text = obj.linked_data.print_disassembly();
auto file_text = obj.linked_data.print_disassembly(print_hex);
asm_functions += obj.linked_data.print_asm_function_disassembly(obj.to_unique_name());
auto file_name = file_util::combine_path(output_dir, obj.to_unique_name() + ".asm");

Expand All @@ -488,7 +491,7 @@ void ObjectFileDB::write_disassembly(const std::string& output_dir,
/*!
* Find code/data zones, identify functions, and disassemble
*/
void ObjectFileDB::find_code() {
void ObjectFileDB::find_code(const Config& config) {
lg::info("Finding code in object files...");
LinkedObjectFile::Stats combined_stats;
Timer timer;
Expand All @@ -499,7 +502,7 @@ void ObjectFileDB::find_code() {
obj.linked_data.find_functions();
obj.linked_data.disassemble_functions();

if (get_config().game_version == 1 || obj.to_unique_name() != "effect-control-v0") {
if (config.game_version == 1 || obj.to_unique_name() != "effect-control-v0") {
obj.linked_data.process_fp_relative_links();
} else {
lg::warn("Skipping process_fp_relative_links in {}", obj.to_unique_name().c_str());
Expand Down Expand Up @@ -619,12 +622,11 @@ std::string ObjectFileDB::process_game_count_file() {
/*!
* This is the main decompiler routine which runs after we've identified functions.
*/
void ObjectFileDB::analyze_functions_ir1() {
void ObjectFileDB::analyze_functions_ir1(const Config& config) {
lg::info("- Analyzing Functions...");
Timer timer;

int total_functions = 0;
const auto& config = get_config();

// Step 1 - analyze the "top level" or "login" code for each object file.
// this will give us type definitions, method definitions, and function definitions...
Expand Down Expand Up @@ -665,7 +667,8 @@ void ObjectFileDB::analyze_functions_ir1() {

unique_names.insert(name);

if (config.asm_functions_by_name.find(name) != config.asm_functions_by_name.end()) {
if (config.hacks.asm_functions_by_name.find(name) !=
config.hacks.asm_functions_by_name.end()) {
func.warnings.info("Flagged as asm by config");
func.suspected_asm = true;
}
Expand Down Expand Up @@ -735,7 +738,10 @@ void ObjectFileDB::analyze_functions_ir1() {

// if we got an inspect method, inspect it.
if (func.is_inspect_method) {
auto result = inspect_inspect_method(func, func.method_of_type, dts, data.linked_data);
auto result = inspect_inspect_method(
func, func.method_of_type, dts, data.linked_data,
config.hacks.types_with_bad_inspect_methods.find(func.method_of_type) !=
config.hacks.types_with_bad_inspect_methods.end());
all_type_defs += ";; " + data.to_unique_name() + "\n";
all_type_defs += result.print_as_deftype() + "\n";
}
Expand Down
28 changes: 16 additions & 12 deletions decompiler/ObjectFile/ObjectFileDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,34 @@ class ObjectFileDB {
ObjectFileDB(const std::vector<std::string>& _dgos,
const std::string& obj_file_name_map_file,
const std::vector<std::string>& object_files,
const std::vector<std::string>& str_files);
const std::vector<std::string>& str_files,
const Config& config);
std::string generate_dgo_listing();
std::string generate_obj_listing();
void process_link_data();
void process_link_data(const Config& config);
void process_labels();
void find_code();
void find_code(const Config& config);
void find_and_write_scripts(const std::string& output_dir);
void dump_raw_objects(const std::string& output_dir);

void write_object_file_words(const std::string& output_dir, bool dump_data, bool dump_code);
void write_disassembly(const std::string& output_dir,
bool disassemble_data,
bool disassemble_code);
bool disassemble_code,
bool print_hex);

void analyze_functions_ir1();
void analyze_functions_ir2(const std::string& output_dir);
void ir2_top_level_pass();
void analyze_functions_ir1(const Config& config);
void analyze_functions_ir2(const std::string& output_dir, const Config& config);
void ir2_top_level_pass(const Config& config);
void ir2_stack_spill_slot_pass();
void ir2_basic_block_pass();
void ir2_atomic_op_pass();
void ir2_type_analysis_pass();
void ir2_atomic_op_pass(const Config& config);
void ir2_type_analysis_pass(const Config& config);
void ir2_register_usage_pass();
void ir2_variable_pass();
void ir2_cfg_build_pass();
void ir2_store_current_forms();
void ir2_build_expressions();
void ir2_build_expressions(const Config& config);
void ir2_insert_lets();
void ir2_rewrite_inline_asm_instructions();
void ir2_insert_anonymous_functions();
Expand All @@ -94,16 +96,18 @@ class ObjectFileDB {

bool lookup_function_type(const FunctionName& name,
const std::string& obj_name,
const Config& config,
TypeSpec* result);

public:
void load_map_file(const std::string& map_data);
void get_objs_from_dgo(const std::string& filename);
void get_objs_from_dgo(const std::string& filename, const Config& config);
void add_obj_from_dgo(const std::string& obj_name,
const std::string& name_in_dgo,
const uint8_t* obj_data,
uint32_t obj_size,
const std::string& dgo_name);
const std::string& dgo_name,
const Config& config);

/*!
* Apply f to all ObjectFileData's. Does it in the right order.
Expand Down
Loading

0 comments on commit 0599d14

Please sign in to comment.