Skip to content
Open
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
53 changes: 53 additions & 0 deletions tests/unit/test_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -2732,7 +2732,60 @@ static void test_x86_lock_btc_reg(void)
OK(uc_close(uc));
}

// Regression: dense x87 memory ops in one TB exhaust TCG temps on 64-bit hosts
// when TCG_MAX_TEMPS is 512. Unicorn's check_exit_request after every qemu_ld/st
// plus live x87 temps overflow temps[] into the ops queue head and SIGSEGV in
// tcg_emit_op. See PR discussion / OpenSWE1R on Apple Silicon.
static void test_x86_tcg_temp_limit_x87_block(void)
{
uc_engine *uc;
/*
* Real-world dense x87 basic block (matrix math) extracted from a 32-bit
* Windows game binary that crashes Unicorn 2.1.4 on Apple Silicon hosts.
* Translation of this TB drives nb_temps past TCG_MAX_TEMPS==512; temps[]
* overflows into the ops queue head and tcg_emit_op SIGSEGVs.
*
* Prologue: sub esp, 0x40; mov ecx, [esp+0x44]; mov eax, [esp+0x48]; ...
*/
static const uint8_t code[] = {
0x83, 0xec, 0x40, 0x8b, 0x4c, 0x24, 0x44, 0x8b, 0x44, 0x24, 0x48, 0xd9, 0x41, 0x10, 0xd9, 0x41, 0x20, 0xd9, 0x41, 0x30, 0xd9, 0xc2, 0xd9, 0xc2, 0xd8, 0x48, 0x08, 0xd9, 0xc9, 0xd8, 0x48, 0x04, 0xd9, 0x01, 0xd9, 0xcb, 0xd9, 0x54, 0x24, 0x30, 0xd8, 0x48, 0x0c, 0xd9, 0x00, 0xd9, 0xcb, 0xde, 0xc2, 0xd9, 0xcb, 0xd9, 0x5c, 0x24, 0x00, 0x8b, 0x51, 0x14, 0xd9, 0xc9, 0xd8, 0x4c, 0x24, 0x00, 0xd9, 0xca, 0xde, 0xc1, 0xd9, 0x41, 0x34, 0xd9, 0xca, 0xde, 0xc1, 0x89, 0x54, 0x24, 0x14, 0x8b, 0x51, 0x24, 0xd9, 0x44, 0x24, 0x14, 0x89, 0x54, 0x24, 0x24, 0x8b, 0x51, 0x18, 0xd9, 0x44, 0x24, 0x24, 0xd9, 0xca, 0xd9, 0x19, 0x89, 0x54, 0x24, 0x18, 0x8b, 0x51, 0x28, 0xd8, 0x48, 0x04, 0xd9, 0x41, 0x04, 0xd9, 0xca, 0xd8, 0x48, 0x08, 0xd9, 0xcb, 0xd9, 0x54, 0x24, 0x34, 0xd8, 0x48, 0x0c, 0xd9, 0x00, 0xd9, 0xcc, 0xde, 0xc2, 0xd9, 0xca, 0xd9, 0x5c, 0x24, 0x04, 0xd9, 0xca, 0xd8, 0x4c, 0x24, 0x04, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0x41, 0x38, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x18, 0x89, 0x54, 0x24, 0x28, 0x8b, 0x51, 0x0c, 0xd9, 0x44, 0x24, 0x28, 0xd9, 0xcb, 0xd9, 0x59, 0x04, 0x89, 0x54, 0x24, 0x0c, 0x8b, 0x51, 0x1c, 0xd8, 0x48, 0x04, 0xd9, 0x41, 0x08, 0xd9, 0xcb, 0xd8, 0x48, 0x08, 0xd9, 0xca, 0xd9, 0x54, 0x24, 0x38, 0xd8, 0x48, 0x0c, 0xd9, 0x00, 0xd9, 0xcb, 0xde, 0xc2, 0xd9, 0xcb, 0xd9, 0x5c, 0x24, 0x08, 0xd9, 0xc9, 0xd8, 0x4c, 0x24, 0x08, 0xd9, 0xca, 0xde, 0xc1, 0xd9, 0xc9, 0xde, 0xc1, 0x89, 0x54, 0x24, 0x1c, 0x8b, 0x51, 0x2c, 0x89, 0x54, 0x24, 0x2c, 0x8b, 0x51, 0x3c, 0xd9, 0x59, 0x08, 0xd9, 0x44, 0x24, 0x2c, 0xd9, 0x44, 0x24, 0x1c, 0xd8, 0x48, 0x04, 0x89, 0x54, 0x24, 0x3c, 0xd9, 0x44, 0x24, 0x3c, 0xd9, 0xca, 0xd8, 0x48, 0x08, 0xd9, 0x00, 0xd9, 0xcb, 0xd8, 0x48, 0x0c, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xca, 0xd8, 0x4c, 0x24, 0x0c, 0xd9, 0xc4, 0xd9, 0xcb, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x30, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x00, 0xd9, 0xca, 0xd9, 0x59, 0x0c, 0xd9, 0xca, 0xd8, 0x48, 0x14, 0xd9, 0xc3, 0xd9, 0xcb, 0xd8, 0x48, 0x1c, 0xd9, 0x44, 0x24, 0x14, 0xd9, 0xcb, 0xd8, 0x48, 0x10, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xcb, 0xd8, 0x48, 0x18, 0xd9, 0x44, 0x24, 0x34, 0xd9, 0xcc, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x04, 0xd9, 0x44, 0x24, 0x24, 0xd9, 0xca, 0xde, 0xc3, 0xd9, 0x44, 0x24, 0x18, 0xd9, 0xcb, 0xd9, 0x59, 0x10, 0xd9, 0xcb, 0xd8, 0x48, 0x14, 0xd9, 0x44, 0x24, 0x38, 0xd9, 0xcd, 0xd8, 0x48, 0x1c, 0xde, 0xc1, 0xd9, 0xcb, 0xd8, 0x48, 0x10, 0xd9, 0x44, 0x24, 0x08, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0xc9, 0xd8, 0x48, 0x18, 0xd9, 0x44, 0x24, 0x28, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0x44, 0x24, 0x1c, 0xd9, 0xcc, 0xd9, 0x59, 0x14, 0xd9, 0xca, 0xd8, 0x48, 0x14, 0xd9, 0x44, 0x24, 0x3c, 0xd9, 0xcd, 0xd8, 0x48, 0x1c, 0xde, 0xc1, 0xd9, 0xc9, 0xd8, 0x48, 0x10, 0xd9, 0x44, 0x24, 0x0c, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xca, 0xd8, 0x48, 0x18, 0xd9, 0x44, 0x24, 0x2c, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xc9, 0xd9, 0x59, 0x18, 0xd9, 0xca, 0xd8, 0x48, 0x14, 0xd9, 0xc4, 0xd9, 0xcc, 0xd8, 0x48, 0x1c, 0xd9, 0xc6, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xca, 0xd8, 0x48, 0x10, 0xd9, 0x44, 0x24, 0x30, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xcb, 0xd8, 0x48, 0x18, 0xd9, 0x44, 0x24, 0x00, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x24, 0xd9, 0xca, 0xd9, 0x59, 0x1c, 0xd9, 0xcc, 0xd8, 0x48, 0x28, 0xd9, 0x44, 0x24, 0x14, 0xd9, 0xcb, 0xd8, 0x48, 0x24, 0xde, 0xc1, 0xd9, 0xcb, 0xd8, 0x48, 0x2c, 0xd9, 0x44, 0x24, 0x34, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0xcc, 0xd8, 0x48, 0x20, 0xd9, 0x44, 0x24, 0x04, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0xcb, 0xd9, 0x59, 0x20, 0xd8, 0x48, 0x28, 0xd9, 0xc9, 0xd8, 0x48, 0x24, 0xd9, 0xcb, 0xd8, 0x48, 0x2c, 0xd9, 0xcb, 0xde, 0xc1, 0xd9, 0xc9, 0xd8, 0x48, 0x20, 0xd9, 0xca, 0xde, 0xc1, 0xd9, 0xc9, 0xde, 0xc1, 0xd9, 0x59, 0x24, 0xd9, 0x44, 0x24, 0x18, 0xd9, 0x44, 0x24, 0x28, 0xd8, 0x48, 0x28, 0xd9, 0x44, 0x24, 0x38, 0xd9, 0xca, 0xd8, 0x48, 0x24, 0xd9, 0x44, 0x24, 0x08, 0xd9, 0xcb, 0xd8, 0x48, 0x2c, 0xd9, 0xc9, 0xde, 0xc2, 0xd9, 0xca, 0xd8, 0x48, 0x20, 0xd9, 0x44, 0x24, 0x2c, 0xd9, 0xcb, 0xde, 0xc2, 0xd9, 0x44, 0x24, 0x1c, 0xd9, 0x44, 0x24, 0x3c, 0xd9, 0xca, 0xde, 0xc3, 0xd9, 0x44, 0x24, 0x0c, 0xd9, 0xcb, 0xd9, 0x59, 0x28, 0xd9, 0xcb, 0xd8, 0x48, 0x28, 0xd9, 0xcb, 0xd8, 0x48, 0x24, 0xd9, 0xc9, 0xd8, 0x48, 0x2c, 0xd9, 0xc9, 0xde, 0xc3, 0xd9, 0xc9, 0xd8, 0x48, 0x20, 0xd9, 0x44, 0x24, 0x30, 0xd9, 0xca, 0xde, 0xc3, 0xd9, 0x44, 0x24, 0x00, 0xd9, 0xc9, 0xde, 0xc3, 0xd9, 0x44, 0x24, 0x14, 0xd9, 0xcb, 0xd9, 0x59, 0x2c, 0xd9, 0xcc, 0xd8, 0x48, 0x34, 0xd9, 0x44, 0x24, 0x34, 0xd9, 0xca, 0xd8, 0x48, 0x3c, 0xde, 0xc1, 0xd9, 0xcc, 0xd8, 0x48, 0x30, 0xd9, 0x44, 0x24, 0x04, 0xd9, 0xc9, 0xde, 0xc5, 0xd9, 0xcb, 0xd8, 0x48, 0x38, 0xd9, 0x44, 0x24, 0x24, 0xd9, 0xc9, 0xde, 0xc5, 0xd9, 0x44, 0x24, 0x18, 0xd9, 0xcd, 0xd9, 0x59, 0x30, 0xd9, 0xca, 0xd8, 0x48, 0x34, 0xd9, 0x44, 0x24, 0x38, 0xd9, 0xca, 0xd8, 0x48, 0x3c, 0xde, 0xc1, 0xd9, 0xcb, 0xd8, 0x48, 0x30, 0xd9, 0x44, 0x24, 0x08, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0xca, 0xd8, 0x48, 0x38, 0xd9, 0x44, 0x24, 0x28, 0xd9, 0xc9, 0xde, 0xc4, 0xd9, 0x44, 0x24, 0x1c, 0xd9, 0xcc, 0xd9, 0x59, 0x34, 0xd9, 0xcc, 0xd8, 0x48, 0x34, 0xd9, 0x44, 0x24, 0x3c, 0xd9, 0xca, 0xd8, 0x48, 0x3c, 0xde, 0xc1, 0xd9, 0xca, 0xd8, 0x48, 0x30, 0xd9, 0x44, 0x24, 0x0c, 0xd9, 0xc9, 0xde, 0xc3, 0xd9, 0xcc, 0xd8, 0x48, 0x38, 0xd9, 0x44, 0x24, 0x2c, 0xd9, 0xc9, 0xde, 0xc3, 0xd9, 0xca, 0xd9, 0x59, 0x38, 0xd9, 0xca, 0xd8, 0x48, 0x34, 0xd9, 0xca, 0xd8, 0x48, 0x3c, 0xd9, 0xcb, 0xd8, 0x48, 0x30, 0xd9, 0xcb, 0xde, 0xc2, 0xd8, 0x48, 0x38, 0xd9, 0xca, 0xde, 0xc1, 0xd9, 0xc9, 0xde, 0xc1, 0xd9, 0x59, 0x3c, 0x83, 0xc4, 0x40, 0xc3, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x51, 0x8b, 0x4c, 0x24, 0x0c, 0x8b, 0x51, 0x14, 0x8b, 0x41, 0x10, 0xd9, 0x41, 0x18, 0x89, 0x54, 0x24, 0x00, 0x89, 0x44, 0x24, 0x0c, 0xd9, 0x44, 0x24, 0x00, 0xd9, 0x44, 0x24, 0x0c, 0xd8, 0x4c, 0x24, 0x0c, 0xd9, 0xc9, 0xd8, 0x4c, 0x24, 0x00, 0xd9, 0xc2, 0xd8, 0xcb, 0xd9, 0xc9, 0xde, 0xc2, 0xc3
};

uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_32, (char *)code, sizeof(code));

/* Two float matrices for ecx/eax */
OK(uc_mem_map(uc, 0x10000, 0x1000, UC_PROT_ALL));
OK(uc_mem_map(uc, 0x11000, 0x1000, UC_PROT_ALL));
float mat[32];
for (int i = 0; i < 32; i++) {
mat[i] = 1.0f;
}
OK(uc_mem_write(uc, 0x10000, mat, sizeof(mat)));
OK(uc_mem_write(uc, 0x11000, mat, sizeof(mat)));

/* Stack: leave room for sub esp,0x40 then [esp+0x44]/[esp+0x48] args */
OK(uc_mem_map(uc, 0x80000, 0x2000, UC_PROT_ALL));
uint32_t esp = 0x81000;
uint32_t arg1 = 0x10000;
uint32_t arg2 = 0x11000;
/* Before prologue: [esp]=ret, [esp+4]=arg1, [esp+8]=arg2 */
uint32_t ret_addr = 0x9000;
OK(uc_mem_map(uc, 0x9000, 0x1000, UC_PROT_ALL));
uint8_t hlt = 0xF4;
OK(uc_mem_write(uc, 0x9000, &hlt, 1));
OK(uc_mem_write(uc, esp, &ret_addr, 4));
OK(uc_mem_write(uc, esp + 4, &arg1, 4));
OK(uc_mem_write(uc, esp + 8, &arg2, 4));
OK(uc_reg_write(uc, UC_X86_REG_ESP, &esp));

uc_err err = uc_emu_start(uc, code_start, 0x9001, 0, 0);
TEST_CHECK(err == UC_ERR_OK);

OK(uc_close(uc));
}

TEST_LIST = {
{"test_x86_tcg_temp_limit_x87_block", test_x86_tcg_temp_limit_x87_block},
{"test_x86_in", test_x86_in},
{"test_x86_out", test_x86_out},
{"test_x86_mem_hook_all", test_x86_mem_hook_all},
Expand Down
Loading