mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
virtmem: Fix stack region mapping on 1.0.0
This commit is contained in:
parent
a15c9945a7
commit
e942b9cc25
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user