diff --git a/src/common/platform/kernel_mapped.hpp b/src/common/platform/kernel_mapped.hpp index 4bcbada7..da0ebe52 100644 --- a/src/common/platform/kernel_mapped.hpp +++ b/src/common/platform/kernel_mapped.hpp @@ -21,6 +21,7 @@ #define WIN32_CLIENT_INFO_LENGTH 62 #define STATIC_UNICODE_BUFFER_LENGTH 261 #define TLS_MINIMUM_AVAILABLE 64 +#define TLS_EXPANSION_SLOTS 1024 #ifndef OS_WINDOWS #define PF_FLOATING_POINT_PRECISION_ERRATA 0 diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index ffd9120b..e19da9d7 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -102,17 +102,44 @@ namespace syscalls for (const auto& t : c.proc.threads | std::views::values) { - t.teb64->access([&](TEB64& teb) { - if (tls_cell < TLS_MINIMUM_AVAILABLE) + if (tls_cell < TLS_MINIMUM_AVAILABLE) + { + if (c.proc.is_wow64_process) { - teb.TlsSlots.arr[tls_cell] = 0; + if (t.teb32.has_value()) + { + t.teb32->access([&](TEB32& teb32) { teb32.TlsSlots.arr[tls_cell] = 0; }); + } } - else if (teb.TlsExpansionSlots) + else { - const emulator_object expansion_slots(c.emu, teb.TlsExpansionSlots); - expansion_slots.write(0, tls_cell - TLS_MINIMUM_AVAILABLE); + t.teb64->access([&](TEB64& teb64) { teb64.TlsSlots.arr[tls_cell] = 0; }); } - }); + } + else if (tls_cell < TLS_MINIMUM_AVAILABLE + TLS_EXPANSION_SLOTS) + { + if (c.proc.is_wow64_process) + { + if (t.teb32.has_value()) + { + t.teb32->access([&](TEB32& teb32) { + if (teb32.TlsExpansionSlots) + { + c.emu.write_memory(teb32.TlsExpansionSlots + (4 * tls_cell) - TLS_MINIMUM_AVAILABLE, 0); + } + }); + } + } + else + { + t.teb64->access([&](TEB64& teb64) { + if (teb64.TlsExpansionSlots) + { + c.emu.write_memory(teb64.TlsExpansionSlots + (8 * tls_cell) - TLS_MINIMUM_AVAILABLE, 0); + } + }); + } + } } return STATUS_SUCCESS;