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 to use PRIVATE memory instead of SHARED on requests #2086

Merged
merged 6 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 8 additions & 2 deletions k11_extension/include/svc/MapProcessMemoryEx.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@
#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);
/// Flags for svcMapProcessMemoryEx
typedef enum MapExFlags
{
MAPEXFLAGS_PRIVATE = BIT(0), ///< Maps the memory as PRIVATE (0xBB05) instead of SHARED (0x5806)
} MapExFlags;

Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, MapExFlags flags);
Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, MapExFlags flags);
4 changes: 2 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, MapExFlags flags)
{
Result res = 0;
u32 sizeInPage = size >> 12;
Expand Down Expand Up @@ -69,7 +69,7 @@ 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);
res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, (flags & MAPEXFLAGS_PRIVATE) ? 0xBB05 : 0x5806, MEMPERM_RW | 0x18, 0);
}

KLinkedList_KBlockInfo__Clear(&list);
Expand Down
10 changes: 7 additions & 3 deletions k11_extension/source/svc/wrappers.s
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,12 @@ ControlMemoryUnsafeWrapper:
.global MapProcessMemoryExWrapper
.type MapProcessMemoryExWrapper, %function
MapProcessMemoryExWrapper:
push {lr}
push {r5, lr} @ We need to save r5 because the old implementation doesn't save it
cmp r0, #0xFFFFFFF2 @ Check magic value, for backwards compatibility
moveq r0, r6 @ If value present, flags present in r5 and dst process in r6, so move dst process back to r0
movne r5, #0 @ If value not present, clear the flags as its the old version
str r5, [sp, #-4]!
str r4, [sp, #-4]!
bl MapProcessMemoryEx
add sp, #4
pop {pc}
add sp, #8
pop {r5, pc}
10 changes: 9 additions & 1 deletion sysmodules/rosalina/include/csvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,23 @@ void svcInvalidateEntireInstructionCache(void);

///@name Memory management
///@{

/// Flags for svcMapProcessMemoryEx
typedef enum MapExFlags
{
MAPEXFLAGS_PRIVATE = BIT(0), ///< Maps the memory as PRIVATE (0xBB05) instead of SHARED (0x5806)
} MapExFlags;

/**
* @brief Maps a block of process memory.
* @param dstProcessHandle Handle of the process to map the memory in (destination)
* @param destAddress Start address of the memory block in the destination process
* @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 flags Extended flags for mapping the memory (see MapExFlags)
*/
Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size);
Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size, MapExFlags flags);

/**
* @brief Unmaps a block of process memory.
Expand Down
3 changes: 2 additions & 1 deletion sysmodules/rosalina/include/plugin/3gx.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ typedef struct CTR_PACKED
u32 compatibility : 2;
u32 eventsSelfManaged : 1;
u32 swapNotNeeded : 1;
u32 unused : 24;
u32 usePrivateMemory : 1;
u32 unused : 23;
};
};
u32 exeLoadChecksum;
Expand Down
1 change: 1 addition & 0 deletions sysmodules/rosalina/include/plugin/plgloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ typedef struct
u32 swapLoadChecksum;

bool eventsSelfManaged;
bool isMemPrivate;
} PluginLoaderContext;

extern PluginLoaderContext PluginLoaderCtx;
Expand Down
9 changes: 6 additions & 3 deletions 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 r4, [sp, #-4]!
ldr r4, [sp, #4]
push {r4, r5, r6}
ldr r4, [sp, #12]
ldr r5, [sp, #16]
mov r6, r0 @ Move the dst handle to r6 to make room for magic value
mov r0, #0xFFFFFFF2 @ Set r0 to magic value, which allows for backwards compatibility
svc 0xA0
ldr r4, [sp], #4
pop {r4, r5, r6}
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, 0);

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, 0);

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, 0);
Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize, 0);

bool codeAvailable = R_SUCCEEDED(codeRes);
bool heapAvailable = R_SUCCEEDED(heapRes);
Expand Down
3 changes: 2 additions & 1 deletion sysmodules/rosalina/source/plugin/file_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ bool TryToLoadPlugin(Handle process)
// Flags
if (!res) {
ctx->eventsSelfManaged = fileHeader.infos.eventsSelfManaged;
ctx->isMemPrivate = fileHeader.infos.usePrivateMemory;
if (ctx->pluginMemoryStrategy == PLG_STRATEGY_SWAP && fileHeader.infos.swapNotNeeded)
ctx->pluginMemoryStrategy = PLG_STRATEGY_NONE;
}
Expand Down Expand Up @@ -292,7 +293,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, 0))))
{
ctx->error.message = "Couldn't map process";
ctx->error.code = res;
Expand Down
7 changes: 4 additions & 3 deletions sysmodules/rosalina/source/plugin/memoryblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,19 +205,20 @@ Result MemoryBlock__MountInProcess(void)
Error *error = &PluginLoaderCtx.error;
PluginHeader *header = &PluginLoaderCtx.header;
MemoryBlock *memblock = &PluginLoaderCtx.memblock;
bool isPrivate = PluginLoaderCtx.isMemPrivate;

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, isPrivate ? MAPEXFLAGS_PRIVATE : 0))))
{
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, isPrivate ? MAPEXFLAGS_PRIVATE : 0))))
{
error->message = "Couldn't map heap memory block";
error->code = res;
Expand All @@ -233,7 +234,7 @@ Result MemoryBlock__UnmountFromProcess(void)

Result res = 0;

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

return res;
Expand Down
1 change: 1 addition & 0 deletions sysmodules/rosalina/source/plugin/plgloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ static void WaitForProcessTerminated(void *arg)
ctx->isSwapFunctionset = false;
ctx->pluginMemoryStrategy = PLG_STRATEGY_SWAP;
ctx->eventsSelfManaged = false;
ctx->isMemPrivate = false;
g_blockMenuOpen = 0;
MemoryBlock__ResetSwapSettings();
//if (!ctx->userLoadParameters.noIRPatch)
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, 0)))
{
svcCloseHandle(processHandle);
return res;
Expand Down