Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ if (WIBO_ENABLE_FIXTURE_TESTS)
wibo_add_fixture_bin(NAME test_tls SOURCES test/test_tls.c)
wibo_add_fixture_bin(NAME test_tls_reloc SOURCES test/test_tls_reloc.c)
wibo_add_fixture_bin(NAME test_fls SOURCES test/test_fls.c)
wibo_add_fixture_bin(NAME test_fpu_state SOURCES test/test_fpu_state.c)
wibo_add_fixture_bin(NAME test_handleapi SOURCES test/test_handleapi.c)
wibo_add_fixture_bin(NAME test_findfile SOURCES test/test_findfile.c)
wibo_add_fixture_bin(NAME test_getfileattributesex SOURCES test/test_getfileattributesex.c)
Expand Down
6 changes: 6 additions & 0 deletions src/macros.S
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@

.intel_syntax noprefix

#ifdef __x86_64__
#define SP rsp
#else
#define SP esp
#endif

#ifdef __x86_64__

.macro LJMP32 teb_reg
Expand Down
6 changes: 5 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ bool wibo::installTibForCurrentThread(TEB *tibPtr) {
return false;
}
currentThreadTeb = tibPtr;
return tebThreadSetup(tibPtr);
if (!tebThreadSetup(tibPtr)) {
return false;
}
initFpState();
return true;
}

void wibo::uninstallTebForCurrentThread() {
Expand Down
13 changes: 13 additions & 0 deletions src/setup.S
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
.no_dead_strip _wibo_reserve
#endif

# void initFpState()
# Configures 53-bit x87 precision and default SSE control state
ASM_GLOBAL(initFpState, @function)
sub SP, 8
mov word ptr [SP], 0x027f
mov dword ptr [SP+4], 0x1f80
fninit
fldcw word ptr [SP]
ldmxcsr dword ptr [SP+4]
add SP, 8
ret
ASM_END(initFpState)

#if defined(__x86_64__) && defined(__linux__)

# void installSelectors(TEB *teb)
Expand Down
1 change: 1 addition & 0 deletions src/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C" {

bool tebThreadSetup(TEB *teb);
bool tebThreadTeardown(TEB *teb);
void initFpState();

#ifdef __cplusplus
}
Expand Down
43 changes: 43 additions & 0 deletions test/test_fpu_state.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <stdint.h>
#include <stdlib.h>
#include <windows.h>

#include "test_assert.h"

static uint16_t g_x87ControlWord;
static uint32_t g_mxcsr;
static uint16_t g_threadX87ControlWord;
static uint32_t g_threadMxcsr;

static void NTAPI capture_fpu_state(PVOID module, DWORD reason, PVOID reserved) {
(void)module;
(void)reserved;
if (reason != DLL_PROCESS_ATTACH) {
return;
}
__asm__ volatile("fnstcw %0" : "=m"(g_x87ControlWord));
__asm__ volatile("stmxcsr %0" : "=m"(g_mxcsr));
}

PIMAGE_TLS_CALLBACK g_fpuStateCallback __attribute__((section(".CRT$XLB"), used)) = capture_fpu_state;

static DWORD WINAPI capture_thread_fpu_state(LPVOID param) {
(void)param;
__asm__ volatile("fnstcw %0" : "=m"(g_threadX87ControlWord));
__asm__ volatile("stmxcsr %0" : "=m"(g_threadMxcsr));
return 0;
}

int main(void) {
TEST_CHECK_EQ(0x027f, g_x87ControlWord);
// Exception status flags may be raised before the process-attach callback runs.
TEST_CHECK_EQ(0x1f80, g_mxcsr & ~0x3f);

HANDLE thread = CreateThread(NULL, 0, capture_thread_fpu_state, NULL, 0, NULL);
TEST_CHECK(thread != NULL);
TEST_CHECK_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
TEST_CHECK(CloseHandle(thread));
TEST_CHECK_EQ(0x027f, g_threadX87ControlWord);
TEST_CHECK_EQ(0x1f80, g_threadMxcsr & ~0x3f);
return EXIT_SUCCESS;
}
Loading