diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index c0d5f456..2790c8f8 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -6,6 +6,8 @@ #include "memory.hpp" +using namespace KernelMemoryTypes; + namespace { struct LoadInfo { u32 codeSegSizeAligned; @@ -26,7 +28,7 @@ namespace { } // namespace bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { -/* const LoadInfo hbInfo = { + const LoadInfo hbInfo = { .codeSegSizeAligned = (header.codeSegSize + 0xFFF) & ~0xFFF, .rodataSegSizeAligned = (header.rodataSegSize + 0xFFF) & ~0xFFF, .dataSegSizeAligned = (header.dataSegSize + 0xFFF) & ~0xFFF, @@ -53,12 +55,6 @@ bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { // suum of aligned values is always aligned, have an extra RW page for libctru const u32 totalSize = hbInfo.codeSegSizeAligned + hbInfo.rodataSegSizeAligned + hbInfo.dataSegSizeAligned + 4_KB; - const auto opt = findPaddr(totalSize); - if (!opt.has_value()) { - Helpers::panic("Failed to find paddr to map 3DSX file's code to"); - return false; - } - // Map the ROM on the kernel side const u32 textOffset = 0; const u32 rodataOffset = textOffset + hbInfo.codeSegSizeAligned; @@ -186,10 +182,10 @@ bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { return false; } } - }*/ + } // Detect and fill _prm structure - /*HB3DSX::PrmStruct pst; + HB3DSX::PrmStruct pst; std::memcpy(&pst, &code[4], sizeof(pst)); if (pst.magic[0] == '_' && pst.magic[1] == 'p' && pst.magic[2] == 'r' && pst.magic[3] == 'm') { // if there was any argv to put, it would go there @@ -205,7 +201,7 @@ bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { // RUNFLAG_APTREINIT: Reinitialize APT. // From libctru. Because there's no previously running software here - pst.runFlags |= 1 << 1;*/ + pst.runFlags |= 1 << 1; /* s64 dummy; bool isN3DS = svcGetSystemInfo(&dummy, 0x10001, 0) == 0; @@ -213,7 +209,8 @@ bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { { pst->heapSize = u32(48_MB); pst->linearHeapSize = u32(64_MB); - } else *//* { + } else */ + { pst.heapSize = u32(24_MB); pst.linearHeapSize = u32(32_MB); } @@ -221,15 +218,19 @@ bool Memory::map3DSX(HB3DSX& hb3dsx, const HB3DSX::Header& header) { std::memcpy(&code[4], &pst, sizeof(pst)); } - const auto paddr = opt.value(); - std::memcpy(&fcram[paddr], &code[0], totalSize); // Copy the 3 segments + BSS to FCRAM + // Text is R-X + allocMemory(textSegAddr, hbInfo.codeSegSizeAligned / Memory::pageSize, FcramRegion::App, true, false, true, MemoryState::Code); + copyToVaddr(textSegAddr, &code[textOffset], hbInfo.codeSegSizeAligned); - allocateMemory(textSegAddr, paddr + textOffset, hbInfo.codeSegSizeAligned, true, true, false, true); // Text is R-X - allocateMemory(rodataSegAddr, paddr + rodataOffset, hbInfo.rodataSegSizeAligned, true, true, false, false); // Rodata is R-- - allocateMemory(dataSegAddr, paddr + dataOffset, hbInfo.dataSegSizeAligned + 0x1000, true, true, true, false); // Data+BSS+Extra is RW- + // Rodata is R-- + allocMemory(rodataSegAddr, hbInfo.rodataSegSizeAligned / Memory::pageSize, FcramRegion::App, true, false, false, MemoryState::Code); + copyToVaddr(rodataSegAddr, &code[rodataOffset], hbInfo.rodataSegSizeAligned); - return true;*/ -return false; + // Data + BSS + Extra is RW-. We allocate 1 extra page (4KB) which is not initialized to anything. + allocMemory(dataSegAddr, (hbInfo.dataSegSizeAligned + 4_KB) / Memory::pageSize, FcramRegion::App, true, true, false, MemoryState::Private); + copyToVaddr(dataSegAddr, &code[dataOffset], hbInfo.dataSegSizeAligned); + + return true; } std::optional Memory::load3DSX(const std::filesystem::path& path) {