mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-10 00:41:19 +12:00
Merge branch 'main' into loadaudio
This commit is contained in:
commit
2cd6dbd9b7
17 changed files with 395 additions and 633 deletions
2
dependencies/vcpkg
vendored
2
dependencies/vcpkg
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit b81bc3a83fdbdffe80325eeabb2ec735a1f3c29d
|
Subproject commit 53bef8994c541b6561884a8395ea35715ece75db
|
13
dependencies/vcpkg_overlay_ports/sdl2/deps.patch
vendored
13
dependencies/vcpkg_overlay_ports/sdl2/deps.patch
vendored
|
@ -1,13 +0,0 @@
|
||||||
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
|
|
||||||
index 65a98efbe..2f99f28f1 100644
|
|
||||||
--- a/cmake/sdlchecks.cmake
|
|
||||||
+++ b/cmake/sdlchecks.cmake
|
|
||||||
@@ -352,7 +352,7 @@ endmacro()
|
|
||||||
# - HAVE_SDL_LOADSO opt
|
|
||||||
macro(CheckLibSampleRate)
|
|
||||||
if(SDL_LIBSAMPLERATE)
|
|
||||||
- find_package(SampleRate QUIET)
|
|
||||||
+ find_package(SampleRate CONFIG REQUIRED)
|
|
||||||
if(SampleRate_FOUND AND TARGET SampleRate::samplerate)
|
|
||||||
set(HAVE_LIBSAMPLERATE TRUE)
|
|
||||||
set(HAVE_LIBSAMPLERATE_H TRUE)
|
|
130
dependencies/vcpkg_overlay_ports/sdl2/portfile.cmake
vendored
130
dependencies/vcpkg_overlay_ports/sdl2/portfile.cmake
vendored
|
@ -1,130 +0,0 @@
|
||||||
vcpkg_from_github(
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libsdl-org/SDL
|
|
||||||
REF "release-${VERSION}"
|
|
||||||
SHA512 90858ae8c5fdddd5e13724e05ad0970e11bbab1df8a0201c3f4ce354dc6018e5d4ab7279402a263c716aacdaa52745f78531dc225d48d790ee9307e2f6198695
|
|
||||||
HEAD_REF main
|
|
||||||
PATCHES
|
|
||||||
deps.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SDL_SHARED)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" FORCE_STATIC_VCRT)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
vulkan SDL_VULKAN
|
|
||||||
x11 SDL_X11
|
|
||||||
wayland SDL_WAYLAND
|
|
||||||
samplerate SDL_LIBSAMPLERATE
|
|
||||||
ibus SDL_IBUS
|
|
||||||
)
|
|
||||||
|
|
||||||
if ("x11" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Xorg dependencies to use feature x11:\nsudo apt install libx11-dev libxft-dev libxext-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("wayland" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Wayland dependencies to use feature wayland:\nsudo apt install libwayland-dev libxkbcommon-dev libegl1-mesa-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("ibus" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install ibus dependencies to use feature ibus:\nsudo apt install libibus-1.0-dev\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
set(configure_opts WINDOWS_USE_MSBUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
${configure_opts}
|
|
||||||
OPTIONS ${FEATURE_OPTIONS}
|
|
||||||
-DSDL_STATIC=${SDL_STATIC}
|
|
||||||
-DSDL_SHARED=${SDL_SHARED}
|
|
||||||
-DSDL_FORCE_STATIC_VCRT=${FORCE_STATIC_VCRT}
|
|
||||||
-DSDL_LIBC=ON
|
|
||||||
-DSDL_TEST=OFF
|
|
||||||
-DSDL_INSTALL_CMAKEDIR="cmake"
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON
|
|
||||||
-DSDL_LIBSAMPLERATE_SHARED=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
SDL_FORCE_STATIC_VCRT
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/licenses"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/aclocal"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB BINS "${CURRENT_PACKAGES_DIR}/debug/bin/*" "${CURRENT_PACKAGES_DIR}/bin/*")
|
|
||||||
if(NOT BINS)
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_UWP AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/lib/SDL2main.lib" "${CURRENT_PACKAGES_DIR}/lib/manual-link/SDL2main.lib")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/SDL2maind.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link/SDL2maind.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB SHARE_FILES "${CURRENT_PACKAGES_DIR}/share/sdl2/*.cmake")
|
|
||||||
foreach(SHARE_FILE ${SHARE_FILES})
|
|
||||||
vcpkg_replace_string("${SHARE_FILE}" "lib/SDL2main" "lib/manual-link/SDL2main")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
|
|
||||||
set(DYLIB_COMPATIBILITY_VERSION_REGEX "set\\(DYLIB_COMPATIBILITY_VERSION (.+)\\)")
|
|
||||||
set(DYLIB_CURRENT_VERSION_REGEX "set\\(DYLIB_CURRENT_VERSION (.+)\\)")
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_COMPATIBILITY_VERSION REGEX ${DYLIB_COMPATIBILITY_VERSION_REGEX})
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_CURRENT_VERSION REGEX ${DYLIB_CURRENT_VERSION_REGEX})
|
|
||||||
string(REGEX REPLACE ${DYLIB_COMPATIBILITY_VERSION_REGEX} "\\1" DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPATIBILITY_VERSION}")
|
|
||||||
string(REGEX REPLACE ${DYLIB_CURRENT_VERSION_REGEX} "\\1" DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}")
|
|
||||||
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2main" "-lSDL2maind")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2 " "-lSDL2d ")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-static " "-lSDL2-staticd ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-lSDL2-static " " ")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-staticd " " ")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "d")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt")
|
|
8
dependencies/vcpkg_overlay_ports/sdl2/usage
vendored
8
dependencies/vcpkg_overlay_ports/sdl2/usage
vendored
|
@ -1,8 +0,0 @@
|
||||||
sdl2 provides CMake targets:
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
|
||||||
target_link_libraries(main
|
|
||||||
PRIVATE
|
|
||||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
|
||||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
|
||||||
)
|
|
58
dependencies/vcpkg_overlay_ports/sdl2/vcpkg.json
vendored
58
dependencies/vcpkg_overlay_ports/sdl2/vcpkg.json
vendored
|
@ -1,58 +0,0 @@
|
||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"version": "2.26.5",
|
|
||||||
"description": "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.",
|
|
||||||
"homepage": "https://www.libsdl.org/download-2.0.php",
|
|
||||||
"license": "Zlib",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
"base"
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"base": {
|
|
||||||
"description": "Base functionality for SDL",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"default-features": false,
|
|
||||||
"features": [
|
|
||||||
"ibus",
|
|
||||||
"wayland",
|
|
||||||
"x11"
|
|
||||||
],
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ibus": {
|
|
||||||
"description": "Build with ibus IME support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"samplerate": {
|
|
||||||
"description": "Use libsamplerate for audio rate conversion",
|
|
||||||
"dependencies": [
|
|
||||||
"libsamplerate"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"vulkan": {
|
|
||||||
"description": "Vulkan functionality for SDL"
|
|
||||||
},
|
|
||||||
"wayland": {
|
|
||||||
"description": "Build with Wayland support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 support",
|
|
||||||
"supports": "!windows"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
|
|
||||||
index 65a98efbe..2f99f28f1 100644
|
|
||||||
--- a/cmake/sdlchecks.cmake
|
|
||||||
+++ b/cmake/sdlchecks.cmake
|
|
||||||
@@ -352,7 +352,7 @@ endmacro()
|
|
||||||
# - HAVE_SDL_LOADSO opt
|
|
||||||
macro(CheckLibSampleRate)
|
|
||||||
if(SDL_LIBSAMPLERATE)
|
|
||||||
- find_package(SampleRate QUIET)
|
|
||||||
+ find_package(SampleRate CONFIG REQUIRED)
|
|
||||||
if(SampleRate_FOUND AND TARGET SampleRate::samplerate)
|
|
||||||
set(HAVE_LIBSAMPLERATE TRUE)
|
|
||||||
set(HAVE_LIBSAMPLERATE_H TRUE)
|
|
|
@ -1,130 +0,0 @@
|
||||||
vcpkg_from_github(
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libsdl-org/SDL
|
|
||||||
REF "release-${VERSION}"
|
|
||||||
SHA512 90858ae8c5fdddd5e13724e05ad0970e11bbab1df8a0201c3f4ce354dc6018e5d4ab7279402a263c716aacdaa52745f78531dc225d48d790ee9307e2f6198695
|
|
||||||
HEAD_REF main
|
|
||||||
PATCHES
|
|
||||||
deps.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SDL_SHARED)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" FORCE_STATIC_VCRT)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
vulkan SDL_VULKAN
|
|
||||||
x11 SDL_X11
|
|
||||||
wayland SDL_WAYLAND
|
|
||||||
samplerate SDL_LIBSAMPLERATE
|
|
||||||
ibus SDL_IBUS
|
|
||||||
)
|
|
||||||
|
|
||||||
if ("x11" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Xorg dependencies to use feature x11:\nsudo apt install libx11-dev libxft-dev libxext-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("wayland" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Wayland dependencies to use feature wayland:\nsudo apt install libwayland-dev libxkbcommon-dev libegl1-mesa-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("ibus" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install ibus dependencies to use feature ibus:\nsudo apt install libibus-1.0-dev\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
set(configure_opts WINDOWS_USE_MSBUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
${configure_opts}
|
|
||||||
OPTIONS ${FEATURE_OPTIONS}
|
|
||||||
-DSDL_STATIC=${SDL_STATIC}
|
|
||||||
-DSDL_SHARED=${SDL_SHARED}
|
|
||||||
-DSDL_FORCE_STATIC_VCRT=${FORCE_STATIC_VCRT}
|
|
||||||
-DSDL_LIBC=ON
|
|
||||||
-DSDL_TEST=OFF
|
|
||||||
-DSDL_INSTALL_CMAKEDIR="cmake"
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON
|
|
||||||
-DSDL_LIBSAMPLERATE_SHARED=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
SDL_FORCE_STATIC_VCRT
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/licenses"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/aclocal"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB BINS "${CURRENT_PACKAGES_DIR}/debug/bin/*" "${CURRENT_PACKAGES_DIR}/bin/*")
|
|
||||||
if(NOT BINS)
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_UWP AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/lib/SDL2main.lib" "${CURRENT_PACKAGES_DIR}/lib/manual-link/SDL2main.lib")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/SDL2maind.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link/SDL2maind.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB SHARE_FILES "${CURRENT_PACKAGES_DIR}/share/sdl2/*.cmake")
|
|
||||||
foreach(SHARE_FILE ${SHARE_FILES})
|
|
||||||
vcpkg_replace_string("${SHARE_FILE}" "lib/SDL2main" "lib/manual-link/SDL2main")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
|
|
||||||
set(DYLIB_COMPATIBILITY_VERSION_REGEX "set\\(DYLIB_COMPATIBILITY_VERSION (.+)\\)")
|
|
||||||
set(DYLIB_CURRENT_VERSION_REGEX "set\\(DYLIB_CURRENT_VERSION (.+)\\)")
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_COMPATIBILITY_VERSION REGEX ${DYLIB_COMPATIBILITY_VERSION_REGEX})
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_CURRENT_VERSION REGEX ${DYLIB_CURRENT_VERSION_REGEX})
|
|
||||||
string(REGEX REPLACE ${DYLIB_COMPATIBILITY_VERSION_REGEX} "\\1" DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPATIBILITY_VERSION}")
|
|
||||||
string(REGEX REPLACE ${DYLIB_CURRENT_VERSION_REGEX} "\\1" DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}")
|
|
||||||
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2main" "-lSDL2maind")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2 " "-lSDL2d ")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-static " "-lSDL2-staticd ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-lSDL2-static " " ")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-staticd " " ")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "d")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt")
|
|
|
@ -1,8 +0,0 @@
|
||||||
sdl2 provides CMake targets:
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
|
||||||
target_link_libraries(main
|
|
||||||
PRIVATE
|
|
||||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
|
||||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
|
||||||
)
|
|
|
@ -1,58 +0,0 @@
|
||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"version": "2.26.5",
|
|
||||||
"description": "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.",
|
|
||||||
"homepage": "https://www.libsdl.org/download-2.0.php",
|
|
||||||
"license": "Zlib",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
"base"
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"base": {
|
|
||||||
"description": "Base functionality for SDL",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"default-features": false,
|
|
||||||
"features": [
|
|
||||||
"ibus",
|
|
||||||
"wayland",
|
|
||||||
"x11"
|
|
||||||
],
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ibus": {
|
|
||||||
"description": "Build with ibus IME support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"samplerate": {
|
|
||||||
"description": "Use libsamplerate for audio rate conversion",
|
|
||||||
"dependencies": [
|
|
||||||
"libsamplerate"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"vulkan": {
|
|
||||||
"description": "Vulkan functionality for SDL"
|
|
||||||
},
|
|
||||||
"wayland": {
|
|
||||||
"description": "Build with Wayland support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 support",
|
|
||||||
"supports": "!windows"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -40,6 +40,7 @@ add_library(CemuCafe
|
||||||
HW/Espresso/Debugger/DebugSymbolStorage.h
|
HW/Espresso/Debugger/DebugSymbolStorage.h
|
||||||
HW/Espresso/Debugger/GDBStub.h
|
HW/Espresso/Debugger/GDBStub.h
|
||||||
HW/Espresso/Debugger/GDBStub.cpp
|
HW/Espresso/Debugger/GDBStub.cpp
|
||||||
|
HW/Espresso/Debugger/GDBBreakpoints.cpp
|
||||||
HW/Espresso/Debugger/GDBBreakpoints.h
|
HW/Espresso/Debugger/GDBBreakpoints.h
|
||||||
HW/Espresso/EspressoISA.h
|
HW/Espresso/EspressoISA.h
|
||||||
HW/Espresso/Interpreter/PPCInterpreterALU.hpp
|
HW/Espresso/Interpreter/PPCInterpreterALU.hpp
|
||||||
|
@ -534,9 +535,9 @@ endif()
|
||||||
|
|
||||||
if (ENABLE_NSYSHID_LIBUSB)
|
if (ENABLE_NSYSHID_LIBUSB)
|
||||||
if (ENABLE_VCPKG)
|
if (ENABLE_VCPKG)
|
||||||
find_package(libusb CONFIG REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
target_include_directories(CemuCafe PRIVATE ${LIBUSB_INCLUDE_DIRS})
|
pkg_check_modules(libusb REQUIRED IMPORTED_TARGET libusb-1.0)
|
||||||
target_link_libraries(CemuCafe PRIVATE ${LIBUSB_LIBRARIES})
|
target_link_libraries(CemuCafe PRIVATE PkgConfig::libusb)
|
||||||
else ()
|
else ()
|
||||||
find_package(libusb MODULE REQUIRED)
|
find_package(libusb MODULE REQUIRED)
|
||||||
target_link_libraries(CemuCafe PRIVATE libusb::libusb)
|
target_link_libraries(CemuCafe PRIVATE libusb::libusb)
|
||||||
|
|
304
src/Cafe/HW/Espresso/Debugger/GDBBreakpoints.cpp
Normal file
304
src/Cafe/HW/Espresso/Debugger/GDBBreakpoints.cpp
Normal file
|
@ -0,0 +1,304 @@
|
||||||
|
#include "GDBBreakpoints.h"
|
||||||
|
#include "Debugger.h"
|
||||||
|
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
|
||||||
|
|
||||||
|
#if defined(ARCH_X86_64) && BOOST_OS_LINUX
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
|
DRType _GetDR(pid_t tid, int drIndex)
|
||||||
|
{
|
||||||
|
size_t drOffset = offsetof(struct user, u_debugreg) + drIndex * sizeof(user::u_debugreg[0]);
|
||||||
|
|
||||||
|
long v;
|
||||||
|
v = ptrace(PTRACE_PEEKUSER, tid, drOffset, nullptr);
|
||||||
|
if (v == -1)
|
||||||
|
perror("ptrace(PTRACE_PEEKUSER)");
|
||||||
|
|
||||||
|
return (DRType)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _SetDR(pid_t tid, int drIndex, DRType newValue)
|
||||||
|
{
|
||||||
|
size_t drOffset = offsetof(struct user, u_debugreg) + drIndex * sizeof(user::u_debugreg[0]);
|
||||||
|
|
||||||
|
long rc = ptrace(PTRACE_POKEUSER, tid, drOffset, newValue);
|
||||||
|
if (rc == -1)
|
||||||
|
perror("ptrace(PTRACE_POKEUSER)");
|
||||||
|
}
|
||||||
|
|
||||||
|
DRType _ReadDR6()
|
||||||
|
{
|
||||||
|
pid_t tid = gettid();
|
||||||
|
|
||||||
|
// linux doesn't let us attach to the current thread / threads in the current thread group
|
||||||
|
// we have to create a child process which then modifies the debug registers and quits
|
||||||
|
pid_t child = fork();
|
||||||
|
if (child == -1)
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child == 0)
|
||||||
|
{
|
||||||
|
if (ptrace(PTRACE_ATTACH, tid, nullptr, nullptr))
|
||||||
|
{
|
||||||
|
perror("attach");
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
waitpid(tid, NULL, 0);
|
||||||
|
|
||||||
|
uint64_t dr6 = _GetDR(tid, 6);
|
||||||
|
|
||||||
|
if (ptrace(PTRACE_DETACH, tid, nullptr, nullptr))
|
||||||
|
perror("detach");
|
||||||
|
|
||||||
|
// since the status code only uses the lower 8 bits, we have to discard the rest of DR6
|
||||||
|
// this should be fine though, since the lower 4 bits of DR6 contain all the bp conditions
|
||||||
|
_exit(dr6 & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for child process
|
||||||
|
int wstatus;
|
||||||
|
waitpid(child, &wstatus, 0);
|
||||||
|
|
||||||
|
return (DRType)WEXITSTATUS(wstatus);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GDBServer::ExecutionBreakpoint::ExecutionBreakpoint(MPTR address, BreakpointType type, bool visible, std::string reason)
|
||||||
|
: m_address(address), m_removedAfterInterrupt(false), m_reason(std::move(reason))
|
||||||
|
{
|
||||||
|
if (type == BreakpointType::BP_SINGLE)
|
||||||
|
{
|
||||||
|
this->m_pauseThreads = true;
|
||||||
|
this->m_restoreAfterInterrupt = false;
|
||||||
|
this->m_deleteAfterAnyInterrupt = false;
|
||||||
|
this->m_pauseOnNextInterrupt = false;
|
||||||
|
this->m_visible = visible;
|
||||||
|
}
|
||||||
|
else if (type == BreakpointType::BP_PERSISTENT)
|
||||||
|
{
|
||||||
|
this->m_pauseThreads = true;
|
||||||
|
this->m_restoreAfterInterrupt = true;
|
||||||
|
this->m_deleteAfterAnyInterrupt = false;
|
||||||
|
this->m_pauseOnNextInterrupt = false;
|
||||||
|
this->m_visible = visible;
|
||||||
|
}
|
||||||
|
else if (type == BreakpointType::BP_RESTORE_POINT)
|
||||||
|
{
|
||||||
|
this->m_pauseThreads = false;
|
||||||
|
this->m_restoreAfterInterrupt = false;
|
||||||
|
this->m_deleteAfterAnyInterrupt = false;
|
||||||
|
this->m_pauseOnNextInterrupt = false;
|
||||||
|
this->m_visible = false;
|
||||||
|
}
|
||||||
|
else if (type == BreakpointType::BP_STEP_POINT)
|
||||||
|
{
|
||||||
|
this->m_pauseThreads = false;
|
||||||
|
this->m_restoreAfterInterrupt = false;
|
||||||
|
this->m_deleteAfterAnyInterrupt = true;
|
||||||
|
this->m_pauseOnNextInterrupt = true;
|
||||||
|
this->m_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_origOpCode = memory_readU32(address);
|
||||||
|
memory_writeU32(address, DEBUGGER_BP_T_GDBSTUB_TW);
|
||||||
|
PPCRecompiler_invalidateRange(address, address + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBServer::ExecutionBreakpoint::~ExecutionBreakpoint()
|
||||||
|
{
|
||||||
|
memory_writeU32(this->m_address, this->m_origOpCode);
|
||||||
|
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 GDBServer::ExecutionBreakpoint::GetVisibleOpCode() const
|
||||||
|
{
|
||||||
|
if (this->m_visible)
|
||||||
|
return memory_readU32(this->m_address);
|
||||||
|
else
|
||||||
|
return this->m_origOpCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBServer::ExecutionBreakpoint::RemoveTemporarily()
|
||||||
|
{
|
||||||
|
memory_writeU32(this->m_address, this->m_origOpCode);
|
||||||
|
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
||||||
|
this->m_restoreAfterInterrupt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBServer::ExecutionBreakpoint::Restore()
|
||||||
|
{
|
||||||
|
memory_writeU32(this->m_address, DEBUGGER_BP_T_GDBSTUB_TW);
|
||||||
|
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
||||||
|
this->m_restoreAfterInterrupt = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace coreinit
|
||||||
|
{
|
||||||
|
#if BOOST_OS_LINUX
|
||||||
|
std::vector<pid_t>& OSGetSchedulerThreadIds();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<std::thread::native_handle_type>& OSGetSchedulerThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBServer::AccessBreakpoint::AccessBreakpoint(MPTR address, AccessPointType type)
|
||||||
|
: m_address(address), m_type(type)
|
||||||
|
{
|
||||||
|
#if defined(ARCH_X86_64) && BOOST_OS_WINDOWS
|
||||||
|
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
||||||
|
{
|
||||||
|
HANDLE hThread = (HANDLE)hThreadNH;
|
||||||
|
CONTEXT ctx{};
|
||||||
|
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||||
|
SuspendThread(hThread);
|
||||||
|
GetThreadContext(hThread, &ctx);
|
||||||
|
|
||||||
|
// use BP 2/3 for gdb stub since cemu's internal debugger uses BP 0/1 already
|
||||||
|
ctx.Dr2 = (DWORD64)memory_getPointerFromVirtualOffset(address);
|
||||||
|
ctx.Dr3 = (DWORD64)memory_getPointerFromVirtualOffset(address);
|
||||||
|
// breakpoint 2
|
||||||
|
SetBits(ctx.Dr7, 4, 1, 1); // breakpoint #3 enabled: true
|
||||||
|
SetBits(ctx.Dr7, 24, 2, 1); // breakpoint #3 condition: 1 (write)
|
||||||
|
SetBits(ctx.Dr7, 26, 2, 3); // breakpoint #3 length: 3 (4 bytes)
|
||||||
|
// breakpoint 3
|
||||||
|
SetBits(ctx.Dr7, 6, 1, 1); // breakpoint #4 enabled: true
|
||||||
|
SetBits(ctx.Dr7, 28, 2, 3); // breakpoint #4 condition: 3 (read & write)
|
||||||
|
SetBits(ctx.Dr7, 30, 2, 3); // breakpoint #4 length: 3 (4 bytes)
|
||||||
|
|
||||||
|
SetThreadContext(hThread, &ctx);
|
||||||
|
ResumeThread(hThread);
|
||||||
|
}
|
||||||
|
#elif defined(ARCH_X86_64) && BOOST_OS_LINUX
|
||||||
|
// linux doesn't let us attach to threads which are in the same thread group as our current thread
|
||||||
|
// we have to create a child process which then modifies the debug registers and quits
|
||||||
|
pid_t child = fork();
|
||||||
|
if (child == -1)
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child == 0)
|
||||||
|
{
|
||||||
|
for (pid_t tid : coreinit::OSGetSchedulerThreadIds())
|
||||||
|
{
|
||||||
|
long rc = ptrace(PTRACE_ATTACH, tid, nullptr, nullptr);
|
||||||
|
if (rc == -1)
|
||||||
|
perror("ptrace(PTRACE_ATTACH)");
|
||||||
|
|
||||||
|
waitpid(tid, nullptr, 0);
|
||||||
|
|
||||||
|
DRType dr7 = _GetDR(tid, 7);
|
||||||
|
// use BP 2/3 for gdb stub since cemu's internal debugger uses BP 0/1 already
|
||||||
|
DRType dr2 = (uint64)memory_getPointerFromVirtualOffset(address);
|
||||||
|
DRType dr3 = (uint64)memory_getPointerFromVirtualOffset(address);
|
||||||
|
// breakpoint 2
|
||||||
|
SetBits(dr7, 4, 1, 1); // breakpoint #3 enabled: true
|
||||||
|
SetBits(dr7, 24, 2, 1); // breakpoint #3 condition: 1 (write)
|
||||||
|
SetBits(dr7, 26, 2, 3); // breakpoint #3 length: 3 (4 bytes)
|
||||||
|
// breakpoint 3
|
||||||
|
SetBits(dr7, 6, 1, 1); // breakpoint #4 enabled: true
|
||||||
|
SetBits(dr7, 28, 2, 3); // breakpoint #4 condition: 3 (read & write)
|
||||||
|
SetBits(dr7, 30, 2, 3); // breakpoint #4 length: 3 (4 bytes)
|
||||||
|
|
||||||
|
_SetDR(tid, 2, dr2);
|
||||||
|
_SetDR(tid, 3, dr3);
|
||||||
|
_SetDR(tid, 7, dr7);
|
||||||
|
|
||||||
|
rc = ptrace(PTRACE_DETACH, tid, nullptr, nullptr);
|
||||||
|
if (rc == -1)
|
||||||
|
perror("ptrace(PTRACE_DETACH)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit child process
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for child process
|
||||||
|
waitpid(child, nullptr, 0);
|
||||||
|
#else
|
||||||
|
cemuLog_log(LogType::Force, "Debugger read/write breakpoints are not supported on non-x86 CPUs yet.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
GDBServer::AccessBreakpoint::~AccessBreakpoint()
|
||||||
|
{
|
||||||
|
#if defined(ARCH_X86_64) && BOOST_OS_WINDOWS
|
||||||
|
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
||||||
|
{
|
||||||
|
HANDLE hThread = (HANDLE)hThreadNH;
|
||||||
|
CONTEXT ctx{};
|
||||||
|
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
||||||
|
SuspendThread(hThread);
|
||||||
|
GetThreadContext(hThread, &ctx);
|
||||||
|
|
||||||
|
// reset BP 2/3 to zero
|
||||||
|
ctx.Dr2 = (DWORD64)0;
|
||||||
|
ctx.Dr3 = (DWORD64)0;
|
||||||
|
// breakpoint 2
|
||||||
|
SetBits(ctx.Dr7, 4, 1, 0);
|
||||||
|
SetBits(ctx.Dr7, 24, 2, 0);
|
||||||
|
SetBits(ctx.Dr7, 26, 2, 0);
|
||||||
|
// breakpoint 3
|
||||||
|
SetBits(ctx.Dr7, 6, 1, 0);
|
||||||
|
SetBits(ctx.Dr7, 28, 2, 0);
|
||||||
|
SetBits(ctx.Dr7, 30, 2, 0);
|
||||||
|
SetThreadContext(hThread, &ctx);
|
||||||
|
ResumeThread(hThread);
|
||||||
|
}
|
||||||
|
#elif defined(ARCH_X86_64) && BOOST_OS_LINUX
|
||||||
|
// linux doesn't let us attach to threads which are in the same thread group as our current thread
|
||||||
|
// we have to create a child process which then modifies the debug registers and quits
|
||||||
|
pid_t child = fork();
|
||||||
|
if (child == -1)
|
||||||
|
{
|
||||||
|
perror("fork");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child == 0)
|
||||||
|
{
|
||||||
|
for (pid_t tid : coreinit::OSGetSchedulerThreadIds())
|
||||||
|
{
|
||||||
|
long rc = ptrace(PTRACE_ATTACH, tid, nullptr, nullptr);
|
||||||
|
if (rc == -1)
|
||||||
|
perror("ptrace(PTRACE_ATTACH)");
|
||||||
|
|
||||||
|
waitpid(tid, nullptr, 0);
|
||||||
|
|
||||||
|
DRType dr7 = _GetDR(tid, 7);
|
||||||
|
// reset BP 2/3 to zero
|
||||||
|
DRType dr2 = 0;
|
||||||
|
DRType dr3 = 0;
|
||||||
|
// breakpoint 2
|
||||||
|
SetBits(dr7, 4, 1, 0);
|
||||||
|
SetBits(dr7, 24, 2, 0);
|
||||||
|
SetBits(dr7, 26, 2, 0);
|
||||||
|
// breakpoint 3
|
||||||
|
SetBits(dr7, 6, 1, 0);
|
||||||
|
SetBits(dr7, 28, 2, 0);
|
||||||
|
SetBits(dr7, 30, 2, 0);
|
||||||
|
|
||||||
|
_SetDR(tid, 2, dr2);
|
||||||
|
_SetDR(tid, 3, dr3);
|
||||||
|
_SetDR(tid, 7, dr7);
|
||||||
|
|
||||||
|
rc = ptrace(PTRACE_DETACH, tid, nullptr, nullptr);
|
||||||
|
if (rc == -1)
|
||||||
|
perror("ptrace(PTRACE_DETACH)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit child process
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for child process
|
||||||
|
waitpid(child, nullptr, 0);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -1,33 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
#include "GDBStub.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined(ARCH_X86_64) && BOOST_OS_LINUX && FALSE
|
#if defined(ARCH_X86_64) && BOOST_OS_LINUX
|
||||||
#include <sys/ptrace.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/user.h>
|
|
||||||
|
|
||||||
// helpers for accessing debug register
|
// helpers for accessing debug register
|
||||||
typedef unsigned long DRType;
|
typedef unsigned long DRType;
|
||||||
|
|
||||||
DRType _GetDR(pid_t tid, int drIndex)
|
DRType _GetDR(pid_t tid, int drIndex);
|
||||||
{
|
void _SetDR(pid_t tid, int drIndex, DRType newValue);
|
||||||
unsigned long v;
|
DRType _ReadDR6();
|
||||||
v = ptrace (PTRACE_PEEKUSER, tid, offsetof (struct user, u_debugreg[drIndex]), 0);
|
|
||||||
return (DRType)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _SetDR(pid_t tid, int drIndex, DRType newValue)
|
|
||||||
{
|
|
||||||
unsigned long v = newValue;
|
|
||||||
ptrace (PTRACE_POKEUSER, tid, offsetof (struct user, u_debugreg[drIndex]), v);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace coreinit
|
|
||||||
{
|
|
||||||
std::vector<std::thread::native_handle_type>& OSGetSchedulerThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class BreakpointType
|
enum class BreakpointType
|
||||||
{
|
{
|
||||||
BP_SINGLE,
|
BP_SINGLE,
|
||||||
|
@ -38,59 +23,10 @@ enum class BreakpointType
|
||||||
|
|
||||||
class GDBServer::ExecutionBreakpoint {
|
class GDBServer::ExecutionBreakpoint {
|
||||||
public:
|
public:
|
||||||
ExecutionBreakpoint(MPTR address, BreakpointType type, bool visible, std::string reason)
|
ExecutionBreakpoint(MPTR address, BreakpointType type, bool visible, std::string reason);
|
||||||
: m_address(address), m_removedAfterInterrupt(false), m_reason(std::move(reason))
|
~ExecutionBreakpoint();
|
||||||
{
|
|
||||||
if (type == BreakpointType::BP_SINGLE)
|
|
||||||
{
|
|
||||||
this->m_pauseThreads = true;
|
|
||||||
this->m_restoreAfterInterrupt = false;
|
|
||||||
this->m_deleteAfterAnyInterrupt = false;
|
|
||||||
this->m_pauseOnNextInterrupt = false;
|
|
||||||
this->m_visible = visible;
|
|
||||||
}
|
|
||||||
else if (type == BreakpointType::BP_PERSISTENT)
|
|
||||||
{
|
|
||||||
this->m_pauseThreads = true;
|
|
||||||
this->m_restoreAfterInterrupt = true;
|
|
||||||
this->m_deleteAfterAnyInterrupt = false;
|
|
||||||
this->m_pauseOnNextInterrupt = false;
|
|
||||||
this->m_visible = visible;
|
|
||||||
}
|
|
||||||
else if (type == BreakpointType::BP_RESTORE_POINT)
|
|
||||||
{
|
|
||||||
this->m_pauseThreads = false;
|
|
||||||
this->m_restoreAfterInterrupt = false;
|
|
||||||
this->m_deleteAfterAnyInterrupt = false;
|
|
||||||
this->m_pauseOnNextInterrupt = false;
|
|
||||||
this->m_visible = false;
|
|
||||||
}
|
|
||||||
else if (type == BreakpointType::BP_STEP_POINT)
|
|
||||||
{
|
|
||||||
this->m_pauseThreads = false;
|
|
||||||
this->m_restoreAfterInterrupt = false;
|
|
||||||
this->m_deleteAfterAnyInterrupt = true;
|
|
||||||
this->m_pauseOnNextInterrupt = true;
|
|
||||||
this->m_visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->m_origOpCode = memory_readU32(address);
|
[[nodiscard]] uint32 GetVisibleOpCode() const;
|
||||||
memory_writeU32(address, DEBUGGER_BP_T_GDBSTUB_TW);
|
|
||||||
PPCRecompiler_invalidateRange(address, address + 4);
|
|
||||||
};
|
|
||||||
~ExecutionBreakpoint()
|
|
||||||
{
|
|
||||||
memory_writeU32(this->m_address, this->m_origOpCode);
|
|
||||||
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] uint32 GetVisibleOpCode() const
|
|
||||||
{
|
|
||||||
if (this->m_visible)
|
|
||||||
return memory_readU32(this->m_address);
|
|
||||||
else
|
|
||||||
return this->m_origOpCode;
|
|
||||||
};
|
|
||||||
[[nodiscard]] bool ShouldBreakThreads() const
|
[[nodiscard]] bool ShouldBreakThreads() const
|
||||||
{
|
{
|
||||||
return this->m_pauseThreads;
|
return this->m_pauseThreads;
|
||||||
|
@ -118,18 +54,8 @@ public:
|
||||||
return m_reason;
|
return m_reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
void RemoveTemporarily()
|
void RemoveTemporarily();
|
||||||
{
|
void Restore();
|
||||||
memory_writeU32(this->m_address, this->m_origOpCode);
|
|
||||||
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
|
||||||
this->m_restoreAfterInterrupt = true;
|
|
||||||
};
|
|
||||||
void Restore()
|
|
||||||
{
|
|
||||||
memory_writeU32(this->m_address, DEBUGGER_BP_T_GDBSTUB_TW);
|
|
||||||
PPCRecompiler_invalidateRange(this->m_address, this->m_address + 4);
|
|
||||||
this->m_restoreAfterInterrupt = false;
|
|
||||||
};
|
|
||||||
void PauseOnNextInterrupt()
|
void PauseOnNextInterrupt()
|
||||||
{
|
{
|
||||||
this->m_pauseOnNextInterrupt = true;
|
this->m_pauseOnNextInterrupt = true;
|
||||||
|
@ -162,115 +88,8 @@ enum class AccessPointType
|
||||||
|
|
||||||
class GDBServer::AccessBreakpoint {
|
class GDBServer::AccessBreakpoint {
|
||||||
public:
|
public:
|
||||||
AccessBreakpoint(MPTR address, AccessPointType type)
|
AccessBreakpoint(MPTR address, AccessPointType type);
|
||||||
: m_address(address), m_type(type)
|
~AccessBreakpoint();
|
||||||
{
|
|
||||||
#if defined(ARCH_X86_64) && BOOST_OS_WINDOWS
|
|
||||||
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
|
||||||
{
|
|
||||||
HANDLE hThread = (HANDLE)hThreadNH;
|
|
||||||
CONTEXT ctx{};
|
|
||||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
|
||||||
SuspendThread(hThread);
|
|
||||||
GetThreadContext(hThread, &ctx);
|
|
||||||
|
|
||||||
// use BP 2/3 for gdb stub since cemu's internal debugger uses BP 0/1 already
|
|
||||||
ctx.Dr2 = (DWORD64)memory_getPointerFromVirtualOffset(address);
|
|
||||||
ctx.Dr3 = (DWORD64)memory_getPointerFromVirtualOffset(address);
|
|
||||||
// breakpoint 2
|
|
||||||
SetBits(ctx.Dr7, 4, 1, 1); // breakpoint #3 enabled: true
|
|
||||||
SetBits(ctx.Dr7, 24, 2, 1); // breakpoint #3 condition: 1 (write)
|
|
||||||
SetBits(ctx.Dr7, 26, 2, 3); // breakpoint #3 length: 3 (4 bytes)
|
|
||||||
// breakpoint 3
|
|
||||||
SetBits(ctx.Dr7, 6, 1, 1); // breakpoint #4 enabled: true
|
|
||||||
SetBits(ctx.Dr7, 28, 2, 3); // breakpoint #4 condition: 3 (read & write)
|
|
||||||
SetBits(ctx.Dr7, 30, 2, 3); // breakpoint #4 length: 3 (4 bytes)
|
|
||||||
|
|
||||||
SetThreadContext(hThread, &ctx);
|
|
||||||
ResumeThread(hThread);
|
|
||||||
}
|
|
||||||
// todo: port the following code to all unix platforms, they seem to differ quite a bit
|
|
||||||
#elif defined(ARCH_X86_64) && BOOST_OS_LINUX && FALSE
|
|
||||||
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
|
||||||
{
|
|
||||||
pid_t pid = (pid_t)(uintptr_t)hThreadNH;
|
|
||||||
ptrace(PTRACE_ATTACH, pid, nullptr, nullptr);
|
|
||||||
waitpid(pid, nullptr, 0);
|
|
||||||
|
|
||||||
DRType dr7 = _GetDR(pid, 7);
|
|
||||||
// use BP 2/3 for gdb stub since cemu's internal debugger uses BP 0/1 already
|
|
||||||
DRType dr2 = (uint64)memory_getPointerFromVirtualOffset(address);
|
|
||||||
DRType dr3 = (uint64)memory_getPointerFromVirtualOffset(address);
|
|
||||||
// breakpoint 2
|
|
||||||
SetBits(dr7, 4, 1, 1); // breakpoint #3 enabled: true
|
|
||||||
SetBits(dr7, 24, 2, 1); // breakpoint #3 condition: 1 (write)
|
|
||||||
SetBits(dr7, 26, 2, 3); // breakpoint #3 length: 3 (4 bytes)
|
|
||||||
// breakpoint 3
|
|
||||||
SetBits(dr7, 6, 1, 1); // breakpoint #4 enabled: true
|
|
||||||
SetBits(dr7, 28, 2, 3); // breakpoint #4 condition: 3 (read & write)
|
|
||||||
SetBits(dr7, 30, 2, 3); // breakpoint #4 length: 3 (4 bytes)
|
|
||||||
|
|
||||||
_SetDR(pid, 2, dr2);
|
|
||||||
_SetDR(pid, 3, dr3);
|
|
||||||
_SetDR(pid, 7, dr7);
|
|
||||||
ptrace(PTRACE_DETACH, pid, nullptr, nullptr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
cemuLog_log(LogType::Force, "Debugger read/write breakpoints are not supported on non-x86 CPUs yet.");
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
~AccessBreakpoint()
|
|
||||||
{
|
|
||||||
#if defined(ARCH_X86_64) && BOOST_OS_WINDOWS
|
|
||||||
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
|
||||||
{
|
|
||||||
HANDLE hThread = (HANDLE)hThreadNH;
|
|
||||||
CONTEXT ctx{};
|
|
||||||
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
|
|
||||||
SuspendThread(hThread);
|
|
||||||
GetThreadContext(hThread, &ctx);
|
|
||||||
|
|
||||||
// reset BP 2/3 to zero
|
|
||||||
ctx.Dr2 = (DWORD64)0;
|
|
||||||
ctx.Dr3 = (DWORD64)0;
|
|
||||||
// breakpoint 2
|
|
||||||
SetBits(ctx.Dr7, 4, 1, 0);
|
|
||||||
SetBits(ctx.Dr7, 24, 2, 0);
|
|
||||||
SetBits(ctx.Dr7, 26, 2, 0);
|
|
||||||
// breakpoint 3
|
|
||||||
SetBits(ctx.Dr7, 6, 1, 0);
|
|
||||||
SetBits(ctx.Dr7, 28, 2, 0);
|
|
||||||
SetBits(ctx.Dr7, 30, 2, 0);
|
|
||||||
SetThreadContext(hThread, &ctx);
|
|
||||||
ResumeThread(hThread);
|
|
||||||
}
|
|
||||||
#elif defined(ARCH_X86_64) && BOOST_OS_LINUX && FALSE
|
|
||||||
for (auto& hThreadNH : coreinit::OSGetSchedulerThreads())
|
|
||||||
{
|
|
||||||
pid_t pid = (pid_t)(uintptr_t)hThreadNH;
|
|
||||||
ptrace(PTRACE_ATTACH, pid, nullptr, nullptr);
|
|
||||||
waitpid(pid, nullptr, 0);
|
|
||||||
|
|
||||||
DRType dr7 = _GetDR(pid, 7);
|
|
||||||
// reset BP 2/3 to zero
|
|
||||||
DRType dr2 = 0;
|
|
||||||
DRType dr3 = 0;
|
|
||||||
// breakpoint 2
|
|
||||||
SetBits(dr7, 4, 1, 0);
|
|
||||||
SetBits(dr7, 24, 2, 0);
|
|
||||||
SetBits(dr7, 26, 2, 0);
|
|
||||||
// breakpoint 3
|
|
||||||
SetBits(dr7, 6, 1, 0);
|
|
||||||
SetBits(dr7, 28, 2, 0);
|
|
||||||
SetBits(dr7, 30, 2, 0);
|
|
||||||
|
|
||||||
_SetDR(pid, 2, dr2);
|
|
||||||
_SetDR(pid, 3, dr3);
|
|
||||||
_SetDR(pid, 7, dr7);
|
|
||||||
ptrace(PTRACE_DETACH, pid, nullptr, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
MPTR GetAddress() const
|
MPTR GetAddress() const
|
||||||
{
|
{
|
||||||
|
@ -284,4 +103,4 @@ public:
|
||||||
private:
|
private:
|
||||||
const MPTR m_address;
|
const MPTR m_address;
|
||||||
const AccessPointType m_type;
|
const AccessPointType m_type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -263,6 +263,14 @@ bool GDBServer::Initialize()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nodelayEnabled = TRUE;
|
||||||
|
if (setsockopt(m_server_socket, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelayEnabled, sizeof(nodelayEnabled)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
closesocket(m_server_socket);
|
||||||
|
m_server_socket = INVALID_SOCKET;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&m_server_addr, 0, sizeof(m_server_addr));
|
memset(&m_server_addr, 0, sizeof(m_server_addr));
|
||||||
m_server_addr.sin_family = AF_INET;
|
m_server_addr.sin_family = AF_INET;
|
||||||
m_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
m_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
|
@ -246,6 +246,22 @@ static void _appendPVPS(LatteDecompilerShaderContext* shaderContext, StringBuf*
|
||||||
_appendChannel(src, aluUnit);
|
_appendChannel(src, aluUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string _FormatFloatAsGLSLConstant(float f)
|
||||||
|
{
|
||||||
|
char floatAsStr[64];
|
||||||
|
size_t floatAsStrLen = fmt::format_to_n(floatAsStr, 64, "{:#}", f).size;
|
||||||
|
size_t floatAsStrLenOrg = floatAsStrLen;
|
||||||
|
if(floatAsStrLen > 0 && floatAsStr[floatAsStrLen-1] == '.')
|
||||||
|
{
|
||||||
|
floatAsStr[floatAsStrLen] = '0';
|
||||||
|
floatAsStrLen++;
|
||||||
|
}
|
||||||
|
cemu_assert(floatAsStrLen < 50); // constant suspiciously long?
|
||||||
|
floatAsStr[floatAsStrLen] = '\0';
|
||||||
|
cemu_assert_debug(floatAsStrLen >= 3); // shortest possible form is "0.0"
|
||||||
|
return floatAsStr;
|
||||||
|
}
|
||||||
|
|
||||||
// tracks PV/PS and register backups
|
// tracks PV/PS and register backups
|
||||||
struct ALUClauseTemporariesState
|
struct ALUClauseTemporariesState
|
||||||
{
|
{
|
||||||
|
@ -926,15 +942,7 @@ void _emitOperandInputCode(LatteDecompilerShaderContext* shaderContext, LatteDec
|
||||||
exponent -= 127;
|
exponent -= 127;
|
||||||
if ((constVal & 0xFF) == 0 && exponent >= -10 && exponent <= 10)
|
if ((constVal & 0xFF) == 0 && exponent >= -10 && exponent <= 10)
|
||||||
{
|
{
|
||||||
char floatAsStr[32];
|
src->add(_FormatFloatAsGLSLConstant(*(float*)&constVal));
|
||||||
size_t floatAsStrLen = fmt::format_to_n(floatAsStr, 32, "{:#}", *(float*)&constVal).size;
|
|
||||||
if(floatAsStrLen > 0 && floatAsStr[floatAsStrLen-1] == '.')
|
|
||||||
{
|
|
||||||
floatAsStr[floatAsStrLen] = '0';
|
|
||||||
floatAsStrLen++;
|
|
||||||
}
|
|
||||||
cemu_assert_debug(floatAsStrLen >= 3); // shortest possible form is "0.0"
|
|
||||||
src->add(std::string_view(floatAsStr, floatAsStrLen));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
src->addFmt("intBitsToFloat(0x{:08x})", constVal);
|
src->addFmt("intBitsToFloat(0x{:08x})", constVal);
|
||||||
|
@ -2561,13 +2569,11 @@ void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContext, Latt
|
||||||
// lod or lod bias parameter
|
// lod or lod bias parameter
|
||||||
if( texOpcode == GPU7_TEX_INST_SAMPLE_L || texOpcode == GPU7_TEX_INST_SAMPLE_LB || texOpcode == GPU7_TEX_INST_SAMPLE_C_L)
|
if( texOpcode == GPU7_TEX_INST_SAMPLE_L || texOpcode == GPU7_TEX_INST_SAMPLE_LB || texOpcode == GPU7_TEX_INST_SAMPLE_C_L)
|
||||||
{
|
{
|
||||||
|
src->add(",");
|
||||||
if(texOpcode == GPU7_TEX_INST_SAMPLE_LB)
|
if(texOpcode == GPU7_TEX_INST_SAMPLE_LB)
|
||||||
src->addFmt("{}", (float)texInstruction->textureFetch.lodBias / 16.0f);
|
src->add(_FormatFloatAsGLSLConstant((float)texInstruction->textureFetch.lodBias / 16.0f));
|
||||||
else
|
else
|
||||||
{
|
|
||||||
src->add(",");
|
|
||||||
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 3, LATTE_DECOMPILER_DTYPE_FLOAT);
|
_emitTEXSampleCoordInputComponent(shaderContext, texInstruction, 3, LATTE_DECOMPILER_DTYPE_FLOAT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( texOpcode == GPU7_TEX_INST_SAMPLE_LZ || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
else if( texOpcode == GPU7_TEX_INST_SAMPLE_LZ || texOpcode == GPU7_TEX_INST_SAMPLE_C_LZ )
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
|
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
|
||||||
#include "Cafe/OS/libs/coreinit/coreinit_Alarm.h"
|
#include "Cafe/OS/libs/coreinit/coreinit_Alarm.h"
|
||||||
#include "Cafe/OS/libs/snd_core/ax.h"
|
#include "Cafe/OS/libs/snd_core/ax.h"
|
||||||
|
#include "Cafe/HW/Espresso/Debugger/GDBStub.h"
|
||||||
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
|
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
|
||||||
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
|
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
|
||||||
|
|
||||||
|
@ -1153,6 +1154,18 @@ namespace coreinit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOOST_OS_LINUX
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
|
||||||
|
std::vector<pid_t> g_schedulerThreadIds;
|
||||||
|
|
||||||
|
std::vector<pid_t>& OSGetSchedulerThreadIds()
|
||||||
|
{
|
||||||
|
return g_schedulerThreadIds;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void OSSchedulerCoreEmulationThread(void* _assignedCoreIndex)
|
void OSSchedulerCoreEmulationThread(void* _assignedCoreIndex)
|
||||||
{
|
{
|
||||||
SetThreadName(fmt::format("OSSchedulerThread[core={}]", (uintptr_t)_assignedCoreIndex).c_str());
|
SetThreadName(fmt::format("OSSchedulerThread[core={}]", (uintptr_t)_assignedCoreIndex).c_str());
|
||||||
|
@ -1160,8 +1173,21 @@ namespace coreinit
|
||||||
#if defined(ARCH_X86_64)
|
#if defined(ARCH_X86_64)
|
||||||
_mm_setcsr(_mm_getcsr() | 0x8000); // flush denormals to zero
|
_mm_setcsr(_mm_getcsr() | 0x8000); // flush denormals to zero
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_OS_LINUX
|
||||||
|
if (g_gdbstub)
|
||||||
|
{
|
||||||
|
// need to allow the GDBStub to attach to our thread
|
||||||
|
prctl(PR_SET_DUMPABLE, (unsigned long)1);
|
||||||
|
prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t tid = gettid();
|
||||||
|
g_schedulerThreadIds.emplace_back(tid);
|
||||||
|
#endif
|
||||||
|
|
||||||
t_schedulerFiber = Fiber::PrepareCurrentThread();
|
t_schedulerFiber = Fiber::PrepareCurrentThread();
|
||||||
|
|
||||||
// create scheduler idle fiber and switch to it
|
// create scheduler idle fiber and switch to it
|
||||||
g_idleLoopFiber[t_assignedCoreIndex] = new Fiber(__OSThreadCoreIdle, nullptr, nullptr);
|
g_idleLoopFiber[t_assignedCoreIndex] = new Fiber(__OSThreadCoreIdle, nullptr, nullptr);
|
||||||
cemu_assert_debug(PPCInterpreter_getCurrentInstance() == nullptr);
|
cemu_assert_debug(PPCInterpreter_getCurrentInstance() == nullptr);
|
||||||
|
@ -1211,6 +1237,9 @@ namespace coreinit
|
||||||
threadItr.join();
|
threadItr.join();
|
||||||
sSchedulerThreads.clear();
|
sSchedulerThreads.clear();
|
||||||
g_schedulerThreadHandles.clear();
|
g_schedulerThreadHandles.clear();
|
||||||
|
#if BOOST_OS_LINUX
|
||||||
|
g_schedulerThreadIds.clear();
|
||||||
|
#endif
|
||||||
// clean up all fibers
|
// clean up all fibers
|
||||||
for (auto& it : g_idleLoopFiber)
|
for (auto& it : g_idleLoopFiber)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include "util/helpers/StringHelpers.h"
|
#include "util/helpers/StringHelpers.h"
|
||||||
#include "ExceptionHandler.h"
|
#include "ExceptionHandler.h"
|
||||||
|
|
||||||
|
#include "Cafe/HW/Espresso/Debugger/GDBStub.h"
|
||||||
|
#include "Cafe/HW/Espresso/Debugger/GDBBreakpoints.h"
|
||||||
|
|
||||||
#if BOOST_OS_LINUX
|
#if BOOST_OS_LINUX
|
||||||
#include "ELFSymbolTable.h"
|
#include "ELFSymbolTable.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,6 +64,16 @@ void DemangleAndPrintBacktrace(char** backtrace, size_t size)
|
||||||
// handle signals that would dump core, print stacktrace and then dump depending on config
|
// handle signals that would dump core, print stacktrace and then dump depending on config
|
||||||
void handlerDumpingSignal(int sig, siginfo_t *info, void *context)
|
void handlerDumpingSignal(int sig, siginfo_t *info, void *context)
|
||||||
{
|
{
|
||||||
|
#if defined(ARCH_X86_64) && BOOST_OS_LINUX
|
||||||
|
// Check for hardware breakpoints
|
||||||
|
if (info->si_signo == SIGTRAP && info->si_code == TRAP_HWBKPT)
|
||||||
|
{
|
||||||
|
uint64 dr6 = _ReadDR6();
|
||||||
|
g_gdbstub->HandleAccessException(dr6);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!CrashLog_Create())
|
if(!CrashLog_Create())
|
||||||
return; // give up if crashlog was already created
|
return; // give up if crashlog was already created
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "cemu",
|
"name": "cemu",
|
||||||
"version-string": "1.0",
|
"version-string": "1.0",
|
||||||
"builtin-baseline": "b81bc3a83fdbdffe80325eeabb2ec735a1f3c29d",
|
"builtin-baseline": "53bef8994c541b6561884a8395ea35715ece75db",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"pugixml",
|
"pugixml",
|
||||||
"zlib",
|
"zlib",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue