Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow plugins with heaps of 5 MiB or less to use PRIVATE memory instead of SHARED #2079

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions k11_extension/include/svc/MapProcessMemoryEx.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@
#include "kernel.h"
#include "svc.h"

Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size);
Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size);
Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared);
Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared);
13 changes: 11 additions & 2 deletions k11_extension/source/svc/MapProcessMemoryEx.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

#include "svc/MapProcessMemoryEx.h"

Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size)
Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared)
{
Result res = 0;
u32 sizeInPage = size >> 12;
Expand Down Expand Up @@ -69,7 +69,16 @@ Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcess
// Check if the destination address is free and large enough
res = KProcessHwInfo__CheckVaState(hwInfoOfProcess(dstProcess), vaDst, size, 0, 0);
if (res == 0)
res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0x5806, MEMPERM_RW | 0x18, 0);
{
if (shared)
{
res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0x5806, MEMPERM_RW | 0x18, 0);
}
else
{
res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0xBB05, MEMPERM_RW | 0x18, 0);
}
}
}

KLinkedList_KBlockInfo__Clear(&list);
Expand Down
3 changes: 2 additions & 1 deletion k11_extension/source/svc/wrappers.s
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ ControlMemoryUnsafeWrapper:
.type MapProcessMemoryExWrapper, %function
MapProcessMemoryExWrapper:
push {lr}
str r5, [sp, #-4]!
str r4, [sp, #-4]!
bl MapProcessMemoryEx
add sp, #4
add sp, #8
pop {pc}
3 changes: 2 additions & 1 deletion sysmodules/rosalina/include/csvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ void svcInvalidateEntireInstructionCache(void);
* @param srcProcessHandle Handle of the process to map the memory from (source)
* @param srcAddress Start address of the memory block in the source process
* @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes)
* @param shared Flag for whether to set the memory's state to SHARED instead of PRIVATE
*/
Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size);
Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size, bool shared);

/**
* @brief Unmaps a block of process memory.
Expand Down
5 changes: 4 additions & 1 deletion sysmodules/rosalina/source/csvc.s
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,13 @@ SVC_BEGIN svcInvalidateEntireInstructionCache
SVC_END

SVC_BEGIN svcMapProcessMemoryEx
str r5, [sp, #-4]!
str r4, [sp, #-4]!
ldr r4, [sp, #4]
ldr r4, [sp, #8]
ldr r5, [sp, #12]
svc 0xA0
ldr r4, [sp], #4
ldr r5, [sp], #4
bx lr
SVC_END

Expand Down
4 changes: 2 additions & 2 deletions sysmodules/rosalina/source/input_redirection.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static Result InputRedirection_DoUndoIrPatches(Handle processHandle, bool doPatc
totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize);

svcGetProcessInfo(&startAddress, processHandle, 0x10005);
res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize);
res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true);

if(R_SUCCEEDED(res) && !patchPrepared)
{
Expand Down Expand Up @@ -356,7 +356,7 @@ static Result InputRedirection_DoUndoHidPatches(Handle processHandle, bool doPat
totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize);

svcGetProcessInfo(&startAddress, processHandle, 0x10005);
res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize);
res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true);

if (R_SUCCEEDED(res) && !patchPrepared)
{
Expand Down
4 changes: 2 additions & 2 deletions sysmodules/rosalina/source/menus/process_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info)
svcQueryProcessMemory(&mem, &out, processHandle, heapStartAddress);
heapTotalSize = mem.size;

Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize);
Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize);
Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize, true);
Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize, true);

bool codeAvailable = R_SUCCEEDED(codeRes);
bool heapAvailable = R_SUCCEEDED(heapRes);
Expand Down
2 changes: 1 addition & 1 deletion sysmodules/rosalina/source/plugin/file_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ bool TryToLoadPlugin(Handle process)

extern u32 g_savedGameInstr[2];

if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000))))
if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000, true))))
{
ctx->error.message = "Couldn't map process";
ctx->error.code = res;
Expand Down
11 changes: 8 additions & 3 deletions sysmodules/rosalina/source/plugin/memoryblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ Result MemoryBlock__IsReady(void)

// Then allocate our plugin memory block
if (R_SUCCEEDED(res))
{
res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, 0x07000000,
g_memBlockSize, MEMOP_REGION_APP | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW);
}

// Finally release game reserve block
if (R_SUCCEEDED(res))
Expand Down Expand Up @@ -209,15 +211,15 @@ Result MemoryBlock__MountInProcess(void)
Result res = 0;

// Executable
if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32)memblock->memblock, header->exeSize))))
if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32) memblock->memblock, header->exeSize, true))))
{
error->message = "Couldn't map exe memory block";
error->code = res;
return res;
}

// Heap (to be used by the plugin)
if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize))))
if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, (header->heapSize > 0x500000) ? true : false))))
{
error->message = "Couldn't map heap memory block";
error->code = res;
Expand All @@ -230,10 +232,13 @@ Result MemoryBlock__UnmountFromProcess(void)
{
Handle target = PluginLoaderCtx.target;
PluginHeader *header = &PluginLoaderCtx.header;
MemoryBlock *memblock = &PluginLoaderCtx.memblock;

Result res = 0;

res = svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize);
res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the logic behind this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/LittlestCube/Luma3DS/blob/48cf6596b16a62aa6fe09d4008d18fe1624a1dee/sysmodules/rosalina/source/plugin/memoryblock.c#L246-L249

Probably doesn't matter now, but two lines under you can see both original Unmaps were kept. The idea was to make sure it was still mapped the normal way with 0x5806 just in case Unmap would somehow break on PRIVATE memory.

Admittedly, perhaps a call to svcControlProcessMemory would have been more prudent, but I'm not sure.


res |= svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize);
res |= svcUnmapProcessMemoryEx(target, header->heapVA, header->heapSize);

return res;
Expand Down
2 changes: 1 addition & 1 deletion sysmodules/rosalina/source/process_patches.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Result OperateOnProcessByName(const char *name, OperateOnProcessCb func)

// NOTE: we suppose .text, .rodata, .data+.bss are contiguous & in that order
u32 totalSize = (u32)(textSize + roSize + rwSize);
if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize)))
if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true)))
{
svcCloseHandle(processHandle);
return res;
Expand Down