Merge pull request #232 from leoetlino/stack/03g-row-bindings

Fix various issues in the functions CSV
This commit is contained in:
Léo Lam
2026-10-18 18:25:05 +01:00
committed by GitHub
3 changed files with 483 additions and 462 deletions
+455 -454
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -622,8 +622,8 @@ FlagHandle Manager::getRevivalFlagHandle(const sead::SafeString& object_name,
void Manager::allocParam1() {
auto* parent_heap = OverlayArenaSystem::instance()->getGameDataWorkHeap();
auto* heap = util::tryCreateDualHeap(0, "param1", parent_heap, nullptr,
sead::Heap::cHeapDirection_Forward, false);
auto* heap = util::createDualHeap(0, "param1", parent_heap, nullptr,
sead::Heap::cHeapDirection_Forward, false);
mFlagBuffer1 = new (heap) TriggerParam;
mFlagBuffer1->copyAllFlags(*mFlagBuffer, heap, true);
heap->adjust();
@@ -649,8 +649,8 @@ void Manager::allocRetryBuffer(sead::Heap* heap) {
if (mRetryBuffer)
return;
auto* buffer_heap = util::tryCreateDualHeap(0x100000, "RetryBuffer", heap, nullptr,
sead::Heap::cHeapDirection_Reverse, false);
auto* buffer_heap = util::createDualHeap(0x100000, "RetryBuffer", heap, nullptr,
sead::Heap::cHeapDirection_Reverse, false);
mRetryBuffer = new (buffer_heap) TriggerParam;
mRetryBuffer->copyPermanentFlags(*mFlagBuffer1, buffer_heap);
buffer_heap->adjust();
+24 -4
View File
@@ -30,6 +30,7 @@ class Function(NamedTuple):
decomp_addr: int
name: str
obj: str
is_weak: bool
@dataclass
@@ -38,6 +39,7 @@ class MatchedFunctions:
not_in_binary: int = 0
shared_inline: int = 0
ambiguous: int = 0
library: int = 0
@dataclass
@@ -118,7 +120,13 @@ def match_functions(decomp_elf: Path, build_dir: Path) -> MatchedFunctions:
matched.not_in_binary += 1
elif len(in_binary) == 1 and len(definitions) == 1:
obj = get_object_name(definitions[0].path, build_dir)
matched.functions.append(Function(info.addr, in_binary[0].address, info.decomp_name, obj))
# The decomp links all libraries before the game code, whereas the original
# interleaves them with it, so their objects would all count as misordered.
if obj.startswith("lib/"):
matched.library += 1
continue
matched.functions.append(
Function(info.addr, in_binary[0].address, info.decomp_name, obj, definitions[0].is_weak))
elif all(definition.is_weak for definition in definitions):
matched.shared_inline += 1
else:
@@ -229,10 +237,13 @@ def main() -> None:
decomp_elf = config.get_decomp_elf().resolve()
matched = match_functions(decomp_elf, decomp_elf.parent)
# A weak function's copy in the original came from whichever object the linker saw first, so
# it can't place its object or make it split. It still counts within its object's main block.
strong_functions = [function for function in matched.functions if not function.is_weak]
main_runs: dict[str, list[Function]] = {}
split_objects: list[str] = []
stray_functions: list[Function] = []
for obj, runs in split_into_blocks(matched.functions).items():
for obj, runs in split_into_blocks(strong_functions).items():
main_run = max(runs, key=len)
main_runs[obj] = main_run
if len(runs) > 1:
@@ -240,13 +251,21 @@ def main() -> None:
stray_functions += [function for run in runs if run is not main_run for function in run]
stray_functions.sort()
main_blocks = {obj: list(run) for obj, run in main_runs.items()}
for function in matched.functions:
run = main_runs.get(function.obj)
if function.is_weak and run and run[0].orig_addr < function.orig_addr < run[-1].orig_addr:
main_blocks[function.obj].append(function)
for block in main_blocks.values():
block.sort()
objects_in_original_order = sorted(main_runs, key=lambda obj: main_runs[obj][0].orig_addr)
misordered_objects = out_of_order(objects_in_original_order,
lambda obj: min(function.decomp_addr for function in main_runs[obj]))
misordered_functions: list[Function] = []
for obj in objects_in_original_order:
misordered_functions += out_of_order(main_runs[obj], lambda function: function.decomp_addr)
misordered_functions += out_of_order(main_blocks[obj], lambda function: function.decomp_addr)
report = Report(
misordered_objects=[f"0x{main_runs[obj][0].orig_addr + ORIGINAL_BASE:016x} {obj}" for obj in misordered_objects],
@@ -267,7 +286,8 @@ def main() -> None:
print(f"{len(matched.functions):>7d} compared functions")
print(f"{Style.DIM}{matched.not_in_binary:>7d} skipped, not in the decomp binary")
print(f"{matched.shared_inline:>7d} skipped, inline in several objects")
print(f"{matched.ambiguous:>7d} skipped, ambiguous name{Style.RESET_ALL}")
print(f"{matched.ambiguous:>7d} skipped, ambiguous name")
print(f"{matched.library:>7d} skipped, library code{Style.RESET_ALL}")
print(f"{len(main_runs):>7d} objects")
print(f"{len(misordered_objects):>7d} {Fore.RED}misordered objects{Fore.RESET}")
print(f"{len(split_objects):>7d} {Fore.YELLOW}objects split in the original{Fore.RESET} "