Remove use of raising cpu exceptions for trigger_ud

This commit is contained in:
Fabian 2018-07-30 17:12:56 -05:00
parent 77525ef4ac
commit 70ae4b720a
8 changed files with 138 additions and 146 deletions

View file

@ -199,7 +199,8 @@ function gen_instruction_body_after_prefix(encodings, size)
default_case: {
body: [].concat(
gen_call(`::codegen::gen_fn0_const`, ["ctx", '"trigger_ud"'])
gen_call(`::codegen::gen_fn0_const`, ["ctx", '"trigger_ud"']),
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
),
}
},
@ -245,6 +246,20 @@ function gen_instruction_body_after_fixed_g(encoding, size)
const reg_postfix = encoding.nonfaulting ? [APPEND_NONFAULTING_FLAG] : [];
const mem_postfix = encoding.memory_nonfaulting ? [APPEND_NONFAULTING_FLAG] : [];
if(encoding.mem_ud)
{
mem_postfix.push(
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
);
}
if(encoding.reg_ud)
{
reg_postfix.push(
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
);
}
if(encoding.ignore_mod)
{
console.assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)");

View file

@ -72,7 +72,7 @@ const encodings = [
{ opcode: 0x60, os: 1, },
{ opcode: 0x61, os: 1, },
{ opcode: 0x62, e: 1, skip: 1, },
{ opcode: 0x63, e: 1, },
{ opcode: 0x63, e: 1, block_boundary: 1, }, // arpl
{ opcode: 0x64, prefix: 1, },
{ opcode: 0x65, prefix: 1, },
{ opcode: 0x66, prefix: 1, },
@ -106,8 +106,8 @@ const encodings = [
{ opcode: 0x8A, nonfaulting: 1, e: 1, },
{ opcode: 0x8B, custom: 1, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0x8C, os: 1, e: 1, skip: 1, },
{ opcode: 0x8D, memory_nonfaulting: 1, os: 1, e: 1, only_mem: 1, requires_prefix_call: 1, custom: 1, }, // lea
{ opcode: 0x8C, block_boundary: 1, os: 1, e: 1, skip: 1, }, // mov reg, sreg: block_boundary as it can trigger #ud
{ opcode: 0x8D, reg_ud: 1, memory_nonfaulting: 1, os: 1, e: 1, requires_prefix_call: 1, custom: 1, }, // lea
{ opcode: 0x8E, block_boundary: 1, e: 1, skip: 1, }, // mov sreg
{ opcode: 0x8F, os: 1, e: 1, fixed_g: 0, requires_prefix_call: 1, custom: 1, }, // pop r/m
@ -281,29 +281,29 @@ const encodings = [
{ opcode: 0x0F01, fixed_g: 6, e: 1, skip: 1, block_boundary: 1, },
{ opcode: 0x0F01, fixed_g: 7, e: 1, skip: 1, block_boundary: 1, },
{ opcode: 0x0F02, os: 1, e: 1, skip: 1 },
{ opcode: 0x0F03, os: 1, e: 1, skip: 1 },
{ opcode: 0x0F04, skip: 1 },
{ opcode: 0x0F05, skip: 1 },
{ opcode: 0x0F02, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lar
{ opcode: 0x0F03, os: 1, e: 1, skip: 1, block_boundary: 1, }, // lsl
{ opcode: 0x0F04, skip: 1, block_boundary: 1, },
{ opcode: 0x0F05, skip: 1, block_boundary: 1, },
{ opcode: 0x0F06, skip: 1, block_boundary: 1, }, // clts
{ opcode: 0x0F07, skip: 1 },
{ opcode: 0x0F08, skip: 1 },
{ opcode: 0x0F07, skip: 1, block_boundary: 1, },
{ opcode: 0x0F08, skip: 1, block_boundary: 1, },
{ opcode: 0x0F09, skip: 1, block_boundary: 1, }, // wbinvd
{ opcode: 0x0F0A, skip: 1 },
{ opcode: 0x0F0A, skip: 1, block_boundary: 1, },
// ud2
// Technically has a next instruction, but Linux uses this for assertions
// and embeds the assertion message after this instruction, which is likely
// the most common use case of ud2
{ opcode: 0x0F0B, skip: 1, block_boundary: 1, no_next_instruction: 1, },
{ opcode: 0x0F0C, skip: 1 },
{ opcode: 0x0F0D, skip: 1 },
{ opcode: 0x0F0E, skip: 1 },
{ opcode: 0x0F0F, skip: 1 },
{ opcode: 0x0F0C, skip: 1, block_boundary: 1, },
{ opcode: 0x0F0D, skip: 1, block_boundary: 1, },
{ opcode: 0x0F0E, skip: 1, block_boundary: 1, },
{ opcode: 0x0F0F, skip: 1, block_boundary: 1, },
{ opcode: 0x0F18, only_mem: 1, e: 1, },
{ opcode: 0x0F18, e: 1, },
{ opcode: 0x0F19, non_faulting: 1, custom: 1, e: 1, },
{ opcode: 0x0F1A, skip: 1, },
{ opcode: 0x0F1B, skip: 1, },
{ opcode: 0x0F1A, skip: 1, block_boundary: 1, },
{ opcode: 0x0F1B, skip: 1, block_boundary: 1, },
{ opcode: 0x0F1C, non_faulting: 1, custom: 1, e: 1, },
{ opcode: 0x0F1D, non_faulting: 1, custom: 1, e: 1, },
{ opcode: 0x0F1E, non_faulting: 1, custom: 1, e: 1, },
@ -313,18 +313,18 @@ const encodings = [
{ opcode: 0x0F21, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov reg, dreg
{ opcode: 0x0F22, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov creg, reg
{ opcode: 0x0F23, ignore_mod: 1, e: 1, skip: 1, block_boundary: 1, }, // mov dreg, reg
{ opcode: 0x0F24, skip: 1 },
{ opcode: 0x0F25, skip: 1 },
{ opcode: 0x0F26, skip: 1 },
{ opcode: 0x0F27, skip: 1 },
{ opcode: 0x0F24, skip: 1, block_boundary: 1, },
{ opcode: 0x0F25, skip: 1, block_boundary: 1, },
{ opcode: 0x0F26, skip: 1, block_boundary: 1, },
{ opcode: 0x0F27, skip: 1, block_boundary: 1, },
{ opcode: 0x0F30, skip: 1, block_boundary: 1, }, // wrmsr
{ opcode: 0x0F31, skip: 1, block_boundary: 1, }, // rdtsc
{ opcode: 0x0F32, skip: 1, block_boundary: 1, }, // rdmsr
{ opcode: 0x0F33, skip: 1 },
{ opcode: 0x0F33, skip: 1, }, // rdpmc
{ opcode: 0x0F34, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysenter
{ opcode: 0x0F35, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysexit
{ opcode: 0x0F36, skip: 1 },
{ opcode: 0x0F36, skip: 1, block_boundary: 1, },
{ opcode: 0x0F37, skip: 1 },
{ opcode: 0x0F38, skip: 1 },
{ opcode: 0x0F39, skip: 1 },
@ -412,27 +412,27 @@ const encodings = [
{ opcode: 0x0FAC, nonfaulting: 1, os: 1, e: 1, imm8: 1, mask_flags: af | of, },
{ opcode: 0x0FAD, nonfaulting: 1, os: 1, e: 1, mask_flags: af | of, },
{ opcode: 0x0FA6, skip: 1 },
{ opcode: 0x0FA7, skip: 1 },
{ opcode: 0x0FA6, skip: 1, block_boundary: 1, }, // ud
{ opcode: 0x0FA7, skip: 1, block_boundary: 1, }, // ud
{ opcode: 0x0FAA, skip: 1 },
{ opcode: 0x0FAE, e: 1, fixed_g: 0, only_mem: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxsave
{ opcode: 0x0FAE, e: 1, fixed_g: 1, only_mem: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxrstor: block_boundary since it uses non-raising cpu exceptions
{ opcode: 0x0FAE, e: 1, fixed_g: 2, only_mem: 1, sse: 1, skip: 1, block_boundary: 1, }, // ldmxcsr
{ opcode: 0x0FAE, e: 1, fixed_g: 3, only_mem: 1, sse: 1, skip: 1, block_boundary: 1, }, // stmxcsr
{ opcode: 0x0FAE, e: 1, fixed_g: 4, only_mem: 1, skip: 1, },
{ opcode: 0x0FAE, e: 1, fixed_g: 0, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxsave
{ opcode: 0x0FAE, e: 1, fixed_g: 1, reg_ud: 1, task_switch_test: 1, skip: 1, block_boundary: 1, }, // fxrstor
{ opcode: 0x0FAE, e: 1, fixed_g: 2, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // ldmxcsr
{ opcode: 0x0FAE, e: 1, fixed_g: 3, reg_ud: 1, sse: 1, skip: 1, block_boundary: 1, }, // stmxcsr
{ opcode: 0x0FAE, e: 1, fixed_g: 5, only_reg: 1, skip: 1, }, // lfence (reg, only 0), xrstor (mem)
{ opcode: 0x0FAE, e: 1, fixed_g: 6, only_reg: 1, skip: 1, }, // mfence (reg, only 0)
{ opcode: 0x0FAE, e: 1, fixed_g: 7, only_reg: 1, skip: 1, }, // sfence (reg, only 0), clflush (mem)
{ opcode: 0x0FAE, e: 1, fixed_g: 4, reg_ud: 1, skip: 1, block_boundary: 1, }, // xsave (mem, not implemented)
{ opcode: 0x0FAE, e: 1, fixed_g: 5, skip: 1, block_boundary: 1, }, // lfence (reg, only 0), xrstor (mem, not implemented)
{ opcode: 0x0FAE, e: 1, fixed_g: 6, skip: 1, block_boundary: 1, }, // mfence (reg, only 0), xsaveopt (mem, not implemented)
{ opcode: 0x0FAE, e: 1, fixed_g: 7, skip: 1, block_boundary: 1, }, // sfence (reg, only 0), clflush (mem)
{ opcode: 0x0FAF, nonfaulting: 1, os: 1, e: 1, mask_flags: af | zf }, // imul
{ opcode: 0x0FB0, nonfaulting: 1, e: 1 }, // cmxchg
{ opcode: 0x0FB1, nonfaulting: 1, os: 1, e: 1 },
{ opcode: 0x0FC7, e: 1, fixed_g: 1, only_mem: 1, }, // cmpxchg8b (memory)
{ opcode: 0x0FC7, e: 1, fixed_g: 6, only_reg: 1, skip: 1, }, // rdrand
{ opcode: 0x0FC7, e: 1, fixed_g: 1, reg_ud: 1, }, // cmpxchg8b (memory)
{ opcode: 0x0FC7, e: 1, fixed_g: 6, mem_ud: 1, skip: 1, }, // rdrand
{ opcode: 0x0FB2, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lss
{ opcode: 0x0FB4, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lfs
@ -442,9 +442,9 @@ const encodings = [
{ opcode: 0x0FB7, nonfaulting: 1, os: 1, e: 1, },
{ opcode: 0xF30FB8, os: 1, e: 1 }, // popcnt
{ opcode: 0x0FB8, os: 1, e: 1, }, // ud
{ opcode: 0x0FB8, os: 1, e: 1, block_boundary: 1, }, // ud
{ opcode: 0x0FB9, }, // ud2
{ opcode: 0x0FB9, block_boundary: 1, }, // ud2
{ opcode: 0x0FBE, nonfaulting: 1, os: 1, e: 1, }, // movsx
{ opcode: 0x0FBF, nonfaulting: 1, os: 1, e: 1, },
@ -475,20 +475,20 @@ const encodings = [
{ sse: 1, opcode: 0x660F11, e: 1 },
{ sse: 1, opcode: 0xF20F11, e: 1 },
{ sse: 1, opcode: 0x0F12, e: 1 },
{ sse: 1, opcode: 0x660F12, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0xF20F12, e: 1, skip: 1, }, // sse3
{ sse: 1, opcode: 0xF30F12, e: 1, skip: 1, }, // sse3
{ sse: 1, opcode: 0x0F13, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F13, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0x0F14, e: 1 },
{ sse: 1, opcode: 0x660F14, e: 1 },
{ sse: 1, opcode: 0x0F15, e: 1 },
{ sse: 1, opcode: 0x660F15, e: 1 },
{ sse: 1, opcode: 0x0F16, e: 1 },
{ sse: 1, opcode: 0x660F16, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0xF30F16, skip: 1, }, // sse3
{ sse: 1, opcode: 0x0F17, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F17, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0x0F28, e: 1 },
{ sse: 1, opcode: 0x660F28, e: 1 },
@ -498,8 +498,8 @@ const encodings = [
{ sse: 1, opcode: 0x660F2A, e: 1, },
{ sse: 1, opcode: 0xF20F2A, e: 1, },
{ sse: 1, opcode: 0xF30F2A, e: 1, },
{ sse: 1, opcode: 0x0F2B, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x660F2B, only_mem: 1, e: 1 },
{ sse: 1, opcode: 0x0F2B, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0x660F2B, reg_ud: 1, e: 1 },
{ sse: 1, opcode: 0xF20F2C, e: 1, },
{ sse: 1, opcode: 0x0F2C, e: 1, skip: 1, },
@ -509,8 +509,8 @@ const encodings = [
{ sse: 1, opcode: 0x0F2E, skip: 1 },
{ sse: 1, opcode: 0x0F2F, skip: 1 },
{ sse: 1, opcode: 0x0F50, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0x660F50, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0x0F50, mem_ud: 1, e: 1 },
{ sse: 1, opcode: 0x660F50, mem_ud: 1, e: 1 },
{ sse: 1, opcode: 0x0F51, skip: 1 },
{ sse: 1, opcode: 0x0F52, skip: 1 },
@ -574,9 +574,9 @@ const encodings = [
{ sse: 1, opcode: 0x660F6B, e: 1 },
{ sse: 1, opcode: 0x0F6B, e: 1 },
{ sse: 1, opcode: 0x660F6C, e: 1 },
{ sse: 1, opcode: 0x0F6C, e: 1, }, // ud
{ sse: 1, opcode: 0x0F6C, e: 1, block_boundary: 1, }, // ud
{ sse: 1, opcode: 0x660F6D, e: 1 },
{ sse: 1, opcode: 0x0F6D, e: 1, }, // ud
{ sse: 1, opcode: 0x0F6D, e: 1, block_boundary: 1, }, // ud
{ sse: 1, opcode: 0x660F6E, e: 1 },
{ sse: 1, opcode: 0x0F6E, e: 1 },
{ sse: 1, opcode: 0xF30F6F, e: 1 },
@ -588,26 +588,26 @@ const encodings = [
{ sse: 1, opcode: 0xF20F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0xF30F70, e: 1, imm8: 1, },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F71, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 4, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F72, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, only_reg: 1 },
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 2, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 3, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 6, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x660F73, e: 1, fixed_g: 7, imm8: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x0F74, e: 1, },
{ sse: 1, opcode: 0x660F74, e: 1, },
@ -638,12 +638,12 @@ const encodings = [
{ sse: 1, opcode: 0xF20FC2, e: 1, imm8: 1 },
{ sse: 1, opcode: 0xF30FC2, e: 1, imm8: 1 },
{ opcode: 0x0FC3, e: 1, only_mem: 1, }, // movnti: Uses normal registers, hence not marked as sse
{ opcode: 0x0FC3, e: 1, reg_ud: 1, }, // movnti: Uses normal registers, hence not marked as sse
{ sse: 1, opcode: 0x0FC4, e: 1, imm8: 1 },
{ sse: 1, opcode: 0x660FC4, e: 1, imm8: 1 },
{ sse: 1, opcode: 0x0FC5, e: 1, only_reg: 1, imm8: 1 },
{ sse: 1, opcode: 0x660FC5, e: 1, only_reg: 1, imm8: 1, },
{ sse: 1, opcode: 0x0FC5, e: 1, mem_ud: 1, imm8: 1 },
{ sse: 1, opcode: 0x660FC5, e: 1, mem_ud: 1, imm8: 1, },
{ sse: 1, opcode: 0x0FC6, skip: 1, },
@ -661,11 +661,12 @@ const encodings = [
{ sse: 1, opcode: 0x660FD5, e: 1 },
{ sse: 1, opcode: 0x660FD6, e: 1 },
{ sse: 1, opcode: 0xF20FD6, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0xF30FD6, only_reg: 1, e: 1 },
{ sse: 1, opcode: 0x0FD6, e: 1, }, // ud
{ sse: 1, opcode: 0x0FD7, e: 1, only_reg: 1 },
{ sse: 1, opcode: 0x660FD7, e: 1, only_reg: 1, },
{ sse: 1, opcode: 0xF20FD6, mem_ud: 1, e: 1 },
{ sse: 1, opcode: 0xF30FD6, mem_ud: 1, e: 1 },
{ sse: 1, opcode: 0x0FD6, e: 1, block_boundary: 1, }, // ud
{ sse: 1, opcode: 0x0FD7, e: 1, mem_ud: 1 },
{ sse: 1, opcode: 0x660FD7, e: 1, mem_ud: 1, },
{ sse: 1, opcode: 0x0FD8, e: 1 },
{ sse: 1, opcode: 0x660FD8, e: 1 },
@ -700,9 +701,9 @@ const encodings = [
{ sse: 1, opcode: 0x660FE6, e: 1, skip: 1, },
{ sse: 1, opcode: 0xF20FE6, e: 1, skip: 1, },
{ sse: 1, opcode: 0xF30FE6, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0FE6, e: 1, }, // ud
{ sse: 1, opcode: 0x0FE7, e: 1, only_mem: 1 },
{ sse: 1, opcode: 0x660FE7, e: 1, only_mem: 1, },
{ sse: 1, opcode: 0x0FE6, e: 1, block_boundary: 1, }, // ud
{ sse: 1, opcode: 0x0FE7, e: 1, reg_ud: 1 },
{ sse: 1, opcode: 0x660FE7, e: 1, reg_ud: 1, },
{ sse: 1, opcode: 0x0FE8, e: 1 },
{ sse: 1, opcode: 0x660FE8, e: 1 },
@ -737,8 +738,8 @@ const encodings = [
{ sse: 1, opcode: 0x660FF6, e: 1 },
// maskmovq (0FF7), maskmovdqu (660FF7) tested manually
// Generated tests don't setup EDI as required (yet)
{ sse: 1, opcode: 0x0FF7, only_reg: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x660FF7, only_reg: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0FF7, mem_ud: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x660FF7, mem_ud: 1, e: 1, skip: 1, },
{ sse: 1, opcode: 0x0FF8, e: 1 },
{ sse: 1, opcode: 0x660FF8, e: 1 },
@ -755,7 +756,7 @@ const encodings = [
{ sse: 1, opcode: 0x0FFE, e: 1 },
{ sse: 1, opcode: 0x660FFE, e: 1 },
{ opcode: 0x0FFF, },
{ opcode: 0x0FFF, block_boundary: 1, }, // ud
];
for(let i = 0; i < 8; i++)

View file

@ -3486,6 +3486,7 @@ CPU.prototype.arpl = function(seg, r16)
if(!this.protected_mode[0] || this.vm86_mode())
{
this.trigger_ud();
return;
}
this.flags_changed[0] &= ~flag_zero;
@ -3513,6 +3514,7 @@ CPU.prototype.lar = function(selector, original)
{
dbg_log("lar #ud");
this.trigger_ud();
return;
}
/** @const */
@ -3550,6 +3552,7 @@ CPU.prototype.lsl = function(selector, original)
{
dbg_log("lsl #ud");
this.trigger_ud();
return;
}
/** @const */

View file

@ -828,15 +828,6 @@ void trigger_de()
__attribute__((noinline))
void trigger_ud()
{
dbg_log("#ud");
dbg_trace();
*instruction_pointer = *previous_ip;
raise_exception(CPU_EXCEPTION_UD);
}
__attribute__((noinline))
void trigger_ud_non_raising()
{
dbg_log("#ud");
dbg_trace();
@ -1513,7 +1504,7 @@ bool task_switch_test_mmx()
}
else if(*cr & CR0_EM)
{
trigger_ud_non_raising();
trigger_ud();
return false;
}

View file

@ -418,17 +418,20 @@ DEFINE_MODRM_INSTR_READ8(instr_8A, write_reg8(r, ___))
DEFINE_MODRM_INSTR_READ16(instr16_8B, write_reg16(r, ___))
DEFINE_MODRM_INSTR_READ32(instr32_8B, write_reg32(r, ___))
void instr_8C_check_sreg(int32_t sreg) {
bool instr_8C_check_sreg(int32_t sreg) {
if(sreg >= 6)
{
dbg_log("mov sreg #ud");
trigger_ud();
return false;
}
return true;
}
void instr16_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg16(r, sreg[seg]); }
void instr16_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write16(addr, sreg[seg]); }
void instr32_8C_reg(int32_t r, int32_t seg) { instr_8C_check_sreg(seg); write_reg32(r, sreg[seg]); }
void instr32_8C_mem(int32_t addr, int32_t seg) { instr_8C_check_sreg(seg); safe_write32(addr, sreg[seg]); }
void instr16_8C_reg(int32_t r, int32_t seg) { if(instr_8C_check_sreg(seg)) write_reg16(r, sreg[seg]); }
void instr16_8C_mem(int32_t addr, int32_t seg) { if(instr_8C_check_sreg(seg)) safe_write16(addr, sreg[seg]); }
void instr32_8C_reg(int32_t r, int32_t seg) { if(instr_8C_check_sreg(seg)) write_reg32(r, sreg[seg]); }
void instr32_8C_mem(int32_t addr, int32_t seg) { if(instr_8C_check_sreg(seg)) safe_write32(addr, sreg[seg]); }
void instr16_8D_reg(int32_t r, int32_t r2)
{

View file

@ -491,7 +491,7 @@ void instr16_8B_mem(int32_t addr, int32_t r);
void instr16_8B_reg(int32_t r1, int32_t r);
void instr32_8B_mem(int32_t addr, int32_t r);
void instr32_8B_reg(int32_t r1, int32_t r);
void instr_8C_check_sreg(int32_t sreg);
bool instr_8C_check_sreg(int32_t sreg);
void instr16_8C_reg(int32_t r, int32_t seg);
void instr16_8C_mem(int32_t addr, int32_t seg);
void instr32_8C_reg(int32_t r, int32_t seg);

View file

@ -24,58 +24,58 @@ bool apic_enabled = false;
void instr_0F00_0_mem(int32_t addr) {
// sldt
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
safe_write16(addr, sreg[LDTR]);
}
void instr_0F00_0_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
write_reg_osize(r, sreg[LDTR]);
}
void instr_0F00_1_mem(int32_t addr) {
// str
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
safe_write16(addr, sreg[TR]);
}
void instr_0F00_1_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
write_reg_osize(r, sreg[TR]);
}
void instr_0F00_2_mem(int32_t addr) {
// lldt
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
if(cpl[0]) { trigger_gp_non_raising(0); return; }
load_ldt(safe_read16(addr));
}
void instr_0F00_2_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
if(cpl[0]) { trigger_gp_non_raising(0); return; }
load_ldt(read_reg16(r));
}
void instr_0F00_3_mem(int32_t addr) {
// ltr
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
if(cpl[0]) { trigger_gp_non_raising(0); return; }
load_tr(safe_read16(addr));
}
void instr_0F00_3_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
if(cpl[0]) { trigger_gp_non_raising(0); return; }
load_tr(read_reg16(r));
}
void instr_0F00_4_mem(int32_t addr) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
verr(safe_read16(addr));
}
void instr_0F00_4_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
verr(read_reg16(r));
}
void instr_0F00_5_mem(int32_t addr) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
verw(safe_read16(addr));
}
void instr_0F00_5_reg(int32_t r) {
if(!protected_mode[0] || vm86_mode()) trigger_ud();
if(!protected_mode[0] || vm86_mode()) { trigger_ud(); return; }
verw(read_reg16(r));
}
@ -316,7 +316,7 @@ void instr_0F13_mem(int32_t addr, int32_t r) {
movl_r128_m64(addr, r);
}
void instr_0F13_reg(int32_t r1, int32_t r2) { unimplemented_sse(); }
void instr_0F13_reg(int32_t r1, int32_t r2) { trigger_ud(); }
void instr_660F13_reg(int32_t r1, int32_t r) { trigger_ud(); }
void instr_660F13_mem(int32_t addr, int32_t r) {
@ -414,7 +414,9 @@ void instr_660F17_mem(int32_t addr, int32_t r) {
}
void instr_660F17_reg(int32_t r1, int32_t r2) { trigger_ud(); }
void instr_0F18_reg(int32_t r1, int32_t r2) { trigger_ud(); }
void instr_0F18_reg(int32_t r1, int32_t r2) {
// reserved nop
}
void instr_0F18_mem(int32_t addr, int32_t r) {
// prefetch
// nop for us
@ -476,6 +478,7 @@ void instr_0F21(int32_t r, int32_t dreg_index) {
{
dbg_log("#ud mov dreg 4/5 with cr4.DE set");
trigger_ud();
return;
}
else
{
@ -565,6 +568,7 @@ void instr_0F23(int32_t r, int32_t dreg_index) {
{
dbg_log("#ud mov dreg 4/5 with cr4.DE set");
trigger_ud();
return;
}
else
{
@ -2176,7 +2180,7 @@ void instr_0FAE_1_reg(int32_t r) { trigger_ud(); }
void instr_0FAE_1_mem(int32_t addr) {
fxrstor(addr);
}
void instr_0FAE_2_reg(int32_t r) { trigger_ud(); }
void instr_0FAE_2_reg(int32_t r) { unimplemented_sse(); }
void instr_0FAE_2_mem(int32_t addr) {
// ldmxcsr
int32_t new_mxcsr = safe_read32s(addr);
@ -2212,8 +2216,8 @@ void instr_0FAE_6_reg(int32_t r) {
dbg_assert_message(r == 0, "Unexpected mfence encoding");
}
void instr_0FAE_6_mem(int32_t addr) {
dbg_assert_message(false, "0fae/5 #ud");
trigger_ud();
// xsaveopt
undefined_instruction();
}
void instr_0FAE_7_reg(int32_t r) {
// sfence
@ -2585,7 +2589,7 @@ void instr_0FC7_6_reg(int32_t r) {
flags_changed[0] = 0;
}
void instr_0FC7_6_mem(int32_t addr) {
undefined_instruction();
trigger_ud();
}
void instr_0FC8() { bswap(EAX); }

View file

@ -284,36 +284,11 @@ else {
process.exit(1);
}
if(exception === "DE" || exception === "GP")
{
// XXX: On gdb execution is stopped at this point. On v86 we
// currently don't have this ability, so we record the exception
// and continue execution
recorded_exceptions.push(exception);
return true;
}
clearTimeout(test_timeout);
waiting_to_receive_next_test = true;
emulator.stop();
if(current_test.fixture.exception !== exception)
{
process.send({
failures: [{
name: "Exception",
actual: exception,
expected: current_test.fixture.exception || "(none)",
}],
img_name: current_test.img_name,
});
}
else
{
process.send(DONE_MSG);
}
// XXX: On gdb execution is stopped at this point. On v86 we
// currently don't have this ability, so we record the exception
// and continue execution
console.log("recorded", exception);
recorded_exceptions.push(exception);
return true;
};