Allow symbol table expansion. (#1191)

* Allow symbol table expansion.

* fix debugger

* fix bits_for_sym

* use a `static_assert` over `throw`
This commit is contained in:
ManDude
2022-02-25 03:43:00 +00:00
committed by GitHub
parent 9c00b0c135
commit 8adac544cf
20 changed files with 97 additions and 58 deletions
+1
View File
@@ -17,6 +17,7 @@ if(MSVC AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
"-Xclang -fcxx-exceptions \
-Xclang -fexceptions \
-Xclang -std=c++17 \
-Xclang -D_CRT_SECURE_NO_WARNINGS \
-mavx \
-Wno-c++11-narrowing -W3")
+27 -3
View File
@@ -9,8 +9,32 @@ constexpr int BASIC_OFFSET = 4;
constexpr int STRUCTURE_ALIGNMENT = 16;
constexpr int ARRAY_DATA_OFFSET = 12; // not including type tag
constexpr s32 GOAL_MAX_SYMBOLS = 0x2000;
constexpr s32 SYM_INFO_OFFSET = 0xff34;
/*!
* Here you can change the size of the symbol table!
* Make sure to also edit the constant in gcommon.gc
*/
constexpr s32 GOAL_MAX_SYMBOLS = 8192; // this MUST be a multiple of 2!!
constexpr s32 SYM_INFO_OFFSET = 8167 * 8 - 4;
// constexpr s32 GOAL_MAX_SYMBOLS = 16384;
// constexpr s32 SYM_INFO_OFFSET = GOAL_MAX_SYMBOLS * 8 - 4;
constexpr s32 SYM_TABLE_MEM_SIZE = GOAL_MAX_SYMBOLS * 8 * 2;
constexpr int bits_for_sym() {
int b = -1;
for (int i = 0; i < 32; ++i) {
if ((GOAL_MAX_SYMBOLS & (1 << i)) != 0) {
if (b != -1) {
// already got a set bit... not a multiple of 2!
// throw 0;
return -1;
}
b = i;
}
}
return b + 1;
}
static_assert(bits_for_sym() != 1, "symbol table invalid length");
enum class RegClass { GPR_64, FLOAT, INT_128, VECTOR_FLOAT, INVALID };
@@ -38,4 +62,4 @@ constexpr double DEGREES_PER_ROT = 65536.0;
constexpr double DEGREES_LENGTH = DEGREES_PER_ROT / 360.0;
constexpr u64 TICKS_PER_SECOND = 300.0;
constexpr float DEFAULT_RES_TIME = -1000000000.0;
constexpr float DEFAULT_RES_TIME = -1000000000.0;
+2 -1
View File
@@ -7,6 +7,7 @@
#include "decompiler/IR2/bitfields.h"
#include "common/type_system/state.h"
#include "common/util/BitUtils.h"
#include "decompiler/util/goal_constants.h"
namespace decompiler {
@@ -640,7 +641,7 @@ TP_Type SimpleExpression::get_type_int2(const TypeState& input,
if (tc(dts, TypeSpec("structure"), arg1_type) && !m_args[0].is_int() &&
is_int_or_uint(dts, arg0_type)) {
if (arg1_type.typespec() == TypeSpec("symbol") &&
arg0_type.is_integer_constant(SYM_INFO_OFFSET + POINTER_SIZE)) {
arg0_type.is_integer_constant(DECOMP_SYM_INFO_OFFSET + POINTER_SIZE)) {
// symbol -> GOAL String
// NOTE - the offset doesn't fit in a s16, so it's loaded into a register first.
// so we expect the arg to be a variable, and the type propagation will figure out the
+2 -1
View File
@@ -10,6 +10,7 @@
#include "common/type_system/state.h"
#include "common/util/print_float.h"
#include "decompiler/IR2/ExpressionHelpers.h"
#include "decompiler/util/goal_constants.h"
/*
* TODO
@@ -956,7 +957,7 @@ void SimpleExpressionElement::update_from_stack_add_i(const Env& env,
// try to find symbol to string stuff
auto arg0_int = get_goal_integer_constant(args.at(0), env);
if (arg0_int && (*arg0_int == SYM_INFO_OFFSET + 4) &&
if (arg0_int && (*arg0_int == DECOMP_SYM_INFO_OFFSET + 4) &&
arg1_type.typespec() == TypeSpec("symbol")) {
result->push_back(pool.alloc_element<GetSymbolStringPointer>(args.at(1)));
return;
+1 -1
View File
@@ -18823,7 +18823,7 @@
(timer uint8 :offset-assert 6)
(overlap uint8 :offset-assert 7)
(effect uint32 :offset-assert 8)
(sound basic :offset-assert 12)
(sound symbol :offset-assert 12)
)
:method-count-assert 9
:size-assert #x10
@@ -806,7 +806,8 @@
"update-sound-banks": [[[21, 52], "t0", "symbol"]],
"(method 16 level-group)": [
[[122, 146], "s1", "continue-point"],
[[115, 154], "s3", "continue-point"]
[[115, 154], "s3", "continue-point"],
[444, "v1", "symbol"]
],
"(method 20 level)": [[[43, 45], "s3", "ramdisk-rpc-fill"]],
@@ -2269,7 +2270,10 @@
"(method 28 entity-ambient)": [[79, "v1", "int"]],
"(method 27 entity-ambient)": [[[15, 250], "s5", "symbol"]],
"(method 27 entity-ambient)": [
[[15, 250], "s5", "symbol"],
[32, "v0", "symbol"]
],
"birth-func-vector-orient": [[[7, 24], "s3", "sprite-vec-data-2d"]],
@@ -4763,7 +4767,7 @@
"(method 11 med-res-level)": [
["_stack_", 16, "res-tag"],
[21, "v0", "(pointer (pointer sparticle-launch-group))"],
[21, "v0", "(pointer symbol)"],
[57, "s4", "(pointer sparticle-launch-group)"]
],
@@ -4022,5 +4022,11 @@
}
},
"(method 11 med-res-level)": {
"vars": {
"s4-0": ["s4-0", "(pointer sparticle-launch-group)"]
}
},
"aaaaaaaaaaaaaaaaaaaaaaa": {}
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "common/common_types.h"
// Separate constants for the decompiler, so we can make changes to the game without breaking
// decompilation.
constexpr s32 DECOMP_SYM_INFO_OFFSET = 8167 * 8 - 4;
+7 -5
View File
@@ -255,7 +255,7 @@ void delete_structure(u32 s) {
/*!
* Allocate a basic of fixed size.
*/
u64 new_basic(u32 heap, u32 type, u32 /*unused*/, u32 pp) {
u64 new_basic(u32 heap, u32 type, u32 /*size*/, u32 pp) {
return alloc_heap_object(heap, type, Ptr<Type>(type)->allocated_size, pp);
}
@@ -708,8 +708,9 @@ Ptr<Symbol> find_symbol_from_c(const char* name) {
}
}
s32 sh1 = hash << 0x13;
s32 sh2 = sh1 >> 0x10;
auto bits = bits_for_sym() - 1;
s32 sh1 = hash << (0x20 - bits);
s32 sh2 = sh1 >> (0x20 - bits - 3);
// will be signed, bottom 3 bits 0 (for alignment, symbol are every 8 bytes)
// upper 16 bits are the same, so we will reach +/- 8 kb around 0.
@@ -1716,14 +1717,15 @@ s32 InitHeapAndSymbol() {
// reset all mips2c functions
Mips2C::gLinkedFunctionTable = {};
// allocate memory for the symbol table
auto symbol_table = kmalloc(kglobalheap, 0x20000, KMALLOC_MEMSET, "symbol-table").cast<u32>();
auto symbol_table =
kmalloc(kglobalheap, SYM_TABLE_MEM_SIZE, KMALLOC_MEMSET, "symbol-table").cast<u32>();
// pointer to the middle symbol is stored in the s7 register.
s7 = symbol_table + (GOAL_MAX_SYMBOLS / 2) * 8 + BASIC_OFFSET;
// pointer to the first symbol (SymbolTable2 is the "lower" symbol table)
SymbolTable2 = symbol_table + BASIC_OFFSET;
// the last symbol we will ever access.
LastSymbol = symbol_table + 0xff00;
LastSymbol = symbol_table + SYM_TABLE_END * 8;
NumSymbols = 0;
// inform compiler the symbol table is reset, and where it is.
reset_output();
+1
View File
@@ -20,6 +20,7 @@ extern Ptr<u32> LastSymbol;
constexpr u32 EMPTY_HASH = 0x8454B6E6;
constexpr u32 OFFSET_MASK = 7;
constexpr u32 CRC_POLY = 0x04c11db7;
constexpr u32 SYM_TABLE_END = GOAL_MAX_SYMBOLS - 32;
constexpr u32 DEFAULT_METHOD_COUNT = 12;
constexpr u32 FALLBACK_UNKNOWN_METHOD_COUNT = 44;
+1 -1
View File
@@ -1120,7 +1120,7 @@
(add-debug-text-3d
#t
(bucket-id debug-draw1)
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (res-lump-struct obj 'effect-name int :time 0.0)))))
(symbol->string (res-lump-struct obj 'effect-name symbol :time 0.0))
gp-0
(font-color white)
(new 'static 'vector2h :y 24)
+2 -7
View File
@@ -527,13 +527,8 @@
(s0-3 (-> (the-as death-info s3-0) sound))
)
(set! sv-288 (-> obj res))
(let ((t1-11
(string->sound-name
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (the-as int (-> (the-as death-info s3-0) sound))))))
)
)
)
(s1-3 s2-5 (the-as symbol s0-3) arg1 s5-0 sv-288 t1-11)
(let ((t1-11 (string->sound-name (symbol->string (-> (the-as death-info s3-0) sound)))))
(s1-3 s2-5 s0-3 arg1 s5-0 sv-288 t1-11)
)
)
)
+10 -10
View File
@@ -1330,32 +1330,32 @@
"#f"
(let ((s4-0 (the-as (pointer sparticle-launch-group) #f)))
(set! sv-16 (new 'static 'res-tag))
(let* ((s3-0 (res-lump-data arg0 'art-name (pointer (pointer sparticle-launch-group)) :tag-ptr (& sv-16)))
(let* ((s3-0 (res-lump-data arg0 'art-name (pointer symbol) :tag-ptr (& sv-16)))
(s2-0 (-> s3-0 0))
)
(cond
((not s3-0)
)
((part-group-pointer? s2-0)
(set! s4-0 (-> s3-0 0))
((part-group-pointer? (the-as pointer s2-0))
(set! s4-0 (the-as (pointer sparticle-launch-group) (-> s3-0 0)))
)
((= (-> s2-0 -1) string)
((= (-> s2-0 type) string)
(set! s4-0 (lookup-part-group-pointer-by-name (the-as string s2-0)))
(if s4-0
(set! (-> s3-0 0) s4-0)
(set! (-> s3-0 0) (the-as symbol s4-0))
)
)
((= (-> s2-0 -1) symbol)
(let ((a0-7 (-> (&+ s2-0 #xff38) 0)))
(set! s4-0 (lookup-part-group-pointer-by-name (the-as string a0-7)))
((= (-> s2-0 type) symbol)
(let ((a0-7 (symbol->string s2-0)))
(set! s4-0 (lookup-part-group-pointer-by-name a0-7))
)
(if s4-0
(set! (-> s3-0 0) s4-0)
(set! (-> s3-0 0) (the-as symbol s4-0))
)
)
)
)
(when s4-0
(when (the-as object s4-0)
(let ((a0-8 (-> s4-0 0)))
(if (and (nonzero? a0-8) (= (-> a0-8 type) sparticle-launch-group))
(set! (-> obj part) (create-launch-control a0-8 obj))
+1 -1
View File
@@ -14,7 +14,7 @@
(timer uint8 :offset-assert 6)
(overlap uint8 :offset-assert 7)
(effect uint32 :offset-assert 8)
(sound basic :offset-assert 12)
(sound symbol :offset-assert 12)
)
:method-count-assert 9
:size-assert #x10
+6 -5
View File
@@ -521,14 +521,15 @@ void Debugger::read_symbol_table() {
u32 empty_pair_offset = (m_debug_context.s7 + FIX_SYM_EMPTY_PAIR - PAIR_OFFSET) - st_base;
std::vector<u8> mem;
mem.resize(0x20000);
mem.resize(SYM_TABLE_MEM_SIZE);
if (!xdbg::read_goal_memory(mem.data(), 0x20000, st_base, m_debug_context, m_memory_handle)) {
if (!xdbg::read_goal_memory(mem.data(), SYM_TABLE_MEM_SIZE, st_base, m_debug_context,
m_memory_handle)) {
fmt::print("Read failed during read_symbol_table\n");
return;
}
reads++;
bytes_read += 0x20000;
bytes_read += SYM_TABLE_MEM_SIZE;
struct SymLower {
u32 type;
@@ -581,8 +582,8 @@ void Debugger::read_symbol_table() {
// GOAL sym - s7
auto sym_offset = s32(offset + st_base + BASIC_OFFSET) - s32(m_debug_context.s7);
ASSERT(sym_offset >= INT16_MIN);
ASSERT(sym_offset <= INT16_MAX);
ASSERT(sym_offset >= -SYM_TABLE_MEM_SIZE / 4);
ASSERT(sym_offset < SYM_TABLE_MEM_SIZE / 4);
std::string str(str_buff);
if (str.length() >= 50) {
+1 -1
View File
@@ -1184,7 +1184,7 @@
(add-debug-text-3d
#t
(bucket-id debug-draw1)
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (res-lump-struct obj 'effect-name int :time 0.0)))))
(symbol->string (res-lump-struct obj 'effect-name symbol :time 0.0))
gp-0
(font-color white)
(new 'static 'vector2h :y 24)
+2 -7
View File
@@ -537,13 +537,8 @@
(s0-3 (-> (the-as death-info s3-0) sound))
)
(set! sv-288 (-> obj res))
(let ((t1-11
(string->sound-name
(the-as string (-> (the-as (pointer uint32) (+ #xff38 (the-as int (-> (the-as death-info s3-0) sound))))))
)
)
)
(s1-3 s2-5 (the-as symbol s0-3) arg1 s5-0 sv-288 t1-11)
(let ((t1-11 (string->sound-name (symbol->string (-> (the-as death-info s3-0) sound)))))
(s1-3 s2-5 s0-3 arg1 s5-0 sv-288 t1-11)
)
)
)
+10 -10
View File
@@ -1426,32 +1426,32 @@
"#f"
(let ((s4-0 (the-as (pointer sparticle-launch-group) #f)))
(set! sv-16 (new 'static 'res-tag))
(let* ((s3-0 (res-lump-data arg0 'art-name (pointer (pointer sparticle-launch-group)) :tag-ptr (& sv-16)))
(let* ((s3-0 (res-lump-data arg0 'art-name (pointer symbol) :tag-ptr (& sv-16)))
(s2-0 (-> s3-0 0))
)
(cond
((not s3-0)
)
((part-group-pointer? s2-0)
(set! s4-0 (-> s3-0 0))
((part-group-pointer? (the-as pointer s2-0))
(set! s4-0 (the-as (pointer sparticle-launch-group) (-> s3-0 0)))
)
((= (-> s2-0 -1) string)
((= (-> s2-0 type) string)
(set! s4-0 (lookup-part-group-pointer-by-name (the-as string s2-0)))
(if s4-0
(set! (-> s3-0 0) s4-0)
(set! (-> s3-0 0) (the-as symbol s4-0))
)
)
((= (-> s2-0 -1) symbol)
(let ((a0-7 (-> (&+ s2-0 #xff38) 0)))
(set! s4-0 (lookup-part-group-pointer-by-name (the-as string a0-7)))
((= (-> s2-0 type) symbol)
(let ((a0-7 (symbol->string s2-0)))
(set! s4-0 (lookup-part-group-pointer-by-name a0-7))
)
(if s4-0
(set! (-> s3-0 0) s4-0)
(set! (-> s3-0 0) (the-as symbol s4-0))
)
)
)
)
(when s4-0
(when (the-as object s4-0)
(let ((a0-8 (-> s4-0 0)))
(if (and (nonzero? a0-8) (= (-> a0-8 type) sparticle-launch-group))
(set! (-> obj part) (create-launch-control a0-8 obj))
+1 -1
View File
@@ -10,7 +10,7 @@
(timer uint8 :offset-assert 6)
(overlap uint8 :offset-assert 7)
(effect uint32 :offset-assert 8)
(sound basic :offset-assert 12)
(sound symbol :offset-assert 12)
)
:method-count-assert 9
:size-assert #x10
+1 -1
View File
@@ -1683,7 +1683,7 @@
a1-49
a2-24
(if v1-142
(-> (the-as (pointer uint32) (+ #xff38 (the-as int v1-142))))
(symbol->string (the-as symbol v1-142))
)
(-> *game-info* current-continue name)
)