Merge pull request #5191 from Sonicadvance1/36

unittests/FEXLinuxTests: Force clang building for tests
This commit is contained in:
LC authored and GitHub committed 2026-01-03 03:06:38 -05:00
commit 62383a1c72
7 files changed
+65 -64

No files matched your search

+2
View File
@@ -6,6 +6,7 @@ ExternalProject_Add(FEXLinuxTests
CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${X86_64_TOOLCHAIN_FILE}"
"-DENABLE_CLANG_THUNKS=True"
"-DBITNESS=64"
INSTALL_COMMAND ""
BUILD_ALWAYS ON)
@@ -17,6 +18,7 @@ ExternalProject_Add(FEXLinuxTests_32
CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${X86_32_TOOLCHAIN_FILE}"
"-DENABLE_CLANG_THUNKS=True"
"-DBITNESS=32"
INSTALL_COMMAND ""
BUILD_ALWAYS ON)
@@ -3,9 +3,6 @@ project(FEXLinuxTests)
set(CMAKE_CXX_STANDARD 20)
unset(CMAKE_C_FLAGS)
unset(CMAKE_CXX_FLAGS)
set(GENERATE_GUEST_INSTALL_TARGETS TRUE)
# Use intel masm syntax. ATT style asm syntax is archaic and hard to read.
@@ -25,7 +25,8 @@ struct cpuid_fn {
cpuid_fn get_cpuid(uint32_t func, uint32_t leaf = 0) {
cpuid_fn fn {};
__cpuid_count(func, leaf, fn.eax, fn.ebx, fn.ecx, fn.edx);
__asm volatile("cpuid" : "=a"(fn.eax), "=b"(fn.ebx), "=c"(fn.ecx), "=d"(fn.edx) : "a"(func), "c"(leaf));
return fn;
}
@@ -29,21 +29,21 @@ __attribute__((naked)) void DoZeroRegSyscallFault(CPUState State) {
__asm volatile(
R"(
// Load flags
push dword [esp + %[FlagsOffset]]
push dword ptr [esp + %[FlagsOffset]]
popfd
// Do getpid syscall.
// Overwrites some arguments.
// Syscall num
mov eax, qword [esp + %[RAXOffset]]
mov eax, dword ptr [esp + %[RAXOffset]]
// Load remaining registers that we can
mov ebx, qword [esp + %[RBXOffset]];
mov ecx, qword [esp + %[RCXOffset]];
mov edx, qword [esp + %[RDXOffset]]
mov esi, qword [esp + %[RSIOffset]]
mov edi, qword [esp + %[RDIOffset]];
mov ebp, qword [esp + %[RBPOffset]];
mov ebx, dword ptr [esp + %[RBXOffset]];
mov ecx, dword ptr [esp + %[RCXOffset]];
mov edx, dword ptr [esp + %[RDXOffset]]
mov esi, dword ptr [esp + %[RSIOffset]]
mov edi, dword ptr [esp + %[RDIOffset]];
mov ebp, dword ptr [esp + %[RBPOffset]];
// Can't load RSP
int 0x80;
@@ -54,12 +54,11 @@ __attribute__((naked)) void DoZeroRegSyscallFault(CPUState State) {
// We long jump from the signal handler, so this won't continue.
)"
:
// integers are offset by 8 for some reason.
// But the stack is also offset by 4-bytes due to the call.
: [RAXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EAX]) - 4), [RDXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EDX]) - 4),
[RSIOffset] "i"(offsetof(CPUState, Registers[TEST_REG_ESI]) - 4), [RDIOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EDI]) - 4),
[RBXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EBX]) - 4), [RCXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_ECX]) - 4),
[RBPOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EBP]) - 4), [FlagsOffset] "i"(offsetof(CPUState, eflags) - 4)
// The stack is offset by 4-bytes due to the call.
: [RAXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EAX]) + 4), [RDXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EDX]) + 4),
[RSIOffset] "i"(offsetof(CPUState, Registers[TEST_REG_ESI]) + 4), [RDIOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EDI]) + 4),
[RBXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EBX]) + 4), [RCXOffset] "i"(offsetof(CPUState, Registers[TEST_REG_ECX]) + 4),
[RBPOffset] "i"(offsetof(CPUState, Registers[TEST_REG_EBP]) + 4), [FlagsOffset] "i"(offsetof(CPUState, eflags) + 4)
: "memory");
}
@@ -30,32 +30,32 @@ __attribute__((naked)) void DoZeroRegSyscallFault(CPUState* State) {
push r15
// Load flags
push qword [rdi + %[FlagsOffset]]
push qword ptr [rdi + %[FlagsOffset]]
popfq
// Do getpid syscall.
// Overwrites some arguments.
// Syscall num
mov rax, qword [rdi + %[RAXOffset]]
mov rax, qword ptr [rdi + %[RAXOffset]]
// Load remaining registers that we can
mov rbx, qword [rdi + %[RBXOffset]];
mov rcx, qword [rdi + %[RCXOffset]];
mov rdx, qword [rdi + %[RDXOffset]]
mov rsi, qword [rdi + %[RSIOffset]]
mov rbp, qword [rdi + %[RBPOffset]];
mov rbx, qword ptr [rdi + %[RBXOffset]];
mov rcx, qword ptr [rdi + %[RCXOffset]];
mov rdx, qword ptr [rdi + %[RDXOffset]]
mov rsi, qword ptr [rdi + %[RSIOffset]]
mov rbp, qword ptr [rdi + %[RBPOffset]];
// Can't load RSP
mov r8, qword [rdi + %[R8Offset]]
mov r9, qword [rdi + %[R9Offset]];
mov r10, qword [rdi + %[R10Offset]]
mov r11, qword [rdi + %[R11Offset]];
mov r12, qword [rdi + %[R12Offset]];
mov r13, qword [rdi + %[R13Offset]];
mov r14, qword [rdi + %[R14Offset]];
mov r15, qword [rdi + %[R15Offset]];
mov r8, qword ptr [rdi + %[R8Offset]]
mov r9, qword ptr [rdi + %[R9Offset]];
mov r10, qword ptr [rdi + %[R10Offset]]
mov r11, qword ptr [rdi + %[R11Offset]];
mov r12, qword ptr [rdi + %[R12Offset]];
mov r13, qword ptr [rdi + %[R13Offset]];
mov r14, qword ptr [rdi + %[R14Offset]];
mov r15, qword ptr [rdi + %[R15Offset]];
// Overwrite RDI last.
mov rdi, qword [rdi + %[RDIOffset]];
mov rdi, qword ptr [rdi + %[RDIOffset]];
syscall;
@@ -66,15 +66,14 @@ __attribute__((naked)) void DoZeroRegSyscallFault(CPUState* State) {
// We long jump from the signal handler, so this won't continue.
)"
:
// integers are offset by 8 for some reason.
: [RAXOffset] "i"(offsetof(CPUState, Registers[REG_RAX]) - 8), [RDXOffset] "i"(offsetof(CPUState, Registers[REG_RDX]) - 8),
[R10Offset] "i"(offsetof(CPUState, Registers[REG_R10]) - 8), [R8Offset] "i"(offsetof(CPUState, Registers[REG_R8]) - 8),
[RSIOffset] "i"(offsetof(CPUState, Registers[REG_RSI]) - 8), [RDIOffset] "i"(offsetof(CPUState, Registers[REG_RDI]) - 8),
[RBXOffset] "i"(offsetof(CPUState, Registers[REG_RBX]) - 8), [RCXOffset] "i"(offsetof(CPUState, Registers[REG_RCX]) - 8),
[RBPOffset] "i"(offsetof(CPUState, Registers[REG_RBP]) - 8), [R9Offset] "i"(offsetof(CPUState, Registers[REG_R9]) - 8),
[R11Offset] "i"(offsetof(CPUState, Registers[REG_R11]) - 8), [R12Offset] "i"(offsetof(CPUState, Registers[REG_R12]) - 8),
[R13Offset] "i"(offsetof(CPUState, Registers[REG_R13]) - 8), [R14Offset] "i"(offsetof(CPUState, Registers[REG_R14]) - 8),
[R15Offset] "i"(offsetof(CPUState, Registers[REG_R15]) - 8), [FlagsOffset] "i"(offsetof(CPUState, eflags) - 8)
: [RAXOffset] "i"(offsetof(CPUState, Registers[REG_RAX])), [RDXOffset] "i"(offsetof(CPUState, Registers[REG_RDX])),
[R10Offset] "i"(offsetof(CPUState, Registers[REG_R10])), [R8Offset] "i"(offsetof(CPUState, Registers[REG_R8])),
[RSIOffset] "i"(offsetof(CPUState, Registers[REG_RSI])), [RDIOffset] "i"(offsetof(CPUState, Registers[REG_RDI])),
[RBXOffset] "i"(offsetof(CPUState, Registers[REG_RBX])), [RCXOffset] "i"(offsetof(CPUState, Registers[REG_RCX])),
[RBPOffset] "i"(offsetof(CPUState, Registers[REG_RBP])), [R9Offset] "i"(offsetof(CPUState, Registers[REG_R9])),
[R11Offset] "i"(offsetof(CPUState, Registers[REG_R11])), [R12Offset] "i"(offsetof(CPUState, Registers[REG_R12])),
[R13Offset] "i"(offsetof(CPUState, Registers[REG_R13])), [R14Offset] "i"(offsetof(CPUState, Registers[REG_R14])),
[R15Offset] "i"(offsetof(CPUState, Registers[REG_R15])), [FlagsOffset] "i"(offsetof(CPUState, eflags))
: "memory");
}
@@ -73,14 +73,14 @@ TEST(13, "mov dr0, rax", "mov dr0, rax", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(14, "rdpmc", "rdpmc", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(15, "sti", "sti", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(16, "swapgs", "swapgs", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(17, "sysret", "sysretd", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(17, "sysret", "sysret", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
TEST(18, "wrmsr", "wrmsr", X86_TRAPNO_GP, 0, 0x80, SIGSEGV);
// Instructions not implemented
TEST(19, "monitor", "monitor", X86_TRAPNO_UD, 0, 2, SIGILL);
TEST(20, "mwait", "mwait", X86_TRAPNO_UD, 0, 2, SIGILL);
TEST(21, "sysenter", "sysenter", X86_TRAPNO_UD, 0, 2, SIGILL);
TEST(22, "sysexit", "sysexitd", X86_TRAPNO_UD, 0, 2, SIGILL);
TEST(22, "sysexit", "sysexit", X86_TRAPNO_UD, 0, 2, SIGILL);
// Differs between dr8 and dr0-7 variants.
// dr0-7: SIGSEGV
@@ -42,13 +42,13 @@ __attribute__((naked, nocf_check)) static void TestFromSignal(const DataStruct*
ffreep st(0);
// Now load **7** values. Keeping the last one zero and our stack top not wrapped around.
fldt [rdi + (0 * 16)];
fldt [rdi + (1 * 16)];
fldt [rdi + (2 * 16)];
fldt [rdi + (3 * 16)];
fldt [rdi + (4 * 16)];
fldt [rdi + (5 * 16)];
fldt [rdi + (6 * 16)];
fld tbyte ptr [rdi + (0 * 16)];
fld tbyte ptr [rdi + (1 * 16)];
fld tbyte ptr [rdi + (2 * 16)];
fld tbyte ptr [rdi + (3 * 16)];
fld tbyte ptr [rdi + (4 * 16)];
fld tbyte ptr [rdi + (5 * 16)];
fld tbyte ptr [rdi + (6 * 16)];
hlt;
RetInstruction:
@@ -86,24 +86,27 @@ __attribute__((naked, nocf_check)) static void TestSetInSignal(DataStruct* data)
// Store values until the status word says nothing is left.
mov eax, 0;
.1:
2:
fstsw ax;
and eax, (7 << 11);
jz .2;
fstpt [rdi];
jz 3f;
fstp tbyte ptr [rdi];
add rdi, 16;
jmp .1;
.2:
jmp 2b
3:
// Now load **7** values. Keeping the last one zero and our stack top not wrapped around.
fldt [rdi + (0 * 16)];
fldt [rdi + (1 * 16)];
fldt [rdi + (2 * 16)];
fldt [rdi + (3 * 16)];
fldt [rdi + (4 * 16)];
fldt [rdi + (5 * 16)];
fldt [rdi + (6 * 16)];
fld tbyte ptr [rdi + (0 * 16)];
fld tbyte ptr [rdi + (1 * 16)];
fld tbyte ptr [rdi + (2 * 16)];
fld tbyte ptr [rdi + (3 * 16)];
fld tbyte ptr [rdi + (4 * 16)];
fld tbyte ptr [rdi + (5 * 16)];
fld tbyte ptr [rdi + (6 * 16)];
ret;
)" ::