Moves SonicUtils in to FEXCore

Removes the extraneous and dead VM CPU backend
This commit is contained in:
Ryan Houdek 2020-11-29 00:17:51 -08:00
parent e23ae78795
commit a28df9f5c1
74 changed files with 74 additions and 1693 deletions

View File

@ -98,9 +98,6 @@ endif()
add_definitions(-Wno-trigraphs)
add_subdirectory(External/SonicUtils/)
include_directories(External/SonicUtils/include/SonicUtils)
add_subdirectory(External/cpp-optparse/)
include_directories(External/cpp-optparse/)

View File

@ -25,6 +25,5 @@ RUN DEBIAN_FRONTEND="noninteractive" apt install -y libboost-dev \
libnuma-dev libcap-dev libglfw3-dev libepoxy-dev
COPY --from=builder /opt/FEX/build/Bin/* /usr/bin/
COPY --from=builder /opt/FEX/build/External/SonicUtils/libSonicUtils.so /usr/lib/
WORKDIR /root

View File

@ -39,8 +39,6 @@ endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories(${CMAKE_SOURCE_DIR}/External/SonicUtils/include/SonicUtils)
# Find our git hash
find_package(Git)

View File

@ -34,7 +34,6 @@ Multiple architecture support is desired for easier bringup and debugging, perfo
* SVM
* "Cycle Accurate" emulation
### Dependencies
* [SonicUtils](https://github.com/Sonicadvance1/SonicUtils)
* clang-tidy if you want to ensure the code stays tidy
* cmake
* A C++17 compliant compiler (There are assumptions made about using Clang and LTO)

View File

@ -204,6 +204,9 @@ set (SRCS
Interface/IR/Passes/DeadGPRStoreElimination.cpp
Interface/IR/Passes/RegisterAllocationPass.cpp
Interface/IR/Passes/SyscallOptimization.cpp
Utils/ELFLoader.cpp
Utils/ELFSymbolDatabase.cpp
Utils/LogManager.cpp
)
if (_M_X86_64)

View File

@ -1,6 +1,6 @@
#pragma once
#include "Common/MathUtils.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cstring>
#include <stdint.h>

View File

@ -1,5 +1,5 @@
#include "Common/Paths.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cstdlib>
#include <filesystem>

View File

@ -1,5 +1,5 @@
#pragma once
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cmath>
#include <cstring>

View File

@ -1,4 +1,4 @@
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include "Interface/Context/Context.h"
#include <FEXCore/Config/Config.h>

View File

@ -1,6 +1,6 @@
#pragma once
#include "Interface/Context/Context.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore {
class BlockCache {

View File

@ -1,5 +1,5 @@
#include "Interface/Core/BlockSamplingData.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cstring>
#include <fstream>

View File

@ -2,8 +2,6 @@
#include <functional>
#include <unordered_map>
#include "LogManager.h"
namespace FEXCore {
namespace Context {
struct Context;

View File

@ -1,13 +1,13 @@
#include "Interface/Context/Context.h"
#include "Interface/Core/Frontend.h"
#include "Interface/Core/InternalThreadState.h"
#include "LogManager.h"
#include <array>
#include <algorithm>
#include <cstring>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Debug/X86Tables.h>
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::Frontend {
using namespace FEXCore::X86Tables;

View File

@ -8,7 +8,7 @@
#include <optional>
#include "Common/NetStream.h"
#include "Common/SoftFloat.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <sys/types.h>
#include <sys/socket.h>

View File

@ -1,4 +1,3 @@
#include "LogManager.h"
#include "Common/MathUtils.h"
#include "Common/SoftFloat.h"
#include "Interface/Context/Context.h"
@ -7,7 +6,7 @@
#include "Interface/Core/InternalThreadState.h"
#include "Interface/Core/Interpreter/InterpreterClass.h"
#include "Interface/HLE/Syscalls.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Core/CPUBackend.h>
#include <FEXCore/IR/IR.h>

View File

@ -9,7 +9,7 @@
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IREmitter.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cstdint>
#include <functional>

View File

@ -3,7 +3,7 @@
#include "Interface/Core/SignalDelegator.h"
#include <FEXCore/Core/X86Enums.h>
#include <LogManager.h>
#include <FEXCore/Utils/LogManager.h>
#include <string.h>

View File

@ -1,6 +1,6 @@
#ifndef NDEBUG
#include <FEXCore/Debug/X86Tables.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <tuple>
#include <vector>

View File

@ -1,4 +1,4 @@
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/Debug/X86Tables.h>

View File

@ -1,7 +1,7 @@
#pragma once
#include <FEXCore/Debug/X86Tables.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::X86Tables {

View File

@ -1,6 +1,6 @@
#include <filesystem>
#include <unistd.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include "FEXCore/Core/CodeLoader.h"
#include "Interface/Context/Context.h"

View File

@ -1,7 +1,7 @@
#include "LogManager.h"
#include "Interface/Context/Context.h"
#include "Interface/HLE/FileManagement.h"
#include <FEXCore/Utils/LogManager.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>

View File

@ -1,3 +1,4 @@
#include <FEXCore/Utils/LogManager.h>
#include "Common/MathUtils.h"
#include "Interface/Context/Context.h"
@ -6,8 +7,6 @@
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "LogManager.h"
#include <FEXCore/Core/X86Enums.h>
#include <fcntl.h>
#include <limits.h>

View File

@ -1,7 +1,7 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "LogManager.h"
#include <stdint.h>
#include <sys/epoll.h>

View File

@ -1,9 +1,9 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "LogManager.h"
#include <sys/time.h>
#include <sys/types.h>

View File

@ -1,5 +1,5 @@
#include <FEXCore/Utils/LogManager.h>
#include "Thunks.h"
#include <LogManager.h>
#include "stdio.h"
#include <dlfcn.h>
@ -10,7 +10,6 @@
#include <Interface/Context/Context.h>
#include "Interface/Core/InternalThreadState.h"
#include "FEXCore/Core/X86Enums.h"
#include <LogManager.h>
#include <mutex>
#include <shared_mutex>
@ -127,4 +126,4 @@ namespace FEXCore {
ThunkHandler* ThunkHandler::Create() {
return new ThunkHandler_impl();
}
}
}

View File

@ -1,6 +1,6 @@
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x32/Syscalls.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::HLE::x32 {
#define REGISTER_SYSCALL_NOT_IMPL_X32(name) REGISTER_SYSCALL_IMPL_X32(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \

View File

@ -5,7 +5,7 @@
#include "Interface/HLE/Syscalls.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::HLE {
void RegisterEpoll();

View File

@ -1,6 +1,6 @@
#include <FEXCore/Utils/LogManager.h>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "LogManager.h"
namespace FEXCore::HLE::x64 {
#define REGISTER_SYSCALL_NOT_IMPL_X64(name) REGISTER_SYSCALL_IMPL_X64(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \

View File

@ -1,9 +1,8 @@
#include <map>
#include "Interface/HLE/Syscalls.h"
#include "Interface/HLE/x64/Syscalls.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <map>
namespace FEXCore::HLE {
void RegisterEpoll();

View File

@ -1,6 +1,6 @@
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IntrusiveIRList.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include "Interface/IR/Passes/RegisterAllocationPass.h"
namespace FEXCore::IR {

View File

@ -2,7 +2,7 @@
#include "Interface/IR/PassManager.h"
#include "Interface/Core/OpcodeDispatcher.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::IR {

View File

@ -1,4 +1,4 @@
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include "Interface/Memory/MemMapper.h"
#include <sys/mman.h>
#include <sys/stat.h>

View File

@ -1,4 +1,4 @@
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include "Interface/Memory/SharedMem.h"
#include <cstddef>
#include <cstdint>

View File

@ -1,5 +1,5 @@
#include <SonicUtils/ELFLoader.h>
#include <SonicUtils/LogManager.h>
#include <FEXCore/Utils/ELFLoader.h>
#include <FEXCore/Utils/LogManager.h>
#include <cstring>
#include <elf.h>
#include <fstream>

View File

@ -1,6 +1,6 @@
#include <SonicUtils/ELFSymbolDatabase.h>
#include <SonicUtils/LogManager.h>
#include <SonicUtils/Common/MathUtils.h>
#include <FEXCore/Utils/ELFSymbolDatabase.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Utils/Common/MathUtils.h>
#include <cstring>
#include <elf.h>

View File

@ -1,4 +1,4 @@
#include <SonicUtils/LogManager.h>
#include <FEXCore/Utils/LogManager.h>
#include <sstream>
#include <vector>

View File

@ -1,5 +1,5 @@
#pragma once
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <stdint.h>
namespace FEXCore::HLE {

View File

@ -2,7 +2,7 @@
#include <FEXCore/IR/IntrusiveIRList.h>
#include <FEXCore/IR/IR.h>
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEXCore::IR {
class Pass;

View File

@ -1,7 +1,7 @@
#pragma once
#include "FEXCore/IR/IR.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cassert>
#include <cstddef>

View File

@ -1,19 +0,0 @@
cmake_minimum_required(VERSION 3.10)
set(NAME SonicUtils)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(SRCS
Source/ELFLoader.cpp
Source/ELFSymbolDatabase.cpp
Source/LogManager.cpp)
if (_M_X86_64)
list(APPEND SRCS Source/VM.cpp)
else()
list(APPEND SRCS Source/VM_Noop.cpp)
endif()
add_library(${NAME} STATIC ${SRCS})
target_include_directories(${NAME} PUBLIC include/)

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +0,0 @@
#include <SonicUtils/VM.h>
#include <stdint.h>
namespace SU::VM {
namespace KVM {
class NoopInstance final : public VMInstance {
public:
void SetPhysicalMemorySize(uint64_t Size) override {}
void *GetPhysicalMemoryPointer() override { return nullptr; }
void AddMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) override {}
void SetVMRIP(uint64_t VirtualAddress) override {}
bool Initialize() override { return false; }
bool SetStepping(bool Step) override { return true; }
bool Run() override { return false; }
int ExitReason() override { return -1; }
uint64_t GetFailEntryReason() override { return ~0U; }
VMInstance::RegisterState GetRegisterState() override { return {}; }
VMInstance::SpecialRegisterState GetSpecialRegisterState() override { return {}; }
void SetRegisterState(VMInstance::RegisterState &State) override {}
void SetSpecialRegisterState(VMInstance::SpecialRegisterState &State) override {}
void Debug() override {}
};
}
VMInstance* VMInstance::Create() {
return new KVM::NoopInstance{};
}
}

View File

@ -1,40 +0,0 @@
#pragma once
#include <stdint.h>
namespace SU::VM {
class VMInstance {
public:
struct RegisterState {
uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
uint64_t rip, rflags;
};
struct SpecialRegisterState {
struct {
uint64_t base;
} fs, gs;
};
static VMInstance* Create();
virtual ~VMInstance() {}
virtual void SetPhysicalMemorySize(uint64_t Size) = 0;
virtual void AddMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) = 0;
virtual void *GetPhysicalMemoryPointer() = 0;
virtual void SetVMRIP(uint64_t VirtualAddress) = 0;
virtual bool SetStepping(bool Step) = 0;
virtual bool Run() = 0;
virtual bool Initialize() = 0;
virtual int ExitReason() = 0;
virtual uint64_t GetFailEntryReason() = 0;
virtual RegisterState GetRegisterState() = 0;
virtual SpecialRegisterState GetSpecialRegisterState() = 0;
virtual void SetRegisterState(RegisterState &State) = 0;
virtual void SetSpecialRegisterState(SpecialRegisterState &State) = 0;
virtual void Debug() = 0;
};
}

View File

@ -2,7 +2,6 @@
This is the frontend application and tooling used for development and debugging of the FEXCore library.
### Dependencies
* [SonicUtils](https://github.com/Sonicadvance1/SonicUtils)
* FEXCore
* cpp-optparse
* imgui

View File

@ -6,5 +6,5 @@ set(SRCS
StringUtil.cpp)
add_library(${NAME} STATIC ${SRCS})
target_link_libraries(${NAME} cpp-optparse tiny-json json-maker)
target_link_libraries(${NAME} cpp-optparse tiny-json json-maker FEXCore)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/cpp-optparse/)

View File

@ -1,5 +1,5 @@
#include "Common/Config.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <cassert>
#include <cstring>

View File

@ -3,7 +3,7 @@
#include <string_view>
#include <unordered_map>
#include "Common/Config.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
namespace FEX::EnvLoader {

View File

@ -1,7 +1,6 @@
set(NAME CommonCore)
set(SRCS
HostFactory.cpp
VMFactory.cpp)
HostFactory.cpp)
add_library(${NAME} STATIC ${SRCS})
target_link_libraries(${NAME} FEXCore)

View File

@ -24,7 +24,7 @@
#include <xbyak/xbyak.h>
using namespace Xbyak;
namespace HostCPUFactory {
namespace HostFactory {
#ifdef _M_X86_64
class HostCore final : public FEXCore::CPU::CPUBackend, public Xbyak::CodeGenerator {
public:
@ -182,11 +182,11 @@ namespace HostCPUFactory {
return nullptr;
}
FEXCore::CPU::CPUBackend *HostCPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
FEXCore::CPU::CPUBackend *CPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
return new HostCore(CTX, Thread, false);
}
#else
FEXCore::CPU::CPUBackend *HostCPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
FEXCore::CPU::CPUBackend *CPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
LogMan::Msg::A("HostCPU factory doesn't exist for this host");
return nullptr;
}

View File

@ -1,290 +0,0 @@
#include "VM.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/CoreState.h>
#include <FEXCore/Core/CPUBackend.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Memory/SharedMem.h>
namespace VMFactory {
class VMCore final : public FEXCore::CPU::CPUBackend {
public:
explicit VMCore(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread, bool Fallback);
~VMCore() override;
std::string GetName() override { return "VM Core"; }
void* CompileCode(FEXCore::IR::IRListView<true> const *IR, FEXCore::Core::DebugData *DebugData) override;
void *MapRegion(void *HostPtr, uint64_t VirtualGuestPtr, uint64_t Size) override {
MemoryRegions.emplace_back(MemoryRegion{HostPtr, VirtualGuestPtr, Size});
LogMan::Throw::A(!IsInitialized, "Tried mapping a new VM region post initialization");
return HostPtr;
}
void Initialize() override;
void ExecuteCode(FEXCore::Core::ThreadState *Thread);
bool NeedsOpDispatch() override { return false; }
private:
FEXCore::Context::Context* CTX;
FEXCore::Core::ThreadState *ThreadState;
bool IsFallback;
void CopyHostStateToGuest();
void CopyGuestCPUToHost();
void CopyHostMemoryToGuest();
void CopyGuestMemoryToHost();
void RecalculatePML4();
struct MemoryRegion {
void *HostPtr;
uint64_t VirtualGuestPtr;
uint64_t Size;
};
std::vector<MemoryRegion> MemoryRegions;
struct PhysicalToVirtual {
uint64_t PhysicalPtr;
uint64_t GuestVirtualPtr;
void *HostPtr;
uint64_t Size;
};
std::vector<PhysicalToVirtual> PhysToVirt;
SU::VM::VMInstance *VM;
bool IsInitialized{false};
};
VMCore::~VMCore() {
delete VM;
}
VMCore::VMCore(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread, bool Fallback)
: CTX {CTX}
, ThreadState {Thread}
, IsFallback {Fallback} {
VM = SU::VM::VMInstance::Create();
}
void VMCore::Initialize() {
// Scan the mapped memory regions and see how much memory backing we need
uint64_t PhysicalMemoryNeeded {};
PhysToVirt.reserve(MemoryRegions.size());
for (auto &Region : MemoryRegions) {
PhysToVirt.emplace_back(PhysicalToVirtual{PhysicalMemoryNeeded, Region.VirtualGuestPtr, Region.HostPtr, Region.Size});
PhysicalMemoryNeeded += Region.Size;
}
LogMan::Msg::D("We need 0x%lx physical memory", PhysicalMemoryNeeded);
VM->SetPhysicalMemorySize(PhysicalMemoryNeeded);
// Map these regions in the VM
for (auto &Region : PhysToVirt) {
if (!Region.Size) continue;
VM->AddMemoryMapping(Region.GuestVirtualPtr, Region.PhysicalPtr, Region.Size);
}
// Initialize the VM with the memory mapping
VM->Initialize();
CopyHostMemoryToGuest();
// Set initial register states
CopyHostStateToGuest();
IsInitialized = true;
}
void VMCore::CopyHostMemoryToGuest() {
void *PhysBase = VM->GetPhysicalMemoryPointer();
for (auto &Region : PhysToVirt) {
void *GuestPtr = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(PhysBase) + Region.PhysicalPtr));
memcpy(GuestPtr, Region.HostPtr, Region.Size);
}
}
void VMCore::CopyGuestMemoryToHost() {
void *PhysBase = VM->GetPhysicalMemoryPointer();
for (auto &Region : PhysToVirt) {
void *GuestPtr = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(PhysBase) + Region.PhysicalPtr));
memcpy(Region.HostPtr, GuestPtr, Region.Size);
}
}
void VMCore::CopyHostStateToGuest() {
auto CompactRFlags = [](auto Arg) -> uint32_t {
uint32_t Res = 2;
for (int i = 0; i < 32; ++i) {
Res |= Arg->flags[i] << i;
}
return Res;
};
SU::VM::VMInstance::RegisterState State;
SU::VM::VMInstance::SpecialRegisterState SpecialState;
State.rax = ThreadState->State.gregs[FEXCore::X86State::REG_RAX];
State.rbx = ThreadState->State.gregs[FEXCore::X86State::REG_RBX];
State.rcx = ThreadState->State.gregs[FEXCore::X86State::REG_RCX];
State.rdx = ThreadState->State.gregs[FEXCore::X86State::REG_RDX];
State.rsi = ThreadState->State.gregs[FEXCore::X86State::REG_RSI];
State.rdi = ThreadState->State.gregs[FEXCore::X86State::REG_RDI];
State.rsp = ThreadState->State.gregs[FEXCore::X86State::REG_RSP];
State.rbp = ThreadState->State.gregs[FEXCore::X86State::REG_RBP];
State.r8 = ThreadState->State.gregs[FEXCore::X86State::REG_R8];
State.r9 = ThreadState->State.gregs[FEXCore::X86State::REG_R9];
State.r10 = ThreadState->State.gregs[FEXCore::X86State::REG_R10];
State.r11 = ThreadState->State.gregs[FEXCore::X86State::REG_R11];
State.r12 = ThreadState->State.gregs[FEXCore::X86State::REG_R12];
State.r13 = ThreadState->State.gregs[FEXCore::X86State::REG_R13];
State.r14 = ThreadState->State.gregs[FEXCore::X86State::REG_R14];
State.r15 = ThreadState->State.gregs[FEXCore::X86State::REG_R15];
State.rip = ThreadState->State.rip;
State.rflags = CompactRFlags(&ThreadState->State);
VM->SetRegisterState(State);
SpecialState.fs.base = ThreadState->State.fs;
SpecialState.gs.base = ThreadState->State.gs;
VM->SetSpecialRegisterState(SpecialState);
}
void VMCore::CopyGuestCPUToHost() {
auto UnpackRFLAGS = [](auto ThreadState, uint64_t GuestFlags) {
for (int i = 0; i < 32; ++i) {
ThreadState->flags[i] = (GuestFlags >> i) & 1;
}
};
SU::VM::VMInstance::RegisterState State;
SU::VM::VMInstance::SpecialRegisterState SpecialState;
State = VM->GetRegisterState();
SpecialState = VM->GetSpecialRegisterState();
// Copy the VM's register state to our host context
ThreadState->State.gregs[FEXCore::X86State::REG_RAX] = State.rax;
ThreadState->State.gregs[FEXCore::X86State::REG_RBX] = State.rbx;
ThreadState->State.gregs[FEXCore::X86State::REG_RCX] = State.rcx;
ThreadState->State.gregs[FEXCore::X86State::REG_RDX] = State.rdx;
ThreadState->State.gregs[FEXCore::X86State::REG_RSI] = State.rsi;
ThreadState->State.gregs[FEXCore::X86State::REG_RDI] = State.rdi;
ThreadState->State.gregs[FEXCore::X86State::REG_RSP] = State.rsp;
ThreadState->State.gregs[FEXCore::X86State::REG_RBP] = State.rbp;
ThreadState->State.gregs[FEXCore::X86State::REG_R8] = State.r8;
ThreadState->State.gregs[FEXCore::X86State::REG_R9] = State.r9;
ThreadState->State.gregs[FEXCore::X86State::REG_R10] = State.r10;
ThreadState->State.gregs[FEXCore::X86State::REG_R11] = State.r11;
ThreadState->State.gregs[FEXCore::X86State::REG_R12] = State.r12;
ThreadState->State.gregs[FEXCore::X86State::REG_R13] = State.r13;
ThreadState->State.gregs[FEXCore::X86State::REG_R14] = State.r14;
ThreadState->State.gregs[FEXCore::X86State::REG_R15] = State.r15;
ThreadState->State.rip = State.rip;
UnpackRFLAGS(&ThreadState->State, State.rflags);
ThreadState->State.fs = SpecialState.fs.base;
ThreadState->State.gs = SpecialState.gs.base;
}
static void VMExecution(FEXCore::Core::ThreadState *Thread) {
auto InternalThread = reinterpret_cast<FEXCore::Core::InternalThreadState*>(Thread);
VMCore *Core = reinterpret_cast<VMCore*>(InternalThread->CPUBackend.get());
Core->ExecuteCode(Thread);
}
static void VMExecutionFallback(FEXCore::Core::ThreadState *Thread) {
auto InternalThread = reinterpret_cast<FEXCore::Core::InternalThreadState*>(Thread);
VMCore *Core = reinterpret_cast<VMCore*>(InternalThread->FallbackBackend.get());
Core->ExecuteCode(Thread);
}
void* VMCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView<true> const *IR, FEXCore::Core::DebugData *DebugData) {
if (IsFallback)
return reinterpret_cast<void*>(VMExecutionFallback);
else
return reinterpret_cast<void*>(VMExecution);
}
void VMCore::ExecuteCode(FEXCore::Core::ThreadState *Thread) {
#if 0
auto DumpState = [this]() {
LogMan::Msg::D("RIP: 0x%016lx", ThreadState->State.rip);
LogMan::Msg::D("RAX RBX RCX RDX");
LogMan::Msg::D("0x%016lx 0x%016lx 0x%016lx 0x%016lx",
ThreadState->State.gregs[FEXCore::X86State::REG_RAX],
ThreadState->State.gregs[FEXCore::X86State::REG_RBX],
ThreadState->State.gregs[FEXCore::X86State::REG_RCX],
ThreadState->State.gregs[FEXCore::X86State::REG_RDX]);
LogMan::Msg::D("RSI RDI RSP RBP");
LogMan::Msg::D("0x%016lx 0x%016lx 0x%016lx 0x%016lx",
ThreadState->State.gregs[FEXCore::X86State::REG_RSI],
ThreadState->State.gregs[FEXCore::X86State::REG_RDI],
ThreadState->State.gregs[FEXCore::X86State::REG_RSP],
ThreadState->State.gregs[FEXCore::X86State::REG_RBP]);
LogMan::Msg::D("R8 R9 R10 R11");
LogMan::Msg::D("0x%016lx 0x%016lx 0x%016lx 0x%016lx",
ThreadState->State.gregs[FEXCore::X86State::REG_R8],
ThreadState->State.gregs[FEXCore::X86State::REG_R9],
ThreadState->State.gregs[FEXCore::X86State::REG_R10],
ThreadState->State.gregs[FEXCore::X86State::REG_R11]);
LogMan::Msg::D("R12 R13 R14 R15");
LogMan::Msg::D("0x%016lx 0x%016lx 0x%016lx 0x%016lx",
ThreadState->State.gregs[FEXCore::X86State::REG_R12],
ThreadState->State.gregs[FEXCore::X86State::REG_R13],
ThreadState->State.gregs[FEXCore::X86State::REG_R14],
ThreadState->State.gregs[FEXCore::X86State::REG_R15]);
};
#endif
CopyHostMemoryToGuest();
CopyHostStateToGuest();
VM->SetStepping(true);
if (VM->Run()) {
int ExitReason = VM->ExitReason();
// 4 = DEBUG
if (ExitReason == 4 || ExitReason == 5) {
CopyGuestCPUToHost();
CopyGuestMemoryToHost();
}
// 5 = HLT
if (ExitReason == 5) {
}
// 8 = Shutdown. Due to an unhandled error
if (ExitReason == 8) {
LogMan::Msg::E("Unhandled VM Fault");
VM->Debug();
CopyGuestCPUToHost();
}
// 9 = Failed Entry
if (ExitReason == 9) {
LogMan::Msg::E("Failed to enter VM due to: 0x%lx", VM->GetFailEntryReason());
}
}
else {
LogMan::Msg::E("VM failed to run");
}
}
FEXCore::CPU::CPUBackend *CPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
return new VMCore(CTX, Thread, false);
}
FEXCore::CPU::CPUBackend *CPUCreationFactoryFallback(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread) {
return new VMCore(CTX, Thread, true);
}
}

View File

@ -1,18 +0,0 @@
namespace FEXCore::CPU {
class CPUBackend;
}
namespace FEXCore::Context{
struct Context;
}
namespace FEXCore::Core {
struct ThreadState;
}
namespace HostCPUFactory {
FEXCore::CPU::CPUBackend *HostCPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread);
}
namespace VMFactory {
FEXCore::CPU::CPUBackend *CPUCreationFactory(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread);
FEXCore::CPU::CPUBackend *CPUCreationFactoryFallback(FEXCore::Context::Context* CTX, FEXCore::Core::ThreadState *Thread);
}

View File

@ -5,7 +5,7 @@
#include "Core/CPU/IR.h"
#include "Core/CPU/IntrusiveIRList.h"
#include "Core/CPU/HostCore/HostCore.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <ucontext.h>
#include <cassert>

View File

@ -7,13 +7,12 @@ if(NOT CMAKE_ASM_NASM_COMPILER_LOADED)
endif()
set(LIBS FEXCore Common CommonCore SonicUtils pthread)
set(LIBS FEXCore Common CommonCore pthread)
set(NAME FEXLoader)
set(SRCS ELFLoader.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -43,7 +42,6 @@ set(SRCS TestHarness.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -52,7 +50,6 @@ set(SRCS TestHarnessRunner.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -61,7 +58,6 @@ set(SRCS LockstepRunner.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -70,7 +66,6 @@ set(SRCS UnitTestGenerator.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -79,7 +74,6 @@ set(SRCS TestSingleStepHardware.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})
@ -90,7 +84,6 @@ set(SRCS
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} ${LIBS})

View File

@ -1,15 +1,14 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "CommonCore/VMFactory.h"
#include "Common/Config.h"
#include "ELFLoader.h"
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/ELFLoader.h>
#include <FEXCore/Utils/LogManager.h>
#include <cstdint>
#include <filesystem>
@ -227,9 +226,6 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DUMPIR, DumpIR());
FEXCore::Context::SetCustomCPUBackendFactory(CTX, VMFactory::CPUCreationFactory);
// FEXCore::Context::SetFallbackCPUBackendFactory(CTX, VMFactory::CPUCreationFactoryFallback);
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
FEXCore::Context::InitCore(CTX, &Loader);
FEXCore::Context::SetApplicationFile(CTX, std::filesystem::canonical(Program));

View File

@ -1,9 +1,6 @@
#pragma once
#include "Common/Config.h"
#include "Common/MathUtils.h"
#include "ELFLoader.h"
#include "ELFSymbolDatabase.h"
#include "LogManager.h"
#include <FEXCore/Core/CodeLoader.h>
#include <bitset>
@ -15,6 +12,9 @@
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Core/CoreState.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Utils/ELFLoader.h>
#include <FEXCore/Utils/ELFSymbolDatabase.h>
namespace FEX::HarnessHelper {
inline bool CompareStates(FEXCore::Core::CPUState const& State1,

View File

@ -1,15 +1,14 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "CommonCore/VMFactory.h"
#include "Common/Config.h"
#include "HarnessHelpers.h"
#include "IRLoader/Loader.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/LogManager.h>
void MsgHandler(LogMan::DebugLevels Level, char const *Message) {
const char *CharLevel{nullptr};
@ -127,7 +126,6 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_GDBSERVER, GdbServerConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ROOTFSPATH, LDPath());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_UNIFIED_MEMORY, UnifiedMemory());
FEXCore::Context::SetCustomCPUBackendFactory(CTX, VMFactory::CPUCreationFactory);
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);

View File

@ -1,5 +1,5 @@
#include "IRLoader/Loader.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <fstream>

View File

@ -5,7 +5,7 @@
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Utils/LogManager.h>
#include <string>
#include <vector>

View File

@ -1,15 +1,14 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "Common/Config.h"
#include "CommonCore/VMFactory.h"
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/CoreState.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/LogManager.h>
#include <cstdint>
#include <fcntl.h>
@ -584,10 +583,6 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SINGLESTEP, 1);
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_MAXBLOCKINST, 1);
if (CoreConfig() == 4) {
FEXCore::Context::SetCustomCPUBackendFactory(CTX, VMFactory::CPUCreationFactory);
}
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
if (ConfigELFType()) {

View File

@ -1,7 +1,5 @@
#include "Common/ArgumentLoader.h"
#include "CommonCore/VMFactory.h"
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
@ -12,6 +10,7 @@
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/LogManager.h>
#include <cassert>
#include <cstdint>
@ -65,7 +64,6 @@ int main(int argc, char **argv) {
auto SHM2 = FEXCore::SHM::AllocateSHMRegion(1ULL << 36);
auto CTX2 = FEXCore::Context::CreateNewContext();
FEXCore::Context::SetCustomCPUBackendFactory(CTX1, VMFactory::CPUCreationFactory);
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_DEFAULTCORE, FEXCore::Config::CONFIG_CUSTOM);
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_SINGLESTEP, 1);
FEXCore::Config::SetConfig(CTX1, FEXCore::Config::CONFIG_MAXBLOCKINST, 1);

View File

@ -1,8 +1,7 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "CommonCore/VMFactory.h"
#include "CommonCore/HostFactory.h"
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/CodeLoader.h>
@ -13,6 +12,7 @@
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/LogManager.h>
#include <cassert>
#include <cstdint>
@ -85,7 +85,7 @@ int main(int argc, char **argv, char **const envp) {
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_SMC_CHECKS, SMCChecksConfig());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_LOCAL_FLAGS, ABILocalFlags());
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_ABI_NO_PF, AbiNoPF());
FEXCore::Context::SetCustomCPUBackendFactory(CTX, HostCPUFactory::HostCPUCreationFactory);
FEXCore::Context::SetCustomCPUBackendFactory(CTX, HostFactory::CPUCreationFactory);
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);

View File

@ -1,16 +1,15 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "Common/Config.h"
#include "ELFLoader.h"
#include "HarnessHelpers.h"
#include "LogManager.h"
#include <FEXCore/Core/CodeLoader.h>
#include <cstdint>
#include <string>
#include <vector>
#include <sys/mman.h>
#include <FEXCore/Utils/ELFLoader.h>
#include <FEXCore/Utils/LogManager.h>
namespace FEX {
uint8_t data[] = {

View File

@ -2,12 +2,12 @@
#include "Common/EnvironmentLoader.h"
#include "Common/Config.h"
#include "LogManager.h"
#include <cstdio>
#include <limits>
#include <vector>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Debug/X86Tables.h>
#include <FEXCore/Utils/LogManager.h>
constexpr std::array<std::pair<int16_t, int16_t>, 3> Disp8Ranges = {{
{static_cast<int16_t>(-16), 16},

View File

@ -7,6 +7,5 @@ set(SRCS Opt.cpp)
add_executable(${NAME} ${SRCS})
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/External/SonicUtils/)
target_link_libraries(${NAME} FEXCore Common CommonCore SonicUtils pthread)
target_link_libraries(${NAME} FEXCore Common CommonCore pthread)

View File

@ -23,7 +23,6 @@ target_link_libraries(${NAME} PRIVATE LLVM)
target_include_directories(${NAME} PRIVATE ${LLVM_INCLUDE_DIRS})
target_include_directories(${NAME} PRIVATE ${CMAKE_SOURCE_DIR}/Source/)
target_include_directories(${NAME} PRIVATE ${CMAKE_SOURCE_DIR}/External/SonicUtils/)
target_include_directories(${NAME} PRIVATE ${CMAKE_SOURCE_DIR}/External/imgui/examples/)
target_link_libraries(${NAME} PRIVATE FEXCore Common CommonCore SonicUtils pthread LLVM epoxy glfw X11 EGL imgui tiny-json json-maker)
target_link_libraries(${NAME} PRIVATE FEXCore Common CommonCore pthread LLVM epoxy glfw X11 EGL imgui tiny-json json-maker)

View File

@ -2,7 +2,6 @@
#include "Disassembler.h"
#include "FEXImGui.h"
#include "IMGui_I.h"
#include "LogManager.h"
#include "IRLexer.h"
#include "Common/Config.h"
#include "Common/StringUtil.h"
@ -17,6 +16,7 @@
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/IR/IR.h>
#include <FEXCore/IR/IntrusiveIRList.h>
#include <FEXCore/Utils/LogManager.h>
#include <imgui.h>
#include <imgui_internal.h>

View File

@ -1,10 +1,10 @@
#include <cstring>
#include <sstream>
#include "IRLexer.h"
#include "LogManager.h"
#include "Common/StringUtil.h"
#include <FEXCore/IR/IR.h>
#include <FEXCore/Utils/LogManager.h>
namespace FEX::Debugger::IR {
bool Lexer::Lex(char const *IR) {

View File

@ -1,14 +1,12 @@
#include "Common/ArgumentLoader.h"
#include "Common/EnvironmentLoader.h"
#include "Common/Config.h"
#include "CommonCore/VMFactory.h"
#include "Tests/HarnessHelpers.h"
#include "MainWindow.h"
#include "Context.h"
#include "GLUtils.h"
#include "IMGui_I.h"
#include "DebuggerState.h"
#include "LogManager.h"
#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/Context.h>
@ -16,6 +14,7 @@
#include <FEXCore/Debug/ContextDebug.h>
#include <FEXCore/Memory/SharedMem.h>
#include <FEXCore/Utils/Event.h>
#include <FEXCore/Utils/LogManager.h>
#include <imgui.h>
#include <epoxy/gl.h>
@ -49,7 +48,6 @@ void CreateCoreCallback(char const *Filename, bool ELF) {
FEXCore::Context::AddGuestMemoryRegion(CTX, SHM);
FEXCore::Config::SetConfig(CTX, FEXCore::Config::CONFIG_DEFAULTCORE, FEX::DebuggerState::GetCoreType());
FEXCore::Context::SetFallbackCPUBackendFactory(CTX, VMFactory::CPUCreationFactoryFallback);
FEXCore::Context::InitializeContext(CTX);

View File

@ -1,17 +0,0 @@
# FEX - Virtual Machine Custom CPUBackend
---
This is a custom CPU backend that is used by the FEX frontend for its Lockstep Runner.
This is used for hardware validation of CPU emulation of the FEXCore's emulation.
## Implementation details
This is implemented using the VM helper library that is living inside of [SonicUtils](https://github.com/Sonicadvance1/SonicUtils).
The helper library sets up a VM using KVM under Linux.
## Limitations
* Only works under KVM
* I don't care about running under Windows, MacOS, or other hypervisors
* Only works under AMD
* Haven't spent time figuring out why it breaks, Intel throws a VMX invalid state entry error.
* Can't launch a bunch of instances due to memory limitations
* Each VM allocates the full VM's memory region upon initialization
* If you launch a VM with 64GB of memory then that full amount is allocated right away