libnx/nx/source/kernel/shmem.c
fincs a05a44fca8
virtmem: Major rewrite to support ASLR, see details:
- Added virtmemLock/Unlock, needed for atomic find-and-map operations
- Added virtmemFindAslr, which looks for a random free area in AslrRegion
  - virtmemReserve still exists for legacy callers who rely on sequential
    allocation in order to avoid race conditions from concurrent uses
- Added virtmemFindStack, which searches within StackRegion instead
  - Removed virtmemReserveStack/FreeStack
- Changed shmem/thread/tmem/codememory-jit to use the new virtmem API
  - Legacy jit still uses virtmemReserve
2020-10-27 12:27:32 +01:00

84 lines
1.6 KiB
C

// Copyright 2017 plutoo
#include <malloc.h>
#include "types.h"
#include "result.h"
#include "kernel/svc.h"
#include "kernel/virtmem.h"
#include "kernel/shmem.h"
Result shmemCreate(SharedMemory* s, size_t size, Permission local_perm, Permission remote_perm)
{
Result rc;
s->handle = INVALID_HANDLE;
s->size = size;
s->map_addr = NULL;
s->perm = local_perm;
rc = svcCreateSharedMemory(&s->handle, size, local_perm, remote_perm);
return rc;
}
void shmemLoadRemote(SharedMemory* s, Handle handle, size_t size, Permission perm)
{
s->handle = handle;
s->size = size;
s->map_addr = NULL;
s->perm = perm;
}
Result shmemMap(SharedMemory* s)
{
Result rc = 0;
if (s->map_addr == NULL)
{
virtmemLock();
void* addr = virtmemFindAslr(s->size, 0x1000);
rc = svcMapSharedMemory(s->handle, addr, s->size, s->perm);
virtmemUnlock();
if (R_SUCCEEDED(rc)) {
s->map_addr = addr;
}
}
else {
rc = MAKERESULT(Module_Libnx, LibnxError_AlreadyMapped);
}
return rc;
}
Result shmemUnmap(SharedMemory* s)
{
Result rc;
rc = svcUnmapSharedMemory(s->handle, s->map_addr, s->size);
if (R_SUCCEEDED(rc)) {
s->map_addr = NULL;
}
return rc;
}
Result shmemClose(SharedMemory* s)
{
Result rc = 0;
if (s->map_addr != NULL) {
rc = shmemUnmap(s);
}
if (R_SUCCEEDED(rc)) {
if (s->handle != INVALID_HANDLE) {
rc = svcCloseHandle(s->handle);
}
s->handle = INVALID_HANDLE;
}
return rc;
}