Browse Source

[dynarmic] nuke zydis/zycore out of orbit forever (#2893)

LLVM does what Zydisn't
Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2893
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
pull/2898/head
lizzie 2 months ago
committed by crueter
parent
commit
d498db1106
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 13
      docs/Deps.md
  2. 2
      shell.nix
  3. 2
      src/dynarmic/CMakeLists.txt
  4. 1
      src/dynarmic/CMakeModules/dynarmicConfig.cmake.in
  5. 27
      src/dynarmic/README.md
  6. 14
      src/dynarmic/externals/CMakeLists.txt
  7. 19
      src/dynarmic/externals/cpmfile.json
  8. 8
      src/dynarmic/src/dynarmic/CMakeLists.txt
  9. 8
      src/dynarmic/src/dynarmic/backend/arm64/a32_interface.cpp
  10. 14
      src/dynarmic/src/dynarmic/backend/arm64/a64_interface.cpp
  11. 6
      src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp
  12. 3
      src/dynarmic/src/dynarmic/backend/arm64/address_space.h
  13. 8
      src/dynarmic/src/dynarmic/backend/riscv64/a32_interface.cpp
  14. 4
      src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp
  15. 16
      src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp
  16. 4
      src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp
  17. 18
      src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp
  18. 8
      src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc
  19. 25
      src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp
  20. 60
      src/dynarmic/src/dynarmic/common/x64_disassemble.cpp
  21. 24
      src/dynarmic/src/dynarmic/common/x64_disassemble.h
  22. 14
      src/dynarmic/src/dynarmic/interface/A32/a32.h
  23. 14
      src/dynarmic/src/dynarmic/interface/A64/a64.h
  24. 2
      src/dynarmic/tests/A32/fuzz_arm.cpp
  25. 2
      src/dynarmic/tests/A32/fuzz_thumb.cpp
  26. 2
      src/dynarmic/tests/A64/a64.cpp
  27. 2
      src/dynarmic/tests/A64/fuzz_with_unicorn.cpp
  28. 4
      src/dynarmic/tests/test_generator.cpp

13
docs/Deps.md

@ -72,9 +72,6 @@ Certain other dependencies will be fetched by CPM regardless. System packages *c
On amd64: On amd64:
* [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended * [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended
* [zycore](https://github.com/zyantific/zycore-c)
* [zydis](https://github.com/zyantific/zydis) 4+
* Note: zydis and zycore-c MUST match. Using one as a system dependency and the other as a bundled dependency WILL break things
On aarch64 OR if `DYNARMIC_TESTS` is on: On aarch64 OR if `DYNARMIC_TESTS` is on:
* [oaknut](https://github.com/merryhime/oaknut) 2.0.1+ * [oaknut](https://github.com/merryhime/oaknut) 2.0.1+
@ -94,7 +91,7 @@ Click on the arrows to expand.
<summary>Arch Linux</summary> <summary>Arch Linux</summary>
```sh ```sh
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip zydis zycore vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers
``` ```
* Building with QT Web Engine requires `qt6-webengine` as well. * Building with QT Web Engine requires `qt6-webengine` as well.
@ -106,7 +103,7 @@ sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glsl
<summary>Ubuntu, Debian, Mint Linux</summary> <summary>Ubuntu, Debian, Mint Linux</summary>
```sh ```sh
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
sudo apt-get install autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libvulkan-dev spirv-tools spirv-headers libusb-1.0-0-dev libxbyak-dev libboost-dev libboost-fiber-dev libboost-context-dev libsdl2-dev libopus-dev libasound2t64 vulkan-utility-libraries-dev
``` ```
* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. * Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required.
@ -189,7 +186,7 @@ brew install molten-vk vulkan-loader
<details> <details>
<summary>FreeBSD</summary> <summary>FreeBSD</summary>
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/jwt-cpp devel/unordered-dense devel/zydis`
As root run: `pkg install devel/cmake devel/sdl20 devel/boost-libs devel/catch2 devel/libfmt devel/nlohmann-json devel/ninja devel/nasm devel/autoconf devel/pkgconf devel/qt6-base devel/simpleini net/enet multimedia/ffnvcodec-headers multimedia/ffmpeg audio/opus archivers/liblz4 lang/gcc12 graphics/glslang graphics/vulkan-utility-libraries graphics/spirv-tools www/cpp-httplib devel/jwt-cpp devel/unordered-dense`
If using FreeBSD 12 or prior, use `devel/pkg-config` instead. If using FreeBSD 12 or prior, use `devel/pkg-config` instead.
@ -237,7 +234,7 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l
* Download and install all dependencies: * Download and install all dependencies:
``` ```
BASE="git make autoconf libtool automake-wrapper jq patch" BASE="git make autoconf libtool automake-wrapper jq patch"
MINGW="SDL2 cmake python-pip qt6-base toolchain ffmpeg boost catch fmt lz4 nlohmann-json openssl zlib zstd enet opus mbedtls vulkan-devel libusb vulkan-memory-allocator unordered_dense zydis clang ccache"
MINGW="SDL2 cmake python-pip qt6-base toolchain ffmpeg boost catch fmt lz4 nlohmann-json openssl zlib zstd enet opus mbedtls vulkan-devel libusb vulkan-memory-allocator unordered_dense clang ccache"
packages="$BASE" packages="$BASE"
for pkg in $MINGW; do for pkg in $MINGW; do
@ -260,7 +257,7 @@ pacman -Syu --needed --noconfirm $packages
<summary>HaikuOS</summary> <summary>HaikuOS</summary>
```sh ```sh
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel zydis_devel libusb1_devel libz_devel glslang mbedtls3
pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel boost1.89_devel vulkan_devel qt6_base_devel libsdl2_devel ffmpeg7_devel libx11_devel enet_devel catch2_devel quazip1_qt6_devel qt6_5compat_devel libusb1_devel libz_devel glslang mbedtls3
``` ```
[Caveats](./Caveats.md#haikuos). [Caveats](./Caveats.md#haikuos).

2
shell.nix

@ -10,7 +10,7 @@ pkgs.mkShellNoCC {
openssl boost fmt nlohmann_json lz4 zlib zstd openssl boost fmt nlohmann_json lz4 zlib zstd
enet libopus vulkan-headers vulkan-utility-libraries enet libopus vulkan-headers vulkan-utility-libraries
spirv-tools spirv-headers simpleini vulkan-memory-allocator spirv-tools spirv-headers simpleini vulkan-memory-allocator
vulkan-loader unzip mbedtls zydis glslang python3 httplib
vulkan-loader unzip mbedtls glslang python3 httplib
cpp-jwt ffmpeg-headless libusb1 cubeb cpp-jwt ffmpeg-headless libusb1 cubeb
qt6.full # eden qt6.full # eden
SDL2 # eden-cli SDL2 # eden-cli

2
src/dynarmic/CMakeLists.txt

@ -137,8 +137,6 @@ endif()
if ("x86_64" IN_LIST ARCHITECTURE) if ("x86_64" IN_LIST ARCHITECTURE)
find_package(xbyak 7 CONFIG) find_package(xbyak 7 CONFIG)
find_package(zycore REQUIRED)
find_package(zydis 4 REQUIRED)
endif() endif()
if (DYNARMIC_USE_LLVM) if (DYNARMIC_USE_LLVM)

1
src/dynarmic/CMakeModules/dynarmicConfig.cmake.in

@ -20,7 +20,6 @@ if (NOT @BUILD_SHARED_LIBS@)
if ("x86_64" IN_LIST ARCHITECTURE) if ("x86_64" IN_LIST ARCHITECTURE)
find_dependency(xbyak 7) find_dependency(xbyak 7)
find_dependency(Zydis 4)
endif() endif()
if (@DYNARMIC_USE_LLVM@) if (@DYNARMIC_USE_LLVM@)

27
src/dynarmic/README.md

@ -389,30 +389,3 @@ THE POSSIBILITY OF SUCH DAMAGE.
損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、 損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、
一切責任を負わないものとします。 一切責任を負わないものとします。
``` ```
### zydis
```
The MIT License (MIT)
Copyright (c) 2014-2020 Florian Bernd
Copyright (c) 2014-2020 Joel Höner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

14
src/dynarmic/externals/CMakeLists.txt

@ -32,17 +32,3 @@ AddJsonPackage(
NAME mcl NAME mcl
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS} BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
) )
# TODO(crueter): maybe it's just Gentoo but zydis system package really sucks
if ("x86_64" IN_LIST ARCHITECTURE)
set(CMAKE_DISABLE_FIND_PACKAGE_Doxygen ON)
AddJsonPackage(
NAME zycore
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
)
AddJsonPackage(
NAME zydis
BUNDLED_PACKAGE ${DYNARMIC_USE_BUNDLED_EXTERNALS}
)
endif()

19
src/dynarmic/externals/cpmfile.json

@ -17,24 +17,5 @@
"patches": [ "patches": [
"0001-assert-macro.patch" "0001-assert-macro.patch"
] ]
},
"zycore": {
"package": "zycore",
"repo": "zyantific/zycore-c",
"sha": "75a36c45ae",
"hash": "e1cf9bdd3163b6429eba94d0f9f82e343de33b77a838748f598c719913c9f91c502b818e37b716e174b55a3a26cdf39d665c4b50a548255973ac287c0e554fb6"
},
"zydis": {
"package": "zydis",
"version": "4",
"repo": "zyantific/zydis",
"sha": "c2d2bab025",
"hash": "3808773593536f78d3ddaf4cf712101d3fb6d981c6cc55555ad686a9adbe3397a727f62f561e8d8755bdcd88a763777da30281cc2924fc160b0386c3f99f5bd9",
"options": [
"ZYDIS_BUILD_TOOLS OFF",
"ZYDIS_BUILD_EXAMPLES OFF",
"ZYDIS_BUILD_DOXYGEN OFF",
"ZYAN_SYSTEM_ZYCORE ON"
]
} }
} }

8
src/dynarmic/src/dynarmic/CMakeLists.txt

@ -144,11 +144,7 @@ if ("x86_64" IN_LIST ARCHITECTURE)
target_compile_definitions(dynarmic PRIVATE XBYAK_STRICT_CHECK_MEM_REG_SIZE=0) target_compile_definitions(dynarmic PRIVATE XBYAK_STRICT_CHECK_MEM_REG_SIZE=0)
target_compile_definitions(dynarmic PRIVATE XBYAK_OLD_DISP_CHECK=1) target_compile_definitions(dynarmic PRIVATE XBYAK_OLD_DISP_CHECK=1)
target_link_libraries(dynarmic
PRIVATE
xbyak::xbyak
Zydis::Zydis
)
target_link_libraries(dynarmic PRIVATE xbyak::xbyak)
target_architecture_specific_sources(dynarmic "x86_64" target_architecture_specific_sources(dynarmic "x86_64"
backend/x64/abi.cpp backend/x64/abi.cpp
@ -192,8 +188,6 @@ if ("x86_64" IN_LIST ARCHITECTURE)
backend/x64/verbose_debugging_output.h backend/x64/verbose_debugging_output.h
common/spin_lock_x64.cpp common/spin_lock_x64.cpp
common/spin_lock_x64.h common/spin_lock_x64.h
common/x64_disassemble.cpp
common/x64_disassemble.h
# A32 # A32
backend/x64/a32_emit_x64.cpp backend/x64/a32_emit_x64.cpp
backend/x64/a32_emit_x64.h backend/x64/a32_emit_x64.h

8
src/dynarmic/src/dynarmic/backend/arm64/a32_interface.cpp

@ -125,10 +125,6 @@ struct Jit::Impl final {
current_state.exclusive_state = false; current_state.exclusive_state = false;
} }
void DumpDisassembly() const {
ASSERT_FALSE("Unimplemented");
}
private: private:
void PerformRequestedCacheInvalidation(HaltReason hr) { void PerformRequestedCacheInvalidation(HaltReason hr) {
if (Has(hr, HaltReason::CacheInvalidation)) { if (Has(hr, HaltReason::CacheInvalidation)) {
@ -235,8 +231,4 @@ void Jit::ClearExclusiveState() {
impl->ClearExclusiveState(); impl->ClearExclusiveState();
} }
void Jit::DumpDisassembly() const {
impl->DumpDisassembly();
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

14
src/dynarmic/src/dynarmic/backend/arm64/a64_interface.cpp

@ -151,12 +151,8 @@ struct Jit::Impl final {
return is_executing; return is_executing;
} }
void DumpDisassembly() const {
current_address_space.DumpDisassembly();
}
std::vector<std::string> Disassemble() const {
ASSERT_FALSE("Unimplemented");
std::string Disassemble() const {
UNREACHABLE();
} }
private: private:
@ -315,11 +311,7 @@ bool Jit::IsExecuting() const {
return impl->IsExecuting(); return impl->IsExecuting();
} }
void Jit::DumpDisassembly() const {
impl->DumpDisassembly();
}
std::vector<std::string> Jit::Disassemble() const {
std::string Jit::Disassemble() const {
return impl->Disassemble(); return impl->Disassemble();
} }

6
src/dynarmic/src/dynarmic/backend/arm64/address_space.cpp

@ -100,12 +100,6 @@ void AddressSpace::ClearCache() {
code.set_offset(prelude_info.end_of_prelude); code.set_offset(prelude_info.end_of_prelude);
} }
void AddressSpace::DumpDisassembly() const {
for (u32* ptr = mem.ptr(); ptr < code.xptr<u32*>(); ptr++) {
std::printf("%s", Common::DisassembleAArch64(*ptr, std::bit_cast<u64>(ptr)).c_str());
}
}
size_t AddressSpace::GetRemainingSize() { size_t AddressSpace::GetRemainingSize() {
return code_cache_size - static_cast<size_t>(code.offset()); return code_cache_size - static_cast<size_t>(code.offset());
} }

3
src/dynarmic/src/dynarmic/backend/arm64/address_space.h

@ -44,9 +44,6 @@ public:
void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors); void InvalidateBasicBlocks(const ankerl::unordered_dense::set<IR::LocationDescriptor>& descriptors);
void ClearCache(); void ClearCache();
void DumpDisassembly() const;
protected: protected:
virtual EmitConfig GetEmitConfig() = 0; virtual EmitConfig GetEmitConfig() = 0;
virtual void RegisterNewBasicBlock(const IR::Block& block, const EmittedBlockInfo& block_info) = 0; virtual void RegisterNewBasicBlock(const IR::Block& block, const EmittedBlockInfo& block_info) = 0;

8
src/dynarmic/src/dynarmic/backend/riscv64/a32_interface.cpp

@ -119,10 +119,6 @@ struct Jit::Impl final {
current_state.exclusive_state = false; current_state.exclusive_state = false;
} }
void DumpDisassembly() const {
UNIMPLEMENTED();
}
private: private:
void RequestCacheInvalidation() { void RequestCacheInvalidation() {
// ASSERT_FALSE("Unimplemented"); // ASSERT_FALSE("Unimplemented");
@ -213,8 +209,4 @@ void Jit::ClearExclusiveState() {
impl->ClearExclusiveState(); impl->ClearExclusiveState();
} }
void Jit::DumpDisassembly() const {
impl->DumpDisassembly();
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

4
src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64_memory.cpp

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage * Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -19,7 +22,6 @@
#include "dynarmic/backend/x64/emit_x64_memory.h" #include "dynarmic/backend/x64/emit_x64_memory.h"
#include "dynarmic/backend/x64/exclusive_monitor_friend.h" #include "dynarmic/backend/x64/exclusive_monitor_friend.h"
#include "dynarmic/backend/x64/perf_map.h" #include "dynarmic/backend/x64/perf_map.h"
#include "dynarmic/common/x64_disassemble.h"
#include "dynarmic/interface/exclusive_monitor.h" #include "dynarmic/interface/exclusive_monitor.h"
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {

16
src/dynarmic/src/dynarmic/backend/x64/a32_interface.cpp

@ -16,6 +16,7 @@
#include <bit> #include <bit>
#include <mcl/scope_exit.hpp> #include <mcl/scope_exit.hpp>
#include "dynarmic/common/common_types.h" #include "dynarmic/common/common_types.h"
#include "dynarmic/common/llvm_disassemble.h"
#include "dynarmic/backend/x64/a32_emit_x64.h" #include "dynarmic/backend/x64/a32_emit_x64.h"
#include "dynarmic/backend/x64/a32_jitstate.h" #include "dynarmic/backend/x64/a32_jitstate.h"
@ -24,7 +25,6 @@
#include "dynarmic/backend/x64/devirtualize.h" #include "dynarmic/backend/x64/devirtualize.h"
#include "dynarmic/backend/x64/jitstate_info.h" #include "dynarmic/backend/x64/jitstate_info.h"
#include "dynarmic/common/atomic.h" #include "dynarmic/common/atomic.h"
#include "dynarmic/common/x64_disassemble.h"
#include "dynarmic/frontend/A32/translate/a32_translate.h" #include "dynarmic/frontend/A32/translate/a32_translate.h"
#include "dynarmic/interface/A32/a32.h" #include "dynarmic/interface/A32/a32.h"
#include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/basic_block.h"
@ -176,14 +176,10 @@ struct Jit::Impl {
return jit_state.SetFpscr(value); return jit_state.SetFpscr(value);
} }
void DumpDisassembly() const {
std::string Disassemble() const {
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size);
}
std::vector<std::string> Disassemble() const {
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
return Common::DisassembleX64(block_of_code.GetCodeBegin(), size);
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
return Common::DisassembleX64(p, p + size);
} }
private: private:
@ -327,8 +323,4 @@ void Jit::ClearExclusiveState() {
impl->ClearExclusiveState(); impl->ClearExclusiveState();
} }
void Jit::DumpDisassembly() const {
impl->DumpDisassembly();
}
} // namespace Dynarmic::A32 } // namespace Dynarmic::A32

4
src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64_memory.cpp

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage * Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -20,7 +23,6 @@
#include "dynarmic/backend/x64/exclusive_monitor_friend.h" #include "dynarmic/backend/x64/exclusive_monitor_friend.h"
#include "dynarmic/backend/x64/perf_map.h" #include "dynarmic/backend/x64/perf_map.h"
#include "dynarmic/common/spin_lock_x64.h" #include "dynarmic/common/spin_lock_x64.h"
#include "dynarmic/common/x64_disassemble.h"
#include "dynarmic/interface/exclusive_monitor.h" #include "dynarmic/interface/exclusive_monitor.h"
namespace Dynarmic::Backend::X64 { namespace Dynarmic::Backend::X64 {

18
src/dynarmic/src/dynarmic/backend/x64/a64_interface.cpp

@ -12,6 +12,7 @@
#include <boost/icl/interval_set.hpp> #include <boost/icl/interval_set.hpp>
#include "dynarmic/common/assert.h" #include "dynarmic/common/assert.h"
#include "dynarmic/common/llvm_disassemble.h"
#include <bit> #include <bit>
#include <mcl/scope_exit.hpp> #include <mcl/scope_exit.hpp>
@ -21,7 +22,6 @@
#include "dynarmic/backend/x64/devirtualize.h" #include "dynarmic/backend/x64/devirtualize.h"
#include "dynarmic/backend/x64/jitstate_info.h" #include "dynarmic/backend/x64/jitstate_info.h"
#include "dynarmic/common/atomic.h" #include "dynarmic/common/atomic.h"
#include "dynarmic/common/x64_disassemble.h"
#include "dynarmic/frontend/A64/translate/a64_translate.h" #include "dynarmic/frontend/A64/translate/a64_translate.h"
#include "dynarmic/interface/A64/a64.h" #include "dynarmic/interface/A64/a64.h"
#include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/basic_block.h"
@ -231,14 +231,10 @@ public:
return is_executing; return is_executing;
} }
void DumpDisassembly() const {
std::string Disassemble() const {
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin()); const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
Common::DumpDisassembledX64(block_of_code.GetCodeBegin(), size);
}
std::vector<std::string> Disassemble() const {
const size_t size = reinterpret_cast<const char*>(block_of_code.getCurr()) - reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
return Common::DisassembleX64(block_of_code.GetCodeBegin(), size);
auto const* p = reinterpret_cast<const char*>(block_of_code.GetCodeBegin());
return Common::DisassembleX64(p, p + size);
} }
private: private:
@ -427,11 +423,7 @@ bool Jit::IsExecuting() const {
return impl->IsExecuting(); return impl->IsExecuting();
} }
void Jit::DumpDisassembly() const {
return impl->DumpDisassembly();
}
std::vector<std::string> Jit::Disassemble() const {
std::string Jit::Disassemble() const {
return impl->Disassemble(); return impl->Disassemble();
} }

8
src/dynarmic/src/dynarmic/backend/x64/emit_x64_memory.cpp.inc

@ -40,11 +40,9 @@ FakeCall AxxEmitX64::FastmemCallback(u64 rip_) {
} }
return result; return result;
} else { } else {
fmt::print("dynarmic: Segfault happened within JITted code at rip = {:016x}\n", rip_);
fmt::print("Segfault wasn't at a fastmem patch location!\n");
fmt::print("Now dumping code.......\n\n");
Common::DumpDisassembledX64((void*)(rip_ & ~u64(0xFFF)), 0x1000);
ASSERT_FALSE("iter != fastmem_patch_info.end()");
fmt::print("dynarmic: Segfault happened within JITted code at rip = {:016x}\n"
"Segfault wasn't at a fastmem patch location!\n", rip_);
UNREACHABLE(); //("iter != fastmem_patch_info.end()");
} }
} }

25
src/dynarmic/src/dynarmic/common/llvm_disassemble.cpp

@ -24,9 +24,8 @@
namespace Dynarmic::Common { namespace Dynarmic::Common {
std::string DisassembleX64(const void* begin, const void* end) { std::string DisassembleX64(const void* begin, const void* end) {
std::string result;
#ifdef DYNARMIC_USE_LLVM #ifdef DYNARMIC_USE_LLVM
std::string result;
LLVMInitializeX86TargetInfo(); LLVMInitializeX86TargetInfo();
LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetMC();
LLVMInitializeX86Disassembler(); LLVMInitializeX86Disassembler();
@ -51,18 +50,17 @@ std::string DisassembleX64(const void* begin, const void* end) {
} }
LLVMDisasmDispose(llvm_ctx); LLVMDisasmDispose(llvm_ctx);
return result;
#else #else
result += fmt::format("(recompile with DYNARMIC_USE_LLVM=ON to disassemble the generated x86_64 code)\n");
result += fmt::format("start: {:016x}, end: {:016x}\n", std::bit_cast<u64>(begin), std::bit_cast<u64>(end));
return fmt::format(
"(recompile with DYNARMIC_USE_LLVM=ON to disassemble the generated x86_64 code)\n"
"start: {:016x}, end: {:016x}\n", std::bit_cast<u64>(begin), std::bit_cast<u64>(end));
#endif #endif
return result;
} }
std::string DisassembleAArch32([[maybe_unused]] bool is_thumb, [[maybe_unused]] u32 pc, [[maybe_unused]] const u8* instructions, [[maybe_unused]] size_t length) { std::string DisassembleAArch32([[maybe_unused]] bool is_thumb, [[maybe_unused]] u32 pc, [[maybe_unused]] const u8* instructions, [[maybe_unused]] size_t length) {
std::string result;
#ifdef DYNARMIC_USE_LLVM #ifdef DYNARMIC_USE_LLVM
std::string result;
LLVMInitializeARMTargetInfo(); LLVMInitializeARMTargetInfo();
LLVMInitializeARMTargetMC(); LLVMInitializeARMTargetMC();
LLVMInitializeARMDisassembler(); LLVMInitializeARMDisassembler();
@ -97,16 +95,14 @@ std::string DisassembleAArch32([[maybe_unused]] bool is_thumb, [[maybe_unused]]
} }
LLVMDisasmDispose(llvm_ctx); LLVMDisasmDispose(llvm_ctx);
return result;
#else #else
result += fmt::format("(disassembly disabled)\n");
return fmt::format("(disassembly disabled)\n");
#endif #endif
return result;
} }
std::string DisassembleAArch64([[maybe_unused]] u32 instruction, [[maybe_unused]] u64 pc) { std::string DisassembleAArch64([[maybe_unused]] u32 instruction, [[maybe_unused]] u64 pc) {
std::string result; std::string result;
#ifdef DYNARMIC_USE_LLVM #ifdef DYNARMIC_USE_LLVM
LLVMInitializeAArch64TargetInfo(); LLVMInitializeAArch64TargetInfo();
LLVMInitializeAArch64TargetMC(); LLVMInitializeAArch64TargetMC();
@ -121,11 +117,10 @@ std::string DisassembleAArch64([[maybe_unused]] u32 instruction, [[maybe_unused]
result += '\n'; result += '\n';
LLVMDisasmDispose(llvm_ctx); LLVMDisasmDispose(llvm_ctx);
return result;
#else #else
result += fmt::format("(disassembly disabled)\n");
return fmt::format("(disassembly disabled)\n");
#endif #endif
return result;
} }
} // namespace Dynarmic::Common } // namespace Dynarmic::Common

60
src/dynarmic/src/dynarmic/common/x64_disassemble.cpp

@ -1,60 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2021 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "dynarmic/common/x64_disassemble.h"
#include <Zydis/Zydis.h>
#include <fmt/printf.h>
#include "dynarmic/common/common_types.h"
namespace Dynarmic::Common {
void DumpDisassembledX64(const void* ptr, size_t size) {
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
size_t offset = 0;
ZydisDecodedInstruction instruction;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(&decoder, static_cast<const char*>(ptr) + offset, size - offset, &instruction, operands))) {
fmt::print("{:016x} ", (u64)ptr + offset);
char buffer[256];
ZydisFormatterFormatInstruction(&formatter, &instruction, operands, instruction.operand_count_visible, buffer, sizeof(buffer), reinterpret_cast<u64>(ptr) + offset, ZYAN_NULL);
puts(buffer);
offset += instruction.length;
}
}
std::vector<std::string> DisassembleX64(const void* ptr, size_t size) {
std::vector<std::string> result;
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64);
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
size_t offset = 0;
ZydisDecodedInstruction instruction;
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT];
while (ZYAN_SUCCESS(ZydisDecoderDecodeFull(&decoder, static_cast<const char*>(ptr) + offset, size - offset, &instruction, operands))) {
char buffer[256];
ZydisFormatterFormatInstruction(&formatter, &instruction, operands, instruction.operand_count_visible, buffer, sizeof(buffer), reinterpret_cast<u64>(ptr) + offset, ZYAN_NULL);
result.push_back(fmt::format("{:016x} {}", (u64)ptr + offset, buffer));
offset += instruction.length;
}
return result;
}
} // namespace Dynarmic::Common

24
src/dynarmic/src/dynarmic/common/x64_disassemble.h

@ -1,24 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project.
* Copyright (c) 2021 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <string>
#include <vector>
#include "dynarmic/common/common_types.h"
namespace Dynarmic::Common {
void DumpDisassembledX64(const void* ptr, size_t size);
/**
* Disassemble `size' bytes from `ptr' and return the disassembled lines as a vector
* of strings.
*/
std::vector<std::string> DisassembleX64(const void* ptr, size_t size);
} // namespace Dynarmic::Common

14
src/dynarmic/src/dynarmic/interface/A32/a32.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage * Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -89,14 +92,9 @@ public:
return is_executing; return is_executing;
} }
/// Debugging: Dump a disassembly all compiled code to the console.
void DumpDisassembly() const;
/**
* Disassemble the instructions following the current pc and return
* the resulting instructions as a vector of their string representations.
*/
std::vector<std::string> Disassemble() const;
/// @brief Disassemble the instructions following the current pc and return
/// the resulting instructions as a vector of their string representations.
std::string Disassemble() const;
private: private:
bool is_executing = false; bool is_executing = false;

14
src/dynarmic/src/dynarmic/interface/A64/a64.h

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* This file is part of the dynarmic project. /* This file is part of the dynarmic project.
* Copyright (c) 2018 MerryMage * Copyright (c) 2018 MerryMage
* SPDX-License-Identifier: 0BSD * SPDX-License-Identifier: 0BSD
@ -119,14 +122,9 @@ public:
*/ */
bool IsExecuting() const; bool IsExecuting() const;
/// Debugging: Dump a disassembly all of compiled code to the console.
void DumpDisassembly() const;
/*
* Disassemble the instructions following the current pc and return
* the resulting instructions as a vector of their string representations.
*/
std::vector<std::string> Disassemble() const;
/// @brief Disassemble the instructions following the current pc and return
/// the resulting instructions as a vector of their string representations.
std::string Disassemble() const;
private: private:
struct Impl; struct Impl;

2
src/dynarmic/tests/A32/fuzz_arm.cpp

@ -417,7 +417,7 @@ static void RunTestInstance(Dynarmic::A32::Jit& jit,
fmt::print("\n"); fmt::print("\n");
fmt::print("x86_64:\n"); fmt::print("x86_64:\n");
jit.DumpDisassembly();
fmt::print("{}", jit.Disassemble());
fmt::print("Interrupts:\n"); fmt::print("Interrupts:\n");
for (const auto& i : uni_env.interrupts) { for (const auto& i : uni_env.interrupts) {

2
src/dynarmic/tests/A32/fuzz_thumb.cpp

@ -183,7 +183,7 @@ static void RunInstance(size_t run_number, ThumbTestEnv& test_env, A32Unicorn<Th
Optimization::Optimize(ir_block, &test_env, {}); Optimization::Optimize(ir_block, &test_env, {});
printf("\n\nIR:\n%s", IR::DumpBlock(ir_block).c_str()); printf("\n\nIR:\n%s", IR::DumpBlock(ir_block).c_str());
printf("\n\nx86_64:\n"); printf("\n\nx86_64:\n");
jit.DumpDisassembly();
printf("%s", jit.Disassemble().c_str());
num_insts += ir_block.CycleCount(); num_insts += ir_block.CycleCount();
} }

2
src/dynarmic/tests/A64/a64.cpp

@ -1630,7 +1630,7 @@ TEST_CASE("A64: rand3", "[a64]") {
jit.SetPstate(0xb0000000); jit.SetPstate(0xb0000000);
jit.SetFpcr(0x01000000); jit.SetFpcr(0x01000000);
env.ticks_left = 110; env.ticks_left = 110;
//jit.DumpDisassembly();
//fmt::print("{}", jit.Disassemble());
CheckedRun([&]() { jit.Run(); }); CheckedRun([&]() { jit.Run(); });
} }

2
src/dynarmic/tests/A64/fuzz_with_unicorn.cpp

@ -279,7 +279,7 @@ static void RunTestInstance(Dynarmic::A64::Jit& jit, A64Unicorn& uni, A64TestEnv
fmt::print("{}\n", IR::DumpBlock(ir_block)); fmt::print("{}\n", IR::DumpBlock(ir_block));
fmt::print("x86_64:\n"); fmt::print("x86_64:\n");
jit.DumpDisassembly();
fmt::print("{}", jit.Disassemble());
fmt::print("Interrupts:\n"); fmt::print("Interrupts:\n");
for (auto& i : uni_env.interrupts) { for (auto& i : uni_env.interrupts) {

4
src/dynarmic/tests/test_generator.cpp

@ -479,7 +479,7 @@ void RunTestInstance(Dynarmic::A32::Jit& jit,
std::puts(i.c_str()); std::puts(i.c_str());
} }
fmt::print("===\n"); fmt::print("===\n");
jit.DumpDisassembly();
fmt::print("{}", jit.Disassemble());
} }
} }
@ -570,7 +570,7 @@ void RunTestInstance(Dynarmic::A64::Jit& jit,
for (const auto& i : jit_env.interrupts) for (const auto& i : jit_env.interrupts)
std::puts(i.c_str()); std::puts(i.c_str());
fmt::print("===\n"); fmt::print("===\n");
jit.DumpDisassembly();
fmt::print("{}", jit.Disassemble());
} }
} }

Loading…
Cancel
Save