Save/restore fs/gs segments when re-entering host code

This commit is contained in:
2025-10-05 13:58:40 -06:00
parent 04516b246c
commit cd7baffc5e
44 changed files with 669 additions and 20 deletions

View File

@@ -76,6 +76,7 @@ HeapObject::~HeapObject() {
namespace kernel32 {
HANDLE WIN_FUNC HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapCreate(%u, %zu, %zu)\n", flOptions, dwInitialSize, dwMaximumSize);
if (dwMaximumSize != 0 && dwInitialSize > dwMaximumSize) {
wibo::lastError = ERROR_INVALID_PARAMETER;
@@ -101,6 +102,7 @@ HANDLE WIN_FUNC HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaxim
}
BOOL WIN_FUNC HeapDestroy(HANDLE hHeap) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapDestroy(%p)\n", hHeap);
auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record) {
@@ -119,6 +121,7 @@ BOOL WIN_FUNC HeapDestroy(HANDLE hHeap) {
}
HANDLE WIN_FUNC GetProcessHeap() {
WIN_API_SEGMENT_GUARD();
ensureProcessHeapInitialized();
wibo::lastError = ERROR_SUCCESS;
DEBUG_LOG("GetProcessHeap() -> %p\n", g_processHeapHandle);
@@ -127,6 +130,7 @@ HANDLE WIN_FUNC GetProcessHeap() {
BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation,
SIZE_T HeapInformationLength) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapSetInformation(%p, %d, %p, %zu)\n", HeapHandle, static_cast<int>(HeapInformationClass),
HeapInformation, HeapInformationLength);
auto record = wibo::handles().getAs<HeapObject>(HeapHandle);
@@ -162,6 +166,7 @@ BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapI
}
LPVOID WIN_FUNC HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapAlloc(%p, 0x%x, %zu) ", hHeap, dwFlags, dwBytes);
auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record) {
@@ -181,6 +186,7 @@ LPVOID WIN_FUNC HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
}
LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapReAlloc(%p, 0x%x, %p, %zu) ", hHeap, dwFlags, lpMem, dwBytes);
auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record) {
@@ -258,6 +264,7 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
}
SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapSize(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
(void)dwFlags;
auto record = wibo::handles().getAs<HeapObject>(hHeap);
@@ -274,16 +281,18 @@ SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return static_cast<SIZE_T>(-1);
}
// if (!mi_heap_check_owned(record->heap, const_cast<LPVOID>(lpMem))) {
// wibo::lastError = ERROR_INVALID_PARAMETER;
// return static_cast<SIZE_T>(-1);
// }
if (!mi_heap_check_owned(record->heap, const_cast<LPVOID>(lpMem))) {
DEBUG_LOG("HeapSize: block %p not owned by heap %p\n", lpMem, record->heap);
wibo::lastError = ERROR_INVALID_PARAMETER;
return static_cast<SIZE_T>(-1);
}
size_t size = mi_usable_size(lpMem);
wibo::lastError = ERROR_SUCCESS;
return static_cast<SIZE_T>(size);
}
BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
WIN_API_SEGMENT_GUARD();
DEBUG_LOG("HeapFree(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
(void)dwFlags;
if (lpMem == nullptr) {
@@ -302,10 +311,11 @@ BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
// if (!mi_heap_check_owned(record->heap, lpMem)) {
// wibo::lastError = ERROR_INVALID_PARAMETER;
// return FALSE;
// }
if (!mi_heap_check_owned(record->heap, lpMem)) {
DEBUG_LOG("HeapFree: block %p not owned by heap %p\n", lpMem, record->heap);
wibo::lastError = ERROR_INVALID_PARAMETER;
return FALSE;
}
mi_free(lpMem);
DEBUG_LOG("-> SUCCESS\n");
wibo::lastError = ERROR_SUCCESS;