diff --git a/CMakeLists.txt b/CMakeLists.txt index e783c447c..f80e4eecc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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/) diff --git a/Dockerfile b/Dockerfile index 4d7d1bff7..02d7694dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/External/FEXCore/CMakeLists.txt b/External/FEXCore/CMakeLists.txt index be0d46634..a5a3a0b0c 100644 --- a/External/FEXCore/CMakeLists.txt +++ b/External/FEXCore/CMakeLists.txt @@ -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) diff --git a/External/FEXCore/Readme.md b/External/FEXCore/Readme.md index b4f5bf3fa..70d0cb7cb 100644 --- a/External/FEXCore/Readme.md +++ b/External/FEXCore/Readme.md @@ -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) diff --git a/External/FEXCore/Source/CMakeLists.txt b/External/FEXCore/Source/CMakeLists.txt index 3cb81f2e3..4d93191fe 100644 --- a/External/FEXCore/Source/CMakeLists.txt +++ b/External/FEXCore/Source/CMakeLists.txt @@ -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) diff --git a/External/FEXCore/Source/Common/BitSet.h b/External/FEXCore/Source/Common/BitSet.h index 9dc08a8ab..e802559db 100644 --- a/External/FEXCore/Source/Common/BitSet.h +++ b/External/FEXCore/Source/Common/BitSet.h @@ -1,6 +1,6 @@ #pragma once #include "Common/MathUtils.h" -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Common/Paths.cpp b/External/FEXCore/Source/Common/Paths.cpp index 709d75053..a1247e547 100644 --- a/External/FEXCore/Source/Common/Paths.cpp +++ b/External/FEXCore/Source/Common/Paths.cpp @@ -1,5 +1,5 @@ #include "Common/Paths.h" -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Common/SoftFloat.h b/External/FEXCore/Source/Common/SoftFloat.h index 1f97479cd..e915ba021 100644 --- a/External/FEXCore/Source/Common/SoftFloat.h +++ b/External/FEXCore/Source/Common/SoftFloat.h @@ -1,5 +1,5 @@ #pragma once -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Config/Config.cpp b/External/FEXCore/Source/Interface/Config/Config.cpp index 07f46dc5c..a2afb03b4 100644 --- a/External/FEXCore/Source/Interface/Config/Config.cpp +++ b/External/FEXCore/Source/Interface/Config/Config.cpp @@ -1,4 +1,4 @@ -#include "LogManager.h" +#include #include "Interface/Context/Context.h" #include diff --git a/External/FEXCore/Source/Interface/Core/BlockCache.h b/External/FEXCore/Source/Interface/Core/BlockCache.h index 3b0e06706..8d357be69 100644 --- a/External/FEXCore/Source/Interface/Core/BlockCache.h +++ b/External/FEXCore/Source/Interface/Core/BlockCache.h @@ -1,6 +1,6 @@ #pragma once #include "Interface/Context/Context.h" -#include "LogManager.h" +#include namespace FEXCore { class BlockCache { diff --git a/External/FEXCore/Source/Interface/Core/BlockSamplingData.cpp b/External/FEXCore/Source/Interface/Core/BlockSamplingData.cpp index 0c1d84ca1..b89ed20a7 100644 --- a/External/FEXCore/Source/Interface/Core/BlockSamplingData.cpp +++ b/External/FEXCore/Source/Interface/Core/BlockSamplingData.cpp @@ -1,5 +1,5 @@ #include "Interface/Core/BlockSamplingData.h" -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Core/CPUID.h b/External/FEXCore/Source/Interface/Core/CPUID.h index 4065cbdd8..f13299f3b 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.h +++ b/External/FEXCore/Source/Interface/Core/CPUID.h @@ -2,8 +2,6 @@ #include #include -#include "LogManager.h" - namespace FEXCore { namespace Context { struct Context; diff --git a/External/FEXCore/Source/Interface/Core/Frontend.cpp b/External/FEXCore/Source/Interface/Core/Frontend.cpp index 2afa80d57..f8648e8a3 100644 --- a/External/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/External/FEXCore/Source/Interface/Core/Frontend.cpp @@ -1,13 +1,13 @@ #include "Interface/Context/Context.h" #include "Interface/Core/Frontend.h" #include "Interface/Core/InternalThreadState.h" -#include "LogManager.h" #include #include #include #include #include +#include namespace FEXCore::Frontend { using namespace FEXCore::X86Tables; diff --git a/External/FEXCore/Source/Interface/Core/GdbServer.cpp b/External/FEXCore/Source/Interface/Core/GdbServer.cpp index a94f36dc4..a0bc792fb 100644 --- a/External/FEXCore/Source/Interface/Core/GdbServer.cpp +++ b/External/FEXCore/Source/Interface/Core/GdbServer.cpp @@ -8,7 +8,7 @@ #include #include "Common/NetStream.h" #include "Common/SoftFloat.h" -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp index ab6f82085..b3df4f816 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -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 #include #include diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 05fcdade8..dd9929c35 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -9,7 +9,7 @@ #include #include -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp b/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp index 54fcf40d8..615744f5f 100644 --- a/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp +++ b/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp @@ -3,7 +3,7 @@ #include "Interface/Core/SignalDelegator.h" #include -#include +#include #include diff --git a/External/FEXCore/Source/Interface/Core/X86DebugInfo.cpp b/External/FEXCore/Source/Interface/Core/X86DebugInfo.cpp index 28d1a2758..54713b2f3 100644 --- a/External/FEXCore/Source/Interface/Core/X86DebugInfo.cpp +++ b/External/FEXCore/Source/Interface/Core/X86DebugInfo.cpp @@ -1,6 +1,6 @@ #ifndef NDEBUG #include -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Core/X86Tables.cpp b/External/FEXCore/Source/Interface/Core/X86Tables.cpp index 4d98156f5..21e4905ea 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables.cpp +++ b/External/FEXCore/Source/Interface/Core/X86Tables.cpp @@ -1,4 +1,4 @@ -#include "LogManager.h" +#include #include #include diff --git a/External/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h b/External/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h index 99b6b38d2..91e7ab1dd 100644 --- a/External/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h +++ b/External/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h @@ -1,7 +1,7 @@ #pragma once #include -#include "LogManager.h" +#include namespace FEXCore::X86Tables { diff --git a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp index e42f0dd5b..1c1c01360 100644 --- a/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp +++ b/External/FEXCore/Source/Interface/HLE/EmulatedFiles/EmulatedFiles.cpp @@ -1,6 +1,6 @@ #include #include -#include "LogManager.h" +#include #include "FEXCore/Core/CodeLoader.h" #include "Interface/Context/Context.h" diff --git a/External/FEXCore/Source/Interface/HLE/FileManagement.cpp b/External/FEXCore/Source/Interface/HLE/FileManagement.cpp index c6ed3fd6f..a14eef870 100644 --- a/External/FEXCore/Source/Interface/HLE/FileManagement.cpp +++ b/External/FEXCore/Source/Interface/HLE/FileManagement.cpp @@ -1,7 +1,7 @@ -#include "LogManager.h" - #include "Interface/Context/Context.h" #include "Interface/HLE/FileManagement.h" + +#include #include #include #include diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls.cpp index fb4378b7d..eebcf886c 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls.cpp @@ -1,3 +1,4 @@ +#include #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 #include #include diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/NotImplemented.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls/NotImplemented.cpp index a74abe920..a9f6f3bb7 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/NotImplemented.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/NotImplemented.cpp @@ -1,7 +1,7 @@ +#include #include "Interface/HLE/Syscalls.h" #include "Interface/HLE/x64/Syscalls.h" #include "Interface/HLE/x32/Syscalls.h" -#include "LogManager.h" #include #include diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp index 27053307f..61e232de5 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp @@ -1,9 +1,9 @@ +#include + #include "Interface/HLE/Syscalls.h" #include "Interface/HLE/x64/Syscalls.h" #include "Interface/HLE/x32/Syscalls.h" -#include "LogManager.h" - #include #include diff --git a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp index 4f72208d0..b782e44c3 100644 --- a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp +++ b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp @@ -1,5 +1,5 @@ +#include #include "Thunks.h" -#include #include "stdio.h" #include @@ -10,7 +10,6 @@ #include #include "Interface/Core/InternalThreadState.h" #include "FEXCore/Core/X86Enums.h" -#include #include #include @@ -127,4 +126,4 @@ namespace FEXCore { ThunkHandler* ThunkHandler::Create() { return new ThunkHandler_impl(); } -} \ No newline at end of file +} diff --git a/External/FEXCore/Source/Interface/HLE/x32/NotImplemented.cpp b/External/FEXCore/Source/Interface/HLE/x32/NotImplemented.cpp index 55aad1a2f..daf6b4465 100644 --- a/External/FEXCore/Source/Interface/HLE/x32/NotImplemented.cpp +++ b/External/FEXCore/Source/Interface/HLE/x32/NotImplemented.cpp @@ -1,6 +1,6 @@ #include "Interface/HLE/Syscalls.h" #include "Interface/HLE/x32/Syscalls.h" -#include "LogManager.h" +#include namespace FEXCore::HLE::x32 { #define REGISTER_SYSCALL_NOT_IMPL_X32(name) REGISTER_SYSCALL_IMPL_X32(name, [](FEXCore::Core::InternalThreadState *Thread) -> uint64_t { \ diff --git a/External/FEXCore/Source/Interface/HLE/x32/Syscalls.cpp b/External/FEXCore/Source/Interface/HLE/x32/Syscalls.cpp index 1e96ed190..9b41da76b 100644 --- a/External/FEXCore/Source/Interface/HLE/x32/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/x32/Syscalls.cpp @@ -5,7 +5,7 @@ #include "Interface/HLE/Syscalls.h" -#include "LogManager.h" +#include namespace FEXCore::HLE { void RegisterEpoll(); diff --git a/External/FEXCore/Source/Interface/HLE/x64/NotImplemented.cpp b/External/FEXCore/Source/Interface/HLE/x64/NotImplemented.cpp index ea95ae07f..54dd391a1 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/NotImplemented.cpp +++ b/External/FEXCore/Source/Interface/HLE/x64/NotImplemented.cpp @@ -1,6 +1,6 @@ +#include #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 { \ diff --git a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp index 4097f8a19..ef2eec9d1 100644 --- a/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp +++ b/External/FEXCore/Source/Interface/HLE/x64/Syscalls.cpp @@ -1,9 +1,8 @@ -#include - #include "Interface/HLE/Syscalls.h" #include "Interface/HLE/x64/Syscalls.h" -#include "LogManager.h" +#include +#include namespace FEXCore::HLE { void RegisterEpoll(); diff --git a/External/FEXCore/Source/Interface/IR/IR.cpp b/External/FEXCore/Source/Interface/IR/IR.cpp index b55ed6ed2..0104e49a3 100644 --- a/External/FEXCore/Source/Interface/IR/IR.cpp +++ b/External/FEXCore/Source/Interface/IR/IR.cpp @@ -1,6 +1,6 @@ #include #include -#include "LogManager.h" +#include #include "Interface/IR/Passes/RegisterAllocationPass.h" namespace FEXCore::IR { diff --git a/External/FEXCore/Source/Interface/IR/Passes/SyscallOptimization.cpp b/External/FEXCore/Source/Interface/IR/Passes/SyscallOptimization.cpp index 27783fc24..6140b2731 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/SyscallOptimization.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/SyscallOptimization.cpp @@ -2,7 +2,7 @@ #include "Interface/IR/PassManager.h" #include "Interface/Core/OpcodeDispatcher.h" -#include "LogManager.h" +#include namespace FEXCore::IR { diff --git a/External/FEXCore/Source/Interface/Memory/MemMapper.cpp b/External/FEXCore/Source/Interface/Memory/MemMapper.cpp index 26a5f34cf..9dc1c4308 100644 --- a/External/FEXCore/Source/Interface/Memory/MemMapper.cpp +++ b/External/FEXCore/Source/Interface/Memory/MemMapper.cpp @@ -1,4 +1,4 @@ -#include "LogManager.h" +#include #include "Interface/Memory/MemMapper.h" #include #include diff --git a/External/FEXCore/Source/Interface/Memory/SharedMem.cpp b/External/FEXCore/Source/Interface/Memory/SharedMem.cpp index b56b0a372..d0015ba3e 100644 --- a/External/FEXCore/Source/Interface/Memory/SharedMem.cpp +++ b/External/FEXCore/Source/Interface/Memory/SharedMem.cpp @@ -1,4 +1,4 @@ -#include "LogManager.h" +#include #include "Interface/Memory/SharedMem.h" #include #include diff --git a/External/SonicUtils/Source/ELFLoader.cpp b/External/FEXCore/Source/Utils/ELFLoader.cpp similarity index 99% rename from External/SonicUtils/Source/ELFLoader.cpp rename to External/FEXCore/Source/Utils/ELFLoader.cpp index 3fdcfbf24..2a8bde262 100644 --- a/External/SonicUtils/Source/ELFLoader.cpp +++ b/External/FEXCore/Source/Utils/ELFLoader.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include #include diff --git a/External/SonicUtils/Source/ELFSymbolDatabase.cpp b/External/FEXCore/Source/Utils/ELFSymbolDatabase.cpp similarity index 98% rename from External/SonicUtils/Source/ELFSymbolDatabase.cpp rename to External/FEXCore/Source/Utils/ELFSymbolDatabase.cpp index eb43e2afa..52eedec93 100644 --- a/External/SonicUtils/Source/ELFSymbolDatabase.cpp +++ b/External/FEXCore/Source/Utils/ELFSymbolDatabase.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include diff --git a/External/SonicUtils/Source/LogManager.cpp b/External/FEXCore/Source/Utils/LogManager.cpp similarity index 97% rename from External/SonicUtils/Source/LogManager.cpp rename to External/FEXCore/Source/Utils/LogManager.cpp index 4a18c6114..36174cc26 100644 --- a/External/SonicUtils/Source/LogManager.cpp +++ b/External/FEXCore/Source/Utils/LogManager.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/External/FEXCore/include/FEXCore/HLE/SyscallVisitor.h b/External/FEXCore/include/FEXCore/HLE/SyscallVisitor.h index c01106f2e..f55c4f5e3 100644 --- a/External/FEXCore/include/FEXCore/HLE/SyscallVisitor.h +++ b/External/FEXCore/include/FEXCore/HLE/SyscallVisitor.h @@ -1,5 +1,5 @@ #pragma once -#include "LogManager.h" +#include #include namespace FEXCore::HLE { diff --git a/External/FEXCore/include/FEXCore/IR/IREmitter.h b/External/FEXCore/include/FEXCore/IR/IREmitter.h index 9d0deca2b..addcfd6f0 100644 --- a/External/FEXCore/include/FEXCore/IR/IREmitter.h +++ b/External/FEXCore/include/FEXCore/IR/IREmitter.h @@ -2,7 +2,7 @@ #include #include -#include "LogManager.h" +#include namespace FEXCore::IR { class Pass; diff --git a/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h b/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h index c3e5da13a..d61151f34 100644 --- a/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h +++ b/External/FEXCore/include/FEXCore/IR/IntrusiveIRList.h @@ -1,7 +1,7 @@ #pragma once #include "FEXCore/IR/IR.h" -#include "LogManager.h" +#include #include #include diff --git a/External/SonicUtils/include/SonicUtils/Common/MathUtils.h b/External/FEXCore/include/FEXCore/Utils/Common/MathUtils.h similarity index 100% rename from External/SonicUtils/include/SonicUtils/Common/MathUtils.h rename to External/FEXCore/include/FEXCore/Utils/Common/MathUtils.h diff --git a/External/SonicUtils/include/SonicUtils/ELFLoader.h b/External/FEXCore/include/FEXCore/Utils/ELFLoader.h similarity index 100% rename from External/SonicUtils/include/SonicUtils/ELFLoader.h rename to External/FEXCore/include/FEXCore/Utils/ELFLoader.h diff --git a/External/SonicUtils/include/SonicUtils/ELFSymbolDatabase.h b/External/FEXCore/include/FEXCore/Utils/ELFSymbolDatabase.h similarity index 100% rename from External/SonicUtils/include/SonicUtils/ELFSymbolDatabase.h rename to External/FEXCore/include/FEXCore/Utils/ELFSymbolDatabase.h diff --git a/External/SonicUtils/include/SonicUtils/LogManager.h b/External/FEXCore/include/FEXCore/Utils/LogManager.h similarity index 100% rename from External/SonicUtils/include/SonicUtils/LogManager.h rename to External/FEXCore/include/FEXCore/Utils/LogManager.h diff --git a/External/SonicUtils/CMakeLists.txt b/External/SonicUtils/CMakeLists.txt deleted file mode 100644 index 64383fdf3..000000000 --- a/External/SonicUtils/CMakeLists.txt +++ /dev/null @@ -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/) diff --git a/External/SonicUtils/Source/VM.cpp b/External/SonicUtils/Source/VM.cpp deleted file mode 100644 index c9b405592..000000000 --- a/External/SonicUtils/Source/VM.cpp +++ /dev/null @@ -1,1165 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -inline uint64_t AlignUp(uint64_t value, uint64_t size) { - return value + (size - value % size) % size; -}; - -class Memmap { -public: - bool AllocateSHMRegion(size_t Size); - void DeallocateSHMRegion(); - int GetFD() { return SHMfd; } - void *MapRegionFlags(size_t Offset, size_t Size, uint32_t flags, bool Fixed); - void *MapRegion(size_t Offset, size_t Size, bool Fixed); - - void *MapRegionMirror(size_t BasePtr, size_t Offset, size_t Size, uint32_t flags, bool Fixed); - void *FakeMapRegion(size_t Offset); - -private: - int SHMfd; - size_t SHMSize; - void *Base; -}; -void *Memmap::MapRegion(size_t Offset, size_t Size, bool Fixed) { - return MapRegionFlags(Offset, Size, PROT_READ | PROT_WRITE, Fixed); -} - -void *Memmap::MapRegionFlags(size_t Offset, size_t Size, uint32_t flags, bool Fixed) { - return mmap(0, Size, flags, MAP_ANONYMOUS | MAP_SHARED, -1, 0); - uintptr_t PtrOffset = reinterpret_cast(Base) + Offset; - void *Ptr = mmap(reinterpret_cast(PtrOffset), Size, flags, - MAP_SHARED | (Fixed ? MAP_FIXED : 0), SHMfd, Offset); - - if (Ptr == MAP_FAILED) { - LogMan::Msg::A("Failed to map memory region [0x%lx, 0x%lx) - %d", Offset, Size, Fixed); - return nullptr; - } - LogMan::Msg::D("Mapped [0x%0lx, 0x%0lx) to 0x%0lx on host", Offset, Offset + Size, Ptr); - - return Ptr; -} - -void *Memmap::MapRegionMirror(size_t BasePtr, size_t Offset, size_t Size, uint32_t flags, bool Fixed) { - uintptr_t PtrOffset = reinterpret_cast(Base) + BasePtr; - void *Ptr = mmap(reinterpret_cast(PtrOffset), Size, flags, - MAP_SHARED | (Fixed ? MAP_FIXED : 0), SHMfd, Offset); - - if (Ptr == MAP_FAILED) { - LogMan::Msg::A("Failed to map memory region [0x%lx, 0x%lx) - %d", Offset, Size, Fixed); - return nullptr; - } - LogMan::Msg::D("Mapped [0x%0lx, 0x%0lx) to 0x%0lx on host", Offset, Offset + Size, Ptr); - - return Ptr; -} - -void *Memmap::FakeMapRegion(size_t Offset) { - uintptr_t PtrOffset = reinterpret_cast(Base) + Offset; - return reinterpret_cast(PtrOffset); -} - -bool Memmap::AllocateSHMRegion(size_t Size) { - const std::string SHMName = "VM" + std::to_string(getpid()); - SHMfd = shm_open(SHMName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - if (SHMfd == -1) { - LogMan::Msg::E("Couldn't open SHM"); - return false; - } - - // Unlink the shm file immediately to not leave it around - shm_unlink(SHMName.c_str()); - - // Extend the SHM to the size we requested - if (ftruncate(SHMfd, Size) != 0) { - LogMan::Msg::E("Couldn't set SHM size"); - return false; - } - - SHMSize = Size; - Base = MapRegion(0, SHMSize, false); - - return true; -} - -void Memmap::DeallocateSHMRegion() { - close(SHMfd); -} - -namespace SU::VM { - - namespace KVM { - struct MemoryRegion { - uint64_t VirtualBase; - uint64_t PhysicalBase; - uint64_t RegionSize; - void *MappedLocation; - }; - - // This only supports 4k pages - class PML4Control final { - public: - // Set the virtual address that this lives in - void SetVirtualAddress(uint64_t Address) { PML4VirtualAddress = Address; } - void SetPhysicalAddress(uint64_t Address) { PML4PhysicalAddress = Address; } - - // Get the virtual address that the PML4 tables start at - // They are mapped linearly in memory - uint64_t GetVirtualAddress() const { return PML4VirtualAddress; } - uint64_t GetPhysicalAddress() const { return PML4PhysicalAddress; } - - // Sets the pointer to the tables - // This is the host pointer that is visible on both Host and Guest - void SetTablePointer(uint64_t *Address) { Tables = Address; } - - // We need to calculate our PML4 table size - // PTE = (MaxVirtualMemory / PAGE_SIZE) * Entry_Size - // PDE = (MaxVirtualMemory >> 21) * Entry_Size - // PDPE = (MaxVirtualMemory >> 30) * Entry_Size - // PML4 = (MaxVirtualMemory >> 39) * Entry_Size - uint64_t GetPML4Size() const { - return (AlignUp(MaxVirtualMemory >> 39, 512) * // PML4 - 512 * // PDPE - 512 + // PDE - AlignUp(MaxVirtualMemory / PAGE_SIZE, 512)) * ENTRY_SIZE; - } - - void AddMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) { - MemoryMappings.emplace_back(MemoryRegion{VirtualAddress, PhysicalAddress, Size}); - } - - uint64_t FindPhysicalInVirtual(uint64_t VirtualAddr) { - for (auto Mapping : MemoryMappings) { - if (VirtualAddr >= Mapping.VirtualBase && - VirtualAddr < (Mapping.VirtualBase + Mapping.RegionSize)) { - return Mapping.PhysicalBase + (VirtualAddr - Mapping.VirtualBase); - } - } - return ~0ULL; - } - - uint64_t FindPhysicalFromTables(uint64_t VirtualAddr) { - uint64_t *PML4_Table = (uint64_t*)((uintptr_t)Tables + 4096 * 0); - uint64_t *PDPE_Table = (uint64_t*)((uintptr_t)Tables + 4096 * 1); - uint64_t *PDE_Table = (uint64_t*)((uintptr_t)Tables + 4096 * 2); - uint64_t *PTE_Table = (uint64_t*)((uintptr_t)Tables + 4096 * 3); - - uint64_t Physical_PML4_Table = PML4PhysicalAddress + 4096 * 0; - uint64_t Physical_PDPE_Table = PML4PhysicalAddress + 4096 * 1; - uint64_t Physical_PDE_Table = PML4PhysicalAddress + 4096 * 2; - uint64_t Physical_PTE_Table = PML4PhysicalAddress + 4096 * 3; - - uint64_t PML4_Offset = (VirtualAddr >> 39) & 0x1FF; - uint64_t PDPE_Offset = (VirtualAddr >> 30) & 0x1FF; - uint64_t PDE_Offset = (VirtualAddr >> 21) & 0x1FF; - uint64_t PTE_Offset = (VirtualAddr >> 12) & 0x1FF; - uint64_t Physical_Offset = (VirtualAddr) & 0xFFF; - return PTE_Table[PTE_Offset] & ~0xFFF; - } - - void SetupTables(); - - private: - - uint64_t GetPML4TableOffset(uint64_t Address) const { - // There is only one PML4 table - return 0; - } - - uint64_t GetPML4EntryOffset(uint64_t Address) const { - LogMan::Throw::A(Address < MaxVirtualMemory, "Address of 0x%lx is larger than our max virtual address size", Address); - - // First get the segment for the PML4 - uint64_t PML4Segment = (Address >> 39) & 0x1FF; - - // Each entry is 8 bytes - // So the table entry is just the segment multiplied by the entry size - return PML4Segment * ENTRY_SIZE; - } - - uint64_t GetPDPEEntryOffset(uint64_t Address) const { - LogMan::Throw::A(Address < MaxVirtualMemory, "Address of 0x%lx is larger than our max virtual address size", Address); - - // Get the segment for the PDPE - uint64_t PDPESegment = (Address >> 30) & 0x1FF; - - // Each entry is 8 bytes - // So the table entry is just the segment multiplied by the entry size - return PDPESegment * ENTRY_SIZE; - } - - uint64_t GetPDEEntryOffset(uint64_t Address) const { - LogMan::Throw::A(Address < MaxVirtualMemory, "Address of 0x%lx is larger than our max virtual address size", Address); - - // Get the segment for the PDE - uint64_t PDESegment = (Address >> 21) & 0x1FF; - - // Each entry is 8 bytes - // So the table entry is just the segment multiplied by the entry size - return PDESegment * ENTRY_SIZE; - } - - uint64_t GetPTEEntryOffset(uint64_t Address) const { - LogMan::Throw::A(Address < MaxVirtualMemory, "Address of 0x%lx is larger than our max virtual address size", Address); - - // Get the segment for the PTE - uint64_t PTESegment = (Address >> 12) & 0x1FF; - - // Each entry is 8 bytes - // So the table entry is just the segment multiplied by the entry size - return PTESegment * ENTRY_SIZE; - } - - uint64_t GetPDPETableOffset(uint64_t Address) const { - uint64_t PDPETables = GetPDPEBase((uint64_t)0ULL); - - // We get the PML4 Entry number - uint64_t PML4Entry = GetPML4EntryOffset(Address) / ENTRY_SIZE; - - // The PML4 entry number selects which PDE table we use - return PDPETables + PML4Entry * 512; - } - - uint64_t GetPDETableOffset(uint64_t Address) const { - uint64_t PDETables = GetPDEBase((uint64_t)0ULL); - - // We get the PML4 Entry number - uint64_t PML4Entry = GetPML4EntryOffset(Address) / ENTRY_SIZE; - - // We get the PDPE Entry number - uint64_t PDPEEntry = GetPDPEEntryOffset(Address) / ENTRY_SIZE; - - return PDETables + PML4Entry * 512 + PDPEEntry * 512; - } - - uint64_t GetPTETableOffset(uint64_t Address) const { - uint64_t PTETables = GetPTEBase((uint64_t)0ULL); - - // We get the PML4 Entry number - uint64_t PML4Entry = GetPML4EntryOffset(Address) / ENTRY_SIZE; - - // We get the PDPE Entry number - uint64_t PDPEEntry = GetPDPEEntryOffset(Address) / ENTRY_SIZE; - - // We get the PDE Entry number - uint64_t PDEEntry = GetPDEEntryOffset(Address) / ENTRY_SIZE; - - return PTETables + PML4Entry * 512 + PDPEEntry * 512 + PDEEntry * 512; - } - - // PML4 base is just at our base pointer location - template - T GetPML4Base(T Base) const { - return Base; - } - - uint64_t GetPML4TableEntryCount() const { - return AlignUp(MaxVirtualMemory >> 39, 512); - } - - template - T GetPDPEBase(T Base) const { - uintptr_t Ptr = reinterpret_cast(Base); - - // PDPE is just past our PML4 table - // PML4 is the top level table, which is only 1 table in size - Ptr += GetPML4TableEntryCount() * ENTRY_SIZE; - - return reinterpret_cast(Ptr); - } - - // The PDPE table size is the number of PML4 entries - // multiplied by the number of PDPE entries - uint64_t GetPDPETableEntryCount() const { - return GetPML4TableEntryCount() * 512; - } - - template - T GetPDEBase(T Base) const { - uintptr_t Ptr = reinterpret_cast(Base); - - // PML4 is the top level table, which is only 1 table in size - // PDPE is just past our PML4 table - // PDE is just past our PDPE table - Ptr += GetPML4TableEntryCount() * ENTRY_SIZE + - GetPDPETableEntryCount() * ENTRY_SIZE; - - return reinterpret_cast(Ptr); - } - - // The PDE table size is the number of PDPE entries - // multiplied by the number of PDE entries - uint64_t GetPDETableEntryCount() const { - return GetPDPETableEntryCount() * 512; - } - - template - T GetPTEBase(T Base) const { - uintptr_t Ptr = reinterpret_cast(Base); - - // PML4 is the top level table, which is only 1 table in size - // PDPE is just past our PML4 table - // PDE is just past our PDPE table - // PTE is just past our PDE table - Ptr += GetPML4TableEntryCount() * ENTRY_SIZE + - GetPDPETableEntryCount() * ENTRY_SIZE + - GetPDETableEntryCount() * ENTRY_SIZE; - - return reinterpret_cast(Ptr); - } - - // The PTE table size is the maximum size of our virtual memory range - // divided by page size, Aligned to the max table size - uint64_t GetPTETableEntryCount() const { - return AlignUp(MaxVirtualMemory / PAGE_SIZE, 512); - } - - std::vector MemoryMappings; - uint64_t PML4VirtualAddress{}; - uint64_t PML4PhysicalAddress{}; - uint64_t *Tables; - constexpr static uint64_t PAGE_SIZE = 4096; - constexpr static uint64_t ENTRY_SIZE = 8; - constexpr static uint64_t MaxVirtualMemory = (1ULL << 36); - }; - - void PML4Control::SetupTables() { - // Walk throw all of our provided mapping regions and set them up in the tables - // We will always map virtual memory to physical memory linearly - // Nothing special going on here - - uint64_t TotalPages{}; - - for (auto &Region : MemoryMappings) - { - uint64_t VirtualAddress = Region.VirtualBase; - uint64_t PhysicalAddress = Region.PhysicalBase; - - if (VirtualAddress & (PAGE_SIZE - 1)) { - fprintf(stderr, "Memory Region virtual address [0x%lx, 0x%lx) needs to be page aligned\n", VirtualAddress, VirtualAddress + Region.RegionSize); - } - if (PhysicalAddress & (PAGE_SIZE - 1)) { - fprintf(stderr, "Memory Region Physical address [0x%lx, 0x%lx) needs to be page aligned\n", PhysicalAddress, PhysicalAddress + Region.RegionSize); - } - if (Region.RegionSize & (PAGE_SIZE - 1)) { - fprintf(stderr, "Memory region [0x%lx, 0x%lx) size 0x%lx is not page aligned\n", VirtualAddress, VirtualAddress + Region.RegionSize, Region.RegionSize); - } - fprintf(stderr, "[Virt] Memory [0x%lx, 0x%lx) mapped to physical address 0x%lx\n", VirtualAddress, VirtualAddress + Region.RegionSize, PhysicalAddress); - - uint64_t NumPages = Region.RegionSize / PAGE_SIZE; - TotalPages += NumPages; - - // Now walk the tables for all the pages and map the table - for (uint64_t i = 0; i < NumPages; ++i) { - uint64_t OffsetVirtual = VirtualAddress + (i * PAGE_SIZE); - uint64_t OffsetPhysical = PhysicalAddress + (i * PAGE_SIZE); - - uint64_t PML4_Table_Offset = GetPML4TableOffset(OffsetVirtual); - uint64_t PDPE_Table_Offset = GetPDPETableOffset(OffsetVirtual); - uint64_t PDE_Table_Offset = GetPDETableOffset(OffsetVirtual); - uint64_t PTE_Table_Offset = GetPTETableOffset(OffsetVirtual); - - // These don't calculate which table they end up in - // Just the offset in to the table - uint64_t PML4_Entry_Offset = GetPML4EntryOffset(OffsetVirtual); - uint64_t PDPE_Entry_Offset = GetPDPEEntryOffset(OffsetVirtual); - uint64_t PDE_Entry_Offset = GetPDEEntryOffset(OffsetVirtual); - uint64_t PTE_Entry_Offset = GetPTEEntryOffset(OffsetVirtual); - - uint64_t PML4_Entry = GetPML4EntryOffset(OffsetVirtual) / ENTRY_SIZE; - uint64_t PDPE_Entry = GetPDPEEntryOffset(OffsetVirtual) / ENTRY_SIZE; - uint64_t PDE_Entry = GetPDEEntryOffset(OffsetVirtual) / ENTRY_SIZE; - uint64_t PTE_Entry = GetPTEEntryOffset(OffsetVirtual) / ENTRY_SIZE; - - uint64_t PDPE_Selected_Table = PML4PhysicalAddress + PDPE_Table_Offset; - uint64_t PDE_Selected_Table = PML4PhysicalAddress + PDE_Table_Offset; - uint64_t PTE_Selected_Table = PML4PhysicalAddress + PTE_Table_Offset; - - uint64_t *PML4_Table = (uint64_t*)((uintptr_t)Tables + PML4_Table_Offset); - uint64_t *PDPE_Table = (uint64_t*)((uintptr_t)Tables + PDPE_Table_Offset); - uint64_t *PDE_Table = (uint64_t*)((uintptr_t)Tables + PDE_Table_Offset); - uint64_t *PTE_Table = (uint64_t*)((uintptr_t)Tables + PTE_Table_Offset); - - // Set the PML4_table to point to Base of the PDPE table offset - PML4_Table[PML4_Entry] = PDPE_Selected_Table | 0b111; - // Continue mapping - PDPE_Table[PDPE_Entry] = PDE_Selected_Table | 0b0000'0000'0111; - // Continue mapping - PDE_Table[PDE_Entry] = PTE_Selected_Table | 0b111; - // This now maps directly to the region's physical address - PTE_Table[PTE_Entry] = OffsetPhysical | 0b0001'00000011; - } - } - } - - class KVMInstance final : public VMInstance { - public: - virtual ~KVMInstance(); - void SetPhysicalMemorySize(uint64_t Size) override { PhysicalUserMemorySize = Size; } - void *GetPhysicalMemoryPointer() override { return VM_Addr; } - - void AddMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) override { - PML4.AddMemoryMapping(VirtualAddress, PhysicalAddress, Size); - } - - void SetVMRIP(uint64_t VirtualAddress) override; - bool Initialize() override; - bool SetStepping(bool Step) override; - bool Run() override; - int ExitReason() override { return VCPUMemory->exit_reason; } - uint64_t GetFailEntryReason() override { return VCPUMemory->fail_entry.hardware_entry_failure_reason; } - VMInstance::RegisterState GetRegisterState() override; - VMInstance::SpecialRegisterState GetSpecialRegisterState() override; - - void SetRegisterState(VMInstance::RegisterState &State) override; - void SetSpecialRegisterState(VMInstance::SpecialRegisterState &State) override; - void Debug() override; - - private: - // FDs - int KVM_FD{-1}; - int VM_FD{-1}; - int VCPU_FD{-1}; - - constexpr static uint64_t VirtualBase = 0x0000'0001'0000'0000; - // This is the size of the user's memory region - uint64_t PhysicalUserMemorySize; - - // This is the actual size of the physical memory including additional structures that need to live in mem - uint64_t PhysicalMemorySize; - PML4Control PML4; - - kvm_run *VCPUMemory; - uint32_t MemorySlot{}; - - // Allocated memory - void *PML4_Addr; - void *VM_Addr; - MemoryRegion IDTRegion { - .RegionSize = 4096, - }; - MemoryRegion GDTRegion { - .RegionSize = 16 * 4096, - }; - MemoryRegion APICRegion { - .RegionSize = 4096, - }; - bool SetupCPUInLongMode(); - bool SetupMemory(); - Memmap Mapper; - }; - - KVMInstance::~KVMInstance() { - // Close all of our descriptors - close(VCPU_FD); - close(VM_FD); - close(KVM_FD); - - // unmap all of our pointers - munmap(VM_Addr, PhysicalMemorySize); - munmap(PML4_Addr, PML4.GetPML4Size()); - munmap(IDTRegion.MappedLocation, IDTRegion.RegionSize); - } - - bool KVMInstance::SetupMemory() { - // ============================ - // Physical Memory map currently - // ============================ - - // Everything is mapped linearly from [0, end) - // [UserMemory, UserMemory + Size) - // [IDTRegion, IDTRegion + Size) - // [GDTRegion, GDTRegion + Size) - // [APICRegion, APICRegion + Size) - // [PML4, PML4 + Size) - // - // ============================ - // Virtual Memory map currently - // ============================ - // Virtual memory map directly mirrors the physical mapping - - uint64_t PhysicalMemoryBase = 0; - // Calculate the amount of physical memory backing we need - PhysicalMemorySize = PhysicalUserMemorySize; - - IDTRegion.PhysicalBase = PhysicalMemorySize; - IDTRegion.VirtualBase = VirtualBase + IDTRegion.PhysicalBase; // Mapped to the same place - PhysicalMemorySize += IDTRegion.RegionSize; - - GDTRegion.PhysicalBase = PhysicalMemorySize; - GDTRegion.VirtualBase = VirtualBase + GDTRegion.PhysicalBase; // Mapped to the same place - PhysicalMemorySize += GDTRegion.RegionSize; - - APICRegion.PhysicalBase = PhysicalMemorySize; - APICRegion.VirtualBase = VirtualBase + APICRegion.PhysicalBase; // Mapped to the same place - PhysicalMemorySize += APICRegion.RegionSize; - - // Physical and virtual map directly atm - PML4.SetPhysicalAddress(PhysicalMemorySize); - PML4.SetVirtualAddress(VirtualBase + PhysicalMemorySize); - - PhysicalMemorySize += PML4.GetPML4Size(); - - // Align up just to make sure we are page aligned - PhysicalMemorySize = AlignUp(PhysicalMemorySize, 4096); - - Mapper.AllocateSHMRegion(1ULL << 37); - - // Physical memory is just [0, PhysicalMemorySize) - // Just map physical zero to virtual zero - // This maps both our user set memory region and our PML4 region to be accessable - PML4.AddMemoryMapping(VirtualBase, 0, PhysicalMemorySize); - - // Set up user memory - { - // Allocate the memory for the user physical memory - VM_Addr = Mapper.MapRegion(0, PhysicalUserMemorySize, true); - LogMan::Throw::A(VM_Addr != (void*)-1ULL, "Couldn't Allocate"); - - // Map this memory to the guest VM - kvm_userspace_memory_region Region = { - .slot = MemorySlot++, - .flags = 0, - .guest_phys_addr = PhysicalMemoryBase, - .memory_size = PhysicalUserMemorySize, - .userspace_addr = (uint64_t)VM_Addr, - }; - - if (ioctl(VM_FD, KVM_SET_USER_MEMORY_REGION, &Region) == -1) { - printf("Couldn't set guestPD region\n"); - return false; - } - - // The PM4L setup with handle the page mapping - } - - // Set up PML4 - { - // Allocate the host facing PML4 memory - PML4_Addr = Mapper.MapRegion(PML4.GetPhysicalAddress(), PML4.GetPML4Size(), true); - LogMan::Throw::A(PML4_Addr != (void*)-1ULL, "Couldn't Allocate"); - - if (PML4_Addr == reinterpret_cast(-1ULL)) { - fprintf(stderr, "Couldn't allocate PML4 table memory"); - return false; - } - PML4.SetTablePointer(reinterpret_cast(PML4_Addr)); - - // Map this address space in to the VM - kvm_userspace_memory_region Region = { - .slot = MemorySlot++, - .flags = 0, - .guest_phys_addr = PML4.GetPhysicalAddress(), - .memory_size = PML4.GetPML4Size(), - .userspace_addr = (uint64_t)PML4_Addr, - }; - - if (ioctl(VM_FD, KVM_SET_USER_MEMORY_REGION, &Region) == -1) { - printf("Couldn't set guestPD region\n"); - return false; - } - - // Setup the tables - PML4.SetupTables(); - } - - // Set up GDT - // GDT contains SEGMENTS - { - GDTRegion.MappedLocation = Mapper.MapRegion(GDTRegion.PhysicalBase, GDTRegion.RegionSize, true); - LogMan::Throw::A(GDTRegion.MappedLocation != (void*)-1ULL, "Couldn't Allocate"); - - // Map this memory to the guest VM - kvm_userspace_memory_region Region = { - .slot = MemorySlot++, - .flags = 0, - .guest_phys_addr = GDTRegion.PhysicalBase, - .memory_size = GDTRegion.RegionSize, - .userspace_addr = (uint64_t)GDTRegion.MappedLocation, - }; - - if (ioctl(VM_FD, KVM_SET_USER_MEMORY_REGION, &Region) == -1) { - printf("Couldn't set guestPD region\n"); - return false; - } - - // Set up the table entries - union GDTSegment { - struct NullSegment { - uint32_t Unused_0; - uint32_t Unused_1; - } Null; - struct CodeSegment { - uint32_t Unused; - unsigned Unused_0 : 8; - unsigned Unused_1 : 1; - unsigned Unused_2 : 1; - unsigned C : 1; - unsigned MustBeSet: 2; - unsigned DPL : 2; - unsigned P : 1; - unsigned Unused_3 : 4; - unsigned Unused_4 : 1; - unsigned L : 1; - unsigned D : 1; - unsigned Unused_5 : 1; - unsigned Unused_6 : 8; - } Code; - struct DataSegment { - uint32_t Unused_0; - unsigned Unused_1 : 11; - unsigned DataType : 2; - unsigned Unused_2 : 2; - unsigned P : 1; - unsigned Unused_3 : 16; - } Data; - } __attribute__((packed)); - - // Even though this is still a GDT segment - // its size has increased to 64 bits which means it takes two slots - struct SystemSegment { - uint16_t SegmentLimitLow; - uint16_t BaseLow; - unsigned BaseLowMid : 8; - unsigned Type : 4; - unsigned MustBeZero_0 : 1; - unsigned DPL : 2; - unsigned P : 1; - unsigned SegmentLimitHigh : 4; - unsigned Unused_0 : 2; - unsigned G : 1; - unsigned BaseLowHigh : 8; - uint32_t BaseHigh; - unsigned Unused_1 : 8; - unsigned MustBeZero_1 : 5; - unsigned Unused_2 : 19; - } __attribute__((packed)); - - GDTSegment DefaultCodeSegment = { - .Code = { - .MustBeSet = 0b11, - }, - }; - GDTSegment DefaultDataSegment = { - .Data = { - .DataType = 0b10, - }, - }; - SystemSegment DefaultSystemSegment = {}; - - unsigned Entries = GDTRegion.RegionSize / sizeof(GDTSegment); - - GDTSegment *GuestEntries = (GDTSegment*)GDTRegion.MappedLocation; - - // Null Segment - GDTSegment NullSegment{}; - - // Data segment - GDTSegment DataSegment = DefaultDataSegment; - DataSegment.Data.P = 1; - - // Code Segment - GDTSegment CodeSegment = DefaultCodeSegment; - CodeSegment.Code.P = 1; - CodeSegment.Code.L = 1; // 64bit Code - CodeSegment.Code.D = 0; // MUST be 0 in 64bit mode. CS.D = 0 and CS.L = 1 - - // 64bit TSS segment - SystemSegment Enable64BitTSS = DefaultSystemSegment; - Enable64BitTSS.Type = 0b1001; - Enable64BitTSS.P = 1; - - unsigned CurrentOffset = 0; - - // Null segment is first - GuestEntries[CurrentOffset++] = NullSegment; - GuestEntries[CurrentOffset++] = CodeSegment; - GuestEntries[CurrentOffset++] = DataSegment; - - void *Ptr = &GuestEntries[CurrentOffset]; - CurrentOffset += 2; - memcpy(Ptr, &Enable64BitTSS, sizeof(SystemSegment)); - } - - // Set up IDT - // When an exception or interrupt occurs, the processor uses the interrupt vector number as an index in to the IDT - // IDT is used in all operating modes - // IDT contains GATES - { - IDTRegion.MappedLocation = Mapper.MapRegion(IDTRegion.PhysicalBase, IDTRegion.RegionSize, true); - LogMan::Throw::A(IDTRegion.MappedLocation != (void*)-1ULL, "Couldn't Allocate"); - - // Map this memory to the guest VM - kvm_userspace_memory_region Region = { - .slot = MemorySlot++, - .flags = 0, - .guest_phys_addr = IDTRegion.PhysicalBase, - .memory_size = IDTRegion.RegionSize, - .userspace_addr = (uint64_t)IDTRegion.MappedLocation, - }; - - if (ioctl(VM_FD, KVM_SET_USER_MEMORY_REGION, &Region) == -1) { - printf("Couldn't set guestPD region\n"); - return false; - } - - union GateDesc { - struct CallGateType { - uint16_t TargetLow; - uint16_t TargetSelector; - unsigned Unused_0 : 8; - unsigned Type : 4; - unsigned MustBeZero : 1; - unsigned DPL : 2; - unsigned P : 1; - uint16_t TargetMid; - uint32_t TargetHigh; - uint32_t Pad; - } Call; - - struct InterruptTrapType { - uint16_t TargetLow; - uint16_t TargetSelector; - unsigned IST : 2; - unsigned Unused_0 : 6; - unsigned Type : 4; - unsigned MustBeZero : 1; - unsigned DPL : 2; - unsigned P : 1; - uint16_t TargetMid; - uint32_t TargetHigh; - uint32_t Pad; - } IntTrap; - } __attribute__((packed)); - - GateDesc Test; - - // Types 0x04-0x07 are illegal in 64bit mode - uint8_t TypeCall = 0x0C; - uint8_t TypeIDT = 0x0E; - uint8_t TypeTrap = 0x0F; - Test.IntTrap.TargetLow = 0; - Test.IntTrap.TargetSelector = 0; - Test.IntTrap.P = 1; // If P == 0 then `Segment not present` fault occurs - Test.IntTrap.IST = 0; // Must be zero otherwise we need a TSS register set up - Test.IntTrap.Type = TypeTrap; - Test.IntTrap.TargetMid = 0; - Test.IntTrap.TargetHigh = 0; - - unsigned Entries = IDTRegion.RegionSize / sizeof(GateDesc); - printf("%d IDT entries\n", Entries); - GateDesc *GuestEntries = (GateDesc*)IDTRegion.MappedLocation; - - // Section 8.2 Vectors of the AMD64 system programmer's manual - // Claims that the first 32 vectors are reserved for predefined exception and interrupt conditions - // The IDT can fit 256 interrupts - - //Back to IDT - for (unsigned i = 0; i < Entries; ++i) { - GuestEntries[i] = Test; - } - } - - // Set up our initial APIC region - { - APICRegion.MappedLocation = Mapper.MapRegion(APICRegion.PhysicalBase, APICRegion.RegionSize, true); - LogMan::Throw::A(APICRegion.MappedLocation != (void*)-1ULL, "Couldn't Allocate"); - - // Map this memory to the guest VM - kvm_userspace_memory_region Region = { - .slot = MemorySlot++, - .flags = 0, - .guest_phys_addr = APICRegion.PhysicalBase, - .memory_size = APICRegion.RegionSize, - .userspace_addr = (uint64_t)APICRegion.MappedLocation, - }; - - if (ioctl(VM_FD, KVM_SET_USER_MEMORY_REGION, &Region) == -1) { - printf("Couldn't set guestPD region\n"); - return false; - } - - uint64_t *APICRegisters = (uint64_t*)APICRegion.MappedLocation; - for (unsigned i = 0; i < 0x54; ++i) { - APICRegisters[i] = ~0ULL; - } - } - - return true; - } - - bool KVMInstance::SetupCPUInLongMode() { - kvm_sregs SpecialRegisters = { - .cs = { - .base = 0, // Ignored in 64bit mode - .limit = 0U, // Ignored in 64bit mode - .present = 1, - .dpl = 0, // Data-pivilege-level Still used in 64bit mode to allow accesses - .db = 0, // Ignored in 64bit mode - .l = 1, // 1 for 64bit execution mode. 0 if you want 32bit compatibility - .g = 0, // Ignored in 64bit mode - }, - .ds = { - .present = 1, - }, - .es = { - .present = 1, - }, - .fs = { - .present = 1, - }, - .gs = { - .present = 1, - }, - .ss = { - .present = 1, - }, - // Do we need the LDT(Local Descriptor Table) and TR (Task Register)? - .tr = { - .base = 0, - .limit = 0, - }, - - .ldt = { - .base = 0, - .limit = 0, - }, - .gdt = { - .base = GDTRegion.VirtualBase, - .limit = (uint16_t)GDTRegion.RegionSize, - }, - .idt = { - .base = IDTRegion.VirtualBase, - .limit = (uint16_t)IDTRegion.RegionSize, - }, - - .cr0 = (1U << 0) | // Protected Mode enable. Required for 64bit mode -// (1U << 1) | // Monitor coprocessor - (0U << 2) | // EM bit. 0 means State x87 FPU is present - (0U << 3) | // TS bit. If set causes a device not available exception - (1U << 31) | // (PG) Enable paging bit. Required for 64bit mode - 0, - .cr3 = PML4.GetPhysicalAddress() | // PDBR in PAE mode. Required for 64bit mode -// (1U << 4) | // Page cache disable - 0, - .cr4 = (1U << 5) | // PAE. Required for 64bit mode -// (1U << 0) | // (VME) VM86 extensions -// (1U << 1) | // (PVI) Virtual interrupt flags -// (1U << 3) | // (DE) Debug extensions -// (1U << 6) | // (MCE) Machine check enable -// (1U << 7) | // (PGE) Global page enable - (1U << 9) | // OSFXSR. Required to enable SSE - // (1U << 18) | // XXX: OSXSave. Required to enable AVX. Requires setting the guest CPUID to say it supports xsave - 0, - .efer = (1U << 10) | // (LMA) Long Mode Active. - (1U << 8) | // (LME) Long Mode Enable - 0, - .apic_base = (1 << 11) | // (AE) APIC Enable - // (APICRegion.PhysicalBase >> 12 << 32), // ABA, APIC Base Address. ABA is zext by 12 bits to form a 52bit physical address - 0, - }; - - kvm_regs Registers = { - .rsp = 0xFF0, - .rip = ~0ULL, - .rflags = 0x2 | // 0x2 is the default state of rflags - (1U << 9) | // By default enable hardware interrupts - (1U << 19) | // By default enable virtual hardware interrupts - (1U << 21) | // CPU ID detection - 0, - }; - - if (ioctl(VCPU_FD, KVM_SET_SREGS, &SpecialRegisters) == -1) { - fprintf(stderr, "Couldn't set kvm_sregs\n"); - return false; - } - - if (ioctl(VCPU_FD, KVM_SET_REGS, &Registers) == -1) { - fprintf(stderr, "Couldn't set kvm_regs\n"); - return false; - } - return true; - } - - bool KVMInstance::Initialize() { - int APIVersion; - int VCPUSize; - int Result; - - // Open the KVM FD - KVM_FD = open("/dev/kvm", O_RDWR | O_CLOEXEC); - if (KVM_FD == -1) { - fprintf(stderr, "Couldn't open /dev/kvm: %s\n", strerror(errno)); - goto err; - } - - // Check the KVM version to make sure we support it - APIVersion = ioctl(KVM_FD, KVM_GET_API_VERSION, 0); - if (APIVersion == -1) { - fprintf(stderr, "Couldn't get KVM Version\n"); - goto err; - } - - if (APIVersion != 12) { - fprintf(stderr, "Unknown KVM version: %d\n", APIVersion); - goto err; - } - - // Create the VM FD - VM_FD = ioctl(KVM_FD, KVM_CREATE_VM, 0); - if (VM_FD == -1) { - fprintf(stderr, "Couldn't create VM FD\n"); - goto err; - } - - // Create the virtual CPU core - VCPU_FD = ioctl(VM_FD, KVM_CREATE_VCPU, 0); - if (VCPU_FD == -1) { - fprintf(stderr, "Couldn't open VM's VCPU"); - goto err; - } - - // Get the VCPU's mmap size - VCPUSize = ioctl(KVM_FD, KVM_GET_VCPU_MMAP_SIZE, 0); - if (VCPUSize == -1 || VCPUSize < sizeof(kvm_run)) { - fprintf(stderr, "Received unexpected kvm_run size: %d\n", VCPUSize); - goto err; - } - - // Map in the kvm_run structure that is mapped to VCPU_FD at offset 0 - VCPUMemory = reinterpret_cast(mmap(nullptr, VCPUSize, PROT_READ | PROT_WRITE, MAP_SHARED, VCPU_FD, 0)); - LogMan::Throw::A(VCPUMemory != (void*)-1ULL, "Couldn't Allocate"); - - if (!SetupMemory()) { - fprintf(stderr, "Couldn't set up the CPU's memory\n"); - goto err; - } - - if (!SetupCPUInLongMode()) { - fprintf(stderr, "Couldn't initialize CPU in Long Mode\n"); - goto err; - } - - // Set a default TSS - // AMD SVM literally doesn't care but Intel VMX mandates it - // Needs to fit under 4GB and also have a minimum of three pages - Result = ioctl(VM_FD, KVM_SET_TSS_ADDR, -1U - (4096 * 3)); - if (Result == -1) { - fprintf(stderr, "Couldn't set TSS ADDR\n"); - goto err; - } - - return true; -err: - if (VCPU_FD != -1) { - close(VCPU_FD); - } - if (VM_FD != -1) { - close(VM_FD); - } - if (KVM_FD != -1) { - close(KVM_FD); - } - return false; - } - - void KVMInstance::SetVMRIP(uint64_t VirtualAddress) { - kvm_regs Registers; - if (ioctl(VCPU_FD, KVM_GET_REGS, &Registers) == -1) { - fprintf(stderr, "Couldn't get current set registers\n"); - return; - } - - // Set RIP - Registers.rip = VirtualAddress; - if (ioctl(VCPU_FD, KVM_SET_REGS, &Registers) == -1) { - fprintf(stderr, "Couldn't set kvm_regs\n"); - return; - } - } - - bool KVMInstance::SetStepping(bool Step) { - kvm_guest_debug GuestDebug{}; - - if (Step) { - GuestDebug.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; - } - else { - GuestDebug.control = 0; - } - - int Result = ioctl(VCPU_FD, KVM_SET_GUEST_DEBUG, &GuestDebug); - if (Result == -1) { - fprintf(stderr, "Couldn't set single step debugging\n"); - return false; - } - return true; - } - - bool KVMInstance::Run() { - // Kick off our virtual CPU - // This ioctl will block until the VM exits - // If single stepping it will return after the CPU has stepping a single instruction - int Result = ioctl(VCPU_FD, KVM_RUN, 0); - if (Result == -1) { - fprintf(stderr, "KVM_RUN failed\n"); - return false; - } - kvm_regs Registers; - ioctl(VCPU_FD, KVM_GET_REGS, &Registers); - printf("RIP is now: 0x%llx\n", Registers.rip); - - return true; - } - - VMInstance::RegisterState KVMInstance::GetRegisterState() { - kvm_regs Registers; - if (ioctl(VCPU_FD, KVM_GET_REGS, &Registers) == -1) { - fprintf(stderr, "Couldn't get KVM register state\n"); - return {}; - } - VMInstance::RegisterState State; - // This map 1:1 - memcpy(&State, &Registers, sizeof(kvm_regs)); - return State; - } - - VMInstance::SpecialRegisterState KVMInstance::GetSpecialRegisterState() { - kvm_sregs Registers; - if (ioctl(VCPU_FD, KVM_GET_SREGS, &Registers) == -1) { - fprintf(stderr, "Couldn't get KVM special register state\n"); - return {}; - } - VMInstance::SpecialRegisterState State; - State.fs.base = Registers.fs.base; - State.gs.base = Registers.gs.base; - return State; - } - - void KVMInstance::SetRegisterState(VMInstance::RegisterState &State) { - kvm_regs Registers; - // This map 1:1 - static_assert(offsetof(kvm_regs, rax) == offsetof(VMInstance::RegisterState, rax)); - static_assert(offsetof(kvm_regs, rbx) == offsetof(VMInstance::RegisterState, rbx)); - static_assert(offsetof(kvm_regs, rcx) == offsetof(VMInstance::RegisterState, rcx)); - static_assert(offsetof(kvm_regs, rdx) == offsetof(VMInstance::RegisterState, rdx)); - static_assert(offsetof(kvm_regs, rsi) == offsetof(VMInstance::RegisterState, rsi)); - static_assert(offsetof(kvm_regs, rdi) == offsetof(VMInstance::RegisterState, rdi)); - static_assert(offsetof(kvm_regs, rsp) == offsetof(VMInstance::RegisterState, rsp)); - static_assert(offsetof(kvm_regs, rbp) == offsetof(VMInstance::RegisterState, rbp)); - static_assert(offsetof(kvm_regs, r8) == offsetof(VMInstance::RegisterState, r8)); - static_assert(offsetof(kvm_regs, r9) == offsetof(VMInstance::RegisterState, r9)); - static_assert(offsetof(kvm_regs, r10) == offsetof(VMInstance::RegisterState, r10)); - static_assert(offsetof(kvm_regs, r11) == offsetof(VMInstance::RegisterState, r11)); - static_assert(offsetof(kvm_regs, r12) == offsetof(VMInstance::RegisterState, r12)); - static_assert(offsetof(kvm_regs, r13) == offsetof(VMInstance::RegisterState, r13)); - static_assert(offsetof(kvm_regs, r14) == offsetof(VMInstance::RegisterState, r14)); - static_assert(offsetof(kvm_regs, r15) == offsetof(VMInstance::RegisterState, r15)); - static_assert(offsetof(kvm_regs, rip) == offsetof(VMInstance::RegisterState, rip)); - static_assert(offsetof(kvm_regs, rflags) == offsetof(VMInstance::RegisterState, rflags)); - - memcpy(&Registers, &State, sizeof(kvm_regs)); - - if (ioctl(VCPU_FD, KVM_SET_REGS, &Registers) == -1) { - fprintf(stderr, "Couldn't set kvm_regs\n"); - return; - } - } - - void KVMInstance::SetSpecialRegisterState(VMInstance::SpecialRegisterState &State) { - kvm_sregs Registers; - - // First read the state so we don't destroy a bunch of data - if (ioctl(VCPU_FD, KVM_GET_SREGS, &Registers) == -1) { - fprintf(stderr, "Couldn't get KVM special register state\n"); - return; - } - Registers.fs.base = State.fs.base; - Registers.gs.base = State.gs.base; - - if (ioctl(VCPU_FD, KVM_SET_SREGS, &Registers) == -1) { - fprintf(stderr, "Couldn't set kvm_sregs\n"); - return; - } - } - - void KVMInstance::Debug() { - kvm_sregs Registers; - if (ioctl(VCPU_FD, KVM_GET_SREGS, &Registers) == -1) { - fprintf(stderr, "Couldn't get KVM special register state\n"); - return; - } - - auto PrintDTable = [](const char *Name, kvm_dtable &Table) { - LogMan::Msg::D("%s 0x%016llx 0x%04x", Name, Table.base, Table.limit); - }; - - auto PrintSegment = [](const char *Name, kvm_segment &Segment) { - LogMan::Msg::D("%s 0x%016llx 0x%08x 0x%04x 0x%02x %d %d %d %d %d %d %d", - Name, Segment.base, Segment.limit, Segment.selector, Segment.type, - Segment.present, Segment.dpl, Segment.db, Segment.s, Segment.l, Segment.g, Segment.avl); - }; - - SU::VM::VMInstance::RegisterState State; - State = GetRegisterState(); - LogMan::Msg::D("================"); - LogMan::Msg::D(" RAX RBX RCX RDX"); - LogMan::Msg::D("%016lx %016lx %016lx %016lx", State.rax, State.rbx, State.rcx, State.rdx); - LogMan::Msg::D(" RSI RDI RSP RBP"); - LogMan::Msg::D("%016lx %016lx %016lx %016lx", State.rsi, State.rdi, State.rsp, State.rbp); - LogMan::Msg::D(" R8 R9 R10 R11"); - LogMan::Msg::D("%016lx %016lx %016lx %016lx", State.r8, State.r9, State.r10, State.r11); - LogMan::Msg::D(" R12 R13 R14 R15"); - LogMan::Msg::D("%016lx %016lx %016lx %016lx", State.r12, State.r13, State.r14, State.r15); - LogMan::Msg::D(" RIP RFLAGS"); - LogMan::Msg::D("%016lx %016lx", State.rip, State.rflags); - - LogMan::Msg::D("================"); - LogMan::Msg::D("cr0: cr2: cr3:"); - LogMan::Msg::D("%016llx %016llx %016llx", Registers.cr0, Registers.cr2, Registers.cr3); - LogMan::Msg::D("cr4: cr6:"); - LogMan::Msg::D("%016llx %016llx", Registers.cr4, Registers.cr8); - - LogMan::Msg::D("================"); - LogMan::Msg::D("Reg Base Limit Select Type p dpl db s l g avl"); - - PrintSegment("CS ", Registers.cs); - PrintSegment("DS ", Registers.ds); - PrintSegment("ES ", Registers.es); - PrintSegment("FS ", Registers.fs); - PrintSegment("GS ", Registers.gs); - PrintSegment("SS ", Registers.ss); - - PrintSegment("TR ", Registers.tr); - PrintSegment("LDT", Registers.ldt); - - LogMan::Msg::D("================"); - PrintDTable("GDT", Registers.gdt); - PrintDTable("IDT", Registers.idt); - - LogMan::Msg::D("================"); - LogMan::Msg::D("EFER: 0x%016llx APIC: 0x%016llx", Registers.efer, Registers.apic_base); - LogMan::Msg::D("================"); - LogMan::Msg::D("Interrupt Bitmap"); - for (int i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; ++i) { - LogMan::Msg::D("Interrupt: %d: 0x%016llx", Registers.interrupt_bitmap[i]); - } - } - } - - VMInstance* VMInstance::Create() { - return new KVM::KVMInstance{}; - } -} diff --git a/External/SonicUtils/Source/VM_Noop.cpp b/External/SonicUtils/Source/VM_Noop.cpp deleted file mode 100644 index 096b760e4..000000000 --- a/External/SonicUtils/Source/VM_Noop.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -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{}; - } -} diff --git a/External/SonicUtils/include/SonicUtils/VM.h b/External/SonicUtils/include/SonicUtils/VM.h deleted file mode 100644 index 835a84166..000000000 --- a/External/SonicUtils/include/SonicUtils/VM.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include - -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; - - }; -} diff --git a/Readme.md b/Readme.md index 5f8580149..6bb18c425 100644 --- a/Readme.md +++ b/Readme.md @@ -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 diff --git a/Source/Common/CMakeLists.txt b/Source/Common/CMakeLists.txt index 67fa5921a..053fa90bd 100644 --- a/Source/Common/CMakeLists.txt +++ b/Source/Common/CMakeLists.txt @@ -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/) diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index 113d3d6ab..221078c60 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -1,5 +1,5 @@ #include "Common/Config.h" -#include "LogManager.h" +#include #include #include diff --git a/Source/Common/EnvironmentLoader.cpp b/Source/Common/EnvironmentLoader.cpp index 27b133272..3c428fc1d 100644 --- a/Source/Common/EnvironmentLoader.cpp +++ b/Source/Common/EnvironmentLoader.cpp @@ -3,7 +3,7 @@ #include #include #include "Common/Config.h" -#include "LogManager.h" +#include namespace FEX::EnvLoader { diff --git a/Source/CommonCore/CMakeLists.txt b/Source/CommonCore/CMakeLists.txt index 2a5e69856..9f2905a57 100644 --- a/Source/CommonCore/CMakeLists.txt +++ b/Source/CommonCore/CMakeLists.txt @@ -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) diff --git a/Source/CommonCore/HostFactory.cpp b/Source/CommonCore/HostFactory.cpp index b961d871f..b54f45057 100644 --- a/Source/CommonCore/HostFactory.cpp +++ b/Source/CommonCore/HostFactory.cpp @@ -24,7 +24,7 @@ #include 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; } diff --git a/Source/CommonCore/VMFactory.cpp b/Source/CommonCore/VMFactory.cpp deleted file mode 100644 index 395edb3c1..000000000 --- a/Source/CommonCore/VMFactory.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#include "VM.h" -#include "LogManager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 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 MemoryRegions; - - struct PhysicalToVirtual { - uint64_t PhysicalPtr; - uint64_t GuestVirtualPtr; - void *HostPtr; - uint64_t Size; - }; - std::vector 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((reinterpret_cast(PhysBase) + Region.PhysicalPtr)); - memcpy(GuestPtr, Region.HostPtr, Region.Size); - } - } - - void VMCore::CopyGuestMemoryToHost() { - void *PhysBase = VM->GetPhysicalMemoryPointer(); - for (auto &Region : PhysToVirt) { - void *GuestPtr = reinterpret_cast((reinterpret_cast(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(Thread); - VMCore *Core = reinterpret_cast(InternalThread->CPUBackend.get()); - Core->ExecuteCode(Thread); - } - - static void VMExecutionFallback(FEXCore::Core::ThreadState *Thread) { - auto InternalThread = reinterpret_cast(Thread); - VMCore *Core = reinterpret_cast(InternalThread->FallbackBackend.get()); - Core->ExecuteCode(Thread); - } - - void* VMCore::CompileCode([[maybe_unused]] FEXCore::IR::IRListView const *IR, FEXCore::Core::DebugData *DebugData) { - if (IsFallback) - return reinterpret_cast(VMExecutionFallback); - else - return reinterpret_cast(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); - } - -} - diff --git a/Source/CommonCore/VMFactory.h b/Source/CommonCore/VMFactory.h deleted file mode 100644 index 28609a793..000000000 --- a/Source/CommonCore/VMFactory.h +++ /dev/null @@ -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); -} diff --git a/Source/Core/CPU/HostCore/HostCore.cpp b/Source/Core/CPU/HostCore/HostCore.cpp index 1d70f3da5..31bf53141 100644 --- a/Source/Core/CPU/HostCore/HostCore.cpp +++ b/Source/Core/CPU/HostCore/HostCore.cpp @@ -5,7 +5,7 @@ #include "Core/CPU/IR.h" #include "Core/CPU/IntrusiveIRList.h" #include "Core/CPU/HostCore/HostCore.h" -#include "LogManager.h" +#include #include #include diff --git a/Source/Tests/CMakeLists.txt b/Source/Tests/CMakeLists.txt index 68ed61357..dc6e0b9b4 100644 --- a/Source/Tests/CMakeLists.txt +++ b/Source/Tests/CMakeLists.txt @@ -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}) diff --git a/Source/Tests/ELFLoader.cpp b/Source/Tests/ELFLoader.cpp index b8fc66de4..60a86079e 100644 --- a/Source/Tests/ELFLoader.cpp +++ b/Source/Tests/ELFLoader.cpp @@ -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 #include #include #include +#include +#include #include #include @@ -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)); diff --git a/Source/Tests/HarnessHelpers.h b/Source/Tests/HarnessHelpers.h index 7ce543d0e..ff4369ddd 100644 --- a/Source/Tests/HarnessHelpers.h +++ b/Source/Tests/HarnessHelpers.h @@ -1,9 +1,6 @@ #pragma once #include "Common/Config.h" #include "Common/MathUtils.h" -#include "ELFLoader.h" -#include "ELFSymbolDatabase.h" -#include "LogManager.h" #include #include @@ -15,6 +12,9 @@ #include #include #include +#include +#include +#include namespace FEX::HarnessHelper { inline bool CompareStates(FEXCore::Core::CPUState const& State1, diff --git a/Source/Tests/IRLoader.cpp b/Source/Tests/IRLoader.cpp index 444abef84..9a3e8d19b 100644 --- a/Source/Tests/IRLoader.cpp +++ b/Source/Tests/IRLoader.cpp @@ -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 #include #include #include +#include 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); diff --git a/Source/Tests/IRLoader/Loader.cpp b/Source/Tests/IRLoader/Loader.cpp index 2e85901b4..fc20adedd 100644 --- a/Source/Tests/IRLoader/Loader.cpp +++ b/Source/Tests/IRLoader/Loader.cpp @@ -1,5 +1,5 @@ #include "IRLoader/Loader.h" -#include "LogManager.h" +#include #include diff --git a/Source/Tests/IRLoader/Loader.h b/Source/Tests/IRLoader/Loader.h index e2a5eff39..00939ffaf 100644 --- a/Source/Tests/IRLoader/Loader.h +++ b/Source/Tests/IRLoader/Loader.h @@ -5,7 +5,7 @@ #include "HarnessHelpers.h" -#include "LogManager.h" +#include #include #include diff --git a/Source/Tests/LockstepRunner.cpp b/Source/Tests/LockstepRunner.cpp index cb83c011b..48732fdfe 100644 --- a/Source/Tests/LockstepRunner.cpp +++ b/Source/Tests/LockstepRunner.cpp @@ -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 #include #include #include #include +#include #include #include @@ -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()) { diff --git a/Source/Tests/TestHarness.cpp b/Source/Tests/TestHarness.cpp index 3da4345ad..edf014c15 100644 --- a/Source/Tests/TestHarness.cpp +++ b/Source/Tests/TestHarness.cpp @@ -1,7 +1,5 @@ #include "Common/ArgumentLoader.h" -#include "CommonCore/VMFactory.h" #include "HarnessHelpers.h" -#include "LogManager.h" #include #include @@ -12,6 +10,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/Source/Tests/TestHarnessRunner.cpp b/Source/Tests/TestHarnessRunner.cpp index 72f4fc966..b5eef5d46 100644 --- a/Source/Tests/TestHarnessRunner.cpp +++ b/Source/Tests/TestHarnessRunner.cpp @@ -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 #include @@ -13,6 +12,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/Source/Tests/TestSingleStepHardware.cpp b/Source/Tests/TestSingleStepHardware.cpp index 441aa512b..d0bbc29f1 100644 --- a/Source/Tests/TestSingleStepHardware.cpp +++ b/Source/Tests/TestSingleStepHardware.cpp @@ -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 #include #include #include #include - +#include +#include namespace FEX { uint8_t data[] = { diff --git a/Source/Tests/UnitTestGenerator.cpp b/Source/Tests/UnitTestGenerator.cpp index d686da9e7..3468fcf72 100644 --- a/Source/Tests/UnitTestGenerator.cpp +++ b/Source/Tests/UnitTestGenerator.cpp @@ -2,12 +2,12 @@ #include "Common/EnvironmentLoader.h" #include "Common/Config.h" -#include "LogManager.h" #include #include #include #include #include +#include constexpr std::array, 3> Disp8Ranges = {{ {static_cast(-16), 16}, diff --git a/Source/Tools/CMakeLists.txt b/Source/Tools/CMakeLists.txt index fb12236a8..a842acdd2 100644 --- a/Source/Tools/CMakeLists.txt +++ b/Source/Tools/CMakeLists.txt @@ -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) diff --git a/Source/Tools/Debugger/CMakeLists.txt b/Source/Tools/Debugger/CMakeLists.txt index 3408ecc4a..4feea61b3 100644 --- a/Source/Tools/Debugger/CMakeLists.txt +++ b/Source/Tools/Debugger/CMakeLists.txt @@ -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) diff --git a/Source/Tools/Debugger/IMGui_I.cpp b/Source/Tools/Debugger/IMGui_I.cpp index 49f285d23..dc6c9d22c 100644 --- a/Source/Tools/Debugger/IMGui_I.cpp +++ b/Source/Tools/Debugger/IMGui_I.cpp @@ -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 #include #include +#include #include #include diff --git a/Source/Tools/Debugger/IRLexer.cpp b/Source/Tools/Debugger/IRLexer.cpp index a78568f31..91620cf41 100644 --- a/Source/Tools/Debugger/IRLexer.cpp +++ b/Source/Tools/Debugger/IRLexer.cpp @@ -1,10 +1,10 @@ #include #include #include "IRLexer.h" -#include "LogManager.h" #include "Common/StringUtil.h" #include +#include namespace FEX::Debugger::IR { bool Lexer::Lex(char const *IR) { diff --git a/Source/Tools/Debugger/Main.cpp b/Source/Tools/Debugger/Main.cpp index ceac45d67..3ef1c8d57 100644 --- a/Source/Tools/Debugger/Main.cpp +++ b/Source/Tools/Debugger/Main.cpp @@ -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 #include @@ -16,6 +14,7 @@ #include #include #include +#include #include #include @@ -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); diff --git a/docs/VMCore.md b/docs/VMCore.md deleted file mode 100644 index 6b244975f..000000000 --- a/docs/VMCore.md +++ /dev/null @@ -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