diff --git a/XenonAnalyse/function.cpp b/XenonAnalyse/function.cpp index 34add40..bc9392a 100644 --- a/XenonAnalyse/function.cpp +++ b/XenonAnalyse/function.cpp @@ -38,8 +38,14 @@ size_t Function::SearchBlock(size_t address) const return -1; } -Function Function::Analyze(const void* code, size_t size, size_t base) +Function Function::Analyze(const void* code, size_t size, size_t base, + const AnalyzerSwitchTableMap* switchMap) { + (void)switchMap; // consumed in a follow-up commit; receiving now so + // that callers can adopt the signature and pass a + // map immediately without waiting for the walker + // change to land. + Function fn{ base, 0 }; if (*((uint32_t*)code + 1) == 0x04000048) // shifted ptr tail call diff --git a/XenonAnalyse/function.h b/XenonAnalyse/function.h index 7df1c6a..ea71ea6 100644 --- a/XenonAnalyse/function.h +++ b/XenonAnalyse/function.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include #ifdef _DEBUG @@ -9,6 +11,29 @@ #define DEBUG(X) #endif +// Optional switch-table map consumed by the block walker in +// Function::Analyze when it reaches an unconditional bctr at a known +// switch-dispatch site. When the caller hands in a populated map, the +// walker pushes every label (and the default) as a successor block +// instead of terminating, which grows `fn.size` to include switch- +// dispatched code that the legacy walker would discard via the end- +// of-Analyze discontinuity pass. +// +// The map is keyed by the BCTR guest VA — NOT by the first-instruction- +// of-pattern VA that XenonAnalyse's own switch-table TOML emits. The +// caller (typically XenonRecomp) performs the switch-base → bctr-VA +// offset math at map-construction time and hands us a pre-keyed map. +// +// Passing nullptr (the default) preserves the legacy walker behavior +// byte-for-byte. No existing callers need to change. +struct AnalyzerSwitchTable +{ + uint32_t defaultLabel{}; + std::vector labels{}; +}; + +using AnalyzerSwitchTableMap = std::unordered_map; + struct Function { struct Block @@ -18,16 +43,16 @@ struct Function size_t projectedSize{ static_cast(-1) }; // scratch DEBUG(size_t parent{}); - Block() + Block() { } Block(size_t base, size_t size) - : base(base), size(size) + : base(base), size(size) { } - Block(size_t base, size_t size, size_t projectedSize) + Block(size_t base, size_t size, size_t projectedSize) : base(base), size(size), projectedSize(projectedSize) { } @@ -45,7 +70,8 @@ struct Function : base(base), size(size) { } - + size_t SearchBlock(size_t address) const; - static Function Analyze(const void* code, size_t size, size_t base); + static Function Analyze(const void* code, size_t size, size_t base, + const AnalyzerSwitchTableMap* switchMap = nullptr); };