mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-07-01 20:06:18 +02:00
Fix Paper Mario TTYD crashes on Android
This fixes the crash in Paper Mario TTYD on Android. The issue was a 32bit svc was being executed at module_start + 0x112F50 so we replace that svc we nop to fix the crash issue.
This commit is contained in:
parent
5575d77520
commit
4bedd49376
1 changed files with 37 additions and 0 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -44,6 +45,40 @@ static_assert(sizeof(MODHeader) == 0x1c, "MODHeader has incorrect size.");
|
||||||
constexpr u32 PageAlignSize(u32 size) {
|
constexpr u32 PageAlignSize(u32 size) {
|
||||||
return static_cast<u32>((size + Core::Memory::YUZU_PAGEMASK) & ~Core::Memory::YUZU_PAGEMASK);
|
return static_cast<u32>((size + Core::Memory::YUZU_PAGEMASK) & ~Core::Memory::YUZU_PAGEMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr u64 PaperMarioTTYDProgramId = 0x0100ECD018EBE000ULL;
|
||||||
|
constexpr u32 PaperMarioTTYDTrapOffset = 0x112F50;
|
||||||
|
|
||||||
|
bool IsPaperMarioTTYD(u64 program_id) {
|
||||||
|
return (program_id & ~0xFFFULL) == PaperMarioTTYDProgramId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyPaperMarioTTYDWorkaround(const Kernel::KProcess& process, std::string_view module_name,
|
||||||
|
std::span<u8> image, size_t module_start) {
|
||||||
|
static constexpr std::array<u8, 8> kTrapThenRet{
|
||||||
|
0xFE, 0xDE, 0xFF, 0xE7, 0xC0, 0x03, 0x5F, 0xD6,
|
||||||
|
};
|
||||||
|
static constexpr std::array<u8, 4> kNop{
|
||||||
|
0x1F, 0x20, 0x03, 0xD5,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!IsPaperMarioTTYD(process.GetProgramId()) || module_name != "sdk") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t trap_offset = module_start + PaperMarioTTYDTrapOffset;
|
||||||
|
if (trap_offset + kTrapThenRet.size() > image.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::equal(kTrapThenRet.begin(), kTrapThenRet.end(), image.begin() + trap_offset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy(kNop.begin(), kNop.end(), image.begin() + trap_offset);
|
||||||
|
LOG_WARNING(Loader, "Applied Paper Mario TTYD boot workaround for {:016X} at nnSdk+{:#x}",
|
||||||
|
process.GetProgramId(), PaperMarioTTYDTrapOffset);
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool NSOHeader::IsSegmentCompressed(size_t segment_num) const {
|
bool NSOHeader::IsSegmentCompressed(size_t segment_num) const {
|
||||||
|
|
@ -149,6 +184,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||||
std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), patchable_section.data());
|
std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), patchable_section.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplyPaperMarioTTYDWorkaround(process, name, codeset.memory, module_start);
|
||||||
|
|
||||||
#ifdef HAS_NCE
|
#ifdef HAS_NCE
|
||||||
// If we are computing the process code layout and using nce backend, patch.
|
// If we are computing the process code layout and using nce backend, patch.
|
||||||
const auto& code = codeset.CodeSegment();
|
const auto& code = codeset.CodeSegment();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue