Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[decompiler] Clean up config more #458

Merged
merged 2 commits into from
May 12, 2021
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
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