diff --git a/Base/etc/shellrc b/Base/etc/shellrc index 32e155e799..eedd1460c4 100644 --- a/Base/etc/shellrc +++ b/Base/etc/shellrc @@ -27,5 +27,6 @@ alias pv=Profiler alias ws=WebServer alias sl=Solitaire alias wv=WebView +alias ue=UserspaceEmulator alias ll='ls -l' diff --git a/DevTools/CMakeLists.txt b/DevTools/CMakeLists.txt index 2337588171..fabef4ec85 100644 --- a/DevTools/CMakeLists.txt +++ b/DevTools/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(HackStudio) add_subdirectory(Inspector) add_subdirectory(Profiler) +add_subdirectory(UserspaceEmulator) add_subdirectory(VisualBuilder) diff --git a/DevTools/UserspaceEmulator/CMakeLists.txt b/DevTools/UserspaceEmulator/CMakeLists.txt new file mode 100644 index 0000000000..16cf8b1ab1 --- /dev/null +++ b/DevTools/UserspaceEmulator/CMakeLists.txt @@ -0,0 +1,8 @@ +set(SOURCES + SoftCPU.cpp + Emulator.cpp + main.cpp +) + +serenity_bin(UserspaceEmulator) +target_link_libraries(UserspaceEmulator LibX86 LibCore) diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp new file mode 100644 index 0000000000..1d6f7e0e35 --- /dev/null +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Emulator.h" +#include "SoftCPU.h" +#include +#include +#include +#include + +namespace UserspaceEmulator { + +Emulator::Emulator() + : m_cpu(*this) +{ +} + +int Emulator::exec(X86::SimpleInstructionStream& stream, u32 base) +{ + size_t offset = 0; + while (!m_shutdown) { + auto insn = X86::Instruction::from_stream(stream, true, true); + out() << "instruction: " << insn.to_string(base + offset); + + (m_cpu.*insn.handler())(insn); + m_cpu.dump(); + + offset += insn.length(); + + if (insn.mnemonic() == "RET") + break; + } + return m_exit_status; +} + +u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) +{ + (void) arg2; + (void) arg3; + + printf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function); + switch (function) { + case SC_getuid: + return virt$getuid(); + case SC_exit: + virt$exit((int)arg1); + return 0; + default: + warn() << "Unimplemented syscall!"; + TODO(); + } +} + +uid_t Emulator::virt$getuid() +{ + return getuid(); +} + +void Emulator::virt$exit(int status) +{ + out() << "exit(" << status << "), shutting down!"; + m_exit_status = status; + m_shutdown = true; +} + +} diff --git a/DevTools/UserspaceEmulator/Emulator.h b/DevTools/UserspaceEmulator/Emulator.h new file mode 100644 index 0000000000..9e2386c35c --- /dev/null +++ b/DevTools/UserspaceEmulator/Emulator.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "SoftCPU.h" +#include +#include +#include + +namespace UserspaceEmulator { + +class Emulator { +public: + Emulator(); + + int exec(X86::SimpleInstructionStream&, u32 base); + u32 virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3); + +private: + SoftCPU m_cpu; + + uid_t virt$getuid(); + void virt$exit(int); + + bool m_shutdown { false }; + int m_exit_status { 0 }; +}; + +} diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp new file mode 100644 index 0000000000..717ab37430 --- /dev/null +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "SoftCPU.h" +#include "Emulator.h" +#include +#include + +namespace UserspaceEmulator { + +SoftCPU::SoftCPU(Emulator& emulator) + : m_emulator(emulator) +{ + m_reg32_table[X86::RegisterEAX] = &m_eax; + m_reg32_table[X86::RegisterEBX] = &m_ebx; + m_reg32_table[X86::RegisterECX] = &m_ecx; + m_reg32_table[X86::RegisterEDX] = &m_edx; + m_reg32_table[X86::RegisterEBP] = &m_ebp; + m_reg32_table[X86::RegisterESP] = &m_esp; + m_reg32_table[X86::RegisterESI] = &m_esi; + m_reg32_table[X86::RegisterEDI] = &m_edi; +} + +void SoftCPU::dump() const +{ + printf("eax: %08x ebx: %08x ecx: %08x edx: %08x\n", m_eax, m_ebx, m_ecx, m_edx); + printf("ebp: %08x esp: %08x esi: %08x edi: %08x\n", m_ebp, m_esp, m_esi, m_edi); +} + +void SoftCPU::AAA(const X86::Instruction&) { TODO(); } +void SoftCPU::AAD(const X86::Instruction&) { TODO(); } +void SoftCPU::AAM(const X86::Instruction&) { TODO(); } +void SoftCPU::AAS(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADC_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::ADD_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::AND_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::ARPL(const X86::Instruction&) { TODO(); } +void SoftCPU::BOUND(const X86::Instruction&) { TODO(); } +void SoftCPU::BSF_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::BSF_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::BSR_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::BSR_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::BSWAP_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::BTC_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTC_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::BTC_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTC_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::BTR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTR_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::BTR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTR_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::BTS_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTS_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::BTS_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BTS_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::BT_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BT_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::BT_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::BT_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_FAR_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_FAR_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_imm16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_imm16_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::CALL_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::CBW(const X86::Instruction&) { TODO(); } +void SoftCPU::CDQ(const X86::Instruction&) { TODO(); } +void SoftCPU::CLC(const X86::Instruction&) { TODO(); } +void SoftCPU::CLD(const X86::Instruction&) { TODO(); } +void SoftCPU::CLI(const X86::Instruction&) { TODO(); } +void SoftCPU::CLTS(const X86::Instruction&) { TODO(); } +void SoftCPU::CMC(const X86::Instruction&) { TODO(); } +void SoftCPU::CMOVcc_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMOVcc_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPSB(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPSD(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPSW(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPXCHG_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPXCHG_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMPXCHG_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::CMP_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::CPUID(const X86::Instruction&) { TODO(); } +void SoftCPU::CWD(const X86::Instruction&) { TODO(); } +void SoftCPU::CWDE(const X86::Instruction&) { TODO(); } +void SoftCPU::DAA(const X86::Instruction&) { TODO(); } +void SoftCPU::DAS(const X86::Instruction&) { TODO(); } +void SoftCPU::DEC_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::DEC_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::DEC_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::DEC_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::DEC_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::DIV_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::DIV_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::DIV_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::ENTER16(const X86::Instruction&) { TODO(); } +void SoftCPU::ENTER32(const X86::Instruction&) { TODO(); } +void SoftCPU::ESCAPE(const X86::Instruction&) { TODO(); } +void SoftCPU::HLT(const X86::Instruction&) { TODO(); } +void SoftCPU::IDIV_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::IDIV_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::IDIV_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg16_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg16_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg32_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::IMUL_reg32_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::INC_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::INC_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::INC_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::INC_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::INC_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::INSB(const X86::Instruction&) { TODO(); } +void SoftCPU::INSD(const X86::Instruction&) { TODO(); } +void SoftCPU::INSW(const X86::Instruction&) { TODO(); } +void SoftCPU::INT3(const X86::Instruction&) { TODO(); } +void SoftCPU::INTO(const X86::Instruction&) { TODO(); } + +void SoftCPU::INT_imm8(const X86::Instruction& insn) +{ + ASSERT(insn.imm8() == 0x82); + m_eax = m_emulator.virt_syscall(m_eax, m_edx, m_ecx, m_ebx); +} + +void SoftCPU::INVLPG(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_AL_DX(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_AX_DX(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_AX_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_EAX_DX(const X86::Instruction&) { TODO(); } +void SoftCPU::IN_EAX_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::IRET(const X86::Instruction&) { TODO(); } +void SoftCPU::JCXZ_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_FAR_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_FAR_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_imm16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_imm16_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::JMP_short_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::Jcc_NEAR_imm(const X86::Instruction&) { TODO(); } +void SoftCPU::Jcc_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::LAHF(const X86::Instruction&) { TODO(); } +void SoftCPU::LAR_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::LAR_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::LDS_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LDS_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LEAVE16(const X86::Instruction&) { TODO(); } +void SoftCPU::LEAVE32(const X86::Instruction&) { TODO(); } +void SoftCPU::LEA_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LEA_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LES_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LES_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LFS_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LFS_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LGDT(const X86::Instruction&) { TODO(); } +void SoftCPU::LGS_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LGS_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LIDT(const X86::Instruction&) { TODO(); } +void SoftCPU::LLDT_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::LMSW_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::LODSB(const X86::Instruction&) { TODO(); } +void SoftCPU::LODSD(const X86::Instruction&) { TODO(); } +void SoftCPU::LODSW(const X86::Instruction&) { TODO(); } +void SoftCPU::LOOPNZ_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::LOOPZ_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::LOOP_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::LSL_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::LSL_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::LSS_reg16_mem16(const X86::Instruction&) { TODO(); } +void SoftCPU::LSS_reg32_mem32(const X86::Instruction&) { TODO(); } +void SoftCPU::LTR_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSB(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSD(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSW(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSX_reg16_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSX_reg32_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVSX_reg32_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVZX_reg16_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVZX_reg32_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVZX_reg32_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_AL_moff8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_AX_moff16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_CR_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_DR_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_EAX_moff32(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_RM16_seg(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_RM32_imm32(const X86::Instruction&) { TODO(); } + +void SoftCPU::MOV_RM32_reg32(const X86::Instruction& insn) +{ + ASSERT(insn.modrm().is_register()); + *m_reg32_table[insn.modrm().register_index()] = *m_reg32_table[insn.register_index()]; +} + +void SoftCPU::MOV_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_moff16_AX(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_moff32_EAX(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_moff8_AL(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg32_CR(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg32_DR(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg32_RM32(const X86::Instruction&) { TODO(); } + +void SoftCPU::MOV_reg32_imm32(const X86::Instruction& insn) +{ + *m_reg32_table[insn.register_index()] = insn.imm32(); +} + +void SoftCPU::MOV_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_reg8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_seg_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MOV_seg_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::MUL_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::MUL_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::MUL_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::NEG_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::NEG_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::NEG_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::NOP(const X86::Instruction&) { TODO(); } +void SoftCPU::NOT_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::NOT_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::NOT_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::OR_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::OUTSB(const X86::Instruction&) { TODO(); } +void SoftCPU::OUTSD(const X86::Instruction&) { TODO(); } +void SoftCPU::OUTSW(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_DX_AL(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_DX_AX(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_DX_EAX(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_imm8_AL(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_imm8_AX(const X86::Instruction&) { TODO(); } +void SoftCPU::OUT_imm8_EAX(const X86::Instruction&) { TODO(); } +void SoftCPU::PADDB_mm1_mm2m64(const X86::Instruction&) { TODO(); } +void SoftCPU::PADDW_mm1_mm2m64(const X86::Instruction&) { TODO(); } +void SoftCPU::PADDD_mm1_mm2m64(const X86::Instruction&) { TODO(); } +void SoftCPU::POPA(const X86::Instruction&) { TODO(); } +void SoftCPU::POPAD(const X86::Instruction&) { TODO(); } +void SoftCPU::POPF(const X86::Instruction&) { TODO(); } +void SoftCPU::POPFD(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_DS(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_ES(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_FS(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_GS(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_SS(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::POP_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSHA(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSHAD(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSHF(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSHFD(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_CS(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_DS(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_ES(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_FS(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_GS(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_SP_8086_80186(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_SS(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::PUSH_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCL_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::RCR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::RDTSC(const X86::Instruction&) { TODO(); } +void SoftCPU::RET(const X86::Instruction&) { TODO(); } +void SoftCPU::RETF(const X86::Instruction&) { TODO(); } +void SoftCPU::RETF_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::RET_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROL_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::ROR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SAHF(const X86::Instruction&) { TODO(); } +void SoftCPU::SALC(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SAR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::SBB_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::SCASB(const X86::Instruction&) { TODO(); } +void SoftCPU::SCASD(const X86::Instruction&) { TODO(); } +void SoftCPU::SCASW(const X86::Instruction&) { TODO(); } +void SoftCPU::SETcc_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::SGDT(const X86::Instruction&) { TODO(); } +void SoftCPU::SHLD_RM16_reg16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHLD_RM16_reg16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHLD_RM32_reg32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHLD_RM32_reg32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHL_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHRD_RM16_reg16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHRD_RM16_reg16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHRD_RM32_reg32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHRD_RM32_reg32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM16_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM16_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM32_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM32_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM8_1(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM8_CL(const X86::Instruction&) { TODO(); } +void SoftCPU::SHR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SIDT(const X86::Instruction&) { TODO(); } +void SoftCPU::SLDT_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::SMSW_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::STC(const X86::Instruction&) { TODO(); } +void SoftCPU::STD(const X86::Instruction&) { TODO(); } +void SoftCPU::STI(const X86::Instruction&) { TODO(); } +void SoftCPU::STOSB(const X86::Instruction&) { TODO(); } +void SoftCPU::STOSD(const X86::Instruction&) { TODO(); } +void SoftCPU::STOSW(const X86::Instruction&) { TODO(); } +void SoftCPU::STR_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::SUB_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::TEST_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::UD0(const X86::Instruction&) { TODO(); } +void SoftCPU::UD1(const X86::Instruction&) { TODO(); } +void SoftCPU::UD2(const X86::Instruction&) { TODO(); } +void SoftCPU::VERR_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::VERW_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::WAIT(const X86::Instruction&) { TODO(); } +void SoftCPU::WBINVD(const X86::Instruction&) { TODO(); } +void SoftCPU::XADD_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::XADD_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::XADD_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::XCHG_AX_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::XCHG_EAX_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::XCHG_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::XCHG_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::XCHG_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::XLAT(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_AL_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_AX_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_EAX_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM16_imm16(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM16_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM16_reg16(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM32_imm32(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM32_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM32_reg32(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM8_imm8(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_RM8_reg8(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_reg16_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_reg32_RM32(const X86::Instruction&) { TODO(); } +void SoftCPU::XOR_reg8_RM8(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVQ_mm1_mm2m64(const X86::Instruction&) { TODO(); } +void SoftCPU::EMMS(const X86::Instruction&) { TODO(); } +void SoftCPU::MOVQ_mm1_m64_mm2(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xC0(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xC1_16(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xC1_32(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD0(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD1_16(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD1_32(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD2(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD3_16(const X86::Instruction&) { TODO(); } +void SoftCPU::wrap_0xD3_32(const X86::Instruction&) { TODO(); } + +} diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h new file mode 100644 index 0000000000..23c00f51f2 --- /dev/null +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace UserspaceEmulator { + +class Emulator; + +class SoftCPU final : public X86::Interpreter { +public: + explicit SoftCPU(Emulator&); + void dump() const; + + virtual void AAA(const X86::Instruction&) override; + virtual void AAD(const X86::Instruction&) override; + virtual void AAM(const X86::Instruction&) override; + virtual void AAS(const X86::Instruction&) override; + virtual void ADC_AL_imm8(const X86::Instruction&) override; + virtual void ADC_AX_imm16(const X86::Instruction&) override; + virtual void ADC_EAX_imm32(const X86::Instruction&) override; + virtual void ADC_RM16_imm16(const X86::Instruction&) override; + virtual void ADC_RM16_imm8(const X86::Instruction&) override; + virtual void ADC_RM16_reg16(const X86::Instruction&) override; + virtual void ADC_RM32_imm32(const X86::Instruction&) override; + virtual void ADC_RM32_imm8(const X86::Instruction&) override; + virtual void ADC_RM32_reg32(const X86::Instruction&) override; + virtual void ADC_RM8_imm8(const X86::Instruction&) override; + virtual void ADC_RM8_reg8(const X86::Instruction&) override; + virtual void ADC_reg16_RM16(const X86::Instruction&) override; + virtual void ADC_reg32_RM32(const X86::Instruction&) override; + virtual void ADC_reg8_RM8(const X86::Instruction&) override; + virtual void ADD_AL_imm8(const X86::Instruction&) override; + virtual void ADD_AX_imm16(const X86::Instruction&) override; + virtual void ADD_EAX_imm32(const X86::Instruction&) override; + virtual void ADD_RM16_imm16(const X86::Instruction&) override; + virtual void ADD_RM16_imm8(const X86::Instruction&) override; + virtual void ADD_RM16_reg16(const X86::Instruction&) override; + virtual void ADD_RM32_imm32(const X86::Instruction&) override; + virtual void ADD_RM32_imm8(const X86::Instruction&) override; + virtual void ADD_RM32_reg32(const X86::Instruction&) override; + virtual void ADD_RM8_imm8(const X86::Instruction&) override; + virtual void ADD_RM8_reg8(const X86::Instruction&) override; + virtual void ADD_reg16_RM16(const X86::Instruction&) override; + virtual void ADD_reg32_RM32(const X86::Instruction&) override; + virtual void ADD_reg8_RM8(const X86::Instruction&) override; + virtual void AND_AL_imm8(const X86::Instruction&) override; + virtual void AND_AX_imm16(const X86::Instruction&) override; + virtual void AND_EAX_imm32(const X86::Instruction&) override; + virtual void AND_RM16_imm16(const X86::Instruction&) override; + virtual void AND_RM16_imm8(const X86::Instruction&) override; + virtual void AND_RM16_reg16(const X86::Instruction&) override; + virtual void AND_RM32_imm32(const X86::Instruction&) override; + virtual void AND_RM32_imm8(const X86::Instruction&) override; + virtual void AND_RM32_reg32(const X86::Instruction&) override; + virtual void AND_RM8_imm8(const X86::Instruction&) override; + virtual void AND_RM8_reg8(const X86::Instruction&) override; + virtual void AND_reg16_RM16(const X86::Instruction&) override; + virtual void AND_reg32_RM32(const X86::Instruction&) override; + virtual void AND_reg8_RM8(const X86::Instruction&) override; + virtual void ARPL(const X86::Instruction&) override; + virtual void BOUND(const X86::Instruction&) override; + virtual void BSF_reg16_RM16(const X86::Instruction&) override; + virtual void BSF_reg32_RM32(const X86::Instruction&) override; + virtual void BSR_reg16_RM16(const X86::Instruction&) override; + virtual void BSR_reg32_RM32(const X86::Instruction&) override; + virtual void BSWAP_reg32(const X86::Instruction&) override; + virtual void BTC_RM16_imm8(const X86::Instruction&) override; + virtual void BTC_RM16_reg16(const X86::Instruction&) override; + virtual void BTC_RM32_imm8(const X86::Instruction&) override; + virtual void BTC_RM32_reg32(const X86::Instruction&) override; + virtual void BTR_RM16_imm8(const X86::Instruction&) override; + virtual void BTR_RM16_reg16(const X86::Instruction&) override; + virtual void BTR_RM32_imm8(const X86::Instruction&) override; + virtual void BTR_RM32_reg32(const X86::Instruction&) override; + virtual void BTS_RM16_imm8(const X86::Instruction&) override; + virtual void BTS_RM16_reg16(const X86::Instruction&) override; + virtual void BTS_RM32_imm8(const X86::Instruction&) override; + virtual void BTS_RM32_reg32(const X86::Instruction&) override; + virtual void BT_RM16_imm8(const X86::Instruction&) override; + virtual void BT_RM16_reg16(const X86::Instruction&) override; + virtual void BT_RM32_imm8(const X86::Instruction&) override; + virtual void BT_RM32_reg32(const X86::Instruction&) override; + virtual void CALL_FAR_mem16(const X86::Instruction&) override; + virtual void CALL_FAR_mem32(const X86::Instruction&) override; + virtual void CALL_RM16(const X86::Instruction&) override; + virtual void CALL_RM32(const X86::Instruction&) override; + virtual void CALL_imm16(const X86::Instruction&) override; + virtual void CALL_imm16_imm16(const X86::Instruction&) override; + virtual void CALL_imm16_imm32(const X86::Instruction&) override; + virtual void CALL_imm32(const X86::Instruction&) override; + virtual void CBW(const X86::Instruction&) override; + virtual void CDQ(const X86::Instruction&) override; + virtual void CLC(const X86::Instruction&) override; + virtual void CLD(const X86::Instruction&) override; + virtual void CLI(const X86::Instruction&) override; + virtual void CLTS(const X86::Instruction&) override; + virtual void CMC(const X86::Instruction&) override; + virtual void CMOVcc_reg16_RM16(const X86::Instruction&) override; + virtual void CMOVcc_reg32_RM32(const X86::Instruction&) override; + virtual void CMPSB(const X86::Instruction&) override; + virtual void CMPSD(const X86::Instruction&) override; + virtual void CMPSW(const X86::Instruction&) override; + virtual void CMPXCHG_RM16_reg16(const X86::Instruction&) override; + virtual void CMPXCHG_RM32_reg32(const X86::Instruction&) override; + virtual void CMPXCHG_RM8_reg8(const X86::Instruction&) override; + virtual void CMP_AL_imm8(const X86::Instruction&) override; + virtual void CMP_AX_imm16(const X86::Instruction&) override; + virtual void CMP_EAX_imm32(const X86::Instruction&) override; + virtual void CMP_RM16_imm16(const X86::Instruction&) override; + virtual void CMP_RM16_imm8(const X86::Instruction&) override; + virtual void CMP_RM16_reg16(const X86::Instruction&) override; + virtual void CMP_RM32_imm32(const X86::Instruction&) override; + virtual void CMP_RM32_imm8(const X86::Instruction&) override; + virtual void CMP_RM32_reg32(const X86::Instruction&) override; + virtual void CMP_RM8_imm8(const X86::Instruction&) override; + virtual void CMP_RM8_reg8(const X86::Instruction&) override; + virtual void CMP_reg16_RM16(const X86::Instruction&) override; + virtual void CMP_reg32_RM32(const X86::Instruction&) override; + virtual void CMP_reg8_RM8(const X86::Instruction&) override; + virtual void CPUID(const X86::Instruction&) override; + virtual void CWD(const X86::Instruction&) override; + virtual void CWDE(const X86::Instruction&) override; + virtual void DAA(const X86::Instruction&) override; + virtual void DAS(const X86::Instruction&) override; + virtual void DEC_RM16(const X86::Instruction&) override; + virtual void DEC_RM32(const X86::Instruction&) override; + virtual void DEC_RM8(const X86::Instruction&) override; + virtual void DEC_reg16(const X86::Instruction&) override; + virtual void DEC_reg32(const X86::Instruction&) override; + virtual void DIV_RM16(const X86::Instruction&) override; + virtual void DIV_RM32(const X86::Instruction&) override; + virtual void DIV_RM8(const X86::Instruction&) override; + virtual void ENTER16(const X86::Instruction&) override; + virtual void ENTER32(const X86::Instruction&) override; + virtual void ESCAPE(const X86::Instruction&) override; + virtual void HLT(const X86::Instruction&) override; + virtual void IDIV_RM16(const X86::Instruction&) override; + virtual void IDIV_RM32(const X86::Instruction&) override; + virtual void IDIV_RM8(const X86::Instruction&) override; + virtual void IMUL_RM16(const X86::Instruction&) override; + virtual void IMUL_RM32(const X86::Instruction&) override; + virtual void IMUL_RM8(const X86::Instruction&) override; + virtual void IMUL_reg16_RM16(const X86::Instruction&) override; + virtual void IMUL_reg16_RM16_imm16(const X86::Instruction&) override; + virtual void IMUL_reg16_RM16_imm8(const X86::Instruction&) override; + virtual void IMUL_reg32_RM32(const X86::Instruction&) override; + virtual void IMUL_reg32_RM32_imm32(const X86::Instruction&) override; + virtual void IMUL_reg32_RM32_imm8(const X86::Instruction&) override; + virtual void INC_RM16(const X86::Instruction&) override; + virtual void INC_RM32(const X86::Instruction&) override; + virtual void INC_RM8(const X86::Instruction&) override; + virtual void INC_reg16(const X86::Instruction&) override; + virtual void INC_reg32(const X86::Instruction&) override; + virtual void INSB(const X86::Instruction&) override; + virtual void INSD(const X86::Instruction&) override; + virtual void INSW(const X86::Instruction&) override; + virtual void INT3(const X86::Instruction&) override; + virtual void INTO(const X86::Instruction&) override; + virtual void INT_imm8(const X86::Instruction&) override; + virtual void INVLPG(const X86::Instruction&) override; + virtual void IN_AL_DX(const X86::Instruction&) override; + virtual void IN_AL_imm8(const X86::Instruction&) override; + virtual void IN_AX_DX(const X86::Instruction&) override; + virtual void IN_AX_imm8(const X86::Instruction&) override; + virtual void IN_EAX_DX(const X86::Instruction&) override; + virtual void IN_EAX_imm8(const X86::Instruction&) override; + virtual void IRET(const X86::Instruction&) override; + virtual void JCXZ_imm8(const X86::Instruction&) override; + virtual void JMP_FAR_mem16(const X86::Instruction&) override; + virtual void JMP_FAR_mem32(const X86::Instruction&) override; + virtual void JMP_RM16(const X86::Instruction&) override; + virtual void JMP_RM32(const X86::Instruction&) override; + virtual void JMP_imm16(const X86::Instruction&) override; + virtual void JMP_imm16_imm16(const X86::Instruction&) override; + virtual void JMP_imm16_imm32(const X86::Instruction&) override; + virtual void JMP_imm32(const X86::Instruction&) override; + virtual void JMP_short_imm8(const X86::Instruction&) override; + virtual void Jcc_NEAR_imm(const X86::Instruction&) override; + virtual void Jcc_imm8(const X86::Instruction&) override; + virtual void LAHF(const X86::Instruction&) override; + virtual void LAR_reg16_RM16(const X86::Instruction&) override; + virtual void LAR_reg32_RM32(const X86::Instruction&) override; + virtual void LDS_reg16_mem16(const X86::Instruction&) override; + virtual void LDS_reg32_mem32(const X86::Instruction&) override; + virtual void LEAVE16(const X86::Instruction&) override; + virtual void LEAVE32(const X86::Instruction&) override; + virtual void LEA_reg16_mem16(const X86::Instruction&) override; + virtual void LEA_reg32_mem32(const X86::Instruction&) override; + virtual void LES_reg16_mem16(const X86::Instruction&) override; + virtual void LES_reg32_mem32(const X86::Instruction&) override; + virtual void LFS_reg16_mem16(const X86::Instruction&) override; + virtual void LFS_reg32_mem32(const X86::Instruction&) override; + virtual void LGDT(const X86::Instruction&) override; + virtual void LGS_reg16_mem16(const X86::Instruction&) override; + virtual void LGS_reg32_mem32(const X86::Instruction&) override; + virtual void LIDT(const X86::Instruction&) override; + virtual void LLDT_RM16(const X86::Instruction&) override; + virtual void LMSW_RM16(const X86::Instruction&) override; + virtual void LODSB(const X86::Instruction&) override; + virtual void LODSD(const X86::Instruction&) override; + virtual void LODSW(const X86::Instruction&) override; + virtual void LOOPNZ_imm8(const X86::Instruction&) override; + virtual void LOOPZ_imm8(const X86::Instruction&) override; + virtual void LOOP_imm8(const X86::Instruction&) override; + virtual void LSL_reg16_RM16(const X86::Instruction&) override; + virtual void LSL_reg32_RM32(const X86::Instruction&) override; + virtual void LSS_reg16_mem16(const X86::Instruction&) override; + virtual void LSS_reg32_mem32(const X86::Instruction&) override; + virtual void LTR_RM16(const X86::Instruction&) override; + virtual void MOVSB(const X86::Instruction&) override; + virtual void MOVSD(const X86::Instruction&) override; + virtual void MOVSW(const X86::Instruction&) override; + virtual void MOVSX_reg16_RM8(const X86::Instruction&) override; + virtual void MOVSX_reg32_RM16(const X86::Instruction&) override; + virtual void MOVSX_reg32_RM8(const X86::Instruction&) override; + virtual void MOVZX_reg16_RM8(const X86::Instruction&) override; + virtual void MOVZX_reg32_RM16(const X86::Instruction&) override; + virtual void MOVZX_reg32_RM8(const X86::Instruction&) override; + virtual void MOV_AL_moff8(const X86::Instruction&) override; + virtual void MOV_AX_moff16(const X86::Instruction&) override; + virtual void MOV_CR_reg32(const X86::Instruction&) override; + virtual void MOV_DR_reg32(const X86::Instruction&) override; + virtual void MOV_EAX_moff32(const X86::Instruction&) override; + virtual void MOV_RM16_imm16(const X86::Instruction&) override; + virtual void MOV_RM16_reg16(const X86::Instruction&) override; + virtual void MOV_RM16_seg(const X86::Instruction&) override; + virtual void MOV_RM32_imm32(const X86::Instruction&) override; + virtual void MOV_RM32_reg32(const X86::Instruction&) override; + virtual void MOV_RM8_imm8(const X86::Instruction&) override; + virtual void MOV_RM8_reg8(const X86::Instruction&) override; + virtual void MOV_moff16_AX(const X86::Instruction&) override; + virtual void MOV_moff32_EAX(const X86::Instruction&) override; + virtual void MOV_moff8_AL(const X86::Instruction&) override; + virtual void MOV_reg16_RM16(const X86::Instruction&) override; + virtual void MOV_reg16_imm16(const X86::Instruction&) override; + virtual void MOV_reg32_CR(const X86::Instruction&) override; + virtual void MOV_reg32_DR(const X86::Instruction&) override; + virtual void MOV_reg32_RM32(const X86::Instruction&) override; + virtual void MOV_reg32_imm32(const X86::Instruction&) override; + virtual void MOV_reg8_RM8(const X86::Instruction&) override; + virtual void MOV_reg8_imm8(const X86::Instruction&) override; + virtual void MOV_seg_RM16(const X86::Instruction&) override; + virtual void MOV_seg_RM32(const X86::Instruction&) override; + virtual void MUL_RM16(const X86::Instruction&) override; + virtual void MUL_RM32(const X86::Instruction&) override; + virtual void MUL_RM8(const X86::Instruction&) override; + virtual void NEG_RM16(const X86::Instruction&) override; + virtual void NEG_RM32(const X86::Instruction&) override; + virtual void NEG_RM8(const X86::Instruction&) override; + virtual void NOP(const X86::Instruction&) override; + virtual void NOT_RM16(const X86::Instruction&) override; + virtual void NOT_RM32(const X86::Instruction&) override; + virtual void NOT_RM8(const X86::Instruction&) override; + virtual void OR_AL_imm8(const X86::Instruction&) override; + virtual void OR_AX_imm16(const X86::Instruction&) override; + virtual void OR_EAX_imm32(const X86::Instruction&) override; + virtual void OR_RM16_imm16(const X86::Instruction&) override; + virtual void OR_RM16_imm8(const X86::Instruction&) override; + virtual void OR_RM16_reg16(const X86::Instruction&) override; + virtual void OR_RM32_imm32(const X86::Instruction&) override; + virtual void OR_RM32_imm8(const X86::Instruction&) override; + virtual void OR_RM32_reg32(const X86::Instruction&) override; + virtual void OR_RM8_imm8(const X86::Instruction&) override; + virtual void OR_RM8_reg8(const X86::Instruction&) override; + virtual void OR_reg16_RM16(const X86::Instruction&) override; + virtual void OR_reg32_RM32(const X86::Instruction&) override; + virtual void OR_reg8_RM8(const X86::Instruction&) override; + virtual void OUTSB(const X86::Instruction&) override; + virtual void OUTSD(const X86::Instruction&) override; + virtual void OUTSW(const X86::Instruction&) override; + virtual void OUT_DX_AL(const X86::Instruction&) override; + virtual void OUT_DX_AX(const X86::Instruction&) override; + virtual void OUT_DX_EAX(const X86::Instruction&) override; + virtual void OUT_imm8_AL(const X86::Instruction&) override; + virtual void OUT_imm8_AX(const X86::Instruction&) override; + virtual void OUT_imm8_EAX(const X86::Instruction&) override; + virtual void PADDB_mm1_mm2m64(const X86::Instruction&) override; + virtual void PADDW_mm1_mm2m64(const X86::Instruction&) override; + virtual void PADDD_mm1_mm2m64(const X86::Instruction&) override; + virtual void POPA(const X86::Instruction&) override; + virtual void POPAD(const X86::Instruction&) override; + virtual void POPF(const X86::Instruction&) override; + virtual void POPFD(const X86::Instruction&) override; + virtual void POP_DS(const X86::Instruction&) override; + virtual void POP_ES(const X86::Instruction&) override; + virtual void POP_FS(const X86::Instruction&) override; + virtual void POP_GS(const X86::Instruction&) override; + virtual void POP_RM16(const X86::Instruction&) override; + virtual void POP_RM32(const X86::Instruction&) override; + virtual void POP_SS(const X86::Instruction&) override; + virtual void POP_reg16(const X86::Instruction&) override; + virtual void POP_reg32(const X86::Instruction&) override; + virtual void PUSHA(const X86::Instruction&) override; + virtual void PUSHAD(const X86::Instruction&) override; + virtual void PUSHF(const X86::Instruction&) override; + virtual void PUSHFD(const X86::Instruction&) override; + virtual void PUSH_CS(const X86::Instruction&) override; + virtual void PUSH_DS(const X86::Instruction&) override; + virtual void PUSH_ES(const X86::Instruction&) override; + virtual void PUSH_FS(const X86::Instruction&) override; + virtual void PUSH_GS(const X86::Instruction&) override; + virtual void PUSH_RM16(const X86::Instruction&) override; + virtual void PUSH_RM32(const X86::Instruction&) override; + virtual void PUSH_SP_8086_80186(const X86::Instruction&) override; + virtual void PUSH_SS(const X86::Instruction&) override; + virtual void PUSH_imm16(const X86::Instruction&) override; + virtual void PUSH_imm32(const X86::Instruction&) override; + virtual void PUSH_imm8(const X86::Instruction&) override; + virtual void PUSH_reg16(const X86::Instruction&) override; + virtual void PUSH_reg32(const X86::Instruction&) override; + virtual void RCL_RM16_1(const X86::Instruction&) override; + virtual void RCL_RM16_CL(const X86::Instruction&) override; + virtual void RCL_RM16_imm8(const X86::Instruction&) override; + virtual void RCL_RM32_1(const X86::Instruction&) override; + virtual void RCL_RM32_CL(const X86::Instruction&) override; + virtual void RCL_RM32_imm8(const X86::Instruction&) override; + virtual void RCL_RM8_1(const X86::Instruction&) override; + virtual void RCL_RM8_CL(const X86::Instruction&) override; + virtual void RCL_RM8_imm8(const X86::Instruction&) override; + virtual void RCR_RM16_1(const X86::Instruction&) override; + virtual void RCR_RM16_CL(const X86::Instruction&) override; + virtual void RCR_RM16_imm8(const X86::Instruction&) override; + virtual void RCR_RM32_1(const X86::Instruction&) override; + virtual void RCR_RM32_CL(const X86::Instruction&) override; + virtual void RCR_RM32_imm8(const X86::Instruction&) override; + virtual void RCR_RM8_1(const X86::Instruction&) override; + virtual void RCR_RM8_CL(const X86::Instruction&) override; + virtual void RCR_RM8_imm8(const X86::Instruction&) override; + virtual void RDTSC(const X86::Instruction&) override; + virtual void RET(const X86::Instruction&) override; + virtual void RETF(const X86::Instruction&) override; + virtual void RETF_imm16(const X86::Instruction&) override; + virtual void RET_imm16(const X86::Instruction&) override; + virtual void ROL_RM16_1(const X86::Instruction&) override; + virtual void ROL_RM16_CL(const X86::Instruction&) override; + virtual void ROL_RM16_imm8(const X86::Instruction&) override; + virtual void ROL_RM32_1(const X86::Instruction&) override; + virtual void ROL_RM32_CL(const X86::Instruction&) override; + virtual void ROL_RM32_imm8(const X86::Instruction&) override; + virtual void ROL_RM8_1(const X86::Instruction&) override; + virtual void ROL_RM8_CL(const X86::Instruction&) override; + virtual void ROL_RM8_imm8(const X86::Instruction&) override; + virtual void ROR_RM16_1(const X86::Instruction&) override; + virtual void ROR_RM16_CL(const X86::Instruction&) override; + virtual void ROR_RM16_imm8(const X86::Instruction&) override; + virtual void ROR_RM32_1(const X86::Instruction&) override; + virtual void ROR_RM32_CL(const X86::Instruction&) override; + virtual void ROR_RM32_imm8(const X86::Instruction&) override; + virtual void ROR_RM8_1(const X86::Instruction&) override; + virtual void ROR_RM8_CL(const X86::Instruction&) override; + virtual void ROR_RM8_imm8(const X86::Instruction&) override; + virtual void SAHF(const X86::Instruction&) override; + virtual void SALC(const X86::Instruction&) override; + virtual void SAR_RM16_1(const X86::Instruction&) override; + virtual void SAR_RM16_CL(const X86::Instruction&) override; + virtual void SAR_RM16_imm8(const X86::Instruction&) override; + virtual void SAR_RM32_1(const X86::Instruction&) override; + virtual void SAR_RM32_CL(const X86::Instruction&) override; + virtual void SAR_RM32_imm8(const X86::Instruction&) override; + virtual void SAR_RM8_1(const X86::Instruction&) override; + virtual void SAR_RM8_CL(const X86::Instruction&) override; + virtual void SAR_RM8_imm8(const X86::Instruction&) override; + virtual void SBB_AL_imm8(const X86::Instruction&) override; + virtual void SBB_AX_imm16(const X86::Instruction&) override; + virtual void SBB_EAX_imm32(const X86::Instruction&) override; + virtual void SBB_RM16_imm16(const X86::Instruction&) override; + virtual void SBB_RM16_imm8(const X86::Instruction&) override; + virtual void SBB_RM16_reg16(const X86::Instruction&) override; + virtual void SBB_RM32_imm32(const X86::Instruction&) override; + virtual void SBB_RM32_imm8(const X86::Instruction&) override; + virtual void SBB_RM32_reg32(const X86::Instruction&) override; + virtual void SBB_RM8_imm8(const X86::Instruction&) override; + virtual void SBB_RM8_reg8(const X86::Instruction&) override; + virtual void SBB_reg16_RM16(const X86::Instruction&) override; + virtual void SBB_reg32_RM32(const X86::Instruction&) override; + virtual void SBB_reg8_RM8(const X86::Instruction&) override; + virtual void SCASB(const X86::Instruction&) override; + virtual void SCASD(const X86::Instruction&) override; + virtual void SCASW(const X86::Instruction&) override; + virtual void SETcc_RM8(const X86::Instruction&) override; + virtual void SGDT(const X86::Instruction&) override; + virtual void SHLD_RM16_reg16_CL(const X86::Instruction&) override; + virtual void SHLD_RM16_reg16_imm8(const X86::Instruction&) override; + virtual void SHLD_RM32_reg32_CL(const X86::Instruction&) override; + virtual void SHLD_RM32_reg32_imm8(const X86::Instruction&) override; + virtual void SHL_RM16_1(const X86::Instruction&) override; + virtual void SHL_RM16_CL(const X86::Instruction&) override; + virtual void SHL_RM16_imm8(const X86::Instruction&) override; + virtual void SHL_RM32_1(const X86::Instruction&) override; + virtual void SHL_RM32_CL(const X86::Instruction&) override; + virtual void SHL_RM32_imm8(const X86::Instruction&) override; + virtual void SHL_RM8_1(const X86::Instruction&) override; + virtual void SHL_RM8_CL(const X86::Instruction&) override; + virtual void SHL_RM8_imm8(const X86::Instruction&) override; + virtual void SHRD_RM16_reg16_CL(const X86::Instruction&) override; + virtual void SHRD_RM16_reg16_imm8(const X86::Instruction&) override; + virtual void SHRD_RM32_reg32_CL(const X86::Instruction&) override; + virtual void SHRD_RM32_reg32_imm8(const X86::Instruction&) override; + virtual void SHR_RM16_1(const X86::Instruction&) override; + virtual void SHR_RM16_CL(const X86::Instruction&) override; + virtual void SHR_RM16_imm8(const X86::Instruction&) override; + virtual void SHR_RM32_1(const X86::Instruction&) override; + virtual void SHR_RM32_CL(const X86::Instruction&) override; + virtual void SHR_RM32_imm8(const X86::Instruction&) override; + virtual void SHR_RM8_1(const X86::Instruction&) override; + virtual void SHR_RM8_CL(const X86::Instruction&) override; + virtual void SHR_RM8_imm8(const X86::Instruction&) override; + virtual void SIDT(const X86::Instruction&) override; + virtual void SLDT_RM16(const X86::Instruction&) override; + virtual void SMSW_RM16(const X86::Instruction&) override; + virtual void STC(const X86::Instruction&) override; + virtual void STD(const X86::Instruction&) override; + virtual void STI(const X86::Instruction&) override; + virtual void STOSB(const X86::Instruction&) override; + virtual void STOSD(const X86::Instruction&) override; + virtual void STOSW(const X86::Instruction&) override; + virtual void STR_RM16(const X86::Instruction&) override; + virtual void SUB_AL_imm8(const X86::Instruction&) override; + virtual void SUB_AX_imm16(const X86::Instruction&) override; + virtual void SUB_EAX_imm32(const X86::Instruction&) override; + virtual void SUB_RM16_imm16(const X86::Instruction&) override; + virtual void SUB_RM16_imm8(const X86::Instruction&) override; + virtual void SUB_RM16_reg16(const X86::Instruction&) override; + virtual void SUB_RM32_imm32(const X86::Instruction&) override; + virtual void SUB_RM32_imm8(const X86::Instruction&) override; + virtual void SUB_RM32_reg32(const X86::Instruction&) override; + virtual void SUB_RM8_imm8(const X86::Instruction&) override; + virtual void SUB_RM8_reg8(const X86::Instruction&) override; + virtual void SUB_reg16_RM16(const X86::Instruction&) override; + virtual void SUB_reg32_RM32(const X86::Instruction&) override; + virtual void SUB_reg8_RM8(const X86::Instruction&) override; + virtual void TEST_AL_imm8(const X86::Instruction&) override; + virtual void TEST_AX_imm16(const X86::Instruction&) override; + virtual void TEST_EAX_imm32(const X86::Instruction&) override; + virtual void TEST_RM16_imm16(const X86::Instruction&) override; + virtual void TEST_RM16_reg16(const X86::Instruction&) override; + virtual void TEST_RM32_imm32(const X86::Instruction&) override; + virtual void TEST_RM32_reg32(const X86::Instruction&) override; + virtual void TEST_RM8_imm8(const X86::Instruction&) override; + virtual void TEST_RM8_reg8(const X86::Instruction&) override; + virtual void UD0(const X86::Instruction&) override; + virtual void UD1(const X86::Instruction&) override; + virtual void UD2(const X86::Instruction&) override; + virtual void VERR_RM16(const X86::Instruction&) override; + virtual void VERW_RM16(const X86::Instruction&) override; + virtual void WAIT(const X86::Instruction&) override; + virtual void WBINVD(const X86::Instruction&) override; + virtual void XADD_RM16_reg16(const X86::Instruction&) override; + virtual void XADD_RM32_reg32(const X86::Instruction&) override; + virtual void XADD_RM8_reg8(const X86::Instruction&) override; + virtual void XCHG_AX_reg16(const X86::Instruction&) override; + virtual void XCHG_EAX_reg32(const X86::Instruction&) override; + virtual void XCHG_reg16_RM16(const X86::Instruction&) override; + virtual void XCHG_reg32_RM32(const X86::Instruction&) override; + virtual void XCHG_reg8_RM8(const X86::Instruction&) override; + virtual void XLAT(const X86::Instruction&) override; + virtual void XOR_AL_imm8(const X86::Instruction&) override; + virtual void XOR_AX_imm16(const X86::Instruction&) override; + virtual void XOR_EAX_imm32(const X86::Instruction&) override; + virtual void XOR_RM16_imm16(const X86::Instruction&) override; + virtual void XOR_RM16_imm8(const X86::Instruction&) override; + virtual void XOR_RM16_reg16(const X86::Instruction&) override; + virtual void XOR_RM32_imm32(const X86::Instruction&) override; + virtual void XOR_RM32_imm8(const X86::Instruction&) override; + virtual void XOR_RM32_reg32(const X86::Instruction&) override; + virtual void XOR_RM8_imm8(const X86::Instruction&) override; + virtual void XOR_RM8_reg8(const X86::Instruction&) override; + virtual void XOR_reg16_RM16(const X86::Instruction&) override; + virtual void XOR_reg32_RM32(const X86::Instruction&) override; + virtual void XOR_reg8_RM8(const X86::Instruction&) override; + virtual void MOVQ_mm1_mm2m64(const X86::Instruction&) override; + virtual void EMMS(const X86::Instruction&) override; + virtual void MOVQ_mm1_m64_mm2(const X86::Instruction&) override; + virtual void wrap_0xC0(const X86::Instruction&) override; + virtual void wrap_0xC1_16(const X86::Instruction&) override; + virtual void wrap_0xC1_32(const X86::Instruction&) override; + virtual void wrap_0xD0(const X86::Instruction&) override; + virtual void wrap_0xD1_16(const X86::Instruction&) override; + virtual void wrap_0xD1_32(const X86::Instruction&) override; + virtual void wrap_0xD2(const X86::Instruction&) override; + virtual void wrap_0xD3_16(const X86::Instruction&) override; + virtual void wrap_0xD3_32(const X86::Instruction&) override; + +private: + Emulator& m_emulator; + + u32* m_reg32_table[8]; + + u32 m_eax { 0 }; + u32 m_ebx { 0 }; + u32 m_ecx { 0 }; + u32 m_edx { 0 }; + u32 m_esp { 0 }; + u32 m_ebp { 0 }; + u32 m_esi { 0 }; + u32 m_edi { 0 }; +}; + +} diff --git a/DevTools/UserspaceEmulator/main.cpp b/DevTools/UserspaceEmulator/main.cpp new file mode 100644 index 0000000000..8f72e03905 --- /dev/null +++ b/DevTools/UserspaceEmulator/main.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Emulator.h" +#include "SoftCPU.h" +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + const char* executable_path = nullptr; + + Core::ArgsParser args_parser; + args_parser.add_positional_argument(executable_path, "Executable path", "executable"); + args_parser.parse(argc, argv); + + MappedFile mapped_file(executable_path); + if (!mapped_file.is_valid()) { + warn() << "Unable to map " << executable_path; + return 1; + } + + auto elf = ELF::Loader::create((const u8*)mapped_file.data(), mapped_file.size()); + + auto main_symbol = elf->find_demangled_function("main"); + if (!main_symbol.has_value()) { + warn() << "Could not find 'main' symbol in executable"; + return 1; + } + + auto main_code = main_symbol.value().raw_data(); + X86::SimpleInstructionStream stream((const u8*)main_code.characters_without_null_termination(), main_code.length()); + + UserspaceEmulator::Emulator emulator; + return emulator.exec(stream, main_symbol.value().value()); +}