virtmem: Fix stack region mapping on 1.0.0

This commit is contained in:
Michael Scire 2018-10-22 13:19:00 -07:00 committed by plutoo
parent a15c9945a7
commit e942b9cc25
3 changed files with 22 additions and 22 deletions

View File

@ -22,15 +22,15 @@ void* virtmemReserve(size_t size);
void virtmemFree(void* addr, size_t size); void virtmemFree(void* addr, size_t size);
/** /**
* @brief Reserves a slice of address space inside the alias memory mapping region(s) (for use with svcMapMemory). * @brief Reserves a slice of address space inside the stack memory mapping region (for use with svcMapMemory).
* @param size The size of the slice of address space that will be reserved (rounded up to page alignment). * @param size The size of the slice of address space that will be reserved (rounded up to page alignment).
* @return Pointer to the slice of address space, or NULL on failure. * @return Pointer to the slice of address space, or NULL on failure.
*/ */
void* virtmemReserveMap(size_t size); void* virtmemReserveStack(size_t size);
/** /**
* @brief Relinquishes a slice of address space reserved with virtmemReserveMap (currently no-op). * @brief Relinquishes a slice of address space reserved with virtmemReserveStack (currently no-op).
* @param addr Pointer to the slice. * @param addr Pointer to the slice.
* @param size Size of the slice. * @param size Size of the slice.
*/ */
void virtmemFreeMap(void* addr, size_t size); void virtmemFreeStack(void* addr, size_t size);

View File

@ -52,7 +52,7 @@ Result threadCreate(
rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory); rc = MAKERESULT(Module_Libnx, LibnxError_OutOfMemory);
} }
else { else {
void* stack_mirror = virtmemReserveMap(stack_sz); void* stack_mirror = virtmemReserveStack(stack_sz);
rc = svcMapMemory(stack_mirror, stack, stack_sz); rc = svcMapMemory(stack_mirror, stack, stack_sz);
if (R_SUCCEEDED(rc)) if (R_SUCCEEDED(rc))
@ -100,7 +100,7 @@ Result threadCreate(
} }
if (R_FAILED(rc)) { if (R_FAILED(rc)) {
virtmemFreeMap(stack_mirror, stack_sz); virtmemFreeStack(stack_mirror, stack_sz);
free(stack); free(stack);
} }
} }
@ -120,7 +120,7 @@ Result threadClose(Thread* t) {
Result rc; Result rc;
rc = svcUnmapMemory(t->stack_mirror, t->stack_mem, t->stack_sz); rc = svcUnmapMemory(t->stack_mirror, t->stack_mem, t->stack_sz);
virtmemFreeMap(t->stack_mirror, t->stack_sz); virtmemFreeStack(t->stack_mirror, t->stack_sz);
free(t->stack_mem); free(t->stack_mem);
svcCloseHandle(t->handle); svcCloseHandle(t->handle);

View File

@ -14,7 +14,6 @@ typedef struct {
enum { enum {
REGION_STACK=0, REGION_STACK=0,
REGION_HEAP=1, REGION_HEAP=1,
REGION_NEW_STACK=2,
REGION_MAX REGION_MAX
}; };
@ -57,30 +56,32 @@ void virtmemSetup(void) {
// Thus we are 32-bit. // Thus we are 32-bit.
g_AddressSpace.start = 0x200000ull; g_AddressSpace.start = 0x200000ull;
g_AddressSpace.end = 0x100000000ull; g_AddressSpace.end = 0x100000000ull;
g_Region[REGION_STACK].start = 0x200000ull;
g_Region[REGION_STACK].end = 0x40000000ull;
} }
else if (rc == 0xDC01) { else if (rc == 0xDC01) {
// Invalid dst-address error means our 36-bit src-address was valid. // Invalid dst-address error means our 36-bit src-address was valid.
// Thus we are 36-bit. // Thus we are 36-bit.
g_AddressSpace.start = 0x8000000ull; g_AddressSpace.start = 0x8000000ull;
g_AddressSpace.end = 0x1000000000ull; g_AddressSpace.end = 0x1000000000ull;
g_Region[REGION_STACK].start = 0x8000000ull;
g_Region[REGION_STACK].end = 0x80000000ull;
} }
else { else {
// Wat. // Wat.
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel)); fatalSimple(MAKERESULT(Module_Libnx, LibnxError_WeirdKernel));
} }
} } else {
if (R_FAILED(_GetRegionFromInfo(&g_Region[REGION_STACK], 14, 15))) {
if (R_FAILED(_GetRegionFromInfo(&g_Region[REGION_STACK], 2, 3))) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Stack)); fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Stack));
} }
}
if (R_FAILED(_GetRegionFromInfo(&g_Region[REGION_HEAP], 4, 5))) { if (R_FAILED(_GetRegionFromInfo(&g_Region[REGION_HEAP], 4, 5))) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Heap)); fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Heap));
} }
// Failure is OK, happens on 1.0.0
// In that case, g_UnkRegion will default to (0, 0).
_GetRegionFromInfo(&g_Region[REGION_NEW_STACK], 14, 15);
} }
void* virtmemReserve(size_t size) { void* virtmemReserve(size_t size) {
@ -157,13 +158,12 @@ void virtmemFree(void* addr, size_t size) {
IGNORE_ARG(size); IGNORE_ARG(size);
} }
void* virtmemReserveMap(size_t size) void* virtmemReserveStack(size_t size)
{ {
Result rc; Result rc;
MemoryInfo meminfo; MemoryInfo meminfo;
u32 pageinfo; u32 pageinfo;
int region_idx = kernelAbove200() ? REGION_NEW_STACK : REGION_STACK;
size = (size + 0xFFF) &~ 0xFFF; size = (size + 0xFFF) &~ 0xFFF;
mutexLock(&g_VirtMemMutex); mutexLock(&g_VirtMemMutex);
@ -175,8 +175,8 @@ void* virtmemReserveMap(size_t size)
addr += 0x1000; addr += 0x1000;
// Make sure we stay inside the reserved map region. // Make sure we stay inside the reserved map region.
if (!_InRegion(&g_Region[region_idx], addr)) { if (!_InRegion(&g_Region[REGION_STACK], addr)) {
addr = g_Region[region_idx].start; addr = g_Region[REGION_STACK].start;
} }
// Query information about address. // Query information about address.
@ -207,7 +207,7 @@ void* virtmemReserveMap(size_t size)
return (void*) addr; return (void*) addr;
} }
void virtmemFreeMap(void* addr, size_t size) { void virtmemFreeStack(void* addr, size_t size) {
IGNORE_ARG(addr); IGNORE_ARG(addr);
IGNORE_ARG(size); IGNORE_ARG(size);
} }