diff --git a/.github/workflows/linux-workflow.yaml b/.github/workflows/linux-workflow.yaml new file mode 100644 index 0000000000..c72db11797 --- /dev/null +++ b/.github/workflows/linux-workflow.yaml @@ -0,0 +1,26 @@ +name: Linux Workflow +on: [push] + +jobs: + build: + name: Build and Test Project (Linux) + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + - name: Get Package Dependencies + run: sudo apt install gcc make cmake build-essential g++ nasm clang-format + - name: Initialize Submodules + run: git submodule update --init --recursive + - name: Build Project with CMake + run: | + mkdir build + cd build + cmake .. + make -j + - name: Test Project with gTest + run: ./test.sh + - name: Check Clang-Formatting + run: | + chmod +x ./third-party/run-clang-format/run-clang-format.py + ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test --color always diff --git a/.gitmodules b/.gitmodules index 3f127b847c..522084739f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "third-party/googletest"] path = third-party/googletest - url = https://github.com/google/googletest.git + url = https://github.com/google/googletest.git \ No newline at end of file diff --git a/common/symbols.h b/common/symbols.h index 750e430d87..a16cfcf543 100644 --- a/common/symbols.h +++ b/common/symbols.h @@ -6,75 +6,76 @@ #ifndef JAK1_SYMBOLS_H #define JAK1_SYMBOLS_H -constexpr int FIX_SYM_EMPTY_CAR = -0xc; +constexpr int FIX_SYM_EMPTY_CAR = -0xc; constexpr int FIX_SYM_EMPTY_PAIR = -0xa; -constexpr int FIX_SYM_EMPTY_CDR = -0x8; -constexpr int FIX_SYM_FALSE = 0x0; // GOAL boolean #f (note that this is equal to the $s7 register) -constexpr int FIX_SYM_TRUE = 0x8; // GOAL boolean #t +constexpr int FIX_SYM_EMPTY_CDR = -0x8; +constexpr int FIX_SYM_FALSE = 0x0; // GOAL boolean #f (note that this is equal to the $s7 register) +constexpr int FIX_SYM_TRUE = 0x8; // GOAL boolean #t // types -constexpr int FIX_SYM_FUNCTION_TYPE = 0x10; // GOAL type of function -constexpr int FIX_SYM_BASIC_TYPE = 0x18; // GOAL structure type with type tag -constexpr int FIX_SYM_STRING_TYPE = 0x20; // GOAL string type (gstring) -constexpr int FIX_SYM_SYMBOL_TYPE = 0x28; // GOAL symbol type -constexpr int FIX_SYM_TYPE_TYPE = 0x30; // GOAL type of type -constexpr int FIX_SYM_OBJECT_TYPE = 0x38; // GOAL parent type of all types -constexpr int FIX_SYM_LINK_BLOCK = 0x40; // GOAL type of link-block (used by linker, but seems to be unused by GOAL) -constexpr int FIX_SYM_INTEGER_TYPE = 0x48; // GOAL integer parent type, assumes unboxed -constexpr int FIX_SYM_SINTEGER_TYPE = 0x50; // GOAL signed integer parent type, assumes unboxed -constexpr int FIX_SYM_UINTEGER_TYPE = 0x58; // GOAL unsinged integer parent type, assumes unboxed -constexpr int FIX_SYM_BINTEGER_TYPE = 0x60; // GOAL "boxed integer" type -constexpr int FIX_SYM_INT8_TYPE = 0x68; // GOAL 8-bit signed integer -constexpr int FIX_SYM_INT16_TYPE = 0x70; // ... -constexpr int FIX_SYM_INT32_TYPE = 0x78; // ... -constexpr int FIX_SYM_INT64_TYPE = 0x80; // ... -constexpr int FIX_SYM_INT128_TYPE = 0x88; // GOAL 128-bit integer type, behaves strangely -constexpr int FIX_SYM_UINT8_TYPE = 0x90; // GOAL 8-bit unsigned integer -constexpr int FIX_SYM_UINT16_TYPE = 0x98; // ... -constexpr int FIX_SYM_UINT32_TYPE = 0xA0; // ... -constexpr int FIX_SYM_UINT64_TYPE = 0xA8; // ... -constexpr int FIX_SYM_UINT128_TYPE = 0xB0; // ... -constexpr int FIX_SYM_FLOAT_TYPE = 0xB8; // GOAL 32-bit floating point type -constexpr int FIX_SYM_PROCESS_TREE_TYPE = 0xC0; // GOAL process-tree type. Used in the gkernel -constexpr int FIX_SYM_PROCESS_TYPE = 0xC8; // GOAL process type -constexpr int FIX_SYM_THREAD_TYPE = 0xD0; // GOAL thread type -constexpr int FIX_SYM_STRUCTURE_TYPE = 0xD8; // GOAL structure type. Any type with fields -constexpr int FIX_SYM_PAIR_TYPE = 0xE0; // GOAL pair type -constexpr int FIX_SYM_POINTER_TYPE = 0xE8; // GOAL pointer type (32-bit) -constexpr int FIX_SYM_NUMBER_TYPE = 0xF0; // GOAL number type (parent of integer/float types) -constexpr int FIX_SYM_ARRAY_TYPE = 0xF8; // GOAL array type -constexpr int FIX_SYM_VU_FUNCTION_TYPE = 0x100; // GOAL vu-function type -constexpr int FIX_SYM_CONNECTABLE_TYPE = 0x108; // GOAL connectable -constexpr int FIX_SYM_STACK_FRAME_TYPE = 0x110; // GOAL stack-frame -constexpr int FIX_SYM_FILE_STREAM_TYPE = 0x118; // GOAL file-stream -constexpr int FIX_SYM_KHEAP = 0x120; // GOAL kheap +constexpr int FIX_SYM_FUNCTION_TYPE = 0x10; // GOAL type of function +constexpr int FIX_SYM_BASIC_TYPE = 0x18; // GOAL structure type with type tag +constexpr int FIX_SYM_STRING_TYPE = 0x20; // GOAL string type (gstring) +constexpr int FIX_SYM_SYMBOL_TYPE = 0x28; // GOAL symbol type +constexpr int FIX_SYM_TYPE_TYPE = 0x30; // GOAL type of type +constexpr int FIX_SYM_OBJECT_TYPE = 0x38; // GOAL parent type of all types +constexpr int FIX_SYM_LINK_BLOCK = + 0x40; // GOAL type of link-block (used by linker, but seems to be unused by GOAL) +constexpr int FIX_SYM_INTEGER_TYPE = 0x48; // GOAL integer parent type, assumes unboxed +constexpr int FIX_SYM_SINTEGER_TYPE = 0x50; // GOAL signed integer parent type, assumes unboxed +constexpr int FIX_SYM_UINTEGER_TYPE = 0x58; // GOAL unsinged integer parent type, assumes unboxed +constexpr int FIX_SYM_BINTEGER_TYPE = 0x60; // GOAL "boxed integer" type +constexpr int FIX_SYM_INT8_TYPE = 0x68; // GOAL 8-bit signed integer +constexpr int FIX_SYM_INT16_TYPE = 0x70; // ... +constexpr int FIX_SYM_INT32_TYPE = 0x78; // ... +constexpr int FIX_SYM_INT64_TYPE = 0x80; // ... +constexpr int FIX_SYM_INT128_TYPE = 0x88; // GOAL 128-bit integer type, behaves strangely +constexpr int FIX_SYM_UINT8_TYPE = 0x90; // GOAL 8-bit unsigned integer +constexpr int FIX_SYM_UINT16_TYPE = 0x98; // ... +constexpr int FIX_SYM_UINT32_TYPE = 0xA0; // ... +constexpr int FIX_SYM_UINT64_TYPE = 0xA8; // ... +constexpr int FIX_SYM_UINT128_TYPE = 0xB0; // ... +constexpr int FIX_SYM_FLOAT_TYPE = 0xB8; // GOAL 32-bit floating point type +constexpr int FIX_SYM_PROCESS_TREE_TYPE = 0xC0; // GOAL process-tree type. Used in the gkernel +constexpr int FIX_SYM_PROCESS_TYPE = 0xC8; // GOAL process type +constexpr int FIX_SYM_THREAD_TYPE = 0xD0; // GOAL thread type +constexpr int FIX_SYM_STRUCTURE_TYPE = 0xD8; // GOAL structure type. Any type with fields +constexpr int FIX_SYM_PAIR_TYPE = 0xE0; // GOAL pair type +constexpr int FIX_SYM_POINTER_TYPE = 0xE8; // GOAL pointer type (32-bit) +constexpr int FIX_SYM_NUMBER_TYPE = 0xF0; // GOAL number type (parent of integer/float types) +constexpr int FIX_SYM_ARRAY_TYPE = 0xF8; // GOAL array type +constexpr int FIX_SYM_VU_FUNCTION_TYPE = 0x100; // GOAL vu-function type +constexpr int FIX_SYM_CONNECTABLE_TYPE = 0x108; // GOAL connectable +constexpr int FIX_SYM_STACK_FRAME_TYPE = 0x110; // GOAL stack-frame +constexpr int FIX_SYM_FILE_STREAM_TYPE = 0x118; // GOAL file-stream +constexpr int FIX_SYM_KHEAP = 0x120; // GOAL kheap // GOAL functions -constexpr int FIX_SYM_NOTHING_FUNC = 0x128; // GOAL nothing-func (does nothing) -constexpr int FIX_SYM_DEL_BASIC_FUNC = 0x130; // GOAL delete-basic function +constexpr int FIX_SYM_NOTHING_FUNC = 0x128; // GOAL nothing-func (does nothing) +constexpr int FIX_SYM_DEL_BASIC_FUNC = 0x130; // GOAL delete-basic function // GOAL allocation symbols (?) -constexpr int FIX_SYM_STATIC = 0x138; // GOAL 'static -constexpr int FIX_SYM_GLOBAL_HEAP = 0x140; // GOAL 'global -constexpr int FIX_SYM_DEBUG_HEAP = 0x148; // GOAL 'debug -constexpr int FIX_SYM_LOADING_LEVEL = 0x150; // ?? -constexpr int FIX_SYM_LOADING_PACKAGE = 0x158; // ?? -constexpr int FIX_SYM_PROCESS_LEVEL_HEAP = 0x160; // ?? -constexpr int FIX_SYM_STACK = 0x168; // GOAL 'stack -constexpr int FIX_SYM_SCRATCH = 0x170; // GOAL 'scratch +constexpr int FIX_SYM_STATIC = 0x138; // GOAL 'static +constexpr int FIX_SYM_GLOBAL_HEAP = 0x140; // GOAL 'global +constexpr int FIX_SYM_DEBUG_HEAP = 0x148; // GOAL 'debug +constexpr int FIX_SYM_LOADING_LEVEL = 0x150; // ?? +constexpr int FIX_SYM_LOADING_PACKAGE = 0x158; // ?? +constexpr int FIX_SYM_PROCESS_LEVEL_HEAP = 0x160; // ?? +constexpr int FIX_SYM_STACK = 0x168; // GOAL 'stack +constexpr int FIX_SYM_SCRATCH = 0x170; // GOAL 'scratch // GOAL random stuff -constexpr int FIX_SYM_SCRATCH_TOP = 0x178; // GOAL *scratch-top* -constexpr int FIX_SYM_ZERO_FUNC = 0x180; // GOAL zero-func (returns 0x0 in $v0 register) -constexpr int FIX_SYM_ASIZE_OF_BASIC_FUNC = 0x188; // GOAL asize-of-basic function -constexpr int FIX_SYM_COPY_BASIC_FUNC = 0x190; // GOAL copy-basic function -constexpr int FIX_SYM_LEVEL = 0x198; // ?? -constexpr int FIX_SYM_ART_GROUP = 0x1a0; // ?? -constexpr int FIX_SYM_TX_PAGE_DIR = 0x1a8; // ?? -constexpr int FIX_SYM_TX_PAGE = 0x1b0; // ?? -constexpr int FIX_SYM_SOUND = 0x1b8; // ?? -constexpr int FIX_SYM_DGO = 0x1c0; // ?? -constexpr int FIX_SYM_TOP_LEVEL = 0x1c8; // ?? -constexpr int FIX_FIXED_SYM_END_OFFSET = 0x1d0; +constexpr int FIX_SYM_SCRATCH_TOP = 0x178; // GOAL *scratch-top* +constexpr int FIX_SYM_ZERO_FUNC = 0x180; // GOAL zero-func (returns 0x0 in $v0 register) +constexpr int FIX_SYM_ASIZE_OF_BASIC_FUNC = 0x188; // GOAL asize-of-basic function +constexpr int FIX_SYM_COPY_BASIC_FUNC = 0x190; // GOAL copy-basic function +constexpr int FIX_SYM_LEVEL = 0x198; // ?? +constexpr int FIX_SYM_ART_GROUP = 0x1a0; // ?? +constexpr int FIX_SYM_TX_PAGE_DIR = 0x1a8; // ?? +constexpr int FIX_SYM_TX_PAGE = 0x1b0; // ?? +constexpr int FIX_SYM_SOUND = 0x1b8; // ?? +constexpr int FIX_SYM_DGO = 0x1c0; // ?? +constexpr int FIX_SYM_TOP_LEVEL = 0x1c8; // ?? +constexpr int FIX_FIXED_SYM_END_OFFSET = 0x1d0; #endif // JAK1_SYMBOLS_H diff --git a/common/type_system/type_util.h b/common/type_system/type_util.h index 4e87474578..fcefbdd2ad 100644 --- a/common/type_system/type_util.h +++ b/common/type_system/type_util.h @@ -1,9 +1,9 @@ #ifndef JAK_TYPE_UTIL_H #define JAK_TYPE_UTIL_H -template +template T align(T current, T alignment, T offset = 0) { - while((current % alignment) != 0) { + while ((current % alignment) != 0) { current++; } return current + offset; diff --git a/common/versions.h b/common/versions.h index 74b1ec0169..5ecb742ac8 100644 --- a/common/versions.h +++ b/common/versions.h @@ -12,7 +12,7 @@ namespace versions { // language version constexpr s32 GOAL_VERSION_MAJOR = 2; constexpr s32 GOAL_VERSION_MINOR = 6; -} +} // namespace versions // GOAL kernel version constexpr int KERNEL_VERSION_MAJOR = 2; diff --git a/decompiler/Function/Function.h b/decompiler/Function/Function.h index d8bfeba202..c972496229 100644 --- a/decompiler/Function/Function.h +++ b/decompiler/Function/Function.h @@ -9,18 +9,18 @@ struct FunctionName { enum class FunctionKind { - UNIDENTIFIED, // hasn't been identified yet. - GLOBAL, // global named function + UNIDENTIFIED, // hasn't been identified yet. + GLOBAL, // global named function METHOD, TOP_LEVEL_INIT, } kind = FunctionKind::UNIDENTIFIED; - std::string function_name; // only applicable for GLOBAL - std::string type_name; // only applicable for METHOD - int method_id = -1; // only applicable for METHOD + std::string function_name; // only applicable for GLOBAL + std::string type_name; // only applicable for METHOD + int method_id = -1; // only applicable for METHOD std::string to_string() const { - switch(kind) { + switch (kind) { case FunctionKind::GLOBAL: return function_name; case FunctionKind::METHOD: @@ -34,13 +34,9 @@ struct FunctionName { } } - bool empty() const { - return kind == FunctionKind::UNIDENTIFIED; - } + bool empty() const { return kind == FunctionKind::UNIDENTIFIED; } - void set_as_top_level() { - kind = FunctionKind::TOP_LEVEL_INIT; - } + void set_as_top_level() { kind = FunctionKind::TOP_LEVEL_INIT; } void set_as_global(std::string name) { kind = FunctionKind::GLOBAL; diff --git a/decompiler/ObjectFile/LinkedObjectFile.cpp b/decompiler/ObjectFile/LinkedObjectFile.cpp index d02fc3bf31..be9eaa1de7 100644 --- a/decompiler/ObjectFile/LinkedObjectFile.cpp +++ b/decompiler/ObjectFile/LinkedObjectFile.cpp @@ -90,7 +90,7 @@ Function& LinkedObjectFile::get_function_at_label(int label_id) { } assert(false); - return functions_by_seg.front().front(); // to avoid error + return functions_by_seg.front().front(); // to avoid error } /*! @@ -520,7 +520,7 @@ std::string LinkedObjectFile::print_disassembly() { result += "; .function " + func.guessed_name.to_string() + "\n"; result += ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"; result += func.prologue.to_string(2) + "\n"; - if(!func.warnings.empty()) { + if (!func.warnings.empty()) { result += "Warnings: " + func.warnings + "\n"; } @@ -581,11 +581,11 @@ std::string LinkedObjectFile::print_disassembly() { // } // hack - if(func.cfg && !func.cfg->is_fully_resolved()) { + if (func.cfg && !func.cfg->is_fully_resolved()) { result += func.cfg->to_dot(); result += "\n"; } - if(func.cfg) { + if (func.cfg) { result += func.cfg->to_form_string() + "\n"; // To debug block stuff. @@ -614,7 +614,6 @@ std::string LinkedObjectFile::print_disassembly() { */ } - result += "\n\n\n"; } @@ -636,7 +635,6 @@ std::string LinkedObjectFile::print_disassembly() { if (word.kind == LinkedWord::TYPE_PTR && word.symbol_name == "string") { result += "; " + get_goal_string(seg, i) + "\n"; - } } } diff --git a/decompiler/ObjectFile/LinkedObjectFile.h b/decompiler/ObjectFile/LinkedObjectFile.h index 4b87dbe345..f897b86475 100644 --- a/decompiler/ObjectFile/LinkedObjectFile.h +++ b/decompiler/ObjectFile/LinkedObjectFile.h @@ -15,7 +15,6 @@ #include "decompiler/Function/Function.h" #include "decompiler/util/LispPrint.h" - /*! * A label to a location in this object file. * Doesn't have to be word aligned. @@ -23,14 +22,14 @@ struct Label { std::string name; int target_segment; - int offset; // in bytes + int offset; // in bytes }; /*! * An object file's data with linking information included. */ class LinkedObjectFile { -public: + public: LinkedObjectFile() = default; void set_segment_count(int n_segs); void push_back_word_to_segment(uint32_t word, int segment); @@ -38,8 +37,15 @@ public: 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); - 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); + 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); void symbol_link_offset(int source_segment, int source_offset, const char* name); Function& get_function_at_label(int label_id); std::string get_label_name(int label_id) const; @@ -83,7 +89,6 @@ public: 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; @@ -116,9 +121,9 @@ public: std::vector> functions_by_seg; std::vector