mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-04 11:45:18 +02:00
ElfReader read the first loadable segment's p_align into firstSegAlign but only ever used it to round down textStart for symbol bookkeeping - the allocation itself used the block allocator's default grain. A module whose relocations are only valid at a more strictly aligned base therefore got loaded somewhere it couldn't work, and the symptom is addresses off by a multiple of 64KB rather than an outright failure. CrossCraft Classic (Zig) declares p_align 0x10000 and hits exactly that. It declares it deliberately: a stage of Zig's PSP pipeline emits mispaired HI16/LO16 relocations, and a 64KB-aligned base makes that harmless - with no low bits in the base no carry is ever needed, so which of a symbol's LO16 entries a HI16 was paired with stops affecting the result. PPSSPP put it at 0x08804000 instead, where the carry does matter: 46 of its addresses came out 64KB low, and it jumped through a bogus vtable a few seconds in. It now loads at 0x08810000 and all 8405 lui/addiu pairs resolve correctly. Worth being clear that the relocation code was never wrong here - it matches what the hardware does, pairing a run of HI16 with the next non-HI16 entry and applying the carry. Only the load address differed. The two AllocAt paths can't move the module, since the caller picked the address, so they just report a misaligned one instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9