2020-09-13 21:32:55 -04:00
|
|
|
#pragma once
|
|
|
|
|
2020-08-22 23:30:17 -04:00
|
|
|
/*!
|
|
|
|
* @file LinkedObjectFile.h
|
|
|
|
* An object file's data with linking information included.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
|
|
|
#include "LinkedWord.h"
|
2021-01-06 20:04:15 -05:00
|
|
|
#include "decompiler/Disasm/DecompilerLabel.h"
|
2020-08-22 23:30:17 -04:00
|
|
|
#include "decompiler/Function/Function.h"
|
2020-10-29 21:27:52 -04:00
|
|
|
#include "common/common_types.h"
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2021-01-06 20:04:15 -05:00
|
|
|
namespace decompiler {
|
2020-08-22 23:30:17 -04:00
|
|
|
/*!
|
|
|
|
* An object file's data with linking information included.
|
|
|
|
*/
|
|
|
|
class LinkedObjectFile {
|
2020-08-26 01:21:33 -04:00
|
|
|
public:
|
2020-08-22 23:30:17 -04:00
|
|
|
LinkedObjectFile() = default;
|
|
|
|
void set_segment_count(int n_segs);
|
|
|
|
void push_back_word_to_segment(uint32_t word, int segment);
|
|
|
|
int get_label_id_for(int seg, int offset);
|
|
|
|
int get_label_at(int seg, int offset) const;
|
|
|
|
bool label_points_to_code(int label_id) const;
|
|
|
|
bool pointer_link_word(int source_segment, int source_offset, int dest_segment, int dest_offset);
|
2020-08-26 01:21:33 -04:00
|
|
|
void pointer_link_split_word(int source_segment,
|
|
|
|
int source_hi_offset,
|
|
|
|
int source_lo_offset,
|
|
|
|
int dest_segment,
|
|
|
|
int dest_offset);
|
|
|
|
void symbol_link_word(int source_segment,
|
|
|
|
int source_offset,
|
|
|
|
const char* name,
|
|
|
|
LinkedWord::Kind kind);
|
2020-08-22 23:30:17 -04:00
|
|
|
void symbol_link_offset(int source_segment, int source_offset, const char* name);
|
|
|
|
Function& get_function_at_label(int label_id);
|
2021-02-09 20:59:14 -05:00
|
|
|
const Function* try_get_function_at_label(int label_id) const;
|
2021-07-01 21:38:19 -04:00
|
|
|
const Function* try_get_function_at_label(const DecompilerLabel& label) const;
|
2020-08-22 23:30:17 -04:00
|
|
|
std::string get_label_name(int label_id) const;
|
|
|
|
uint32_t set_ordered_label_names();
|
|
|
|
void find_code();
|
|
|
|
std::string print_words();
|
|
|
|
void find_functions();
|
|
|
|
void disassemble_functions();
|
|
|
|
void process_fp_relative_links();
|
|
|
|
std::string print_scripts();
|
2021-05-11 20:49:54 -04:00
|
|
|
std::string print_disassembly(bool write_hex);
|
2020-08-22 23:30:17 -04:00
|
|
|
bool has_any_functions();
|
|
|
|
void append_word_to_string(std::string& dest, const LinkedWord& word) const;
|
2020-10-24 14:27:50 -04:00
|
|
|
std::string print_function_disassembly(Function& func,
|
|
|
|
int seg,
|
|
|
|
bool write_hex,
|
|
|
|
const std::string& extra_name);
|
|
|
|
std::string print_asm_function_disassembly(const std::string& my_name);
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2021-01-06 20:04:15 -05:00
|
|
|
u32 read_data_word(const DecompilerLabel& label);
|
2021-01-18 13:33:32 -05:00
|
|
|
const DecompilerLabel& get_label_by_name(const std::string& name) const;
|
2021-01-06 20:04:15 -05:00
|
|
|
std::string get_goal_string_by_label(const DecompilerLabel& label) const;
|
2021-01-09 20:01:48 -05:00
|
|
|
std::string get_goal_string(int seg, int word_idx, bool with_quotes = true) const;
|
|
|
|
bool is_string(int seg, int byte_idx) const;
|
2020-10-24 22:51:40 -04:00
|
|
|
|
2020-08-22 23:30:17 -04:00
|
|
|
struct Stats {
|
|
|
|
uint32_t total_code_bytes = 0;
|
|
|
|
uint32_t total_v2_code_bytes = 0;
|
|
|
|
uint32_t total_v2_pointers = 0;
|
|
|
|
uint32_t total_v2_pointer_seeks = 0;
|
|
|
|
uint32_t total_v2_link_bytes = 0;
|
|
|
|
uint32_t total_v2_symbol_links = 0;
|
|
|
|
uint32_t total_v2_symbol_count = 0;
|
|
|
|
|
|
|
|
uint32_t v3_code_bytes = 0;
|
|
|
|
uint32_t v3_pointers = 0;
|
|
|
|
uint32_t v3_split_pointers = 0;
|
|
|
|
uint32_t v3_word_pointers = 0;
|
|
|
|
uint32_t v3_pointer_seeks = 0;
|
|
|
|
uint32_t v3_link_bytes = 0;
|
|
|
|
|
|
|
|
uint32_t v3_symbol_count = 0;
|
|
|
|
uint32_t v3_symbol_link_offset = 0;
|
|
|
|
uint32_t v3_symbol_link_word = 0;
|
|
|
|
|
|
|
|
uint32_t data_bytes = 0;
|
|
|
|
uint32_t code_bytes = 0;
|
|
|
|
|
|
|
|
uint32_t function_count = 0;
|
|
|
|
uint32_t decoded_ops = 0;
|
|
|
|
|
|
|
|
uint32_t n_fp_reg_use = 0;
|
|
|
|
uint32_t n_fp_reg_use_resolved = 0;
|
|
|
|
|
|
|
|
void add(const Stats& other) {
|
|
|
|
total_code_bytes += other.total_code_bytes;
|
|
|
|
total_v2_code_bytes += other.total_v2_code_bytes;
|
|
|
|
total_v2_pointers += other.total_v2_pointers;
|
|
|
|
total_v2_pointer_seeks += other.total_v2_pointer_seeks;
|
|
|
|
total_v2_link_bytes += other.total_v2_link_bytes;
|
|
|
|
total_v2_symbol_links += other.total_v2_symbol_links;
|
|
|
|
total_v2_symbol_count += other.total_v2_symbol_count;
|
|
|
|
v3_code_bytes += other.v3_code_bytes;
|
|
|
|
v3_pointers += other.v3_pointers;
|
|
|
|
v3_pointer_seeks += other.v3_pointer_seeks;
|
|
|
|
v3_link_bytes += other.v3_link_bytes;
|
|
|
|
v3_word_pointers += other.v3_word_pointers;
|
|
|
|
v3_split_pointers += other.v3_split_pointers;
|
|
|
|
v3_symbol_count += other.v3_symbol_count;
|
|
|
|
v3_symbol_link_offset += other.v3_symbol_link_offset;
|
|
|
|
v3_symbol_link_word += other.v3_symbol_link_word;
|
|
|
|
data_bytes += other.data_bytes;
|
|
|
|
code_bytes += other.code_bytes;
|
|
|
|
function_count += other.function_count;
|
|
|
|
decoded_ops += other.decoded_ops;
|
|
|
|
n_fp_reg_use += other.n_fp_reg_use;
|
|
|
|
n_fp_reg_use_resolved += other.n_fp_reg_use_resolved;
|
|
|
|
}
|
|
|
|
} stats;
|
|
|
|
|
|
|
|
int segments = 0;
|
|
|
|
std::vector<std::vector<LinkedWord>> words_by_seg;
|
|
|
|
std::vector<uint32_t> offset_of_data_zone_by_seg;
|
|
|
|
std::vector<std::vector<Function>> functions_by_seg;
|
2021-01-06 20:04:15 -05:00
|
|
|
std::vector<DecompilerLabel> labels;
|
2020-08-22 23:30:17 -04:00
|
|
|
|
2020-08-26 01:21:33 -04:00
|
|
|
private:
|
2020-10-04 17:08:10 -04:00
|
|
|
goos::Object to_form_script(int seg, int word_idx, std::vector<bool>& seen);
|
|
|
|
goos::Object to_form_script_object(int seg, int byte_idx, std::vector<bool>& seen);
|
2020-08-22 23:30:17 -04:00
|
|
|
bool is_empty_list(int seg, int byte_idx);
|
|
|
|
|
|
|
|
std::vector<std::unordered_map<int, int>> label_per_seg_by_offset;
|
|
|
|
};
|
2021-01-06 20:04:15 -05:00
|
|
|
} // namespace decompiler
|