From 6f4c6ae0bbf6dae71c59a4d572bad7290fa17d09 Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Fri, 23 Feb 2024 22:57:57 +0200 Subject: [PATCH] code: Add clang-format target and CI workflow (#82) * code: Add clang format target, rules and CI workflow * code: Run clang format on sources --- .ci/clang-format.sh | 37 + .github/workflows/format.yml | 21 + CMakeLists.txt | 51 + src/.clang-format | 256 +++++ src/Emulator/Host/controller.cpp | 7 +- src/Emulator/Host/controller.h | 11 +- src/GUI/ElfViewer.cpp | 79 +- src/Util/config.cpp | 23 +- src/Util/config.h | 2 +- src/common/disassembler.cpp | 29 +- src/common/disassembler.h | 6 +- src/common/discord.cpp | 40 +- src/common/discord.h | 22 +- src/common/fs_file.cpp | 16 +- src/common/fs_file.h | 44 +- src/common/io_file.cpp | 6 +- src/common/io_file.h | 3 +- src/common/log.cpp | 116 ++- src/common/log.h | 30 +- src/common/native_clock.cpp | 8 +- src/common/rdtsc.cpp | 2 +- src/common/string_util.cpp | 2 +- src/common/string_util.h | 2 +- src/common/types.h | 12 +- src/core/PS4/GPU/gpu_memory.cpp | 37 +- src/core/PS4/GPU/gpu_memory.h | 28 +- src/core/PS4/GPU/tile_manager.cpp | 58 +- src/core/PS4/GPU/video_out_buffer.cpp | 55 +- src/core/PS4/GPU/video_out_buffer.h | 7 +- .../HLE/Graphics/Objects/video_out_ctx.cpp | 14 +- .../PS4/HLE/Graphics/Objects/video_out_ctx.h | 18 +- src/core/PS4/HLE/Graphics/graphics_ctx.h | 10 +- src/core/PS4/HLE/Graphics/graphics_render.cpp | 11 +- src/core/PS4/HLE/Graphics/graphics_render.h | 41 +- src/core/PS4/HLE/Graphics/video_out.cpp | 132 ++- src/core/PS4/HLE/Graphics/video_out.h | 30 +- src/core/aerolib/aerolib.cpp | 3 +- src/core/aerolib/stubs.cpp | 23 +- src/core/file_sys/fs.cpp | 10 +- src/core/file_sys/fs.h | 16 +- src/core/hle/error_codes.h | 22 +- src/core/hle/kernel/Objects/event_queue.cpp | 6 +- src/core/hle/kernel/Objects/event_queue.h | 29 +- .../hle/kernel/Objects/physical_memory.cpp | 4 +- src/core/hle/kernel/Objects/physical_memory.h | 14 +- src/core/hle/kernel/cpu_management.cpp | 2 +- src/core/hle/kernel/event_queues.cpp | 25 +- src/core/hle/kernel/event_queues.h | 4 +- src/core/hle/kernel/memory_management.cpp | 61 +- src/core/hle/kernel/memory_management.h | 28 +- src/core/hle/libraries/libc/libc.cpp | 294 +++--- src/core/hle/libraries/libc/libc.h | 2 +- src/core/hle/libraries/libc/libc_cxa.cpp | 47 +- src/core/hle/libraries/libc/libc_stdio.cpp | 4 +- src/core/hle/libraries/libc/libc_stdlib.cpp | 7 +- src/core/hle/libraries/libc/libc_stdlib.h | 3 +- src/core/hle/libraries/libc/printf.h | 494 ++++----- src/core/hle/libraries/libc/va_ctx.h | 47 +- .../hle/libraries/libkernel/file_system.cpp | 20 +- .../hle/libraries/libkernel/file_system.h | 8 +- .../hle/libraries/libkernel/libkernel.cpp | 47 +- src/core/hle/libraries/libkernel/libkernel.h | 2 +- .../libraries/libkernel/thread_management.cpp | 207 ++-- .../libraries/libkernel/thread_management.h | 39 +- .../libraries/libkernel/time_management.cpp | 7 +- src/core/hle/libraries/libpad/pad.cpp | 30 +- src/core/hle/libraries/libpad/pad.h | 2 +- src/core/hle/libraries/libs.cpp | 14 +- src/core/hle/libraries/libs.h | 58 +- .../libscegnmdriver/libscegnmdriver.cpp | 6 +- .../libsystemservice/system_service.cpp | 8 +- .../libsystemservice/system_service.h | 2 +- .../libuserservice/libuserservice.cpp | 8 +- .../libraries/libuserservice/usr_mng_codes.h | 15 +- src/core/linker.cpp | 934 +++++++++--------- src/core/linker.h | 63 +- src/core/loader/elf.cpp | 332 ++++--- src/core/loader/elf.h | 94 +- src/core/loader/symbols_resolver.cpp | 15 +- src/core/loader/symbols_resolver.h | 10 +- src/core/virtual_memory.cpp | 79 +- src/core/virtual_memory.h | 17 +- src/emulator.cpp | 146 ++- src/emulator.h | 6 +- src/main.cpp | 7 +- src/video_core/gpu_memory.cpp | 37 +- src/video_core/gpu_memory.h | 16 +- src/video_core/tile_manager.cpp | 40 +- src/vulkan_util.cpp | 164 +-- src/vulkan_util.h | 39 +- 90 files changed, 2942 insertions(+), 1941 deletions(-) create mode 100755 .ci/clang-format.sh create mode 100644 .github/workflows/format.yml create mode 100644 src/.clang-format diff --git a/.ci/clang-format.sh b/.ci/clang-format.sh new file mode 100755 index 00000000..8aa078f0 --- /dev/null +++ b/.ci/clang-format.sh @@ -0,0 +1,37 @@ +#!/bin/bash -ex + +if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dist/*.desktop \ + dist/*.svg dist/*.xml; then + echo Trailing whitespace found, aborting + exit 1 +fi + +# Default clang-format points to default 3.5 version one +CLANG_FORMAT=clang-format-15 +$CLANG_FORMAT --version + +if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then + # Get list of every file modified in this pull request + files_to_lint="$(git diff --name-only --diff-filter=ACMRTUXB $COMMIT_RANGE | grep '^src/[^.]*[.]\(cpp\|h\)$' || true)" +else + # Check everything for branch pushes + files_to_lint="$(find src/ -name '*.cpp' -or -name '*.h')" +fi + +# Turn off tracing for this because it's too verbose +set +x + +for f in $files_to_lint; do + d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true) + if ! [ -z "$d" ]; then + echo "!!! $f not compliant to coding style, here is the fix:" + echo "$d" + fail=1 + fi +done + +set -x + +if [ "$fail" = 1 ]; then + exit 1 +fi diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 00000000..a823da8b --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,21 @@ +name: Clang Format + +on: + push: + branches: [ "*" ] + pull_request: + branches: [ main ] + +jobs: + clang-format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install + run: sudo apt-get install clang-format-15 + - name: Build + env: + COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} + run: ./.ci/clang-format.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f148834..c440341c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,57 @@ function(create_target_directory_groups target_name) endforeach() endfunction() + +# Setup a custom clang-format target (if clang-format can be found) that will run +# against all the src files. This should be used before making a pull request. +# ======================================================================= + +set(CLANG_FORMAT_POSTFIX "-15") +find_program(CLANG_FORMAT + NAMES clang-format${CLANG_FORMAT_POSTFIX} + clang-format + PATHS ${PROJECT_BINARY_DIR}/externals) +# if find_program doesn't find it, try to download from externals +if (NOT CLANG_FORMAT) + if (WIN32) + message(STATUS "Clang format not found! Downloading...") + set(CLANG_FORMAT "${PROJECT_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe") + file(DOWNLOAD + https://github.com/citra-emu/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe + "${CLANG_FORMAT}" SHOW_PROGRESS + STATUS DOWNLOAD_SUCCESS) + if (NOT DOWNLOAD_SUCCESS EQUAL 0) + message(WARNING "Could not download clang format! Disabling the clang format target") + file(REMOVE ${CLANG_FORMAT}) + unset(CLANG_FORMAT) + endif() + else() + message(WARNING "Clang format not found! Disabling the clang format target") + endif() +endif() + +if (CLANG_FORMAT) + set(SRCS ${PROJECT_SOURCE_DIR}/src) + set(CCOMMENT "Running clang format against all the .h and .cpp files in src/") + if (WIN32) + if(MINGW) + add_custom_target(clang-format + COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp -o -iname *.mm | xargs `cygpath -u ${CLANG_FORMAT}` -i + COMMENT ${CCOMMENT}) + else() + add_custom_target(clang-format + COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}" + COMMENT ${CCOMMENT}) + endif() + else() + add_custom_target(clang-format + COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i + COMMENT ${CCOMMENT}) + endif() + unset(SRCS) + unset(CCOMMENT) +endif() + add_subdirectory(third-party) include_directories(src) diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 00000000..b7d6b4ab --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,256 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +--- +Language: Java +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never +--- +Language: ObjC +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never +... diff --git a/src/Emulator/Host/controller.cpp b/src/Emulator/Host/controller.cpp index 599fb46f..b2bf4541 100644 --- a/src/Emulator/Host/controller.cpp +++ b/src/Emulator/Host/controller.cpp @@ -1,8 +1,9 @@ -#include "controller.h" #include +#include "controller.h" namespace Emulator::Host::Controller { -GameController::GameController() { m_states_num = 0; +GameController::GameController() { + m_states_num = 0; m_last_state = State(); } void GameController::readState(State* state, bool* isConnected, int* connectedCount) { @@ -50,4 +51,4 @@ void GameController::checKButton(int id, u32 button, bool isPressed) { addState(state); } -} // namespace Emulator::Host::Controller \ No newline at end of file +} // namespace Emulator::Host::Controller \ No newline at end of file diff --git a/src/Emulator/Host/controller.h b/src/Emulator/Host/controller.h index 33c1550c..22061a06 100644 --- a/src/Emulator/Host/controller.h +++ b/src/Emulator/Host/controller.h @@ -1,17 +1,17 @@ #pragma once -#include "common/types.h" #include +#include "common/types.h" namespace Emulator::Host::Controller { struct State { - u32 buttonsState =0; + u32 buttonsState = 0; u64 time = 0; }; constexpr u32 MAX_STATES = 64; class GameController { - public: +public: GameController(); virtual ~GameController() = default; @@ -20,8 +20,7 @@ class GameController { void checKButton(int id, u32 button, bool isPressed); void addState(const State& state); - - private: +private: std::mutex m_mutex; bool m_connected = false; State m_last_state; @@ -31,4 +30,4 @@ class GameController { State m_states[MAX_STATES]; }; -} // namespace Emulator::HLE::Libraries::Controller \ No newline at end of file +} // namespace Emulator::Host::Controller \ No newline at end of file diff --git a/src/GUI/ElfViewer.cpp b/src/GUI/ElfViewer.cpp index 641a1437..7ac8ce52 100644 --- a/src/GUI/ElfViewer.cpp +++ b/src/GUI/ElfViewer.cpp @@ -1,5 +1,5 @@ -#include "core/loader/elf.h" #include "GUI/ElfViewer.h" +#include "core/loader/elf.h" #include "imgui.h" ElfViewer::ElfViewer(Core::Loader::Elf* elf) { @@ -14,83 +14,82 @@ void ElfViewer::Display(bool enabled) { static int selected = -1; ImGui::Begin("Self/Elf Viewer", &enabled); - - ImGui::BeginChild("Left Tree pane", ImVec2(300, 0), false);//left tree - if (elf->isSelfFile()) - { - if (ImGui::TreeNode("Self")) - { - if (ImGui::TreeNodeEx("Self Header", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Self Header")) - { + + ImGui::BeginChild("Left Tree pane", ImVec2(300, 0), false); // left tree + if (elf->isSelfFile()) { + if (ImGui::TreeNode("Self")) { + if (ImGui::TreeNodeEx("Self Header", + ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, + "Self Header")) { if (ImGui::IsItemClicked()) selected = SELF_HEADER; } - - if (ImGui::TreeNode("Self Segment Header")) - { + + if (ImGui::TreeNode("Self Segment Header")) { const auto self = elf->GetSElfHeader(); - for (u16 i = 0; i < self.segment_count; i++) - { - if (ImGui::TreeNodeEx((void*)(intptr_t)i, ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "%d", i)) - { + for (u16 i = 0; i < self.segment_count; i++) { + if (ImGui::TreeNodeEx((void*)(intptr_t)i, + ImGuiTreeNodeFlags_Leaf | + ImGuiTreeNodeFlags_NoTreePushOnOpen, + "%d", i)) { if (ImGui::IsItemClicked()) - selected = SEG_HEADER_START+i; + selected = SEG_HEADER_START + i; } } ImGui::TreePop(); } - ImGui::TreeNodeEx("Self Id Header", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Self Id Header"); + ImGui::TreeNodeEx("Self Id Header", + ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, + "Self Id Header"); ImGui::TreePop(); } } - if (ImGui::TreeNode("Elf")) - { + if (ImGui::TreeNode("Elf")) { const auto elf_header = elf->GetElfHeader(); - if (ImGui::TreeNodeEx("Elf Header", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "Elf Header")) - { + if (ImGui::TreeNodeEx("Elf Header", + ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, + "Elf Header")) { if (ImGui::IsItemClicked()) selected = ELF_HEADER; } - if (ImGui::TreeNode("Elf Program Headers")) - { + if (ImGui::TreeNode("Elf Program Headers")) { const auto pheader = elf->GetProgramHeader(); - for (u16 i = 0; i < elf_header.e_phnum; i++) - { - std::string ProgramInfo = elf->ElfPheaderFlagsStr(pheader[i].p_flags) + " " + elf->ElfPheaderTypeStr(pheader[i].p_type); - if (ImGui::TreeNodeEx((void*)(intptr_t)i,ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, "%d - %s", i,ProgramInfo.c_str())) - { + for (u16 i = 0; i < elf_header.e_phnum; i++) { + std::string ProgramInfo = elf->ElfPheaderFlagsStr(pheader[i].p_flags) + " " + + elf->ElfPheaderTypeStr(pheader[i].p_type); + if (ImGui::TreeNodeEx((void*)(intptr_t)i, + ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen, + "%d - %s", i, ProgramInfo.c_str())) { if (ImGui::IsItemClicked()) selected = ELF_PROGRAM_HEADER_START + i; } } ImGui::TreePop(); } - if (elf_header.e_shnum != 0) - { - if (ImGui::TreeNode("Elf Section Headers")) - { + if (elf_header.e_shnum != 0) { + if (ImGui::TreeNode("Elf Section Headers")) { ImGui::TreePop(); } } ImGui::TreePop(); } - ImGui::EndChild();//end of left tree + ImGui::EndChild(); // end of left tree ImGui::SameLine(); - ImGui::BeginChild("Table View", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us + ImGui::BeginChild( + "Table View", + ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us if (selected == SELF_HEADER) { ImGui::TextWrapped("%s", elf->SElfHeaderStr().c_str()); } - if (selected >= 100 && selected < 200) - { - ImGui::TextWrapped("%s", elf->SELFSegHeader(selected-100).c_str()); + if (selected >= 100 && selected < 200) { + ImGui::TextWrapped("%s", elf->SELFSegHeader(selected - 100).c_str()); } if (selected == ELF_HEADER) { ImGui::TextWrapped("%s", elf->ElfHeaderStr().c_str()); } - if (selected >= 200 && selected < 300) - { + if (selected >= 200 && selected < 300) { ImGui::TextWrapped("%s", elf->ElfPHeaderStr(selected - 200).c_str()); } ImGui::EndChild(); diff --git a/src/Util/config.cpp b/src/Util/config.cpp index 7c5a4fa7..24631a0e 100644 --- a/src/Util/config.cpp +++ b/src/Util/config.cpp @@ -10,12 +10,20 @@ namespace Config { bool isNeo = false; u32 screenWidth = 1280; u32 screenHeight = 720; -u32 logLevel = 0; // TRACE = 0 , DEBUG = 1 , INFO = 2 , WARN = 3 , ERROR = 4 , CRITICAL = 5, OFF = 6 +u32 logLevel = 0; // TRACE = 0 , DEBUG = 1 , INFO = 2 , WARN = 3 , ERROR = 4 , CRITICAL = 5, OFF = 6 -bool isNeoMode() { return isNeo; } -u32 getScreenWidth() { return screenWidth; } -u32 getScreenHeight() { return screenHeight; } -u32 getLogLevel() { return logLevel; } +bool isNeoMode() { + return isNeo; +} +u32 getScreenWidth() { + return screenWidth; +} +u32 getScreenHeight() { + return screenHeight; +} +u32 getLogLevel() { + return logLevel; +} void load(const std::filesystem::path& path) { // If the configuration file does not exist, create it and return @@ -67,7 +75,8 @@ void save(const std::filesystem::path& path) { } } else { if (error) { - fmt::print("Filesystem error accessing {} (error: {})\n", path.string(), error.message().c_str()); + fmt::print("Filesystem error accessing {} (error: {})\n", path.string(), + error.message().c_str()); } fmt::print("Saving new configuration file {}\n", path.string()); } @@ -81,4 +90,4 @@ void save(const std::filesystem::path& path) { file << data; file.close(); } -} // namespace Config +} // namespace Config diff --git a/src/Util/config.h b/src/Util/config.h index 1397a643..5b5c3a78 100644 --- a/src/Util/config.h +++ b/src/Util/config.h @@ -12,4 +12,4 @@ u32 getLogLevel(); u32 getScreenWidth(); u32 getScreenHeight(); -}; // namespace Config +}; // namespace Config diff --git a/src/common/disassembler.cpp b/src/common/disassembler.cpp index 668a230b..37d58103 100644 --- a/src/common/disassembler.cpp +++ b/src/common/disassembler.cpp @@ -1,31 +1,32 @@ -#include "common/disassembler.h" #include +#include "common/disassembler.h" namespace Common { Disassembler::Disassembler() { - ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); - ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL); + ZydisDecoderInit(&m_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_STACK_WIDTH_64); + ZydisFormatterInit(&m_formatter, ZYDIS_FORMATTER_STYLE_INTEL); } Disassembler::~Disassembler() = default; void Disassembler::printInstruction(void* code, u64 address) { - ZydisDecodedInstruction instruction; - ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE]; - ZyanStatus status = ZydisDecoderDecodeFull(&m_decoder, code, sizeof(code), - &instruction, operands); + ZydisDecodedInstruction instruction; + ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE]; + ZyanStatus status = + ZydisDecoderDecodeFull(&m_decoder, code, sizeof(code), &instruction, operands); if (!ZYAN_SUCCESS(status)) { - fmt::print("decode instruction failed at {}\n", fmt::ptr(code)); + fmt::print("decode instruction failed at {}\n", fmt::ptr(code)); } else { - printInst(instruction, operands,address); - } + printInst(instruction, operands, address); + } } -void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address) { - const int bufLen = 256; - char szBuffer[bufLen]; - ZydisFormatterFormatInstruction(&m_formatter, &inst, operands,inst.operand_count_visible, +void Disassembler::printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, + u64 address) { + const int bufLen = 256; + char szBuffer[bufLen]; + ZydisFormatterFormatInstruction(&m_formatter, &inst, operands, inst.operand_count_visible, szBuffer, sizeof(szBuffer), address, ZYAN_NULL); fmt::print("instruction: {}\n", szBuffer); } diff --git a/src/common/disassembler.h b/src/common/disassembler.h index 9933b6a6..6f7bbd4a 100644 --- a/src/common/disassembler.h +++ b/src/common/disassembler.h @@ -7,15 +7,15 @@ namespace Common { class Disassembler { public: - Disassembler(); - ~Disassembler(); + Disassembler(); + ~Disassembler(); void printInst(ZydisDecodedInstruction& inst, ZydisDecodedOperand* operands, u64 address); void printInstruction(void* code, u64 address); private: ZydisDecoder m_decoder; - ZydisFormatter m_formatter; + ZydisFormatter m_formatter; }; } // namespace Common diff --git a/src/common/discord.cpp b/src/common/discord.cpp index d8c6384f..95ae0f3e 100644 --- a/src/common/discord.cpp +++ b/src/common/discord.cpp @@ -4,34 +4,34 @@ #include void Discord::RPC::init() { - DiscordEventHandlers handlers{}; - Discord_Initialize("1139939140494971051", &handlers, 1, nullptr); + DiscordEventHandlers handlers{}; + Discord_Initialize("1139939140494971051", &handlers, 1, nullptr); - startTimestamp = time(nullptr); - enabled = true; + startTimestamp = time(nullptr); + enabled = true; } void Discord::RPC::update(Discord::RPCStatus status, const std::string& game) { - DiscordRichPresence rpc{}; + DiscordRichPresence rpc{}; - if (status == Discord::RPCStatus::Playing) { - rpc.details = "Playing a game"; - rpc.state = game.c_str(); - } else { - rpc.details = "Idle"; - } + if (status == Discord::RPCStatus::Playing) { + rpc.details = "Playing a game"; + rpc.state = game.c_str(); + } else { + rpc.details = "Idle"; + } - rpc.largeImageKey = "shadps4"; - rpc.largeImageText = "ShadPS4 is a PS4 emulator"; - rpc.startTimestamp = startTimestamp; + rpc.largeImageKey = "shadps4"; + rpc.largeImageText = "ShadPS4 is a PS4 emulator"; + rpc.startTimestamp = startTimestamp; - Discord_UpdatePresence(&rpc); + Discord_UpdatePresence(&rpc); } void Discord::RPC::stop() { - if (enabled) { - enabled = false; - Discord_ClearPresence(); - Discord_Shutdown(); - } + if (enabled) { + enabled = false; + Discord_ClearPresence(); + Discord_Shutdown(); + } } diff --git a/src/common/discord.h b/src/common/discord.h index 0be14428..14a6b17c 100644 --- a/src/common/discord.h +++ b/src/common/discord.h @@ -1,19 +1,19 @@ #pragma once -#include #include #include +#include namespace Discord { - enum class RPCStatus { Idling, Playing }; +enum class RPCStatus { Idling, Playing }; - class RPC { - std::uint64_t startTimestamp; - bool enabled = false; +class RPC { + std::uint64_t startTimestamp; + bool enabled = false; - public: - void init(); - void update(RPCStatus status, const std::string& title); - void stop(); - }; -} // namespace Discord +public: + void init(); + void update(RPCStatus status, const std::string& title); + void stop(); +}; +} // namespace Discord diff --git a/src/common/fs_file.cpp b/src/common/fs_file.cpp index 007ec72d..97bb456a 100644 --- a/src/common/fs_file.cpp +++ b/src/common/fs_file.cpp @@ -24,8 +24,8 @@ bool File::open(const std::string& path, OpenMode mode) { bool File::close() { if (!isOpen() || std::fclose(m_file) != 0) [[unlikely]] { - m_file = nullptr; - return false; + m_file = nullptr; + return false; } m_file = nullptr; @@ -56,9 +56,9 @@ bool File::seek(s64 offset, SeekMode mode) { u64 File::tell() const { if (isOpen()) [[likely]] { #ifdef _WIN64 - return _ftelli64(m_file); + return _ftelli64(m_file); #else - return ftello64(m_file); + return ftello64(m_file); #endif } @@ -69,22 +69,22 @@ u64 File::getFileSize() { #ifdef _WIN64 const u64 pos = _ftelli64(m_file); if (_fseeki64(m_file, 0, SEEK_END) != 0) { - return 0; + return 0; } const u64 size = _ftelli64(m_file); if (_fseeki64(m_file, pos, SEEK_SET) != 0) { - return 0; + return 0; } #else const u64 pos = ftello64(m_file); if (fseeko64(m_file, 0, SEEK_END) != 0) { - return 0; + return 0; } const u64 size = ftello64(m_file); if (fseeko64(m_file, pos, SEEK_SET) != 0) { - return 0; + return 0; } #endif return size; diff --git a/src/common/fs_file.h b/src/common/fs_file.h index adc99605..969379cd 100644 --- a/src/common/fs_file.h +++ b/src/common/fs_file.h @@ -2,19 +2,15 @@ #include #include -#include #include +#include #include #include "common/types.h" namespace Common::FS { -enum class OpenMode : u32 { - Read = 0x1, - Write = 0x2, - ReadWrite = Read | Write -}; +enum class OpenMode : u32 { Read = 0x1, Write = 0x2, ReadWrite = Read | Write }; enum class SeekMode : u32 { Set, @@ -23,7 +19,7 @@ enum class SeekMode : u32 { }; class File { - public: +public: File(); explicit File(const std::string& path, OpenMode mode = OpenMode::Read); ~File(); @@ -52,27 +48,27 @@ class File { const char* getOpenMode(OpenMode mode) const { switch (mode) { - case OpenMode::Read: - return "rb"; - case OpenMode::Write: - return "wb"; - case OpenMode::ReadWrite: - return "r+b"; - default: - return "r"; + case OpenMode::Read: + return "rb"; + case OpenMode::Write: + return "wb"; + case OpenMode::ReadWrite: + return "r+b"; + default: + return "r"; } } int getSeekMode(SeekMode mode) const { switch (mode) { - case SeekMode::Set: - return SEEK_SET; - case SeekMode::Cur: - return SEEK_CUR; - case SeekMode::End: - return SEEK_END; - default: - return SEEK_SET; + case SeekMode::Set: + return SEEK_SET; + case SeekMode::Cur: + return SEEK_CUR; + case SeekMode::End: + return SEEK_END; + default: + return SEEK_SET; } } @@ -80,7 +76,7 @@ class File { return m_file; } - private: +private: std::FILE* m_file{}; }; diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index 86874c08..0f342fe7 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -1,6 +1,6 @@ #include "io_file.h" -//#include "helpers.hpp" +// #include "helpers.hpp" #ifdef _MSC_VER // 64 bit offsets for MSVC @@ -118,8 +118,8 @@ FILE* IOFile::getHandle() { } void IOFile::setAppDataDir(const std::filesystem::path& dir) { - //if (dir == "") - // Helpers::panic("Failed to set app data directory"); + // if (dir == "") + // Helpers::panic("Failed to set app data directory"); appData = dir; } diff --git a/src/common/io_file.h b/src/common/io_file.h index 85f7a78e..e057d874 100644 --- a/src/common/io_file.h +++ b/src/common/io_file.h @@ -5,7 +5,8 @@ class IOFile { FILE* handle = nullptr; - static inline std::filesystem::path appData =""; // Directory for holding app data. AppData on Windows + static inline std::filesystem::path appData = + ""; // Directory for holding app data. AppData on Windows public: IOFile() : handle(nullptr) {} diff --git a/src/common/log.cpp b/src/common/log.cpp index f4bb55f8..130dcc9a 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -1,10 +1,10 @@ +#include +#include #include #include #include #include #include -#include -#include #include "common/log.h" #ifdef _WIN64 #include @@ -30,19 +30,20 @@ uint64_t tls_access(int64_t tls_offset) { #ifdef _WIN64 static LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS pExp) noexcept { auto orig_rip = pExp->ContextRecord->Rip; - while (*(uint8_t *)pExp->ContextRecord->Rip == 0x66) pExp->ContextRecord->Rip++; + while (*(uint8_t*)pExp->ContextRecord->Rip == 0x66) + pExp->ContextRecord->Rip++; - if (*(uint8_t *)pExp->ContextRecord->Rip == 0xcd) { - int reg = *(uint8_t *)(pExp->ContextRecord->Rip + 1) - 0x80; - int sizes = *(uint8_t *)(pExp->ContextRecord->Rip + 2); + if (*(uint8_t*)pExp->ContextRecord->Rip == 0xcd) { + int reg = *(uint8_t*)(pExp->ContextRecord->Rip + 1) - 0x80; + int sizes = *(uint8_t*)(pExp->ContextRecord->Rip + 2); int pattern_size = sizes & 0xF; int imm_size = sizes >> 4; int64_t tls_offset; if (imm_size == 4) - tls_offset = *(int32_t *)(pExp->ContextRecord->Rip + pattern_size); + tls_offset = *(int32_t*)(pExp->ContextRecord->Rip + pattern_size); else - tls_offset = *(int64_t *)(pExp->ContextRecord->Rip + pattern_size); + tls_offset = *(int64_t*)(pExp->ContextRecord->Rip + pattern_size); (&pExp->ContextRecord->Rax)[reg] = tls_access(tls_offset); /* TLS_ACCESS */ pExp->ContextRecord->Rip += pattern_size + imm_size; @@ -53,57 +54,61 @@ static LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS pExp) noexcept { pExp->ContextRecord->Rip = orig_rip; const u32 ec = pExp->ExceptionRecord->ExceptionCode; switch (ec) { - case EXCEPTION_ACCESS_VIOLATION: { - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ACCESS_VIOLATION ({:#x}). ", ec); - const auto info = pExp->ExceptionRecord->ExceptionInformation; - switch (info[0]) { - case 0: - LOG_CRITICAL_IF(log_file_exceptions, "Read violation at address {:#x}.", info[1]); - break; - case 1: - LOG_CRITICAL_IF(log_file_exceptions, "Write violation at address {:#x}.", info[1]); - break; - case 8: - LOG_CRITICAL_IF(log_file_exceptions, "DEP violation at address {:#x}.", info[1]); - break; - default: - break; - } + case EXCEPTION_ACCESS_VIOLATION: { + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ACCESS_VIOLATION ({:#x}). ", ec); + const auto info = pExp->ExceptionRecord->ExceptionInformation; + switch (info[0]) { + case 0: + LOG_CRITICAL_IF(log_file_exceptions, "Read violation at address {:#x}.", info[1]); break; - } - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({:#x}). ", ec); + case 1: + LOG_CRITICAL_IF(log_file_exceptions, "Write violation at address {:#x}.", info[1]); break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_DATATYPE_MISALIGNMENT ({:#x}). ", ec); - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({:#x}). ", ec); - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ILLEGAL_INSTRUCTION ({:#x}). ", ec); - break; - case EXCEPTION_IN_PAGE_ERROR: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_IN_PAGE_ERROR ({:#x}). ", ec); - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_INT_DIVIDE_BY_ZERO ({:#x}). ", ec); - break; - case EXCEPTION_PRIV_INSTRUCTION: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_PRIV_INSTRUCTION ({:#x}). ", ec); - break; - case EXCEPTION_STACK_OVERFLOW: - LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_STACK_OVERFLOW ({:#x}). ", ec); + case 8: + LOG_CRITICAL_IF(log_file_exceptions, "DEP violation at address {:#x}.", info[1]); break; default: - return EXCEPTION_CONTINUE_SEARCH; + break; + } + break; + } + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({:#x}). ", + ec); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_DATATYPE_MISALIGNMENT ({:#x}). ", + ec); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({:#x}). ", + ec); + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_ILLEGAL_INSTRUCTION ({:#x}). ", + ec); + break; + case EXCEPTION_IN_PAGE_ERROR: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_IN_PAGE_ERROR ({:#x}). ", ec); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_INT_DIVIDE_BY_ZERO ({:#x}). ", + ec); + break; + case EXCEPTION_PRIV_INSTRUCTION: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_PRIV_INSTRUCTION ({:#x}). ", ec); + break; + case EXCEPTION_STACK_OVERFLOW: + LOG_CRITICAL_IF(log_file_exceptions, "Exception EXCEPTION_STACK_OVERFLOW ({:#x}). ", ec); + break; + default: + return EXCEPTION_CONTINUE_SEARCH; } Flush(); return EXCEPTION_CONTINUE_SEARCH; } #endif - int Init(bool use_stdout) { sinks.clear(); if (use_stdout) { @@ -114,8 +119,10 @@ int Init(bool use_stdout) { #else sinks.push_back(std::make_shared("shadps4.txt", true)); #endif - spdlog::set_default_logger(std::make_shared("shadps4 logger", begin(sinks), end(sinks))); - auto f = std::make_unique("%^|%L|: %v%$", spdlog::pattern_time_type::local, std::string("")); // disable eol + spdlog::set_default_logger( + std::make_shared("shadps4 logger", begin(sinks), end(sinks))); + auto f = std::make_unique( + "%^|%L|: %v%$", spdlog::pattern_time_type::local, std::string("")); // disable eol spdlog::set_formatter(std::move(f)); spdlog::set_level(static_cast(Config::getLogLevel())); @@ -129,13 +136,14 @@ int Init(bool use_stdout) { old_terminate = std::set_terminate([]() { try { std::rethrow_exception(std::current_exception()); - } catch (const std::exception &e) { + } catch (const std::exception& e) { LOG_CRITICAL_IF(log_file_exceptions, "Unhandled C++ exception. {}", e.what()); } catch (...) { LOG_CRITICAL_IF(log_file_exceptions, "Unhandled C++ exception. UNKNOWN"); } Flush(); - if (old_terminate) old_terminate(); + if (old_terminate) + old_terminate(); }); return 0; @@ -145,4 +153,4 @@ void SetLevel(spdlog::level::level_enum log_level) { spdlog::set_level(log_level); } -} // namespace Common::Log +} // namespace Common::Log diff --git a/src/common/log.h b/src/common/log.h index 1242c6f3..a9b4aa2e 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -13,18 +13,24 @@ namespace Common::Log { #define LOG_ERROR SPDLOG_ERROR #define LOG_CRITICAL SPDLOG_CRITICAL -#define LOG_TRACE_IF(flag, ...) \ - if (flag) LOG_TRACE(__VA_ARGS__) -#define LOG_DEBUG_IF(flag, ...) \ - if (flag) LOG_DEBUG(__VA_ARGS__) -#define LOG_INFO_IF(flag, ...) \ - if (flag) LOG_INFO(__VA_ARGS__) -#define LOG_WARN_IF(flag, ...) \ - if (flag) LOG_WARN(__VA_ARGS__) -#define LOG_ERROR_IF(flag, ...) \ - if (flag) LOG_ERROR(__VA_ARGS__) -#define LOG_CRITICAL_IF(flag, ...) \ - if (flag) LOG_CRITICAL(__VA_ARGS__) +#define LOG_TRACE_IF(flag, ...) \ + if (flag) \ + LOG_TRACE(__VA_ARGS__) +#define LOG_DEBUG_IF(flag, ...) \ + if (flag) \ + LOG_DEBUG(__VA_ARGS__) +#define LOG_INFO_IF(flag, ...) \ + if (flag) \ + LOG_INFO(__VA_ARGS__) +#define LOG_WARN_IF(flag, ...) \ + if (flag) \ + LOG_WARN(__VA_ARGS__) +#define LOG_ERROR_IF(flag, ...) \ + if (flag) \ + LOG_ERROR(__VA_ARGS__) +#define LOG_CRITICAL_IF(flag, ...) \ + if (flag) \ + LOG_CRITICAL(__VA_ARGS__) int Init(bool use_stdout); diff --git a/src/common/native_clock.cpp b/src/common/native_clock.cpp index e722de0d..057eee68 100644 --- a/src/common/native_clock.cpp +++ b/src/common/native_clock.cpp @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/uint128.h" #include "common/native_clock.h" #include "common/rdtsc.h" +#include "common/uint128.h" #ifdef _WIN64 #include #else @@ -13,8 +13,8 @@ namespace Common { NativeClock::NativeClock() - : rdtsc_frequency{EstimateRDTSCFrequency()}, ns_rdtsc_factor{GetFixedPoint64Factor(std::nano::den, - rdtsc_frequency)}, + : rdtsc_frequency{EstimateRDTSCFrequency()}, ns_rdtsc_factor{GetFixedPoint64Factor( + std::nano::den, rdtsc_frequency)}, us_rdtsc_factor{GetFixedPoint64Factor(std::micro::den, rdtsc_frequency)}, ms_rdtsc_factor{GetFixedPoint64Factor(std::milli::den, rdtsc_frequency)} {} @@ -40,4 +40,4 @@ u64 NativeClock::GetProcessTimeUS() const { return ret.tv_nsec / 1000 + ret.tv_sec * 1000000; } -} // namespace Common::X64 +} // namespace Common diff --git a/src/common/rdtsc.cpp b/src/common/rdtsc.cpp index 8d231a98..48d1b7a4 100644 --- a/src/common/rdtsc.cpp +++ b/src/common/rdtsc.cpp @@ -28,7 +28,7 @@ static u64 GetTimeNs() { FILETIME filetime; GetSystemTimePreciseAsFileTime(&filetime); return Multiplier * ((static_cast(filetime.dwHighDateTime) << 32) + - static_cast(filetime.dwLowDateTime) - WindowsEpochToUnixEpoch); + static_cast(filetime.dwLowDateTime) - WindowsEpochToUnixEpoch); #elif defined(__APPLE__) return clock_gettime_nsec_np(CLOCK_REALTIME); #else diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 19f6020c..fc7e4bdf 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -5,7 +5,7 @@ namespace Common { -std::vector SplitString(const std::string &str, char delimiter) { +std::vector SplitString(const std::string& str, char delimiter) { std::istringstream iss(str); std::vector output(1); diff --git a/src/common/string_util.h b/src/common/string_util.h index a9a8c888..6d7b4208 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include namespace Common { diff --git a/src/common/types.h b/src/common/types.h index 4d86ec25..a15febf3 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -22,6 +22,12 @@ static_assert(sizeof(u128) == 16, "u128 must be 128 bits wide"); #define PS4_SYSV_ABI __attribute__((sysv_abi)) // UDLs for memory size values -constexpr unsigned long long operator""_KB(unsigned long long x) { return 1024ULL * x; } -constexpr unsigned long long operator""_MB(unsigned long long x) { return 1024_KB * x; } -constexpr unsigned long long operator""_GB(unsigned long long x) { return 1024_MB * x; } +constexpr unsigned long long operator""_KB(unsigned long long x) { + return 1024ULL * x; +} +constexpr unsigned long long operator""_MB(unsigned long long x) { + return 1024_KB * x; +} +constexpr unsigned long long operator""_GB(unsigned long long x) { + return 1024_MB * x; +} diff --git a/src/core/PS4/GPU/gpu_memory.cpp b/src/core/PS4/GPU/gpu_memory.cpp index 8f3086bc..4dc09d8d 100644 --- a/src/core/PS4/GPU/gpu_memory.cpp +++ b/src/core/PS4/GPU/gpu_memory.cpp @@ -1,10 +1,11 @@ -#include "gpu_memory.h" #include #include +#include "gpu_memory.h" #include "common/singleton.h" -void* GPU::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, void* todo /*CommandBuffer?*/, u64 virtual_addr, u64 size, +void* GPU::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + void* todo /*CommandBuffer?*/, u64 virtual_addr, u64 size, const GPUObject& info) { auto* gpumemory = Common::Singleton::Instance(); @@ -23,9 +24,12 @@ void GPU::memorySetAllocArea(u64 virtual_addr, u64 size) { gpumemory->m_heaps.push_back(h); } -u64 GPU::calculate_hash(const u08* buf, u64 size) { return (size > 0 && buf != nullptr ? XXH3_64bits(buf, size) : 0); } +u64 GPU::calculate_hash(const u08* buf, u64 size) { + return (size > 0 && buf != nullptr ? XXH3_64bits(buf, size) : 0); +} -bool GPU::vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem) { +bool GPU::vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanMemory* mem) { static std::atomic_uint64_t unique_id = 0; VkPhysicalDeviceMemoryProperties memory_properties{}; @@ -66,7 +70,8 @@ void GPU::flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx) { int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) { int index = 0; for (const auto& heap : m_heaps) { - if ((virtual_addr >= heap.allocated_virtual_addr && virtual_addr < heap.allocated_virtual_addr + heap.allocated_size) || + if ((virtual_addr >= heap.allocated_virtual_addr && + virtual_addr < heap.allocated_virtual_addr + heap.allocated_size) || ((virtual_addr + size - 1) >= heap.allocated_virtual_addr && (virtual_addr + size - 1) < heap.allocated_virtual_addr + heap.allocated_size)) { return index; @@ -76,7 +81,8 @@ int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) { return -1; } -void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, void* todo, const u64* virtual_addr, const u64* size, +void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + void* todo, const u64* virtual_addr, const u64* size, int virtual_addr_num, const GPUObject& info) { auto* gpumemory = Common::Singleton::Instance(); @@ -101,7 +107,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi for (int h = 0; h < virtual_addr_num; h++) { if (info.check_hash) { - objInfo.hash[h] = GPU::calculate_hash(reinterpret_cast(virtual_addr[h]), size[h]); + objInfo.hash[h] = + GPU::calculate_hash(reinterpret_cast(virtual_addr[h]), size[h]); } else { objInfo.hash[h] = 0; } @@ -109,7 +116,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi objInfo.submit_id = submit_id; objInfo.check_hash = info.check_hash; - objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, virtual_addr_num, &objInfo.mem); + objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, + virtual_addr_num, &objInfo.mem); objInfo.update_func = info.getUpdateFunc(); int index = static_cast(heap.objects.size()); @@ -123,7 +131,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi return objInfo.gpu_object.obj; } -GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id) { +GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u64* size, + int virtual_addr_num, int heap_id, int obj_id) { auto& heap = m_heaps[heap_id]; GPU::HeapBlock heapBlock{}; @@ -135,7 +144,8 @@ GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u6 return heapBlock; } -void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id) { +void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, + int obj_id) { auto& heap = m_heaps[heap_id]; auto& heapObj = heap.objects[obj_id]; @@ -147,7 +157,9 @@ void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, for (int i = 0; i < heapObj.block.virtual_addr_num; i++) { if (objInfo.check_hash) { - hash[i] = GPU::calculate_hash(reinterpret_cast(heapObj.block.virtual_addr[i]), heapObj.block.size[i]); + hash[i] = GPU::calculate_hash( + reinterpret_cast(heapObj.block.virtual_addr[i]), + heapObj.block.size[i]); } else { hash[i] = 0; } @@ -166,7 +178,8 @@ void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, } if (need_update) { - objInfo.update_func(ctx, objInfo.obj_params, objInfo.gpu_object.obj, heapObj.block.virtual_addr, heapObj.block.size, + objInfo.update_func(ctx, objInfo.obj_params, objInfo.gpu_object.obj, + heapObj.block.virtual_addr, heapObj.block.size, heapObj.block.virtual_addr_num); } } diff --git a/src/core/PS4/GPU/gpu_memory.h b/src/core/PS4/GPU/gpu_memory.h index eb3f1e5b..3de4db83 100644 --- a/src/core/PS4/GPU/gpu_memory.h +++ b/src/core/PS4/GPU/gpu_memory.h @@ -1,9 +1,9 @@ #pragma once -#include -#include "common/types.h" #include #include +#include +#include "common/types.h" namespace GPU { @@ -24,7 +24,7 @@ struct HeapBlock { }; class GPUObject { - public: +public: GPUObject() = default; virtual ~GPUObject() = default; u64 obj_params[8] = {}; @@ -32,9 +32,11 @@ class GPUObject { bool isReadOnly = false; MemoryObjectType objectType = MemoryObjectType::InvalidObj; - using create_func_t = void* (*)(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, const u64* virtual_addr, const u64* size, int virtual_addr_num, + using create_func_t = void* (*)(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, + const u64* virtual_addr, const u64* size, int virtual_addr_num, HLE::Libs::Graphics::VulkanMemory* mem); - using update_func_t = void (*)(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, void* obj, const u64* virtual_addr, const u64* size, + using update_func_t = void (*)(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, + void* obj, const u64* virtual_addr, const u64* size, int virtual_addr_num); virtual create_func_t getCreateFunc() const = 0; @@ -63,23 +65,27 @@ struct MemoryHeap { }; class GPUMemory { - public: +public: GPUMemory() {} virtual ~GPUMemory() {} int getHeapId(u64 vaddr, u64 size); std::mutex m_mutex; std::vector m_heaps; - void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr, + void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr, const u64* size, int virtual_addr_num, const GPUObject& info); - HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id); + HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, + int heap_id, int obj_id); void update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id); void flushAllHeaps(HLE::Libs::Graphics::GraphicCtx* ctx); }; void memorySetAllocArea(u64 virtual_addr, u64 size); -void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size, +void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size, const GPUObject& info); u64 calculate_hash(const u08* buf, u64 size); -bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem); +bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanMemory* mem); void flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx); -} // namespace GPU \ No newline at end of file +} // namespace GPU \ No newline at end of file diff --git a/src/core/PS4/GPU/tile_manager.cpp b/src/core/PS4/GPU/tile_manager.cpp index 9a362243..9d74b3a6 100644 --- a/src/core/PS4/GPU/tile_manager.cpp +++ b/src/core/PS4/GPU/tile_manager.cpp @@ -1,20 +1,22 @@ -#include "tile_manager.h" -#include "common/singleton.h" #include +#include "common/singleton.h" +#include "tile_manager.h" namespace GPU { -static u32 IntLog2(u32 i) { return 31 - __builtin_clz(i | 1u); } +static u32 IntLog2(u32 i) { + return 31 - __builtin_clz(i | 1u); +} class TileManager { - public: - TileManager(){} - virtual ~TileManager() { } +public: + TileManager() {} + virtual ~TileManager() {} std::mutex m_mutex; }; class TileManager32 { - public: +public: u32 m_macro_tile_height = 0; u32 m_bank_height = 0; u32 m_num_banks = 0; @@ -69,25 +71,26 @@ class TileManager32 { return pipe; } - static u32 getBankIdx(u32 x, u32 y, u32 bank_width, u32 bank_height, u32 num_banks, u32 num_pipes) { + static u32 getBankIdx(u32 x, u32 y, u32 bank_width, u32 bank_height, u32 num_banks, + u32 num_pipes) { const u32 x_shift_offset = IntLog2(bank_width * num_pipes); const u32 y_shift_offset = IntLog2(bank_height); const u32 xs = x >> x_shift_offset; const u32 ys = y >> y_shift_offset; u32 bank = 0; switch (num_banks) { - case 8: - bank |= (((xs >> 3u) ^ (ys >> 5u)) & 0x1u) << 0u; - bank |= (((xs >> 4u) ^ (ys >> 4u) ^ (ys >> 5u)) & 0x1u) << 1u; - bank |= (((xs >> 5u) ^ (ys >> 3u)) & 0x1u) << 2u; - break; - case 16: - bank |= (((xs >> 3u) ^ (ys >> 6u)) & 0x1u) << 0u; - bank |= (((xs >> 4u) ^ (ys >> 5u) ^ (ys >> 6u)) & 0x1u) << 1u; - bank |= (((xs >> 5u) ^ (ys >> 4u)) & 0x1u) << 2u; - bank |= (((xs >> 6u) ^ (ys >> 3u)) & 0x1u) << 3u; - break; - default:; + case 8: + bank |= (((xs >> 3u) ^ (ys >> 5u)) & 0x1u) << 0u; + bank |= (((xs >> 4u) ^ (ys >> 4u) ^ (ys >> 5u)) & 0x1u) << 1u; + bank |= (((xs >> 5u) ^ (ys >> 3u)) & 0x1u) << 2u; + break; + case 16: + bank |= (((xs >> 3u) ^ (ys >> 6u)) & 0x1u) << 0u; + bank |= (((xs >> 4u) ^ (ys >> 5u) ^ (ys >> 6u)) & 0x1u) << 1u; + bank |= (((xs >> 5u) ^ (ys >> 4u)) & 0x1u) << 2u; + bank |= (((xs >> 6u) ^ (ys >> 3u)) & 0x1u) << 3u; + break; + default:; } return bank; @@ -110,11 +113,13 @@ class TileManager32 { tile_bytes = 512; } - u64 macro_tile_bytes = (128 / 8) * (m_macro_tile_height / 8) * tile_bytes / (m_num_pipes * m_num_banks); + u64 macro_tile_bytes = + (128 / 8) * (m_macro_tile_height / 8) * tile_bytes / (m_num_pipes * m_num_banks); u64 macro_tiles_per_row = m_padded_width / 128; u64 macro_tile_row_index = y / m_macro_tile_height; u64 macro_tile_column_index = x / 128; - u64 macro_tile_index = (macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index; + u64 macro_tile_index = + (macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index; u64 macro_tile_offset = macro_tile_index * macro_tile_bytes; u64 macro_tiles_per_slice = macro_tiles_per_row * (m_padded_height / m_macro_tile_height); u64 slice_bytes = macro_tiles_per_slice * macro_tile_bytes; @@ -133,20 +138,21 @@ class TileManager32 { u64 pipe_interleave_offset = total_offset & 0xffu; u64 offset = total_offset >> 8u; - u64 byte_offset = pipe_interleave_offset | (pipe << (8u)) | (bank << (8u + m_pipe_bits)) | (offset << (8u + m_pipe_bits + m_bank_bits)); + u64 byte_offset = pipe_interleave_offset | (pipe << (8u)) | (bank << (8u + m_pipe_bits)) | + (offset << (8u + m_pipe_bits + m_bank_bits)); return ((byte_offset << 3u) | bit_offset) / 8; } }; -void convertTileToLinear(void* dst, const void* src,u32 width, u32 height, bool is_neo) { +void convertTileToLinear(void* dst, const void* src, u32 width, u32 height, bool is_neo) { TileManager32 t; t.Init(width, height, is_neo); auto* g_TileManager = Common::Singleton::Instance(); std::scoped_lock lock{g_TileManager->m_mutex}; - + for (u32 y = 0; y < height; y++) { u32 x = 0; u64 linear_offset = y * width * 4; @@ -166,4 +172,4 @@ void convertTileToLinear(void* dst, const void* src,u32 width, u32 height, bool } } } -} // namespace GPU +} // namespace GPU diff --git a/src/core/PS4/GPU/video_out_buffer.cpp b/src/core/PS4/GPU/video_out_buffer.cpp index 1a9c30a4..5300f66e 100644 --- a/src/core/PS4/GPU/video_out_buffer.cpp +++ b/src/core/PS4/GPU/video_out_buffer.cpp @@ -2,14 +2,14 @@ #include "common/log.h" -#include "common/debug.h" #include +#include "common/debug.h" #include "tile_manager.h" -constexpr bool log_file_videoOutBuffer = true; // disable it to disable logging +constexpr bool log_file_videoOutBuffer = true; // disable it to disable logging -static void update_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, void* obj, const u64* virtual_addr, const u64* size, - int virtual_addr_num) { +static void update_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, void* obj, + const u64* virtual_addr, const u64* size, int virtual_addr_num) { auto pitch = params[GPU::VideoOutBufferObj::PITCH_PARAM]; bool tiled = (params[GPU::VideoOutBufferObj::IS_TILE_PARAM] != 0); @@ -21,19 +21,22 @@ static void update_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED; - if (tiled) - { + if (tiled) { std::vector tempbuff(*size); - GPU::convertTileToLinear(tempbuff.data(), reinterpret_cast(*virtual_addr), width, height, neo); - Graphics::Vulkan::vulkanFillImage(ctx, vk_obj, tempbuff.data(), *size, pitch, static_cast(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); + GPU::convertTileToLinear(tempbuff.data(), reinterpret_cast(*virtual_addr), width, + height, neo); + Graphics::Vulkan::vulkanFillImage( + ctx, vk_obj, tempbuff.data(), *size, pitch, + static_cast(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); } else { - Graphics::Vulkan::vulkanFillImage(ctx, vk_obj, reinterpret_cast(*virtual_addr), *size, pitch, - static_cast(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); + Graphics::Vulkan::vulkanFillImage( + ctx, vk_obj, reinterpret_cast(*virtual_addr), *size, pitch, + static_cast(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); } - } -static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, const u64* virtual_addr, const u64* size, int virtual_addr_num, +static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params, + const u64* virtual_addr, const u64* size, int virtual_addr_num, HLE::Libs::Graphics::VulkanMemory* mem) { auto pixel_format = params[GPU::VideoOutBufferObj::PIXEL_FORMAT_PARAM]; auto width = params[GPU::VideoOutBufferObj::WIDTH_PARAM]; @@ -44,9 +47,15 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params VkFormat vk_format = VK_FORMAT_UNDEFINED; switch (pixel_format) { - case static_cast(GPU::VideoOutBufferFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break; - case static_cast(GPU::VideoOutBufferFormat::B8G8R8A8Srgb): vk_format = VK_FORMAT_B8G8R8A8_SRGB; break; - default: LOG_CRITICAL_IF(log_file_videoOutBuffer, "unknown pixelFormat = {}\n", pixel_format); std::exit(0); + case static_cast(GPU::VideoOutBufferFormat::R8G8B8A8Srgb): + vk_format = VK_FORMAT_R8G8B8A8_SRGB; + break; + case static_cast(GPU::VideoOutBufferFormat::B8G8R8A8Srgb): + vk_format = VK_FORMAT_B8G8R8A8_SRGB; + break; + default: + LOG_CRITICAL_IF(log_file_videoOutBuffer, "unknown pixelFormat = {}\n", pixel_format); + std::exit(0); } vk_obj->extent.width = width; @@ -72,8 +81,9 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params image_info.format = vk_obj->format; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.initialLayout = vk_obj->layout; - image_info.usage = - static_cast(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + image_info.usage = static_cast(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT) | + VK_IMAGE_USAGE_TRANSFER_DST_BIT; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; image_info.samples = VK_SAMPLE_COUNT_1_BIT; @@ -124,7 +134,8 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params create_info.subresourceRange.layerCount = 1; create_info.subresourceRange.levelCount = 1; - vkCreateImageView(ctx->m_device, &create_info, nullptr, &vk_obj->image_view[HLE::Libs::Graphics::VulkanImage::VIEW_DEFAULT]); + vkCreateImageView(ctx->m_device, &create_info, nullptr, + &vk_obj->image_view[HLE::Libs::Graphics::VulkanImage::VIEW_DEFAULT]); if (vk_obj->image_view[HLE::Libs::Graphics::VulkanImage::VIEW_DEFAULT] == nullptr) { LOG_CRITICAL_IF(log_file_videoOutBuffer, "vk_obj->image_view is null\n"); @@ -134,6 +145,10 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params return vk_obj; } -GPU::GPUObject::create_func_t GPU::VideoOutBufferObj::getCreateFunc() const { return create_func; } +GPU::GPUObject::create_func_t GPU::VideoOutBufferObj::getCreateFunc() const { + return create_func; +} -GPU::GPUObject::update_func_t GPU::VideoOutBufferObj::getUpdateFunc() const { return update_func; } +GPU::GPUObject::update_func_t GPU::VideoOutBufferObj::getUpdateFunc() const { + return update_func; +} diff --git a/src/core/PS4/GPU/video_out_buffer.h b/src/core/PS4/GPU/video_out_buffer.h index a7876b03..cc59a948 100644 --- a/src/core/PS4/GPU/video_out_buffer.h +++ b/src/core/PS4/GPU/video_out_buffer.h @@ -13,7 +13,7 @@ enum class VideoOutBufferFormat : u64 { }; class VideoOutBufferObj : public GPUObject { - public: +public: static constexpr int PIXEL_FORMAT_PARAM = 0; static constexpr int WIDTH_PARAM = 1; static constexpr int HEIGHT_PARAM = 2; @@ -21,7 +21,8 @@ class VideoOutBufferObj : public GPUObject { static constexpr int IS_NEO_PARAM = 4; static constexpr int PITCH_PARAM = 5; - explicit VideoOutBufferObj(VideoOutBufferFormat pixel_format, u32 width, u32 height, bool is_tiled, bool is_neo, u32 pitch) { + explicit VideoOutBufferObj(VideoOutBufferFormat pixel_format, u32 width, u32 height, + bool is_tiled, bool is_neo, u32 pitch) { obj_params[PIXEL_FORMAT_PARAM] = static_cast(pixel_format); obj_params[WIDTH_PARAM] = width; obj_params[HEIGHT_PARAM] = height; @@ -35,4 +36,4 @@ class VideoOutBufferObj : public GPUObject { create_func_t getCreateFunc() const override; update_func_t getUpdateFunc() const override; }; -} // namespace GPU +} // namespace GPU diff --git a/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp b/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp index 3947d645..714a6b9a 100644 --- a/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp +++ b/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp @@ -17,7 +17,7 @@ int VideoOutCtx::Open() { int handle = -1; if (!m_video_out_ctx.isOpened) { - handle = 1; // positive return , should be more than 1 ? + handle = 1; // positive return , should be more than 1 ? } m_video_out_ctx.isOpened = true; @@ -35,7 +35,7 @@ void VideoOutCtx::Close(s32 handle) { m_video_out_ctx.isOpened = false; if (m_video_out_ctx.m_flip_evtEq.size() > 0) { - BREAKPOINT(); // we need to clear all events if they have been created + BREAKPOINT(); // we need to clear all events if they have been created } m_video_out_ctx.m_flip_rate = 0; @@ -57,7 +57,7 @@ VideoConfigInternal* VideoOutCtx::getCtx(int handle) { if (handle != 1) [[unlikely]] { return nullptr; } - return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more + return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more } void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out) { @@ -91,11 +91,12 @@ bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { bool FlipQueue::flip(u32 micros) { const auto request = [&]() -> Request* { std::unique_lock lock{m_mutex}; - m_submit_cond.wait_for(lock, std::chrono::microseconds(micros), [&] { return !m_requests.empty(); }); + m_submit_cond.wait_for(lock, std::chrono::microseconds(micros), + [&] { return !m_requests.empty(); }); if (m_requests.empty()) { return nullptr; } - return &m_requests.at(0); // Process first request + return &m_requests.at(0); // Process first request }(); if (!request) { @@ -111,7 +112,8 @@ bool FlipQueue::flip(u32 micros) { std::scoped_lock cfg_lock{request->cfg->m_mutex}; for (auto& flip_eq : request->cfg->m_flip_evtEq) { if (flip_eq != nullptr) { - flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, Core::Kernel::EVFILT_VIDEO_OUT, reinterpret_cast(request->flip_arg)); + flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, Core::Kernel::EVFILT_VIDEO_OUT, + reinterpret_cast(request->flip_arg)); } } } diff --git a/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.h b/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.h index 781e0c61..baaa15c3 100644 --- a/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.h +++ b/src/core/PS4/HLE/Graphics/Objects/video_out_ctx.h @@ -2,8 +2,8 @@ #include #include -#include #include +#include #include using namespace HLE::Libs::Graphics::VideoOut; @@ -32,14 +32,15 @@ struct VideoConfigInternal { }; class FlipQueue { - public: +public: FlipQueue() {} virtual ~FlipQueue() {} void getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out); bool submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg); bool flip(u32 micros); - private: + +private: struct Request { VideoConfigInternal* cfg; int index; @@ -55,24 +56,27 @@ class FlipQueue { class VideoOutCtx { - public: +public: VideoOutCtx() {} virtual ~VideoOutCtx() {} void Init(u32 width, u32 height); int Open(); void Close(s32 handle); VideoConfigInternal* getCtx(int handle); - FlipQueue& getFlipQueue() { return m_flip_queue; } + FlipQueue& getFlipQueue() { + return m_flip_queue; + } HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { std::scoped_lock lock{m_mutex}; - + if (!m_graphic_ctx) { m_graphic_ctx = Emu::getGraphicCtx(); } return m_graphic_ctx; } - private: + +private: std::mutex m_mutex; VideoConfigInternal m_video_out_ctx; FlipQueue m_flip_queue; diff --git a/src/core/PS4/HLE/Graphics/graphics_ctx.h b/src/core/PS4/HLE/Graphics/graphics_ctx.h index cd2b6a3c..bc2c37c8 100644 --- a/src/core/PS4/HLE/Graphics/graphics_ctx.h +++ b/src/core/PS4/HLE/Graphics/graphics_ctx.h @@ -1,10 +1,10 @@ #pragma once -#include "common/types.h" +#include +#include #include #include -#include -#include +#include "common/types.h" namespace HLE::Libs::Graphics { @@ -31,7 +31,7 @@ struct GraphicCtx { VkInstance m_instance = nullptr; VkPhysicalDevice m_physical_device = nullptr; VkDevice m_device = nullptr; - VulkanQueueInfo queues[11]; // VULKAN_QUEUES_NUM + VulkanQueueInfo queues[11]; // VULKAN_QUEUES_NUM }; enum class VulkanImageType { Unknown, VideoOut }; @@ -71,4 +71,4 @@ struct VideoOutVulkanImage : public VulkanImage { VideoOutVulkanImage() : VulkanImage(VulkanImageType::VideoOut) {} }; -} // namespace HLE::Libs::Graphics +} // namespace HLE::Libs::Graphics diff --git a/src/core/PS4/HLE/Graphics/graphics_render.cpp b/src/core/PS4/HLE/Graphics/graphics_render.cpp index 84dae4c0..605295c5 100644 --- a/src/core/PS4/HLE/Graphics/graphics_render.cpp +++ b/src/core/PS4/HLE/Graphics/graphics_render.cpp @@ -1,7 +1,7 @@ -#include "graphics_render.h" #include #include "common/singleton.h" #include "emulator.h" +#include "graphics_render.h" static thread_local GPU::CommandPool g_command_pool; @@ -155,7 +155,8 @@ void GPU::CommandPool::createPool(int id) { alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; alloc_info.commandBufferCount = m_pool[id].buffers_count; - if (vkAllocateCommandBuffers(ctx->m_device, &alloc_info, m_pool[id].buffers.data()) != VK_SUCCESS) { + if (vkAllocateCommandBuffers(ctx->m_device, &alloc_info, m_pool[id].buffers.data()) != + VK_SUCCESS) { fmt::print("Can't allocate command buffers\n"); std::exit(0); } @@ -168,7 +169,8 @@ void GPU::CommandPool::createPool(int id) { fence_info.pNext = nullptr; fence_info.flags = 0; - if (vkCreateFence(ctx->m_device, &fence_info, nullptr, &m_pool[id].fences[i]) != VK_SUCCESS) { + if (vkCreateFence(ctx->m_device, &fence_info, nullptr, &m_pool[id].fences[i]) != + VK_SUCCESS) { fmt::print("Can't create fence\n"); std::exit(0); } @@ -178,7 +180,8 @@ void GPU::CommandPool::createPool(int id) { semaphore_info.pNext = nullptr; semaphore_info.flags = 0; - if (vkCreateSemaphore(ctx->m_device, &semaphore_info, nullptr, &m_pool[id].semaphores[i]) != VK_SUCCESS) { + if (vkCreateSemaphore(ctx->m_device, &semaphore_info, nullptr, &m_pool[id].semaphores[i]) != + VK_SUCCESS) { fmt::print("Can't create semas\n"); std::exit(0); } diff --git a/src/core/PS4/HLE/Graphics/graphics_render.h b/src/core/PS4/HLE/Graphics/graphics_render.h index c85f3948..5daa27de 100644 --- a/src/core/PS4/HLE/Graphics/graphics_render.h +++ b/src/core/PS4/HLE/Graphics/graphics_render.h @@ -6,7 +6,7 @@ namespace GPU { class CommandPool { - public: +public: CommandPool() = default; ~CommandPool() {} @@ -17,16 +17,20 @@ class CommandPool { return &m_pool[id]; } - private: +private: void createPool(int id); void deleteAllPool(); std::array m_pool{}; }; class CommandBuffer { - public: - explicit CommandBuffer(int queue) : m_queue(queue) { allocateBuffer(); } - virtual ~CommandBuffer() { freeBuffer(); } +public: + explicit CommandBuffer(int queue) : m_queue(queue) { + allocateBuffer(); + } + virtual ~CommandBuffer() { + freeBuffer(); + } void allocateBuffer(); void freeBuffer(); void waitForFence(); @@ -34,9 +38,14 @@ class CommandBuffer { void end() const; void executeWithSemaphore(); void execute(); - u32 getIndex() const { return m_index; } - HLE::Libs::Graphics::VulkanCommandPool* getPool() { return m_pool; } - private: + u32 getIndex() const { + return m_index; + } + HLE::Libs::Graphics::VulkanCommandPool* getPool() { + return m_pool; + } + +private: int m_queue = -1; u32 m_index = static_cast(-1); HLE::Libs::Graphics::VulkanCommandPool* m_pool = nullptr; @@ -44,22 +53,26 @@ class CommandBuffer { }; class Framebuffer { - public: +public: Framebuffer() {} virtual ~Framebuffer() {} }; class RenderCtx { - public: +public: RenderCtx() = default; virtual ~RenderCtx() {} - void setGraphicCtx(HLE::Libs::Graphics::GraphicCtx* ctx) { m_graphic_ctx = ctx; } - HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { return m_graphic_ctx; } + void setGraphicCtx(HLE::Libs::Graphics::GraphicCtx* ctx) { + m_graphic_ctx = ctx; + } + HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { + return m_graphic_ctx; + } - private: +private: Framebuffer m_framebuffer{}; HLE::Libs::Graphics::GraphicCtx* m_graphic_ctx = nullptr; }; void renderCreateCtx(); -}; // namespace GPU +}; // namespace GPU diff --git a/src/core/PS4/HLE/Graphics/video_out.cpp b/src/core/PS4/HLE/Graphics/video_out.cpp index 7fdb2193..e083a38f 100644 --- a/src/core/PS4/HLE/Graphics/video_out.cpp +++ b/src/core/PS4/HLE/Graphics/video_out.cpp @@ -1,25 +1,25 @@ #include #include #include -#include "common/log.h" +#include "Objects/video_out_ctx.h" +#include "Util/config.h" #include "common/debug.h" -#include "core/loader/symbols_resolver.h" -#include "core/PS4/HLE/Graphics/video_out.h" +#include "common/log.h" +#include "common/singleton.h" #include "core/PS4/GPU/gpu_memory.h" #include "core/PS4/GPU/video_out_buffer.h" +#include "core/PS4/HLE/Graphics/video_out.h" #include "core/hle/error_codes.h" -#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" #include "core/hle/libraries/libs.h" +#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" #include "core/hle/libraries/libuserservice/usr_mng_codes.h" -#include "Util/config.h" -#include "Objects/video_out_ctx.h" -#include "common/singleton.h" +#include "core/loader/symbols_resolver.h" #include "emulator.h" #include "graphics_render.h" namespace HLE::Libs::Graphics::VideoOut { -constexpr bool log_file_videoout = true; // disable it to disable logging +constexpr bool log_file_videoout = true; // disable it to disable logging void videoOutInit(u32 width, u32 height) { auto* videoOut = Common::Singleton::Instance(); @@ -33,19 +33,28 @@ bool videoOutFlip(u32 micros) { std::string getPixelFormatString(s32 format) { switch (format) { - case SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB: return "PIXEL_FORMAT_A8R8G8B8_SRGB"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB: return "PIXEL_FORMAT_A8B8G8R8_SRGB"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10: return "PIXEL_FORMAT_A2R10G10B10"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_SRGB: return "PIXEL_FORMAT_A2R10G10B10_SRGB"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_BT2020_PQ: return "PIXEL_FORMAT_A2R10G10B10_BT2020_PQ"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_A16R16G16B16_FLOAT: return "PIXEL_FORMAT_A16R16G16B16_FLOAT"; - case SCE_VIDEO_OUT_PIXEL_FORMAT_YCBCR420_BT709: return "PIXEL_FORMAT_YCBCR420_BT709"; - default: return "Unknown pixel format"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB: + return "PIXEL_FORMAT_A8R8G8B8_SRGB"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB: + return "PIXEL_FORMAT_A8B8G8R8_SRGB"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10: + return "PIXEL_FORMAT_A2R10G10B10"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_SRGB: + return "PIXEL_FORMAT_A2R10G10B10_SRGB"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A2R10G10B10_BT2020_PQ: + return "PIXEL_FORMAT_A2R10G10B10_BT2020_PQ"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_A16R16G16B16_FLOAT: + return "PIXEL_FORMAT_A16R16G16B16_FLOAT"; + case SCE_VIDEO_OUT_PIXEL_FORMAT_YCBCR420_BT709: + return "PIXEL_FORMAT_YCBCR420_BT709"; + default: + return "Unknown pixel format"; } } -void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, - u32 height, u32 pitchInPixel) { +void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, + u32 pixelFormat, u32 tilingMode, u32 aspectRatio, + u32 width, u32 height, u32 pitchInPixel) { PRINT_FUNCTION_NAME(); auto tileMode = magic_enum::enum_cast(tilingMode); @@ -81,11 +90,13 @@ static void flip_trigger_event_func(Core::Kernel::EqueueEvent* event, void* trig event->event.data = reinterpret_cast(trigger_data); } -static void flip_delete_event_func(Core::Kernel::SceKernelEqueue eq, Core::Kernel::EqueueEvent* event) { - BREAKPOINT(); // TODO +static void flip_delete_event_func(Core::Kernel::SceKernelEqueue eq, + Core::Kernel::EqueueEvent* event) { + BREAKPOINT(); // TODO } -s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 handle, void* udata) { +s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 handle, + void* udata) { PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); @@ -119,13 +130,14 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 h return result; } -s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, s32 bufferNum, +s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, + s32 bufferNum, const SceVideoOutBufferAttribute* attribute) { PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); auto* ctx = videoOut->getCtx(handle); - if (handle == 1) { // main port + if (handle == 1) { // main port if (startIndex < 0 || startIndex > 15) { LOG_TRACE_IF(log_file_videoout, "invalid startIndex = {}\n", startIndex); return SCE_VIDEO_OUT_ERROR_INVALID_VALUE; @@ -168,7 +180,7 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co GPU::renderCreateCtx(); // try to calculate buffer size - u64 buffer_size = 0; // still calculation is probably partial or wrong :D + u64 buffer_size = 0; // still calculation is probably partial or wrong :D if (attribute->tilingMode == 0) { buffer_size = 1920 * 1088 * 4; } else { @@ -193,7 +205,9 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co format = GPU::VideoOutBufferFormat::R8G8B8A8Srgb; } - GPU::VideoOutBufferObj buffer_info(format, attribute->width, attribute->height, attribute->tilingMode == 0, Config::isNeoMode(), buffer_pitch); + GPU::VideoOutBufferObj buffer_info(format, attribute->width, attribute->height, + attribute->tilingMode == 0, Config::isNeoMode(), + buffer_pitch); for (int i = 0; i < bufferNum; i++) { if (ctx->buffers[i + startIndex].buffer != nullptr) { @@ -205,10 +219,13 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co ctx->buffers[i + startIndex].buffer = addresses[i]; ctx->buffers[i + startIndex].buffer_size = buffer_size; ctx->buffers[i + startIndex].buffer_pitch = buffer_pitch; - ctx->buffers[i + startIndex].buffer_render = static_cast( - GPU::memoryCreateObj(0, videoOut->getGraphicCtx(), nullptr, reinterpret_cast(addresses[i]), buffer_size, buffer_info)); + ctx->buffers[i + startIndex].buffer_render = + static_cast(GPU::memoryCreateObj( + 0, videoOut->getGraphicCtx(), nullptr, reinterpret_cast(addresses[i]), + buffer_size, buffer_info)); - LOG_INFO_IF(log_file_videoout, "buffers[{}] = {:#x}\n", i + startIndex, reinterpret_cast(addresses[i])); + LOG_INFO_IF(log_file_videoout, "buffers[{}] = {:#x}\n", i + startIndex, + reinterpret_cast(addresses[i])); } return registration_index; @@ -234,14 +251,16 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode auto* ctx = videoOut->getCtx(handle); if (flipMode != 1) { - // BREAKPOINT(); // only flipmode==1 is supported - LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flipmode {}\n", bufferIndex);//openBOR needs 2 but seems to work + // BREAKPOINT(); // only flipmode==1 is supported + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flipmode {}\n", + bufferIndex); // openBOR needs 2 but seems to work } if (bufferIndex == -1) { - BREAKPOINT(); // blank output not supported + BREAKPOINT(); // blank output not supported } if (bufferIndex < -1 || bufferIndex > 15) { - LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n", bufferIndex); + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n", + bufferIndex); return SCE_VIDEO_OUT_ERROR_INVALID_INDEX; } LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex); @@ -252,7 +271,8 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flip queue is full\n"); return SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL; } - Core::Libraries::LibSceGnmDriver::sceGnmFlushGarlic(); // hackish should be done that neccesary for niko's homebrew + Core::Libraries::LibSceGnmDriver::sceGnmFlushGarlic(); // hackish should be done that neccesary + // for niko's homebrew return SCE_OK; } @@ -280,7 +300,8 @@ s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutio return SCE_OK; } -s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, const void* param) { +s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, + const void* param) { PRINT_FUNCTION_NAME(); if (userId != SCE_USER_SERVICE_USER_ID_SYSTEM && userId != 0) { BREAKPOINT(); @@ -300,7 +321,7 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 i if (handle < 0) { LOG_TRACE_IF(log_file_videoout, "sceVideoOutOpen all available handles are open\n"); - return SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY; // it is alreadyOpened + return SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY; // it is alreadyOpened } return handle; @@ -319,25 +340,38 @@ s32 PS4_SYSV_ABI sceVideoOutUnregisterBuffers(s32 handle, s32 attributeIndex) { void videoOutRegisterLib(Core::Loader::SymbolsResolver* sym) { using namespace Core; - LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetFlipStatus); + LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutGetFlipStatus); LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSubmitFlip); - LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutRegisterBuffers); - LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutAddFlipEvent); - LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSetFlipRate); - LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSetBufferAttribute); - LIB_FUNCTION("6kPnj51T62Y", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetResolutionStatus); + LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutRegisterBuffers); + LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutAddFlipEvent); + LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutSetFlipRate); + LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutSetBufferAttribute); + LIB_FUNCTION("6kPnj51T62Y", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutGetResolutionStatus); LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutOpen); - LIB_FUNCTION("zgXifHT9ErY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutIsFlipPending); - LIB_FUNCTION("N5KDtkIjjJ4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutUnregisterBuffers); + LIB_FUNCTION("zgXifHT9ErY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutIsFlipPending); + LIB_FUNCTION("N5KDtkIjjJ4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, + sceVideoOutUnregisterBuffers); LIB_FUNCTION("uquVH4-Du78", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutClose); // openOrbis appears to have libSceVideoOut_v1 module libSceVideoOut_v1.1 LIB_FUNCTION("Up36PTk687E", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutOpen); - LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutSetFlipRate); - LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutAddFlipEvent); - LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutSetBufferAttribute); - LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutRegisterBuffers); + LIB_FUNCTION("CBiu4mCE1DA", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, + sceVideoOutSetFlipRate); + LIB_FUNCTION("HXzjK9yI30k", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, + sceVideoOutAddFlipEvent); + LIB_FUNCTION("i6-sR91Wt-4", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, + sceVideoOutSetBufferAttribute); + LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, + sceVideoOutRegisterBuffers); LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutSubmitFlip); - LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutGetFlipStatus); + LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, + sceVideoOutGetFlipStatus); } -} // namespace HLE::Libs::Graphics::VideoOut +} // namespace HLE::Libs::Graphics::VideoOut diff --git a/src/core/PS4/HLE/Graphics/video_out.h b/src/core/PS4/HLE/Graphics/video_out.h index 8a8a88d5..b4d382a2 100644 --- a/src/core/PS4/HLE/Graphics/video_out.h +++ b/src/core/PS4/HLE/Graphics/video_out.h @@ -9,12 +9,12 @@ class SymbolsResolver; namespace HLE::Libs::Graphics::VideoOut { -using SceUserServiceUserId = s32; // TODO move it to proper place +using SceUserServiceUserId = s32; // TODO move it to proper place // SceVideoOutBusType -constexpr int SCE_VIDEO_OUT_BUS_TYPE_MAIN = 0; // Main output -constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_SOCIAL_SCREEN = 5; // Aux output for social -constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_GAME_LIVE_STREAMING = 6; // Aux output for screaming +constexpr int SCE_VIDEO_OUT_BUS_TYPE_MAIN = 0; // Main output +constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_SOCIAL_SCREEN = 5; // Aux output for social +constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_GAME_LIVE_STREAMING = 6; // Aux output for screaming // SceVideoOutRefreshRate constexpr int SCE_VIDEO_OUT_REFRESH_RATE_UNKNOWN = 0; @@ -37,9 +37,16 @@ constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE = 0; constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_VR = 7; constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_STRICT_COLORIMETRY = 8; -enum SceVideoOutEventId : s16 { SCE_VIDEO_OUT_EVENT_FLIP = 0, SCE_VIDEO_OUT_EVENT_VBLANK = 1, SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START = 2 }; +enum SceVideoOutEventId : s16 { + SCE_VIDEO_OUT_EVENT_FLIP = 0, + SCE_VIDEO_OUT_EVENT_VBLANK = 1, + SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START = 2 +}; -enum SceVideoOutTilingMode : s32 { SCE_VIDEO_OUT_TILING_MODE_TILE = 0, SCE_VIDEO_OUT_TILING_MODE_LINEAR = 1 }; +enum SceVideoOutTilingMode : s32 { + SCE_VIDEO_OUT_TILING_MODE_TILE = 0, + SCE_VIDEO_OUT_TILING_MODE_LINEAR = 1 +}; enum AspectRatioMode : s32 { SCE_VIDEO_OUT_ASPECT_RATIO_16_9 = 0 }; @@ -101,17 +108,20 @@ std::string getPixelFormatString(s32 format); void videoOutRegisterLib(Core::Loader::SymbolsResolver* sym); bool videoOutFlip(u32 micros); -void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, - u32 height, u32 pitchInPixel); +void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, + u32 pixelFormat, u32 tilingMode, u32 aspectRatio, + u32 width, u32 height, u32 pitchInPixel); s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 handle, void* udata); -s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, s32 bufferNum, +s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses, + s32 bufferNum, const SceVideoOutBufferAttribute* attribute); s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate); s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle); s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg); s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, SceVideoOutFlipStatus* status); s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status); -s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, const void* param); +s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, + const void* param); s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle); } // namespace HLE::Libs::Graphics::VideoOut diff --git a/src/core/aerolib/aerolib.cpp b/src/core/aerolib/aerolib.cpp index eb93fe18..c7cb3a2f 100644 --- a/src/core/aerolib/aerolib.cpp +++ b/src/core/aerolib/aerolib.cpp @@ -6,8 +6,7 @@ namespace Core::AeroLib { // Use a direct table here + binary search as contents are static static constexpr NidEntry NIDS[] = { -#define STUB(nid, name) \ - { nid, #name }, +#define STUB(nid, name) {nid, #name}, #include "aerolib.inl" #undef STUB }; diff --git a/src/core/aerolib/stubs.cpp b/src/core/aerolib/stubs.cpp index e971ae31..73d8ab6a 100644 --- a/src/core/aerolib/stubs.cpp +++ b/src/core/aerolib/stubs.cpp @@ -5,16 +5,16 @@ namespace Core::AeroLib { // Helper to provide stub implementations for missing functions -// +// // This works by pre-compiling generic stub functions ("slots"), and then // on lookup, setting up the nid_entry they are matched with -// +// // If it runs out of stubs with name information, it will return // a default implemetnation without function name details // Up to 512, larger values lead to more resolve stub slots // and to longer compile / CI times -// +// // Must match STUBS_LIST define constexpr u32 MAX_STUBS = 128; @@ -24,11 +24,11 @@ u64 UnresolvedStub() { } static u64 UnknownStub() { - LOG_ERROR("Stub: Unknown (nid: Unknown) called, returning zero to {}\n", __builtin_return_address(0)); + LOG_ERROR("Stub: Unknown (nid: Unknown) called, returning zero to {}\n", + __builtin_return_address(0)); return 0; } - static const NidEntry* stub_nids[MAX_STUBS]; static std::string stub_nids_unknown[MAX_STUBS]; @@ -36,17 +36,18 @@ template static u64 CommonStub() { auto entry = stub_nids[stub_index]; if (entry) { - LOG_ERROR("Stub: {} (nid: {}) called, returning zero to {}\n", entry->name, entry->nid, __builtin_return_address(0)); + LOG_ERROR("Stub: {} (nid: {}) called, returning zero to {}\n", entry->name, entry->nid, + __builtin_return_address(0)); } else { - LOG_ERROR("Stub: Unknown (nid: {}) called, returning zero to {}\n", stub_nids_unknown[stub_index], __builtin_return_address(0)); + LOG_ERROR("Stub: Unknown (nid: {}) called, returning zero to {}\n", + stub_nids_unknown[stub_index], __builtin_return_address(0)); } return 0; } static u32 UsedStubEntries; -#define XREP_1(x) \ - &CommonStub, +#define XREP_1(x) &CommonStub, #define XREP_2(x) XREP_1(x) XREP_1(x + 1) #define XREP_4(x) XREP_2(x) XREP_2(x + 2) @@ -60,9 +61,7 @@ static u32 UsedStubEntries; #define STUBS_LIST XREP_128(0) -static u64 (*stub_handlers[MAX_STUBS])() = { - STUBS_LIST -}; +static u64 (*stub_handlers[MAX_STUBS])() = {STUBS_LIST}; u64 GetStub(const char* nid) { if (UsedStubEntries >= MAX_STUBS) { diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 18884b74..fa60c04a 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -4,7 +4,7 @@ namespace Core::FileSys { -constexpr int RESERVED_HANDLES = 3; // First 3 handles are stdin,stdout,stderr +constexpr int RESERVED_HANDLES = 3; // First 3 handles are stdin,stdout,stderr void MntPoints::mount(const std::string& host_folder, const std::string& guest_folder) { std::scoped_lock lock{m_mutex}; @@ -15,7 +15,7 @@ void MntPoints::mount(const std::string& host_folder, const std::string& guest_f m_mnt_pairs.push_back(pair); } -void MntPoints::unmount(const std::string& path) {} // TODO! +void MntPoints::unmount(const std::string& path) {} // TODO! void MntPoints::unmountAll() { std::scoped_lock lock{m_mutex}; m_mnt_pairs.clear(); @@ -40,10 +40,10 @@ std::string MntPoints::getHostFile(const std::string& guest_file) { std::scoped_lock lock{m_mutex}; for (auto& pair : m_mnt_pairs) { - //horrible code but it works :D + // horrible code but it works :D int find = guest_file.find(pair.guest_path); if (find == 0) { - std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size()-1); + std::string npath = guest_file.substr(pair.guest_path.size(), guest_file.size() - 1); std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/'); return pair.host_path + npath; } @@ -88,4 +88,4 @@ File* HandleTable::getFile(const std::string& host_name) { } return nullptr; } -} // namespace Core::FileSys \ No newline at end of file +} // namespace Core::FileSys \ No newline at end of file diff --git a/src/core/file_sys/fs.h b/src/core/file_sys/fs.h index 8bfdbff9..23a23976 100644 --- a/src/core/file_sys/fs.h +++ b/src/core/file_sys/fs.h @@ -5,16 +5,16 @@ #include #include -#include "common/fs_file.h" #include +#include "common/fs_file.h" namespace Core::FileSys { class MntPoints { - public: +public: struct MntPair { std::string host_path; - std::string guest_path; // e.g /app0/ + std::string guest_path; // e.g /app0/ }; MntPoints() = default; @@ -25,7 +25,7 @@ class MntPoints { std::string getHostDirectory(const std::string& guest_directory); std::string getHostFile(const std::string& guest_file); - private: +private: std::vector m_mnt_pairs; std::mutex m_mutex; }; @@ -36,12 +36,12 @@ struct File { std::string m_host_name; std::string m_guest_name; IOFile f; - //std::vector dirents; + // std::vector dirents; u32 dirents_index; std::mutex m_mutex; }; class HandleTable { - public: +public: HandleTable() {} virtual ~HandleTable() {} int createHandle(); @@ -49,9 +49,9 @@ class HandleTable { File* getFile(int d); File* getFile(const std::string& host_name); - private: +private: std::vector m_files; std::mutex m_mutex; }; -} // namespace Core::FileSys +} // namespace Core::FileSys diff --git a/src/core/hle/error_codes.h b/src/core/hle/error_codes.h index 80f0de40..06438176 100644 --- a/src/core/hle/error_codes.h +++ b/src/core/hle/error_codes.h @@ -231,14 +231,14 @@ constexpr int SCE_KERNEL_ERROR_ESTART = 0x80020064; constexpr int SCE_KERNEL_ERROR_ESTOP = 0x80020065; // videoOut -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; // invalid addresses -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; // invalid tiling mode -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; // invalid aspect ration -constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue -constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot already used -constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; // invalid addresses +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; // invalid tiling mode +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; // invalid aspect ration +constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue +constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot already used +constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full +constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option diff --git a/src/core/hle/kernel/Objects/event_queue.cpp b/src/core/hle/kernel/Objects/event_queue.cpp index 8720daf6..eb999b3f 100644 --- a/src/core/hle/kernel/Objects/event_queue.cpp +++ b/src/core/hle/kernel/Objects/event_queue.cpp @@ -15,7 +15,7 @@ int EqueueInternal::addEvent(const EqueueEvent& event) { m_events.push_back(event); if (event.isTriggered) { - BREAKPOINT(); // we don't support that either yet + BREAKPOINT(); // we don't support that either yet } return 0; @@ -42,7 +42,7 @@ bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) { std::scoped_lock lock{m_mutex}; if (m_events.size() > 1) { - BREAKPOINT(); // we currently support one event + BREAKPOINT(); // we currently support one event } auto& event = m_events[0]; @@ -61,7 +61,7 @@ int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { int ret = 0; if (m_events.size() > 1) { - BREAKPOINT(); // we currently support one event + BREAKPOINT(); // we currently support one event } auto& event = m_events[0]; diff --git a/src/core/hle/kernel/Objects/event_queue.h b/src/core/hle/kernel/Objects/event_queue.h index 407ccee9..d03508c3 100644 --- a/src/core/hle/kernel/Objects/event_queue.h +++ b/src/core/hle/kernel/Objects/event_queue.h @@ -1,23 +1,23 @@ #pragma once +#include #include #include #include -#include #include "common/types.h" namespace Core::Kernel { constexpr s16 EVFILT_READ = -1; constexpr s16 EVFILT_WRITE = -2; -constexpr s16 EVFILT_AIO = -3; // attached to aio requests -constexpr s16 EVFILT_VNODE = -4; // attached to vnodes -constexpr s16 EVFILT_PROC = -5; // attached to struct proc -constexpr s16 EVFILT_SIGNAL = -6; // attached to struct proc -constexpr s16 EVFILT_TIMER = -7; // timers -constexpr s16 EVFILT_FS = -9; // filesystem events -constexpr s16 EVFILT_LIO = -10; // attached to lio requests -constexpr s16 EVFILT_USER = -11; // User events +constexpr s16 EVFILT_AIO = -3; // attached to aio requests +constexpr s16 EVFILT_VNODE = -4; // attached to vnodes +constexpr s16 EVFILT_PROC = -5; // attached to struct proc +constexpr s16 EVFILT_SIGNAL = -6; // attached to struct proc +constexpr s16 EVFILT_TIMER = -7; // timers +constexpr s16 EVFILT_FS = -9; // filesystem events +constexpr s16 EVFILT_LIO = -10; // attached to lio requests +constexpr s16 EVFILT_USER = -11; // User events constexpr s16 EVFILT_POLLING = -12; constexpr s16 EVFILT_VIDEO_OUT = -13; constexpr s16 EVFILT_GRAPHICS_CORE = -14; @@ -61,17 +61,20 @@ struct EqueueEvent { }; class EqueueInternal { - public: +public: EqueueInternal() = default; virtual ~EqueueInternal(); - void setName(const std::string& m_name) { this->m_name = m_name; } + void setName(const std::string& m_name) { + this->m_name = m_name; + } int addEvent(const EqueueEvent& event); int waitForEvents(SceKernelEvent* ev, int num, u32 micros); bool triggerEvent(u64 ident, s16 filter, void* trigger_data); int getTriggeredEvents(SceKernelEvent* ev, int num); - private: + +private: std::string m_name; - std::mutex m_mutex; + std::mutex m_mutex; std::vector m_events; std::condition_variable m_cond; }; diff --git a/src/core/hle/kernel/Objects/physical_memory.cpp b/src/core/hle/kernel/Objects/physical_memory.cpp index 58900f81..7f4475de 100644 --- a/src/core/hle/kernel/Objects/physical_memory.cpp +++ b/src/core/hle/kernel/Objects/physical_memory.cpp @@ -6,8 +6,8 @@ static u64 AlignUp(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); } -bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, - u64* physAddrOut, int memoryType) { +bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, + int memoryType) { std::scoped_lock lock{m_mutex}; u64 find_free_pos = 0; diff --git a/src/core/hle/kernel/Objects/physical_memory.h b/src/core/hle/kernel/Objects/physical_memory.h index 200e81d5..329b30b0 100644 --- a/src/core/hle/kernel/Objects/physical_memory.h +++ b/src/core/hle/kernel/Objects/physical_memory.h @@ -4,13 +4,13 @@ #include #include "common/types.h" -#include "core/virtual_memory.h" #include "core/PS4/GPU/gpu_memory.h" +#include "core/virtual_memory.h" namespace Core::Kernel { class PhysicalMemory { - public: +public: struct AllocatedBlock { u64 start_addr; u64 size; @@ -24,11 +24,13 @@ class PhysicalMemory { PhysicalMemory() {} virtual ~PhysicalMemory() {} - public: - bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType); - bool Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, GPU::MemoryMode gpu_mode); +public: + bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, + int memoryType); + bool Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, + GPU::MemoryMode gpu_mode); - private: +private: std::vector m_allocatedBlocks; std::mutex m_mutex; }; diff --git a/src/core/hle/kernel/cpu_management.cpp b/src/core/hle/kernel/cpu_management.cpp index 5ae6e639..71bf2f6b 100644 --- a/src/core/hle/kernel/cpu_management.cpp +++ b/src/core/hle/kernel/cpu_management.cpp @@ -1,7 +1,7 @@ +#include "Util/config.h" #include "common/log.h" #include "core/hle/kernel/cpu_management.h" #include "core/hle/libraries/libs.h" -#include "Util/config.h" namespace Core::Kernel { diff --git a/src/core/hle/kernel/event_queues.cpp b/src/core/hle/kernel/event_queues.cpp index 016b21ed..5f5de544 100644 --- a/src/core/hle/kernel/event_queues.cpp +++ b/src/core/hle/kernel/event_queues.cpp @@ -1,31 +1,36 @@ #include "common/debug.h" #include "common/log.h" -#include "core/hle/kernel/event_queues.h" #include "core/hle/error_codes.h" +#include "core/hle/kernel/event_queues.h" #include "core/hle/libraries/libs.h" namespace Core::Kernel { -constexpr bool log_file_equeues = true; // disable it to disable logging +constexpr bool log_file_equeues = true; // disable it to disable logging int PS4_SYSV_ABI sceKernelCreateEqueue(SceKernelEqueue* eq, const char* name) { PRINT_FUNCTION_NAME(); if (eq == nullptr) { - LOG_TRACE_IF(log_file_equeues, "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL eq invalid\n"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL eq invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (name == nullptr) { - LOG_TRACE_IF(log_file_equeues, "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EFAULT name invalid\n"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EFAULT name invalid\n"); return SCE_KERNEL_ERROR_EFAULT; } if (name == NULL) { - LOG_TRACE_IF(log_file_equeues, "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL name is null\n"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL name is null\n"); return SCE_KERNEL_ERROR_EINVAL; } - if (strlen(name) > 31) { // max is 32 including null terminator - LOG_TRACE_IF(log_file_equeues, "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_ENAMETOOLONG name size exceeds 32 bytes\n"); + if (strlen(name) > 31) { // max is 32 including null terminator + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_ENAMETOOLONG name size " + "exceeds 32 bytes\n"); return SCE_KERNEL_ERROR_ENAMETOOLONG; } *eq = new EqueueInternal; @@ -35,8 +40,8 @@ int PS4_SYSV_ABI sceKernelCreateEqueue(SceKernelEqueue* eq, const char* name) { return SCE_OK; } -int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, - int num, int* out, SceKernelUseconds* timo) { +int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int num, int* out, + SceKernelUseconds* timo) { PRINT_FUNCTION_NAME(); if (eq == nullptr) { @@ -51,7 +56,7 @@ int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, return SCE_KERNEL_ERROR_EINVAL; } - if (timo == nullptr) { // wait until an event arrives without timing out + if (timo == nullptr) { // wait until an event arrives without timing out *out = eq->waitForEvents(ev, num, 0); } diff --git a/src/core/hle/kernel/event_queues.h b/src/core/hle/kernel/event_queues.h index 2f39f83a..caaeee7a 100644 --- a/src/core/hle/kernel/event_queues.h +++ b/src/core/hle/kernel/event_queues.h @@ -8,7 +8,7 @@ using SceKernelUseconds = u32; using SceKernelEqueue = EqueueInternal*; int PS4_SYSV_ABI sceKernelCreateEqueue(SceKernelEqueue* eq, const char* name); -int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, - int num, int* out, SceKernelUseconds *timo); +int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int num, int* out, + SceKernelUseconds* timo); } // namespace Core::Kernel diff --git a/src/core/hle/kernel/memory_management.cpp b/src/core/hle/kernel/memory_management.cpp index db61d2d6..5d406f55 100644 --- a/src/core/hle/kernel/memory_management.cpp +++ b/src/core/hle/kernel/memory_management.cpp @@ -1,18 +1,18 @@ #include -#include #include #include -#include "common/log.h" +#include #include "common/debug.h" +#include "common/log.h" #include "common/singleton.h" +#include "core/hle/error_codes.h" +#include "core/hle/kernel/Objects/physical_memory.h" #include "core/hle/kernel/memory_management.h" #include "core/hle/libraries/libs.h" -#include "core/hle/kernel/Objects/physical_memory.h" -#include "core/hle/error_codes.h" namespace Core::Kernel { -constexpr bool log_file_memory = true; // disable it to disable logging +constexpr bool log_file_memory = true; // disable it to disable logging bool is16KBAligned(u64 n) { return ((n % (16ull * 1024) == 0)); @@ -23,24 +23,31 @@ u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() { return SCE_KERNEL_MAIN_DMEM_SIZE; } -int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, u64 alignment, int memoryType, s64* physAddrOut) { +int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, + u64 alignment, int memoryType, s64* physAddrOut) { PRINT_FUNCTION_NAME(); if (searchStart < 0 || searchEnd <= searchStart) { - LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL searchStart,searchEnd invalid\n"); + LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned " + "SCE_KERNEL_ERROR_EINVAL searchStart,searchEnd invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } bool isInRange = (searchStart < len && searchEnd > len); if (len <= 0 || !is16KBAligned(len) || !isInRange) { - LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL memory range invalid\n"); + LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned " + "SCE_KERNEL_ERROR_EINVAL memory range invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if ((alignment != 0 || is16KBAligned(alignment)) && !std::has_single_bit(alignment)) { - LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); + LOG_TRACE_IF( + log_file_memory, + "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (physAddrOut == nullptr) { - LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL physAddrOut is null\n"); + LOG_TRACE_IF( + log_file_memory, + "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL physAddrOut is null\n"); return SCE_KERNEL_ERROR_EINVAL; } auto memtype = magic_enum::enum_cast(memoryType); @@ -53,8 +60,10 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u u64 physical_addr = 0; auto* physical_memory = Common::Singleton::Instance(); - if (!physical_memory->Alloc(searchStart, searchEnd, len, alignment, &physical_addr, memoryType)) { - LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EAGAIN can't allocate physical memory\n"); + if (!physical_memory->Alloc(searchStart, searchEnd, len, alignment, &physical_addr, + memoryType)) { + LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned " + "SCE_KERNEL_ERROR_EAGAIN can't allocate physical memory\n"); return SCE_KERNEL_ERROR_EAGAIN; } *physAddrOut = static_cast(physical_addr); @@ -62,19 +71,24 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u return SCE_OK; } -int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment) { +int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, + s64 directMemoryStart, u64 alignment) { PRINT_FUNCTION_NAME(); if (len == 0 || !is16KBAligned(len)) { - LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL len invalid\n"); + LOG_TRACE_IF(log_file_memory, + "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL len invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (!is16KBAligned(directMemoryStart)) { - LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL directMemoryStart invalid\n"); + LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL " + "directMemoryStart invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (alignment != 0) { if ((!std::has_single_bit(alignment) && !is16KBAligned(alignment))) { - LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); + LOG_TRACE_IF( + log_file_memory, + "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } } @@ -89,12 +103,13 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl GPU::MemoryMode gpu_mode = GPU::MemoryMode::NoAccess; switch (prot) { - case 0x32: - case 0x33: // SCE_KERNEL_PROT_CPU_READ|SCE_KERNEL_PROT_CPU_WRITE|SCE_KERNEL_PROT_GPU_READ|SCE_KERNEL_PROT_GPU_ALL - cpu_mode = VirtualMemory::MemoryMode::ReadWrite; - gpu_mode = GPU::MemoryMode::ReadWrite; - break; - default: BREAKPOINT(); + case 0x32: + case 0x33: // SCE_KERNEL_PROT_CPU_READ|SCE_KERNEL_PROT_CPU_WRITE|SCE_KERNEL_PROT_GPU_READ|SCE_KERNEL_PROT_GPU_ALL + cpu_mode = VirtualMemory::MemoryMode::ReadWrite; + gpu_mode = GPU::MemoryMode::ReadWrite; + break; + default: + BREAKPOINT(); } auto in_addr = reinterpret_cast(*addr); @@ -106,7 +121,7 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl LOG_INFO_IF(log_file_memory, "in_addr = {:#x}\n", in_addr); LOG_INFO_IF(log_file_memory, "out_addr = {:#x}\n", out_addr); - *addr = reinterpret_cast(out_addr); // return out_addr to first functions parameter + *addr = reinterpret_cast(out_addr); // return out_addr to first functions parameter if (out_addr == 0) { return SCE_KERNEL_ERROR_ENOMEM; diff --git a/src/core/hle/kernel/memory_management.h b/src/core/hle/kernel/memory_management.h index 8c2e43ca..81a26e25 100644 --- a/src/core/hle/kernel/memory_management.h +++ b/src/core/hle/kernel/memory_management.h @@ -2,33 +2,35 @@ #include "common/types.h" -constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5376_MB; // ~ 6GB +constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5376_MB; // ~ 6GB namespace Core::Kernel { enum MemoryTypes : u32 { - SCE_KERNEL_WB_ONION = 0, // write - back mode (Onion bus) - SCE_KERNEL_WC_GARLIC = 3, // write - combining mode (Garlic bus) - SCE_KERNEL_WB_GARLIC = 10 // write - back mode (Garlic bus) + SCE_KERNEL_WB_ONION = 0, // write - back mode (Onion bus) + SCE_KERNEL_WC_GARLIC = 3, // write - combining mode (Garlic bus) + SCE_KERNEL_WB_GARLIC = 10 // write - back mode (Garlic bus) }; enum MemoryFlags : u32 { - SCE_KERNEL_MAP_FIXED = 0x0010, // Fixed + SCE_KERNEL_MAP_FIXED = 0x0010, // Fixed SCE_KERNEL_MAP_NO_OVERWRITE = 0x0080, SCE_KERNEL_MAP_NO_COALESCE = 0x400000 }; enum MemoryProtection : u32 { - SCE_KERNEL_PROT_CPU_READ = 0x01, // Permit reads from the CPU - SCE_KERNEL_PROT_CPU_RW = 0x02, // Permit reads/writes from the CPU - SCE_KERNEL_PROT_CPU_WRITE = 0x02, // Permit reads/writes from the CPU (same) - SCE_KERNEL_PROT_GPU_READ = 0x10, // Permit reads from the GPU - SCE_KERNEL_PROT_GPU_WRITE = 0x20, // Permit writes from the GPU - SCE_KERNEL_PROT_GPU_RW = 0x30 // Permit reads/writes from the GPU + SCE_KERNEL_PROT_CPU_READ = 0x01, // Permit reads from the CPU + SCE_KERNEL_PROT_CPU_RW = 0x02, // Permit reads/writes from the CPU + SCE_KERNEL_PROT_CPU_WRITE = 0x02, // Permit reads/writes from the CPU (same) + SCE_KERNEL_PROT_GPU_READ = 0x10, // Permit reads from the GPU + SCE_KERNEL_PROT_GPU_WRITE = 0x20, // Permit writes from the GPU + SCE_KERNEL_PROT_GPU_RW = 0x30 // Permit reads/writes from the GPU }; u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize(); -int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, u64 alignment, int memoryType, s64* physAddrOut); -int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment); +int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, + u64 alignment, int memoryType, s64* physAddrOut); +int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, + s64 directMemoryStart, u64 alignment); } // namespace Core::Kernel diff --git a/src/core/hle/libraries/libc/libc.cpp b/src/core/hle/libraries/libc/libc.cpp index 8d273695..49ea9a44 100644 --- a/src/core/hle/libraries/libc/libc.cpp +++ b/src/core/hle/libraries/libc/libc.cpp @@ -1,7 +1,7 @@ #include #include "common/debug.h" -#include "common/singleton.h" #include "common/log.h" +#include "common/singleton.h" #include "core/hle/libraries/libc/libc.h" #include "core/hle/libraries/libc/libc_cxa.h" #include "core/hle/libraries/libc/libc_math.h" @@ -12,7 +12,7 @@ namespace Core::Libraries::LibC { -constexpr bool log_file_libc = true; // disable it to disable logging +constexpr bool log_file_libc = true; // disable it to disable logging static u32 g_need_sceLibc = 1; using cxa_destructor_func_t = void (*)(void*); @@ -82,55 +82,73 @@ PS4_SYSV_ABI void* ps4__Znwm(u64 count) { } static constexpr u16 lowercaseTable[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, - 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, - 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, - 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, - 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, - 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, - 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, - 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, + 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, + 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, + 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, + 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, + 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, }; -const PS4_SYSV_ABI u16* ps4__Getptolower() { return &lowercaseTable[0]; } +const PS4_SYSV_ABI u16* ps4__Getptolower() { + return &lowercaseTable[0]; +} static constexpr u16 uppercaseTable[256] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, - 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x007B, 0x007C, 0x007D, - 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, - 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, - 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, - 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, - 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, - 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, + 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, + 0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, + 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x0060, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, + 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083, + 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, + 0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, + 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, + 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, }; -const PS4_SYSV_ABI u16* ps4__Getptoupper() { return &uppercaseTable[0]; } +const PS4_SYSV_ABI u16* ps4__Getptoupper() { + return &uppercaseTable[0]; +} namespace CharacterType { enum : u16 { - HexDigit = 0x1, // '0'-'9', 'A'-'F', 'a'-'f' - Uppercase = 0x2, // 'A'-'Z' + HexDigit = 0x1, // '0'-'9', 'A'-'F', 'a'-'f' + Uppercase = 0x2, // 'A'-'Z' Space = 0x4, Punctuation = 0x08, - Lowercase = 0x10, // 'a'-'z' - DecimalDigit = 0x20, // '0'-'9' - Control = 0x40, // CR, FF, HT, NL, VT - Control2 = 0x80, // BEL, BS, etc + Lowercase = 0x10, // 'a'-'z' + DecimalDigit = 0x20, // '0'-'9' + Control = 0x40, // CR, FF, HT, NL, VT + Control2 = 0x80, // BEL, BS, etc ExtraSpace = 0x100, ExtraAlphabetic = 0x200, ExtraBlank = 0x400 @@ -170,101 +188,101 @@ static constexpr u16 characterTypeTable[256] = { CharacterType::Control2, CharacterType::Control2, CharacterType::Control2, - CharacterType::Space, // - CharacterType::Punctuation, // ! - CharacterType::Punctuation, // " - CharacterType::Punctuation, // # - CharacterType::Punctuation, // $ - CharacterType::Punctuation, // % - CharacterType::Punctuation, // & - CharacterType::Punctuation, // ' - CharacterType::Punctuation, // ( - CharacterType::Punctuation, // ) - CharacterType::Punctuation, // * - CharacterType::Punctuation, // + - CharacterType::Punctuation, // , - CharacterType::Punctuation, // - - CharacterType::Punctuation, // . - CharacterType::Punctuation, // / - CharacterType::HexDigit | CharacterType::DecimalDigit, // 0 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 1 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 2 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 3 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 4 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 5 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 6 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 7 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 8 - CharacterType::HexDigit | CharacterType::DecimalDigit, // 9 - CharacterType::Punctuation, // : - CharacterType::Punctuation, // ; - CharacterType::Punctuation, // < - CharacterType::Punctuation, // = - CharacterType::Punctuation, // > - CharacterType::Punctuation, // ? - CharacterType::Punctuation, // @ - CharacterType::HexDigit | CharacterType::Uppercase, // A - CharacterType::HexDigit | CharacterType::Uppercase, // B - CharacterType::HexDigit | CharacterType::Uppercase, // C - CharacterType::HexDigit | CharacterType::Uppercase, // D - CharacterType::HexDigit | CharacterType::Uppercase, // E - CharacterType::HexDigit | CharacterType::Uppercase, // F - CharacterType::Uppercase, // G - CharacterType::Uppercase, // H - CharacterType::Uppercase, // I - CharacterType::Uppercase, // J - CharacterType::Uppercase, // K - CharacterType::Uppercase, // L - CharacterType::Uppercase, // M - CharacterType::Uppercase, // N - CharacterType::Uppercase, // O - CharacterType::Uppercase, // P - CharacterType::Uppercase, // Q - CharacterType::Uppercase, // R - CharacterType::Uppercase, // S - CharacterType::Uppercase, // T - CharacterType::Uppercase, // U - CharacterType::Uppercase, // V - CharacterType::Uppercase, // W - CharacterType::Uppercase, // X - CharacterType::Uppercase, // Y - CharacterType::Uppercase, // Z - CharacterType::Punctuation, // [ - CharacterType::Punctuation, // - CharacterType::Punctuation, // ] - CharacterType::Punctuation, // ^ - CharacterType::Punctuation, // _ - CharacterType::Punctuation, // ` - CharacterType::HexDigit | CharacterType::Lowercase, // a - CharacterType::HexDigit | CharacterType::Lowercase, // b - CharacterType::HexDigit | CharacterType::Lowercase, // c - CharacterType::HexDigit | CharacterType::Lowercase, // d - CharacterType::HexDigit | CharacterType::Lowercase, // e - CharacterType::HexDigit | CharacterType::Lowercase, // f - CharacterType::Lowercase, // g - CharacterType::Lowercase, // h - CharacterType::Lowercase, // i - CharacterType::Lowercase, // j - CharacterType::Lowercase, // k - CharacterType::Lowercase, // l - CharacterType::Lowercase, // m - CharacterType::Lowercase, // n - CharacterType::Lowercase, // o - CharacterType::Lowercase, // p - CharacterType::Lowercase, // q - CharacterType::Lowercase, // r - CharacterType::Lowercase, // s - CharacterType::Lowercase, // t - CharacterType::Lowercase, // u - CharacterType::Lowercase, // v - CharacterType::Lowercase, // w - CharacterType::Lowercase, // x - CharacterType::Lowercase, // y - CharacterType::Lowercase, // z - CharacterType::Punctuation, // { - CharacterType::Punctuation, // | - CharacterType::Punctuation, // } - CharacterType::Punctuation, // ~ + CharacterType::Space, // + CharacterType::Punctuation, // ! + CharacterType::Punctuation, // " + CharacterType::Punctuation, // # + CharacterType::Punctuation, // $ + CharacterType::Punctuation, // % + CharacterType::Punctuation, // & + CharacterType::Punctuation, // ' + CharacterType::Punctuation, // ( + CharacterType::Punctuation, // ) + CharacterType::Punctuation, // * + CharacterType::Punctuation, // + + CharacterType::Punctuation, // , + CharacterType::Punctuation, // - + CharacterType::Punctuation, // . + CharacterType::Punctuation, // / + CharacterType::HexDigit | CharacterType::DecimalDigit, // 0 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 1 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 2 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 3 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 4 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 5 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 6 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 7 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 8 + CharacterType::HexDigit | CharacterType::DecimalDigit, // 9 + CharacterType::Punctuation, // : + CharacterType::Punctuation, // ; + CharacterType::Punctuation, // < + CharacterType::Punctuation, // = + CharacterType::Punctuation, // > + CharacterType::Punctuation, // ? + CharacterType::Punctuation, // @ + CharacterType::HexDigit | CharacterType::Uppercase, // A + CharacterType::HexDigit | CharacterType::Uppercase, // B + CharacterType::HexDigit | CharacterType::Uppercase, // C + CharacterType::HexDigit | CharacterType::Uppercase, // D + CharacterType::HexDigit | CharacterType::Uppercase, // E + CharacterType::HexDigit | CharacterType::Uppercase, // F + CharacterType::Uppercase, // G + CharacterType::Uppercase, // H + CharacterType::Uppercase, // I + CharacterType::Uppercase, // J + CharacterType::Uppercase, // K + CharacterType::Uppercase, // L + CharacterType::Uppercase, // M + CharacterType::Uppercase, // N + CharacterType::Uppercase, // O + CharacterType::Uppercase, // P + CharacterType::Uppercase, // Q + CharacterType::Uppercase, // R + CharacterType::Uppercase, // S + CharacterType::Uppercase, // T + CharacterType::Uppercase, // U + CharacterType::Uppercase, // V + CharacterType::Uppercase, // W + CharacterType::Uppercase, // X + CharacterType::Uppercase, // Y + CharacterType::Uppercase, // Z + CharacterType::Punctuation, // [ + CharacterType::Punctuation, // + CharacterType::Punctuation, // ] + CharacterType::Punctuation, // ^ + CharacterType::Punctuation, // _ + CharacterType::Punctuation, // ` + CharacterType::HexDigit | CharacterType::Lowercase, // a + CharacterType::HexDigit | CharacterType::Lowercase, // b + CharacterType::HexDigit | CharacterType::Lowercase, // c + CharacterType::HexDigit | CharacterType::Lowercase, // d + CharacterType::HexDigit | CharacterType::Lowercase, // e + CharacterType::HexDigit | CharacterType::Lowercase, // f + CharacterType::Lowercase, // g + CharacterType::Lowercase, // h + CharacterType::Lowercase, // i + CharacterType::Lowercase, // j + CharacterType::Lowercase, // k + CharacterType::Lowercase, // l + CharacterType::Lowercase, // m + CharacterType::Lowercase, // n + CharacterType::Lowercase, // o + CharacterType::Lowercase, // p + CharacterType::Lowercase, // q + CharacterType::Lowercase, // r + CharacterType::Lowercase, // s + CharacterType::Lowercase, // t + CharacterType::Lowercase, // u + CharacterType::Lowercase, // v + CharacterType::Lowercase, // w + CharacterType::Lowercase, // x + CharacterType::Lowercase, // y + CharacterType::Lowercase, // z + CharacterType::Punctuation, // { + CharacterType::Punctuation, // | + CharacterType::Punctuation, // } + CharacterType::Punctuation, // ~ CharacterType::Control2, 0, 0, @@ -396,7 +414,9 @@ static constexpr u16 characterTypeTable[256] = { 0, }; -const PS4_SYSV_ABI u16* ps4__Getpctype() { return &characterTypeTable[0]; } +const PS4_SYSV_ABI u16* ps4__Getpctype() { + return &characterTypeTable[0]; +} void libcSymbolsRegister(Loader::SymbolsResolver* sym) { // cxa functions @@ -441,8 +461,8 @@ void libcSymbolsRegister(Loader::SymbolsResolver* sym) { // misc LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &g_need_sceLibc); - LIB_OBJ("2sWzhYqFH4E","libc", 1, "libc", 1, 1,stdout); - LIB_OBJ("H8AprKeZtNg", "libc", 1, "libc", 1, 1, stderr); + LIB_OBJ("2sWzhYqFH4E", "libc", 1, "libc", 1, 1, stdout); + LIB_OBJ("H8AprKeZtNg", "libc", 1, "libc", 1, 1, stderr); LIB_FUNCTION("bzQExy189ZI", "libc", 1, "libc", 1, 1, ps4_init_env); LIB_FUNCTION("XKRegsFpEpk", "libc", 1, "libc", 1, 1, ps4_catchReturnFromMain); LIB_FUNCTION("-QgqOT5u2Vk", "libc", 1, "libc", 1, 1, ps4__Assert); @@ -458,4 +478,4 @@ void libcSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("sUP1hBaouOw", "libc", 1, "libc", 1, 1, ps4__Getpctype); } -}; // namespace Core::Libraries::LibC +}; // namespace Core::Libraries::LibC diff --git a/src/core/hle/libraries/libc/libc.h b/src/core/hle/libraries/libc/libc.h index 522bb111..70d4d80a 100644 --- a/src/core/hle/libraries/libc/libc.h +++ b/src/core/hle/libraries/libc/libc.h @@ -8,4 +8,4 @@ namespace Core::Libraries::LibC { void libcSymbolsRegister(Loader::SymbolsResolver* sym); -} // namespace Core::Libraries::LibC +} // namespace Core::Libraries::LibC diff --git a/src/core/hle/libraries/libc/libc_cxa.cpp b/src/core/hle/libraries/libc/libc_cxa.cpp index 2b27b648..eab0d970 100644 --- a/src/core/hle/libraries/libc/libc_cxa.cpp +++ b/src/core/hle/libraries/libc/libc_cxa.cpp @@ -1,13 +1,14 @@ #include "libc_cxa.h" -#include "common/log.h" #include "common/debug.h" +#include "common/log.h" -// adapted from https://opensource.apple.com/source/libcppabi/libcppabi-14/src/cxa_guard.cxx.auto.html +// adapted from +// https://opensource.apple.com/source/libcppabi/libcppabi-14/src/cxa_guard.cxx.auto.html namespace Core::Libraries::LibC { -constexpr bool log_file_cxa = true; // disable it to disable logging +constexpr bool log_file_cxa = true; // disable it to disable logging // This file implements the __cxa_guard_* functions as defined at: // http://www.codesourcery.com/public/cxx-abi/abi.html @@ -55,15 +56,25 @@ __attribute__((noinline)) static pthread_mutex_t* guard_mutex() { } // helper functions for getting/setting flags in guard_object -static bool initializerHasRun(u64* guard_object) { return (*((u08*)guard_object) != 0); } +static bool initializerHasRun(u64* guard_object) { + return (*((u08*)guard_object) != 0); +} -static void setInitializerHasRun(u64* guard_object) { *((u08*)guard_object) = 1; } +static void setInitializerHasRun(u64* guard_object) { + *((u08*)guard_object) = 1; +} -static bool inUse(u64* guard_object) { return (((u08*)guard_object)[1] != 0); } +static bool inUse(u64* guard_object) { + return (((u08*)guard_object)[1] != 0); +} -static void setInUse(u64* guard_object) { ((u08*)guard_object)[1] = 1; } +static void setInUse(u64* guard_object) { + ((u08*)guard_object)[1] = 1; +} -static void setNotInUse(u64* guard_object) { ((u08*)guard_object)[1] = 0; } +static void setNotInUse(u64* guard_object) { + ((u08*)guard_object)[1] = 0; +} // // Returns 1 if the caller needs to run the initializer and then either @@ -75,7 +86,8 @@ static void setNotInUse(u64* guard_object) { ((u08*)guard_object)[1] = 0; } // int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) { // Double check that the initializer has not already been run - if (initializerHasRun(guard_object)) return 0; + if (initializerHasRun(guard_object)) + return 0; // We now need to acquire a lock that allows only one thread // to run the initializer. If a different thread calls @@ -89,7 +101,8 @@ int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) { int result = ::pthread_mutex_lock(guard_mutex()); if (result != 0) { - LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_lock failed with {}\n", result); + LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_lock failed with {}\n", + result); } // At this point all other threads will block in __cxa_guard_acquire() @@ -97,7 +110,8 @@ int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) { if (initializerHasRun(guard_object)) { int result = ::pthread_mutex_unlock(guard_mutex()); if (result != 0) { - LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", result); + LOG_TRACE_IF(log_file_cxa, + "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", result); } return 0; } @@ -107,7 +121,8 @@ int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) { // But if the same thread can call __cxa_guard_acquire() on the // *same* guard object again, we call abort(); if (inUse(guard_object)) { - LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): initializer for function local static variable called enclosing function\n"); + LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): initializer for function local static " + "variable called enclosing function\n"); } // mark this guard object as being in use @@ -129,7 +144,8 @@ void PS4_SYSV_ABI ps4___cxa_guard_release(u64* guard_object) { // release global mutex int result = ::pthread_mutex_unlock(guard_mutex()); if (result != 0) { - LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", result); + LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", + result); } } @@ -139,11 +155,12 @@ void PS4_SYSV_ABI ps4___cxa_guard_release(u64* guard_object) { void PS4_SYSV_ABI ps4___cxa_guard_abort(u64* guard_object) { int result = ::pthread_mutex_unlock(guard_mutex()); if (result != 0) { - LOG_TRACE_IF(log_file_cxa, "__cxa_guard_abort(): pthread_mutex_unlock failed with {}\n", result); + LOG_TRACE_IF(log_file_cxa, "__cxa_guard_abort(): pthread_mutex_unlock failed with {}\n", + result); } // now reset state, so possible to try to initialize again setNotInUse(guard_object); } -} // namespace Core::Libraries::LibC +} // namespace Core::Libraries::LibC diff --git a/src/core/hle/libraries/libc/libc_stdio.cpp b/src/core/hle/libraries/libc/libc_stdio.cpp index aae85483..3f817cd6 100644 --- a/src/core/hle/libraries/libc/libc_stdio.cpp +++ b/src/core/hle/libraries/libc/libc_stdio.cpp @@ -4,7 +4,7 @@ namespace Core::Libraries::LibC { -constexpr bool log_file_libc = true; // disable it to disable logging +constexpr bool log_file_libc = true; // disable it to disable logging int PS4_SYSV_ABI ps4_printf(VA_ARGS) { VA_CTX(ctx); @@ -13,7 +13,7 @@ int PS4_SYSV_ABI ps4_printf(VA_ARGS) { int PS4_SYSV_ABI ps4_fprintf(FILE* file, VA_ARGS) { int fd = fileno(file); - if (fd == 1 || fd == 2) { // output stdout and stderr to console + if (fd == 1 || fd == 2) { // output stdout and stderr to console VA_CTX(ctx); return printf_ctx(&ctx); } diff --git a/src/core/hle/libraries/libc/libc_stdlib.cpp b/src/core/hle/libraries/libc/libc_stdlib.cpp index 87fe74e3..d1990c16 100644 --- a/src/core/hle/libraries/libc/libc_stdlib.cpp +++ b/src/core/hle/libraries/libc/libc_stdlib.cpp @@ -1,11 +1,11 @@ #include -#include "common/log.h" #include "common/debug.h" +#include "common/log.h" #include "core/hle/libraries/libc/libc_stdlib.h" namespace Core::Libraries::LibC { -constexpr bool log_file_libc = true; // disable it to disable logging +constexpr bool log_file_libc = true; // disable it to disable logging void PS4_SYSV_ABI ps4_exit(int code) { std::exit(code); @@ -35,7 +35,8 @@ int qsort_compair(const void* arg1, const void* arg2) { return compair_ps4(arg1, arg2); } -void PS4_SYSV_ABI ps4_qsort(void* ptr, size_t count, size_t size, int(PS4_SYSV_ABI* comp)(const void*, const void*)) { +void PS4_SYSV_ABI ps4_qsort(void* ptr, size_t count, size_t size, + int(PS4_SYSV_ABI* comp)(const void*, const void*)) { compair_ps4 = comp; std::qsort(ptr, count, size, qsort_compair); } diff --git a/src/core/hle/libraries/libc/libc_stdlib.h b/src/core/hle/libraries/libc/libc_stdlib.h index bd8f7e67..4aa6a1d8 100644 --- a/src/core/hle/libraries/libc/libc_stdlib.h +++ b/src/core/hle/libraries/libc/libc_stdlib.h @@ -9,7 +9,8 @@ void PS4_SYSV_ABI ps4_exit(int code); int PS4_SYSV_ABI ps4_atexit(void (*func)()); void* PS4_SYSV_ABI ps4_malloc(size_t size); void PS4_SYSV_ABI ps4_free(void* ptr); -void PS4_SYSV_ABI ps4_qsort(void* ptr, size_t count, size_t size, int(PS4_SYSV_ABI* comp)(const void*, const void*)); +void PS4_SYSV_ABI ps4_qsort(void* ptr, size_t count, size_t size, + int(PS4_SYSV_ABI* comp)(const void*, const void*)); int PS4_SYSV_ABI ps4_rand(); } // namespace Core::Libraries::LibC diff --git a/src/core/hle/libraries/libc/printf.h b/src/core/hle/libraries/libc/printf.h index 1fa58253..f93df492 100644 --- a/src/core/hle/libraries/libc/printf.h +++ b/src/core/hle/libraries/libc/printf.h @@ -140,7 +140,9 @@ static inline unsigned int _strlen(const char* str) { // internal test if char is a digit (0-9) // \return true if char is a digit -static inline bool _is_digit(char ch) { return (ch >= '0') && (ch <= '9'); } +static inline bool _is_digit(char ch) { + return (ch >= '0') && (ch <= '9'); +} // internal ASCII string to unsigned int conversion static inline unsigned int _atoi(const char** str) { @@ -152,7 +154,8 @@ static inline unsigned int _atoi(const char** str) { } // internal itoa format -static inline size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, +static inline size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) { const size_t start_idx = idx; @@ -160,7 +163,8 @@ static inline size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, si while (!(flags & FLAGS_LEFT) && (len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) { buf[len++] = '0'; } - while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) { + while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && + (len < PRINTF_NTOA_BUFFER_SIZE)) { buf[len++] = '0'; } @@ -191,7 +195,7 @@ static inline size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, si if (negative) { buf[len++] = '-'; } else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists + buf[len++] = '+'; // ignore the space if the '+' exists } else if (flags & FLAGS_SPACE) { buf[len++] = ' '; } @@ -220,7 +224,8 @@ static inline size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, si } // internal itoa for 'long' type -static inline size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, +static inline size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) { char buf[PRINTF_NTOA_BUFFER_SIZE]; size_t len = 0U; @@ -229,18 +234,22 @@ static inline size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size if (!(flags & FLAGS_PRECISION) || value) { do { const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + buf[len++] = + digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; value /= base; } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, + width, flags); } // internal itoa for 'long long' type #if defined(PRINTF_SUPPORT_LONG_LONG) -static inline size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, - unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) { +static inline size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, + unsigned long long value, bool negative, + unsigned long long base, unsigned int prec, unsigned int width, + unsigned int flags) { char buf[PRINTF_NTOA_BUFFER_SIZE]; size_t len = 0U; @@ -248,18 +257,20 @@ static inline size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, if (!(flags & FLAGS_PRECISION) || value) { do { const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + buf[len++] = + digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; value /= base; } while (value && (len < PRINTF_NTOA_BUFFER_SIZE)); } - return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); + return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, + width, flags); } -#endif // PRINTF_SUPPORT_LONG_LONG +#endif // PRINTF_SUPPORT_LONG_LONG #if defined(PRINTF_SUPPORT_FLOAT) -static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, - unsigned int flags) { +static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, + unsigned int prec, unsigned int width, unsigned int flags) { char buf[PRINTF_FTOA_BUFFER_SIZE]; size_t len = 0U; double diff = 0.0; @@ -268,7 +279,8 @@ static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t ma const double thres_max = (double)0x7FFFFFFF; // powers of 10 - static const double pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + static const double pow10[] = {1, 10, 100, 1000, 10000, + 100000, 1000000, 10000000, 100000000, 1000000000}; // test for negative bool negative = false; @@ -304,8 +316,9 @@ static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t ma ++frac; } - // TBD: for very large numbers switch back to native sprintf for exponentials. Anyone want to write code to replace this? - // Normal printf behavior is to print EVERY whole number digit which can be 100s of characters overflowing your buffers == bad + // TBD: for very large numbers switch back to native sprintf for exponentials. Anyone want to + // write code to replace this? Normal printf behavior is to print EVERY whole number digit which + // can be 100s of characters overflowing your buffers == bad if (value > thres_max) { return 0U; } @@ -349,7 +362,8 @@ static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t ma } // pad leading zeros - while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) { + while (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD) && (len < width) && + (len < PRINTF_FTOA_BUFFER_SIZE)) { buf[len++] = '0'; } @@ -361,7 +375,7 @@ static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t ma if (negative) { buf[len++] = '-'; } else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists + buf[len++] = '+'; // ignore the space if the '+' exists } else if (flags & FLAGS_SPACE) { buf[len++] = ' '; } @@ -388,7 +402,7 @@ static inline size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t ma return idx; } -#endif // PRINTF_SUPPORT_FLOAT +#endif // PRINTF_SUPPORT_FLOAT // internal vsnprintf static inline int _vsnprintf(out_fct_type out, char* buffer, const char* format, VaList* va_list) { @@ -417,32 +431,34 @@ static inline int _vsnprintf(out_fct_type out, char* buffer, const char* format, flags = 0U; do { switch (*format) { - case '0': - flags |= FLAGS_ZEROPAD; - format++; - n = 1U; - break; - case '-': - flags |= FLAGS_LEFT; - format++; - n = 1U; - break; - case '+': - flags |= FLAGS_PLUS; - format++; - n = 1U; - break; - case ' ': - flags |= FLAGS_SPACE; - format++; - n = 1U; - break; - case '#': - flags |= FLAGS_HASH; - format++; - n = 1U; - break; - default: n = 0U; break; + case '0': + flags |= FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; } } while (n); @@ -451,10 +467,10 @@ static inline int _vsnprintf(out_fct_type out, char* buffer, const char* format, if (_is_digit(*format)) { width = _atoi(&format); } else if (*format == '*') { - const int w = vaArgInteger(va_list); // const int w = va.next(cpu, mem); + const int w = vaArgInteger(va_list); // const int w = va.next(cpu, mem); if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding + flags |= FLAGS_LEFT; // reverse padding width = (unsigned int)-w; } else { width = (unsigned int)w; @@ -470,212 +486,234 @@ static inline int _vsnprintf(out_fct_type out, char* buffer, const char* format, if (_is_digit(*format)) { precision = _atoi(&format); } else if (*format == '*') { - precision = vaArgInteger(va_list); // precision = (unsigned int)va.next(cpu, mem); + precision = + vaArgInteger(va_list); // precision = (unsigned int)va.next(cpu, mem); format++; } } // evaluate length field switch (*format) { - case 'l': - flags |= FLAGS_LONG; + case 'l': + flags |= FLAGS_LONG; + format++; + if (*format == 'l') { + flags |= FLAGS_LONG_LONG; format++; - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - format++; - } - break; - case 'h': - flags |= FLAGS_SHORT; + } + break; + case 'h': + flags |= FLAGS_SHORT; + format++; + if (*format == 'h') { + flags |= FLAGS_CHAR; format++; - if (*format == 'h') { - flags |= FLAGS_CHAR; - format++; - } - break; + } + break; #if defined(PRINTF_SUPPORT_PTRDIFF_T) - case 't': - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; #endif - case 'j': - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - case 'z': - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - format++; - break; - default: break; + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); + format++; + break; + default: + break; } // evaluate specifier switch (*format) { - case 'd': - case 'i': - case 'u': - case 'x': - case 'X': - case 'o': - case 'b': { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') { - base = 16U; - } else if (*format == 'o') { - base = 8U; - } else if (*format == 'b') { - base = 2U; - flags &= ~FLAGS_HASH; // no hash for bin format - } else { - base = 10U; - flags &= ~FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; - } - - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) { - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - } - - // convert the integer - if ((*format == 'i') || (*format == 'd')) { - // signed - if (flags & FLAGS_LONG_LONG) { -#if defined(PRINTF_SUPPORT_LONG_LONG) - auto value = vaArgLongLong(va_list); // const long long value = va.next(cpu, mem); - idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, - precision, width, flags); -#endif - } else if (flags & FLAGS_LONG) { - auto value = vaArgLong(va_list); // const long value = va.next(cpu, mem); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, - flags); - } else { - // const int value = (flags & FLAGS_CHAR) ? (char)va.next(cpu, mem) : (flags & FLAGS_SHORT) ? (short - // int)va.next(cpu, mem): va.next(cpu, mem); - const int value = (flags & FLAGS_CHAR) ? static_cast(vaArgInteger(va_list)) - : (flags & FLAGS_SHORT) ? static_cast(vaArgInteger(va_list)) - : vaArgInteger(va_list); - idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, - flags); - } - } else { - // unsigned - if (flags & FLAGS_LONG_LONG) { -#if defined(PRINTF_SUPPORT_LONG_LONG) - // idx = _ntoa_long_long(out, buffer, idx, maxlen, va.next(cpu, mem), false, base, precision, width, - // flags); - idx = - _ntoa_long_long(out, buffer, idx, maxlen, static_cast(vaArgLongLong(va_list)), false, base, precision, width, flags); -#endif - } else if (flags & FLAGS_LONG) { - // idx = _ntoa_long(out, buffer, idx, maxlen, va.next(cpu, mem), false, base, precision, width, flags); - idx = _ntoa_long(out, buffer, idx, maxlen, static_cast(vaArgLong(va_list)), false, base, precision, width, flags); - } else { - // const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va.next(cpu, mem) : (flags & FLAGS_SHORT) ? - // (unsigned short int)va.next(cpu, mem) : va.next(cpu, mem); - const unsigned int value = (flags & FLAGS_CHAR) ? static_cast(vaArgInteger(va_list)) - : (flags & FLAGS_SHORT) ? static_cast(vaArgInteger(va_list)) - : static_cast(vaArgInteger(va_list)); - idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') { + base = 16U; + } else if (*format == 'o') { + base = 8U; + } else if (*format == 'b') { + base = 2U; + flags &= ~FLAGS_HASH; // no hash for bin format + } else { + base = 10U; + flags &= ~FLAGS_HASH; // no hash for dec format } + // uppercase + if (*format == 'X') { + flags |= FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) { + flags &= ~(FLAGS_PLUS | FLAGS_SPACE); + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) { + // signed + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + auto value = vaArgLongLong( + va_list); // const long long value = va.next(cpu, mem); + idx = _ntoa_long_long(out, buffer, idx, maxlen, + (unsigned long long)(value > 0 ? value : 0 - value), + value < 0, base, precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + auto value = vaArgLong(va_list); // const long value = va.next(cpu, mem); + idx = _ntoa_long(out, buffer, idx, maxlen, + (unsigned long)(value > 0 ? value : 0 - value), value < 0, + base, precision, width, flags); + } else { + // const int value = (flags & FLAGS_CHAR) ? (char)va.next(cpu, mem) : + // (flags & FLAGS_SHORT) ? (short int)va.next(cpu, mem): va.next(cpu, + // mem); + const int value = + (flags & FLAGS_CHAR) ? static_cast(vaArgInteger(va_list)) + : (flags & FLAGS_SHORT) ? static_cast(vaArgInteger(va_list)) + : vaArgInteger(va_list); + idx = _ntoa_long(out, buffer, idx, maxlen, + (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, + precision, width, flags); + } + } else { + // unsigned + if (flags & FLAGS_LONG_LONG) { +#if defined(PRINTF_SUPPORT_LONG_LONG) + // idx = _ntoa_long_long(out, buffer, idx, maxlen, va.next(cpu, mem), false, base, precision, width, flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, + static_cast(vaArgLongLong(va_list)), false, base, + precision, width, flags); +#endif + } else if (flags & FLAGS_LONG) { + // idx = _ntoa_long(out, buffer, idx, maxlen, va.next(cpu, mem), + // false, base, precision, width, flags); + idx = _ntoa_long(out, buffer, idx, maxlen, static_cast(vaArgLong(va_list)), + false, base, precision, width, flags); + } else { + // const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned + // char)va.next(cpu, mem) : (flags & FLAGS_SHORT) ? + // (unsigned short int)va.next(cpu, mem) : va.next(cpu, mem); + const unsigned int value = + (flags & FLAGS_CHAR) ? static_cast(vaArgInteger(va_list)) + : (flags & FLAGS_SHORT) ? static_cast(vaArgInteger(va_list)) + : static_cast(vaArgInteger(va_list)); + idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, + flags); + } + } + format++; + break; + } #if defined(PRINTF_SUPPORT_FLOAT) - case 'f': - case 'F': - // idx = _ftoa(out, buffer, idx, maxlen, va.next(cpu, mem), precision, width, flags); - idx = _ftoa(out, buffer, idx, maxlen, vaArgDouble(va_list), precision, width, flags); - format++; - break; -#endif // PRINTF_SUPPORT_FLOAT - case 'c': { - unsigned int l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } + case 'f': + case 'F': + // idx = _ftoa(out, buffer, idx, maxlen, va.next(cpu, mem), precision, width, + // flags); + idx = _ftoa(out, buffer, idx, maxlen, vaArgDouble(va_list), precision, width, flags); + format++; + break; +#endif // PRINTF_SUPPORT_FLOAT + case 'c': { + unsigned int l = 1U; + // pre padding + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); } - // char output - // out((char)va.next(cpu, mem), buffer, idx++, maxlen); - out(static_cast(vaArgInteger(va_list)), buffer, idx++, maxlen); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; } - - case 's': { - const char* p = vaArgPtr(va_list); // const char *p = va.next>(cpu, mem).get(mem); - p = p != nullptr ? p : "(null)"; - unsigned int l = _strlen(p); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); + // char output + // out((char)va.next(cpu, mem), buffer, idx++, maxlen); + out(static_cast(vaArgInteger(va_list)), buffer, idx++, maxlen); + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; } + format++; + break; + } - case 'p': { - width = sizeof(void*) * 2U; - flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; + case 's': { + const char* p = vaArgPtr( + va_list); // const char *p = va.next>(cpu, mem).get(mem); + p = p != nullptr ? p : "(null)"; + unsigned int l = _strlen(p); + // pre padding + if (flags & FLAGS_PRECISION) { + l = (l < precision ? l : precision); + } + if (!(flags & FLAGS_LEFT)) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & FLAGS_LEFT) { + while (l++ < width) { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p': { + width = sizeof(void*) * 2U; + flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE; #if defined(PRINTF_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) { - // idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va.next>(cpu, mem).address(), false, 16U, precision, - // width, flags); - idx = _ntoa_long_long(out, buffer, idx, maxlen, reinterpret_cast(vaArgPtr(va_list)), false, 16U, precision, - width, flags); - } else { + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) { + // idx = _ntoa_long_long(out, buffer, idx, maxlen, + // (uintptr_t)va.next>(cpu, mem).address(), false, 16U, precision, width, + // flags); + idx = _ntoa_long_long(out, buffer, idx, maxlen, + reinterpret_cast(vaArgPtr(va_list)), false, + 16U, precision, width, flags); + } else { #endif - // idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va.next>(cpu, mem).address()), false, 16U, - // precision, width, flags); - idx = _ntoa_long(out, buffer, idx, maxlen, static_cast(reinterpret_cast(vaArgPtr(va_list))), false, - 16U, precision, width, flags); + // idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned + // long)((uintptr_t)va.next>(cpu, mem).address()), false, 16U, precision, + // width, flags); + idx = _ntoa_long( + out, buffer, idx, maxlen, + static_cast(reinterpret_cast(vaArgPtr(va_list))), + false, 16U, precision, width, flags); #if defined(PRINTF_SUPPORT_LONG_LONG) - } -#endif - format++; - break; } +#endif + format++; + break; + } - case '%': - out('%', buffer, idx++, maxlen); - format++; - break; + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; - default: - out(*format, buffer, idx++, maxlen); - format++; - break; + default: + out(*format, buffer, idx++, maxlen); + format++; + break; } } @@ -700,4 +738,4 @@ static int vsnprintf_ctx(char* s, size_t n, const char* format, VaList* arg) { std::strcpy(s, buffer); return result; } -} // namespace Core::Libraries::LibC +} // namespace Core::Libraries::LibC diff --git a/src/core/hle/libraries/libc/va_ctx.h b/src/core/hle/libraries/libc/va_ctx.h index d17e1e58..f83dd3de 100644 --- a/src/core/hle/libraries/libc/va_ctx.h +++ b/src/core/hle/libraries/libc/va_ctx.h @@ -1,29 +1,30 @@ -#include "common/types.h" #include +#include "common/types.h" -#define VA_ARGS \ - uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, \ - __m128 xmm2, __m128 xmm3, __m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7, ... +#define VA_ARGS \ + uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, \ + uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, __m128 xmm2, __m128 xmm3, \ + __m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7, ... -#define VA_CTX(ctx) \ - alignas(16) VaCtx ctx; \ - (ctx).reg_save_area.gp[0] = rdi; \ - (ctx).reg_save_area.gp[1] = rsi; \ - (ctx).reg_save_area.gp[2] = rdx; \ - (ctx).reg_save_area.gp[3] = rcx; \ - (ctx).reg_save_area.gp[4] = r8; \ - (ctx).reg_save_area.gp[5] = r9; \ - (ctx).reg_save_area.fp[0] = xmm0; \ - (ctx).reg_save_area.fp[1] = xmm1; \ - (ctx).reg_save_area.fp[2] = xmm2; \ - (ctx).reg_save_area.fp[3] = xmm3; \ - (ctx).reg_save_area.fp[4] = xmm4; \ - (ctx).reg_save_area.fp[5] = xmm5; \ - (ctx).reg_save_area.fp[6] = xmm6; \ - (ctx).reg_save_area.fp[7] = xmm7; \ - (ctx).va_list.reg_save_area = &(ctx).reg_save_area; \ - (ctx).va_list.gp_offset = offsetof(VaRegSave, gp); \ - (ctx).va_list.fp_offset = offsetof(VaRegSave, fp); \ +#define VA_CTX(ctx) \ + alignas(16) VaCtx ctx; \ + (ctx).reg_save_area.gp[0] = rdi; \ + (ctx).reg_save_area.gp[1] = rsi; \ + (ctx).reg_save_area.gp[2] = rdx; \ + (ctx).reg_save_area.gp[3] = rcx; \ + (ctx).reg_save_area.gp[4] = r8; \ + (ctx).reg_save_area.gp[5] = r9; \ + (ctx).reg_save_area.fp[0] = xmm0; \ + (ctx).reg_save_area.fp[1] = xmm1; \ + (ctx).reg_save_area.fp[2] = xmm2; \ + (ctx).reg_save_area.fp[3] = xmm3; \ + (ctx).reg_save_area.fp[4] = xmm4; \ + (ctx).reg_save_area.fp[5] = xmm5; \ + (ctx).reg_save_area.fp[6] = xmm6; \ + (ctx).reg_save_area.fp[7] = xmm7; \ + (ctx).va_list.reg_save_area = &(ctx).reg_save_area; \ + (ctx).va_list.gp_offset = offsetof(VaRegSave, gp); \ + (ctx).va_list.fp_offset = offsetof(VaRegSave, fp); \ (ctx).va_list.overflow_arg_area = &overflow_arg_area; namespace Core::Libraries::LibC { diff --git a/src/core/hle/libraries/libkernel/file_system.cpp b/src/core/hle/libraries/libkernel/file_system.cpp index 57d08cae..47b33d34 100644 --- a/src/core/hle/libraries/libkernel/file_system.cpp +++ b/src/core/hle/libraries/libkernel/file_system.cpp @@ -1,17 +1,18 @@ -#include "common/log.h" +#include +#include +#include #include "common/debug.h" +#include "common/log.h" #include "core/hle/libraries/libkernel/file_system.h" #include "core/hle/libraries/libs.h" -#include -#include -#include namespace Core::Libraries::LibKernel { -constexpr bool log_file_fs = true; // disable it to disable logging +constexpr bool log_file_fs = true; // disable it to disable logging int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { - LOG_INFO_IF(log_file_fs, "sceKernelOpen path = {} flags = {:#x} mode = {:#x}\n", path, flags, mode); + LOG_INFO_IF(log_file_fs, "sceKernelOpen path = {} flags = {:#x} mode = {:#x}\n", path, flags, + mode); auto* h = Common::Singleton::Instance(); auto* mnt = Common::Singleton::Instance(); @@ -34,7 +35,7 @@ int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n"); int result = sceKernelOpen(path, flags, mode); if (result < 0) { - BREAKPOINT(); // posix calls different only for their return values + BREAKPOINT(); // posix calls different only for their return values } return result; } @@ -45,7 +46,7 @@ size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) { size_t total_read = 0; file->m_mutex.lock(); for (int i = 0; i < iovcnt; i++) { - total_read += file->f.readBytes(iov[i].iov_base,iov[i].iov_len).second; + total_read += file->f.readBytes(iov[i].iov_base, iov[i].iov_len).second; } file->m_mutex.unlock(); return total_read; @@ -57,7 +58,8 @@ void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("+WRlkKjZvag", "libkernel", 1, "libkernel", 1, 1, _readv); // openOrbis (to check if it is valid out of OpenOrbis - LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, posix_open); // _open shoudld be equal to open function + LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1, + posix_open); // _open shoudld be equal to open function } } // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libkernel/file_system.h b/src/core/hle/libraries/libkernel/file_system.h index 8a3ef3bb..887f5f81 100644 --- a/src/core/hle/libraries/libkernel/file_system.h +++ b/src/core/hle/libraries/libkernel/file_system.h @@ -9,14 +9,14 @@ class SymbolsResolver; namespace Core::Libraries::LibKernel { struct SceKernelIovec { - void *iov_base; + void* iov_base; size_t iov_len; }; -int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode); +int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, /* SceKernelMode*/ u16 mode); -int PS4_SYSV_ABI posix_open(const char *path, int flags, /* SceKernelMode*/ u16 mode); +int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode); -void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym); +void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym); } // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libkernel/libkernel.cpp b/src/core/hle/libraries/libkernel/libkernel.cpp index 9eadbcb8..41df7d50 100644 --- a/src/core/hle/libraries/libkernel/libkernel.cpp +++ b/src/core/hle/libraries/libkernel/libkernel.cpp @@ -13,8 +13,8 @@ #include "core/loader/elf.h" #ifdef _WIN64 -#include #include +#include #else #include #endif @@ -22,20 +22,26 @@ namespace Core::Libraries::LibKernel { -constexpr bool log_libkernel_file = true; // disable it to disable logging +constexpr bool log_libkernel_file = true; // disable it to disable logging -static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return +static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len) { BREAKPOINT(); return 0; } -static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT(); } +static PS4_SYSV_ABI void stack_chk_fail() { + BREAKPOINT(); +} -int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { BREAKPOINT(); } +int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { + BREAKPOINT(); +} -void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) { std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); } +void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) { + std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); +} struct iovec { void* iov_base; /* Base address. */ @@ -43,7 +49,8 @@ struct iovec { }; size_t PS4_SYSV_ABI _writev(int fd, const struct iovec* iov, int iovcn) { - // weird it gives fd ==0 and writes to stdout , i am not sure if it that is valid (found in openorbis) + // weird it gives fd ==0 and writes to stdout , i am not sure if it that is valid (found in + // openorbis) size_t total_written = 0; for (int i = 0; i < iovcn; i++) { total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout); @@ -52,15 +59,18 @@ size_t PS4_SYSV_ABI _writev(int fd, const struct iovec* iov, int iovcn) { } static thread_local int libc_error; -int* PS4_SYSV_ABI __Error() { return &libc_error; } +int* PS4_SYSV_ABI __Error() { + return &libc_error; +} #define PROT_READ 0x1 #define PROT_WRITE 0x2 -int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, off_t offset, void** res) { +int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, off_t offset, + void** res) { #ifdef _WIN64 PRINT_FUNCTION_NAME(); - if (prot > 3) // READ,WRITE or bitwise READ | WRITE supported + if (prot > 3) // READ,WRITE or bitwise READ | WRITE supported { LOG_ERROR_IF(log_libkernel_file, "sceKernelMmap prot ={} not supported\n", prot); } @@ -76,7 +86,8 @@ int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, mmap_fd = (HANDLE)_get_osfhandle(fd); h = CreateFileMapping(mmap_fd, NULL, flProtect, 0, end, NULL); int k = GetLastError(); - if (NULL == h) return -1; + if (NULL == h) + return -1; DWORD dwDesiredAccess; if (prot & PROT_WRITE) dwDesiredAccess = FILE_MAP_WRITE; @@ -102,7 +113,8 @@ int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, PS4_SYSV_ABI void* posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) { void* ptr; LOG_INFO_IF(log_libkernel_file, "posix mmap redirect to sceKernelMmap\n"); - // posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK + // posix call the difference is that there is a different behaviour when it doesn't return 0 or + // SCE_OK int result = sceKernelMmap(addr, len, prot, flags, fd, offset, &ptr); if (result != 0) { BREAKPOINT(); @@ -114,9 +126,12 @@ void LibKernel_Register(Loader::SymbolsResolver* sym) { // obj LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard); // memory - LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelAllocateDirectMemory); - LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelGetDirectMemorySize); - LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelMapDirectMemory); + LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, + Kernel::sceKernelAllocateDirectMemory); + LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, + Kernel::sceKernelGetDirectMemorySize); + LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, + Kernel::sceKernelMapDirectMemory); LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory); LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", 1, 1, sceKernelMunmap); // equeue @@ -135,4 +150,4 @@ void LibKernel_Register(Loader::SymbolsResolver* sym) { Core::Libraries::LibKernel::pthreadSymbolsRegister(sym); } -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libkernel/libkernel.h b/src/core/hle/libraries/libkernel/libkernel.h index 2d65a54d..ffd8b505 100644 --- a/src/core/hle/libraries/libkernel/libkernel.h +++ b/src/core/hle/libraries/libkernel/libkernel.h @@ -15,4 +15,4 @@ int* PS4_SYSV_ABI __Error(); void LibKernel_Register(Loader::SymbolsResolver* sym); -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libkernel/thread_management.cpp b/src/core/hle/libraries/libkernel/thread_management.cpp index 6d82be94..642e57ac 100644 --- a/src/core/hle/libraries/libkernel/thread_management.cpp +++ b/src/core/hle/libraries/libkernel/thread_management.cpp @@ -11,7 +11,7 @@ namespace Core::Libraries::LibKernel { thread_local ScePthread g_pthread_self{}; PThreadCxt* g_pthread_cxt = nullptr; -constexpr bool log_pthread_file = true; // disable it to disable logging +constexpr bool log_pthread_file = true; // disable it to disable logging void init_pthreads() { g_pthread_cxt = new PThreadCxt{}; @@ -49,9 +49,12 @@ int PS4_SYSV_ABI scePthreadAttrInit(ScePthreadAttr* attr) { result = (result == 0 ? scePthreadAttrSetdetachstate(attr, PTHREAD_CREATE_JOINABLE) : result); switch (result) { - case 0: return SCE_OK; - case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case ENOMEM: + return SCE_KERNEL_ERROR_ENOMEM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } @@ -62,12 +65,20 @@ int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachst int pstate = PTHREAD_CREATE_JOINABLE; switch (detachstate) { - case 0: pstate = PTHREAD_CREATE_JOINABLE; break; - case 1: pstate = PTHREAD_CREATE_DETACHED; break; - default: LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetdetachstate invalid detachstate: {}\n", detachstate); std::exit(0); + case 0: + pstate = PTHREAD_CREATE_JOINABLE; + break; + case 1: + pstate = PTHREAD_CREATE_DETACHED; + break; + default: + LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetdetachstate invalid detachstate: {}\n", + detachstate); + std::exit(0); } - // int result = pthread_attr_setdetachstate(&(*attr)->pth_attr, pstate); doesn't seem to work correctly + // int result = pthread_attr_setdetachstate(&(*attr)->pth_attr, pstate); doesn't seem to work + // correctly int result = 0; (*attr)->detached = (pstate == PTHREAD_CREATE_DETACHED); @@ -82,9 +93,16 @@ int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inherit int pinherit_sched = PTHREAD_INHERIT_SCHED; switch (inheritSched) { - case 0: pinherit_sched = PTHREAD_EXPLICIT_SCHED; break; - case 4: pinherit_sched = PTHREAD_INHERIT_SCHED; break; - default: LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetinheritsched invalid inheritSched: {}\n", inheritSched); std::exit(0); + case 0: + pinherit_sched = PTHREAD_EXPLICIT_SCHED; + break; + case 4: + pinherit_sched = PTHREAD_INHERIT_SCHED; + break; + default: + LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetinheritsched invalid inheritSched: {}\n", + inheritSched); + std::exit(0); } int result = pthread_attr_setinheritsched(&(*attr)->pth_attr, pinherit_sched); @@ -92,7 +110,8 @@ int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inherit return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL; } -int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param) { +int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr, + const SceKernelSchedParam* param) { if (param == nullptr || attr == nullptr || *attr == nullptr) { return SCE_KERNEL_ERROR_EINVAL; } @@ -116,9 +135,11 @@ int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) return SCE_KERNEL_ERROR_EINVAL; } - int ppolicy = SCHED_OTHER; // winpthreads only supports SCHED_OTHER + int ppolicy = SCHED_OTHER; // winpthreads only supports SCHED_OTHER if (policy != SCHED_OTHER) { - LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetschedpolicy policy={} not supported by winpthreads\n", policy); + LOG_TRACE_IF(log_pthread_file, + "scePthreadAttrSetschedpolicy policy={} not supported by winpthreads\n", + policy); } (*attr)->policy = policy; @@ -126,9 +147,12 @@ int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL; } -ScePthread PS4_SYSV_ABI scePthreadSelf() { return g_pthread_self; } +ScePthread PS4_SYSV_ABI scePthreadSelf() { + return g_pthread_self; +} -int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, const /*SceKernelCpumask*/ u64 mask) { +int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, + const /*SceKernelCpumask*/ u64 mask) { PRINT_FUNCTION_NAME(); if (pattr == nullptr || *pattr == nullptr) { @@ -151,7 +175,8 @@ int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpuma return result; } -int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr, pthreadEntryFunc start_routine, void* arg, const char* name) { +int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr, + pthreadEntryFunc start_routine, void* arg, const char* name) { PRINT_DUMMY_FUNCTION_NAME(); return 0; } @@ -169,7 +194,8 @@ void* createMutex(void* addr) { return addr; } -int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, const char* name) { +int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, + const char* name) { PRINT_FUNCTION_NAME(); if (mutex == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -192,11 +218,16 @@ int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMut } switch (result) { - case 0: return SCE_OK; - case EAGAIN: return SCE_KERNEL_ERROR_EAGAIN; - case EINVAL: return SCE_KERNEL_ERROR_EINVAL; - case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case EAGAIN: + return SCE_KERNEL_ERROR_EAGAIN; + case EINVAL: + return SCE_KERNEL_ERROR_EINVAL; + case ENOMEM: + return SCE_KERNEL_ERROR_ENOMEM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } @@ -209,20 +240,31 @@ int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr) { result = (result == 0 ? scePthreadMutexattrSetprotocol(attr, 0) : result); switch (result) { - case 0: return SCE_OK; - case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case ENOMEM: + return SCE_KERNEL_ERROR_ENOMEM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) { int ptype = PTHREAD_MUTEX_DEFAULT; switch (type) { - case 1: ptype = PTHREAD_MUTEX_ERRORCHECK; break; - case 2: ptype = PTHREAD_MUTEX_RECURSIVE; break; - case 3: - case 4: ptype = PTHREAD_MUTEX_NORMAL; break; - default: LOG_TRACE_IF(log_pthread_file, "scePthreadMutexattrSettype invalid type: {}\n", type); std::exit(0); + case 1: + ptype = PTHREAD_MUTEX_ERRORCHECK; + break; + case 2: + ptype = PTHREAD_MUTEX_RECURSIVE; + break; + case 3: + case 4: + ptype = PTHREAD_MUTEX_NORMAL; + break; + default: + LOG_TRACE_IF(log_pthread_file, "scePthreadMutexattrSettype invalid type: {}\n", type); + std::exit(0); } int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype); @@ -233,13 +275,23 @@ int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol) { int pprotocol = PTHREAD_PRIO_NONE; switch (protocol) { - case 0: pprotocol = PTHREAD_PRIO_NONE; break; - case 1: pprotocol = PTHREAD_PRIO_INHERIT; break; - case 2: pprotocol = PTHREAD_PRIO_PROTECT; break; - default: LOG_TRACE_IF(log_pthread_file, "scePthreadMutexattrSetprotocol invalid protocol: {}\n", protocol); std::exit(0); + case 0: + pprotocol = PTHREAD_PRIO_NONE; + break; + case 1: + pprotocol = PTHREAD_PRIO_INHERIT; + break; + case 2: + pprotocol = PTHREAD_PRIO_PROTECT; + break; + default: + LOG_TRACE_IF(log_pthread_file, "scePthreadMutexattrSetprotocol invalid protocol: {}\n", + protocol); + std::exit(0); } - int result = 0; // pthread_mutexattr_setprotocol(&(*attr)->p, pprotocol); //it appears that pprotocol has issues in winpthreads + int result = 0; // pthread_mutexattr_setprotocol(&(*attr)->p, pprotocol); //it appears that + // pprotocol has issues in winpthreads (*attr)->pprotocol = pprotocol; return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL; @@ -253,13 +305,19 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { } int result = pthread_mutex_lock(&(*mutex)->pth_mutex); - LOG_INFO_IF(log_pthread_file, "scePthreadMutexLock name={} result={}\n", (*mutex)->name, result); + LOG_INFO_IF(log_pthread_file, "scePthreadMutexLock name={} result={}\n", (*mutex)->name, + result); switch (result) { - case 0: return SCE_OK; - case EAGAIN: return SCE_KERNEL_ERROR_EAGAIN; - case EINVAL: return SCE_KERNEL_ERROR_EINVAL; - case EDEADLK: return SCE_KERNEL_ERROR_EDEADLK; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case EAGAIN: + return SCE_KERNEL_ERROR_EAGAIN; + case EINVAL: + return SCE_KERNEL_ERROR_EINVAL; + case EDEADLK: + return SCE_KERNEL_ERROR_EDEADLK; + default: + return SCE_KERNEL_ERROR_EINVAL; } } int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { @@ -270,13 +328,18 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { } int result = pthread_mutex_unlock(&(*mutex)->pth_mutex); - LOG_INFO_IF(log_pthread_file, "scePthreadMutexUnlock name={} result={}\n", (*mutex)->name, result); + LOG_INFO_IF(log_pthread_file, "scePthreadMutexUnlock name={} result={}\n", (*mutex)->name, + result); switch (result) { - case 0: return SCE_OK; + case 0: + return SCE_OK; - case EINVAL: return SCE_KERNEL_ERROR_EINVAL; - case EPERM: return SCE_KERNEL_ERROR_EPERM; - default: return SCE_KERNEL_ERROR_EINVAL; + case EINVAL: + return SCE_KERNEL_ERROR_EINVAL; + case EPERM: + return SCE_KERNEL_ERROR_EPERM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } @@ -294,7 +357,8 @@ void* createCond(void* addr) { return addr; } -int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name) { +int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, + const char* name) { if (cond == nullptr) { return SCE_KERNEL_ERROR_EINVAL; } @@ -318,11 +382,16 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat } switch (result) { - case 0: return SCE_OK; - case EAGAIN: return SCE_KERNEL_ERROR_EAGAIN; - case EINVAL: return SCE_KERNEL_ERROR_EINVAL; - case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case EAGAIN: + return SCE_KERNEL_ERROR_EAGAIN; + case EINVAL: + return SCE_KERNEL_ERROR_EINVAL; + case ENOMEM: + return SCE_KERNEL_ERROR_ENOMEM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } @@ -332,9 +401,12 @@ int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) { int result = pthread_condattr_init(&(*attr)->cond_attr); switch (result) { - case 0: return SCE_OK; - case ENOMEM: return SCE_KERNEL_ERROR_ENOMEM; - default: return SCE_KERNEL_ERROR_EINVAL; + case 0: + return SCE_OK; + case ENOMEM: + return SCE_KERNEL_ERROR_ENOMEM; + default: + return SCE_KERNEL_ERROR_EINVAL; } } @@ -359,7 +431,9 @@ int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthre LOG_INFO_IF(log_pthread_file, "posix pthread_mutex_init redirect to scePthreadMutexInit\n"); int result = scePthreadMutexInit(mutex, attr, nullptr); if (result < 0) { - int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP ? result + -SCE_KERNEL_ERROR_UNKNOWN : POSIX_EOTHER; + int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP + ? result + -SCE_KERNEL_ERROR_UNKNOWN + : POSIX_EOTHER; return rt; } return result; @@ -369,7 +443,9 @@ int PS4_SYSV_ABI posix_pthread_mutex_lock(ScePthreadMutex* mutex) { LOG_INFO_IF(log_pthread_file, "posix pthread_mutex_lock redirect to scePthreadMutexLock\n"); int result = scePthreadMutexLock(mutex); if (result < 0) { - int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP ? result + -SCE_KERNEL_ERROR_UNKNOWN : POSIX_EOTHER; + int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP + ? result + -SCE_KERNEL_ERROR_UNKNOWN + : POSIX_EOTHER; return rt; } return result; @@ -379,17 +455,22 @@ int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex) { LOG_INFO_IF(log_pthread_file, "posix pthread_mutex_unlock redirect to scePthreadMutexUnlock\n"); int result = scePthreadMutexUnlock(mutex); if (result < 0) { - int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP ? result + -SCE_KERNEL_ERROR_UNKNOWN : POSIX_EOTHER; + int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP + ? result + -SCE_KERNEL_ERROR_UNKNOWN + : POSIX_EOTHER; return rt; } return result; } int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) { - LOG_INFO_IF(log_pthread_file, "posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast\n"); + LOG_INFO_IF(log_pthread_file, + "posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast\n"); int result = scePthreadCondBroadcast(cond); if (result != 0) { - int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP ? result + -SCE_KERNEL_ERROR_UNKNOWN : POSIX_EOTHER; + int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP + ? result + -SCE_KERNEL_ERROR_UNKNOWN + : POSIX_EOTHER; return rt; } return result; @@ -412,7 +493,7 @@ void pthreadSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("1FGvU0i9saQ", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexattrSetprotocol); LIB_FUNCTION("9UK1vLZQft4", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexLock); LIB_FUNCTION("tn3VlD0hG60", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexUnlock); - //cond calls + // cond calls LIB_FUNCTION("2Tb92quprl0", "libkernel", 1, "libkernel", 1, 1, scePthreadCondInit); LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit); LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast); @@ -428,4 +509,4 @@ void pthreadSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); } -} // namespace Core::Libraries::LibKernel \ No newline at end of file +} // namespace Core::Libraries::LibKernel \ No newline at end of file diff --git a/src/core/hle/libraries/libkernel/thread_management.h b/src/core/hle/libraries/libkernel/thread_management.h index dc8e9d79..5b4a53dc 100644 --- a/src/core/hle/libraries/libkernel/thread_management.h +++ b/src/core/hle/libraries/libkernel/thread_management.h @@ -71,13 +71,21 @@ struct PthreadCondAttrInternal { }; class PThreadCxt { - public: - ScePthreadMutexattr* getDefaultMutexattr() { return &m_default_mutexattr; } - void setDefaultMutexattr(ScePthreadMutexattr attr) { m_default_mutexattr = attr; } - ScePthreadCondattr* getDefaultCondattr() { return &m_default_condattr; } - void setDefaultCondattr(ScePthreadCondattr attr) { m_default_condattr = attr; } +public: + ScePthreadMutexattr* getDefaultMutexattr() { + return &m_default_mutexattr; + } + void setDefaultMutexattr(ScePthreadMutexattr attr) { + m_default_mutexattr = attr; + } + ScePthreadCondattr* getDefaultCondattr() { + return &m_default_condattr; + } + void setDefaultCondattr(ScePthreadCondattr attr) { + m_default_condattr = attr; + } - private: +private: ScePthreadMutexattr m_default_mutexattr = nullptr; ScePthreadCondattr m_default_condattr = nullptr; }; @@ -88,17 +96,21 @@ void pthreadInitSelfMainThread(); int PS4_SYSV_ABI scePthreadAttrInit(ScePthreadAttr* attr); int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate); int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched); -int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr, const SceKernelSchedParam* param); +int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr, + const SceKernelSchedParam* param); int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy); ScePthread PS4_SYSV_ABI scePthreadSelf(); -int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, const /*SceKernelCpumask*/ u64 mask); +int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, + const /*SceKernelCpumask*/ u64 mask); int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask); -int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr, pthreadEntryFunc start_routine, void* arg, const char* name); +int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr, + pthreadEntryFunc start_routine, void* arg, const char* name); /*** * Mutex calls */ -int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, const char* name); +int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, + const char* name); int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr); int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type); int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol); @@ -107,10 +119,11 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex); /**** * Cond calls */ -int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, const char* name); +int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr, + const char* name); int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr); int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond); - /**** +/**** * Posix calls */ int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr); @@ -119,4 +132,4 @@ int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex); int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond); void pthreadSymbolsRegister(Loader::SymbolsResolver* sym); -} // namespace Core::Libraries::LibKernel \ No newline at end of file +} // namespace Core::Libraries::LibKernel \ No newline at end of file diff --git a/src/core/hle/libraries/libkernel/time_management.cpp b/src/core/hle/libraries/libkernel/time_management.cpp index 00861a1b..646e6782 100644 --- a/src/core/hle/libraries/libkernel/time_management.cpp +++ b/src/core/hle/libraries/libkernel/time_management.cpp @@ -26,10 +26,11 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() { void timeSymbolsRegister(Loader::SymbolsResolver* sym) { clock = std::make_unique(); initial_ptc = clock->GetUptime(); - LIB_FUNCTION("4J2sUJmuHZQ", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTime); + LIB_FUNCTION("4J2sUJmuHZQ", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTime); LIB_FUNCTION("fgxnMeTNUtY", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTimeCounter); - LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTimeCounterFrequency); + LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1, + sceKernelGetProcessTimeCounterFrequency); LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc); } -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel diff --git a/src/core/hle/libraries/libpad/pad.cpp b/src/core/hle/libraries/libpad/pad.cpp index 670422fb..fe9aec14 100644 --- a/src/core/hle/libraries/libpad/pad.cpp +++ b/src/core/hle/libraries/libpad/pad.cpp @@ -1,22 +1,22 @@ +#include "Emulator/Host/controller.h" #include "common/log.h" #include "common/singleton.h" -#include "core/hle/libraries/libpad/pad.h" #include "core/hle/error_codes.h" +#include "core/hle/libraries/libpad/pad.h" #include "core/hle/libraries/libs.h" -#include "Emulator/Host/controller.h" namespace Core::Libraries::LibPad { -constexpr bool log_file_pad = true; // disable it to disable logging +constexpr bool log_file_pad = true; // disable it to disable logging int PS4_SYSV_ABI scePadInit() { return SCE_OK; } -int PS4_SYSV_ABI scePadOpen(Core::Libraries::LibUserService::SceUserServiceUserId userId, s32 type, s32 index, - const ScePadOpenParam* pParam) { +int PS4_SYSV_ABI scePadOpen(Core::Libraries::LibUserService::SceUserServiceUserId userId, s32 type, + s32 index, const ScePadOpenParam* pParam) { LOG_INFO_IF(log_file_pad, "scePadOpen userid = {} type = {} index = {}\n", userId, type, index); - return 1; // dummy + return 1; // dummy } int PS4_SYSV_ABI scePadReadState(int32_t handle, ScePadData* pData) { @@ -28,19 +28,19 @@ int PS4_SYSV_ABI scePadReadState(int32_t handle, ScePadData* pData) { controller->readState(&state, &isConnected, &connectedCount); pData->buttons = state.buttonsState; - pData->leftStick.x = 128; // dummy - pData->leftStick.y = 128; // dummy - pData->rightStick.x = 0; // dummy - pData->rightStick.y = 0; // dummy - pData->analogButtons.r2 = 0;//dummy - pData->analogButtons.l2 = 0;//dummy + pData->leftStick.x = 128; // dummy + pData->leftStick.y = 128; // dummy + pData->rightStick.x = 0; // dummy + pData->rightStick.y = 0; // dummy + pData->analogButtons.r2 = 0; // dummy + pData->analogButtons.l2 = 0; // dummy pData->orientation.x = 0; pData->orientation.y = 0; pData->orientation.z = 0; pData->orientation.w = 0; pData->timestamp = state.time; - pData->connected = true; // isConnected; //TODO fix me proper - pData->connectedCount = 1;//connectedCount; + pData->connected = true; // isConnected; //TODO fix me proper + pData->connectedCount = 1; // connectedCount; pData->deviceUniqueDataLen = 0; return SCE_OK; @@ -52,4 +52,4 @@ void padSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("YndgXqQVV7c", "libScePad", 1, "libScePad", 1, 1, scePadReadState); } -} // namespace Emulator::HLE::Libraries::LibPad +} // namespace Core::Libraries::LibPad diff --git a/src/core/hle/libraries/libpad/pad.h b/src/core/hle/libraries/libpad/pad.h index b1d9f51f..84e9fced 100644 --- a/src/core/hle/libraries/libpad/pad.h +++ b/src/core/hle/libraries/libpad/pad.h @@ -95,4 +95,4 @@ int PS4_SYSV_ABI scePadReadState(int32_t handle, ScePadData* pData); void padSymbolsRegister(Loader::SymbolsResolver* sym); -}; // namespace Core::Libraries::LibPad +}; // namespace Core::Libraries::LibPad diff --git a/src/core/hle/libraries/libs.cpp b/src/core/hle/libraries/libs.cpp index 815a7c54..14458183 100644 --- a/src/core/hle/libraries/libs.cpp +++ b/src/core/hle/libraries/libs.cpp @@ -1,11 +1,11 @@ -#include "core/hle/libraries/libs.h" #include "core/PS4/HLE/Graphics/video_out.h" -#include "core/hle/libraries/libkernel/libkernel.h" -#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" -#include "core/hle/libraries/libuserservice/libuserservice.h" -#include "core/hle/libraries/libpad/pad.h" -#include "core/hle/libraries/libsystemservice/system_service.h" #include "core/hle/libraries/libc/libc.h" +#include "core/hle/libraries/libkernel/libkernel.h" +#include "core/hle/libraries/libpad/pad.h" +#include "core/hle/libraries/libs.h" +#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" +#include "core/hle/libraries/libsystemservice/system_service.h" +#include "core/hle/libraries/libuserservice/libuserservice.h" namespace Core::Libraries { @@ -19,4 +19,4 @@ void InitHLELibs(Loader::SymbolsResolver* sym) { LibC::libcSymbolsRegister(sym); } -} // namespace Core::Libraries +} // namespace Core::Libraries diff --git a/src/core/hle/libraries/libs.h b/src/core/hle/libraries/libs.h index dc88423b..3d42736c 100644 --- a/src/core/hle/libraries/libs.h +++ b/src/core/hle/libraries/libs.h @@ -3,40 +3,38 @@ #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" -#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ - {\ - Loader::SymbolRes sr{}; \ - sr.name = nid; \ - sr.library = lib; \ - sr.library_version = libversion;\ - sr.module = mod;\ - sr.module_version_major = moduleVersionMajor;\ - sr.module_version_minor = moduleVersionMinor;\ - sr.type = STT_FUN;\ - auto func = reinterpret_cast(function);\ - sym->AddSymbol(sr, func);\ - } - -#define LIB_OBJ(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ - { \ - Loader::SymbolRes sr{}; \ - sr.name = nid; \ - sr.library = lib; \ - sr.library_version = libversion; \ - sr.module = mod; \ - sr.module_version_major = moduleVersionMajor; \ - sr.module_version_minor = moduleVersionMinor; \ - sr.type = STT_OBJECT; \ - auto func = reinterpret_cast(function); \ - sym->AddSymbol(sr, func); \ +#define LIB_FUNCTION(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ + { \ + Loader::SymbolRes sr{}; \ + sr.name = nid; \ + sr.library = lib; \ + sr.library_version = libversion; \ + sr.module = mod; \ + sr.module_version_major = moduleVersionMajor; \ + sr.module_version_minor = moduleVersionMinor; \ + sr.type = STT_FUN; \ + auto func = reinterpret_cast(function); \ + sym->AddSymbol(sr, func); \ } -#define PRINT_FUNCTION_NAME() \ - { \ - LOG_INFO_IF(true, "{}()\n", __func__); \ +#define LIB_OBJ(nid, lib, libversion, mod, moduleVersionMajor, moduleVersionMinor, function) \ + { \ + Loader::SymbolRes sr{}; \ + sr.name = nid; \ + sr.library = lib; \ + sr.library_version = libversion; \ + sr.module = mod; \ + sr.module_version_major = moduleVersionMajor; \ + sr.module_version_minor = moduleVersionMinor; \ + sr.type = STT_OBJECT; \ + auto func = reinterpret_cast(function); \ + sym->AddSymbol(sr, func); \ } -#define PRINT_DUMMY_FUNCTION_NAME() \ +#define PRINT_FUNCTION_NAME() \ + { LOG_INFO_IF(true, "{}()\n", __func__); } + +#define PRINT_DUMMY_FUNCTION_NAME() \ { LOG_WARN_IF(true, "dummy {}()\n", __func__); } namespace Core::Libraries { diff --git a/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp b/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp index 3205433f..4fb25552 100644 --- a/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp +++ b/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp @@ -1,7 +1,7 @@ #include "common/log.h" #include "core/PS4/GPU/gpu_memory.h" -#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" #include "core/hle/libraries/libs.h" +#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" #include "emulator.h" namespace Core::Libraries::LibSceGnmDriver { @@ -20,5 +20,5 @@ void LibSceGnmDriver_Register(Loader::SymbolsResolver* sym) { LIB_FUNCTION("yvZ73uQUqrk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitDone); LIB_FUNCTION("iBt3Oe00Kvc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmFlushGarlic); } - -}; + +}; // namespace Core::Libraries::LibSceGnmDriver diff --git a/src/core/hle/libraries/libsystemservice/system_service.cpp b/src/core/hle/libraries/libsystemservice/system_service.cpp index 314dae47..113415fd 100644 --- a/src/core/hle/libraries/libsystemservice/system_service.cpp +++ b/src/core/hle/libraries/libsystemservice/system_service.cpp @@ -24,8 +24,10 @@ s32 PS4_SYSV_ABI sceSystemServiceGetStatus(SceSystemServiceStatus* status) { } void systemServiceSymbolsRegister(Loader::SymbolsResolver* sym) { - LIB_FUNCTION("Vo5V8KAwCmk", "libSceSystemService", 1, "libSceSystemService", 1, 1, sceSystemServiceHideSplashScreen); - LIB_FUNCTION("rPo6tV8D9bM", "libSceSystemService", 1, "libSceSystemService", 1, 1, sceSystemServiceGetStatus); + LIB_FUNCTION("Vo5V8KAwCmk", "libSceSystemService", 1, "libSceSystemService", 1, 1, + sceSystemServiceHideSplashScreen); + LIB_FUNCTION("rPo6tV8D9bM", "libSceSystemService", 1, "libSceSystemService", 1, 1, + sceSystemServiceGetStatus); } -}; // namespace Core::Libraries::LibSystemService +}; // namespace Core::Libraries::LibSystemService diff --git a/src/core/hle/libraries/libsystemservice/system_service.h b/src/core/hle/libraries/libsystemservice/system_service.h index af2e358d..9138e5ff 100644 --- a/src/core/hle/libraries/libsystemservice/system_service.h +++ b/src/core/hle/libraries/libsystemservice/system_service.h @@ -23,4 +23,4 @@ s32 PS4_SYSV_ABI sceSystemServiceGetStatus(SceSystemServiceStatus* status); void systemServiceSymbolsRegister(Loader::SymbolsResolver* sym); -}; // namespace Core::Libraries::LibSystemService +}; // namespace Core::Libraries::LibSystemService diff --git a/src/core/hle/libraries/libuserservice/libuserservice.cpp b/src/core/hle/libraries/libuserservice/libuserservice.cpp index bcef432c..79ef3d28 100644 --- a/src/core/hle/libraries/libuserservice/libuserservice.cpp +++ b/src/core/hle/libraries/libuserservice/libuserservice.cpp @@ -1,7 +1,7 @@ #include "common/log.h" -#include "core/hle/libraries/libuserservice/libuserservice.h" #include "core/hle/error_codes.h" #include "core/hle/libraries/libs.h" +#include "core/hle/libraries/libuserservice/libuserservice.h" namespace Core::Libraries::LibUserService { @@ -21,8 +21,10 @@ s32 PS4_SYSV_ABI sceUserServiceGetLoginUserIdList(SceUserServiceLoginUserIdList* } void userServiceSymbolsRegister(Loader::SymbolsResolver* sym) { - LIB_FUNCTION("j3YMu1MVNNo", "libSceUserService", 1, "libSceUserService", 1, 1, sceUserServiceInitialize); - LIB_FUNCTION("fPhymKNvK-A", "libSceUserService", 1, "libSceUserService", 1, 1, sceUserServiceGetLoginUserIdList); + LIB_FUNCTION("j3YMu1MVNNo", "libSceUserService", 1, "libSceUserService", 1, 1, + sceUserServiceInitialize); + LIB_FUNCTION("fPhymKNvK-A", "libSceUserService", 1, "libSceUserService", 1, 1, + sceUserServiceGetLoginUserIdList); } } // namespace Core::Libraries::LibUserService diff --git a/src/core/hle/libraries/libuserservice/usr_mng_codes.h b/src/core/hle/libraries/libuserservice/usr_mng_codes.h index ffe58570..bf367ee5 100644 --- a/src/core/hle/libraries/libuserservice/usr_mng_codes.h +++ b/src/core/hle/libraries/libuserservice/usr_mng_codes.h @@ -1,12 +1,11 @@ #pragma once -//constants - -constexpr int SCE_USER_SERVICE_MAX_LOGIN_USERS = 4; //max users logged in at once -constexpr int SCE_USER_SERVICE_MAX_USER_NAME_LENGTH = 16;//Max length for user name - -constexpr int SCE_USER_SERVICE_USER_ID_INVALID = -1;//invalid user ID -constexpr int SCE_USER_SERVICE_USER_ID_SYSTEM = 255; //generic id for device -constexpr int SCE_USER_SERVICE_USER_ID_EVERYONE = 254; // generic id for user (mostly used in common dialogs) +// constants +constexpr int SCE_USER_SERVICE_MAX_LOGIN_USERS = 4; // max users logged in at once +constexpr int SCE_USER_SERVICE_MAX_USER_NAME_LENGTH = 16; // Max length for user name +constexpr int SCE_USER_SERVICE_USER_ID_INVALID = -1; // invalid user ID +constexpr int SCE_USER_SERVICE_USER_ID_SYSTEM = 255; // generic id for device +constexpr int SCE_USER_SERVICE_USER_ID_EVERYONE = + 254; // generic id for user (mostly used in common dialogs) diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 611d6b1b..40094a57 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include "common/log.h" #include "common/string_util.h" #include "core/aerolib/aerolib.h" @@ -14,21 +14,17 @@ constexpr bool debug_loader = true; static u64 g_load_addr = SYSTEM_RESERVED + CODE_BASE_OFFSET; -static u64 get_aligned_size(const elf_program_header& phdr) -{ - return (phdr.p_align != 0 ? (phdr.p_memsz + (phdr.p_align - 1)) & ~(phdr.p_align - 1) : phdr.p_memsz); +static u64 get_aligned_size(const elf_program_header& phdr) { + return (phdr.p_align != 0 ? (phdr.p_memsz + (phdr.p_align - 1)) & ~(phdr.p_align - 1) + : phdr.p_memsz); } -static u64 calculate_base_size(const elf_header& ehdr, std::span phdr) -{ +static u64 calculate_base_size(const elf_header& ehdr, std::span phdr) { u64 base_size = 0; - for (u16 i = 0; i < ehdr.e_phnum; i++) - { - if (phdr[i].p_memsz != 0 && (phdr[i].p_type == PT_LOAD || phdr[i].p_type == PT_SCE_RELRO)) - { + for (u16 i = 0; i < ehdr.e_phnum; i++) { + if (phdr[i].p_memsz != 0 && (phdr[i].p_type == PT_LOAD || phdr[i].p_type == PT_SCE_RELRO)) { u64 last_addr = phdr[i].p_vaddr + get_aligned_size(phdr[i]); - if (last_addr > base_size) - { + if (last_addr > base_size) { base_size = last_addr; } } @@ -36,23 +32,16 @@ static u64 calculate_base_size(const elf_header& ehdr, std::span(nVal >> 6u) & 0x3fu]; enc += pCodes[nVal & 0x3fu]; - } - else - { + } else { enc += pCodes[static_cast(nVal >> 12u) & 0x3fu]; enc += pCodes[static_cast(nVal >> 6u) & 0x3fu]; enc += pCodes[nVal & 0x3fu]; @@ -65,8 +54,7 @@ Linker::Linker() = default; Linker::~Linker() = default; -Module* Linker::LoadModule(const std::string& elf_name) -{ +Module* Linker::LoadModule(const std::string& elf_name) { std::scoped_lock lock{m_mutex}; auto& m = m_modules.emplace_back(); @@ -86,8 +74,7 @@ Module* Linker::LoadModule(const std::string& elf_name) return &m; } -Module* Linker::FindModule(/*u32 id*/) -{ +Module* Linker::FindModule(/*u32 id*/) { // TODO atm we only have 1 module so we don't need to iterate on vector if (m_modules.empty()) [[unlikely]] { return nullptr; @@ -95,7 +82,7 @@ Module* Linker::FindModule(/*u32 id*/) return &m_modules[0]; } -struct TLSPattern{ +struct TLSPattern { uint8_t pattern[5]; uint8_t pattern_size; uint8_t imm_size; @@ -103,24 +90,30 @@ struct TLSPattern{ }; constexpr TLSPattern tls_patterns[] = { - {{0x64, 0x48, 0xA1}, 3, 8, 0}, // 64 48 A1 | 00 00 00 00 00 00 00 00 # mov rax, qword ptr fs:[64b imm] + {{0x64, 0x48, 0xA1}, + 3, + 8, + 0}, // 64 48 A1 | 00 00 00 00 00 00 00 00 # mov rax, qword ptr fs:[64b imm] - {{0x64, 0x48, 0x8B, 0x4, 0x25}, 5, 4, 0}, // 64 48 8B 04 25 | 00 00 00 00 # mov rax,qword ptr fs:[0] - {{0x64, 0x48, 0x8B, 0xC, 0x25}, 5, 4, 1}, // rcx - {{0x64, 0x48, 0x8B, 0x14, 0x25}, 5, 4, 2}, // rdx - {{0x64, 0x48, 0x8B, 0x1C, 0x25}, 5, 4, 3}, // rbx - {{0x64, 0x48, 0x8B, 0x24, 0x25}, 5, 4, 4}, // rsp - {{0x64, 0x48, 0x8B, 0x2C, 0x25}, 5, 4, 5}, // rbp - {{0x64, 0x48, 0x8B, 0x34, 0x25}, 5, 4, 6}, // rsi - {{0x64, 0x48, 0x8B, 0x3C, 0x25}, 5, 4, 7}, // rdi - {{0x64, 0x4C, 0x8B, 0x4, 0x25}, 5, 4, 8}, // r8 - {{0x64, 0x4C, 0x8B, 0xC, 0x25}, 5, 4, 9}, // r9 - {{0x64, 0x4C, 0x8B, 0x14, 0x25}, 5, 4, 10},// r10 - {{0x64, 0x4C, 0x8B, 0x1C, 0x25}, 5, 4, 11},// r11 - {{0x64, 0x4C, 0x8B, 0x24, 0x25}, 5, 4, 12},// r12 - {{0x64, 0x4C, 0x8B, 0x2C, 0x25}, 5, 4, 13},// r13 - {{0x64, 0x4C, 0x8B, 0x34, 0x25}, 5, 4, 14},// r14 - {{0x64, 0x4C, 0x8B, 0x3C, 0x25}, 5, 4, 15},// r15 + {{0x64, 0x48, 0x8B, 0x4, 0x25}, + 5, + 4, + 0}, // 64 48 8B 04 25 | 00 00 00 00 # mov rax,qword ptr fs:[0] + {{0x64, 0x48, 0x8B, 0xC, 0x25}, 5, 4, 1}, // rcx + {{0x64, 0x48, 0x8B, 0x14, 0x25}, 5, 4, 2}, // rdx + {{0x64, 0x48, 0x8B, 0x1C, 0x25}, 5, 4, 3}, // rbx + {{0x64, 0x48, 0x8B, 0x24, 0x25}, 5, 4, 4}, // rsp + {{0x64, 0x48, 0x8B, 0x2C, 0x25}, 5, 4, 5}, // rbp + {{0x64, 0x48, 0x8B, 0x34, 0x25}, 5, 4, 6}, // rsi + {{0x64, 0x48, 0x8B, 0x3C, 0x25}, 5, 4, 7}, // rdi + {{0x64, 0x4C, 0x8B, 0x4, 0x25}, 5, 4, 8}, // r8 + {{0x64, 0x4C, 0x8B, 0xC, 0x25}, 5, 4, 9}, // r9 + {{0x64, 0x4C, 0x8B, 0x14, 0x25}, 5, 4, 10}, // r10 + {{0x64, 0x4C, 0x8B, 0x1C, 0x25}, 5, 4, 11}, // r11 + {{0x64, 0x4C, 0x8B, 0x24, 0x25}, 5, 4, 12}, // r12 + {{0x64, 0x4C, 0x8B, 0x2C, 0x25}, 5, 4, 13}, // r13 + {{0x64, 0x4C, 0x8B, 0x34, 0x25}, 5, 4, 14}, // r14 + {{0x64, 0x4C, 0x8B, 0x3C, 0x25}, 5, 4, 15}, // r15 }; void PatchTLS(u64 segment_addr, u64 segment_size) { @@ -133,9 +126,13 @@ void PatchTLS(u64 segment_addr, u64 segment_size) { if (remaining_size >= total_size) { if (memcmp(code, tls_pattern.pattern, tls_pattern.pattern_size) == 0) { if (tls_pattern.imm_size == 4) - printf("PATTERN32 FOUND @ %p, reg: %d offset: %X\n", code, tls_pattern.target_reg, *(uint32_t*)(code + tls_pattern.pattern_size)); + printf("PATTERN32 FOUND @ %p, reg: %d offset: %X\n", code, + tls_pattern.target_reg, + *(uint32_t*)(code + tls_pattern.pattern_size)); else - printf("PATTERN64 FOUND @ %p, reg: %d offset: %lX\n", code, tls_pattern.target_reg, *(uint64_t*)(code + tls_pattern.pattern_size)); + printf("PATTERN64 FOUND @ %p, reg: %d offset: %lX\n", code, + tls_pattern.target_reg, + *(uint64_t*)(code + tls_pattern.pattern_size)); code[0] = 0xcd; code[1] = 0x80 + tls_pattern.target_reg; code[2] = tls_pattern.pattern_size | (tls_pattern.imm_size << 4); @@ -151,389 +148,377 @@ void PatchTLS(u64 segment_addr, u64 segment_size) { } void Linker::LoadModuleToMemory(Module* m) { - //get elf header, program header + // get elf header, program header const auto elf_header = m->elf.GetElfHeader(); const auto elf_pheader = m->elf.GetProgramHeader(); - u64 base_size = calculate_base_size(elf_header, elf_pheader); - m->aligned_base_size = (base_size & ~(static_cast(0x1000) - 1)) + 0x1000;//align base size to 0x1000 block size (TODO is that the default block size or it can be changed? + u64 base_size = calculate_base_size(elf_header, elf_pheader); + m->aligned_base_size = (base_size & ~(static_cast(0x1000) - 1)) + + 0x1000; // align base size to 0x1000 block size (TODO is that the default + // block size or it can be changed? - m->base_virtual_addr = VirtualMemory::memory_alloc(g_load_addr, m->aligned_base_size, VirtualMemory::MemoryMode::ExecuteReadWrite); + m->base_virtual_addr = VirtualMemory::memory_alloc(g_load_addr, m->aligned_base_size, + VirtualMemory::MemoryMode::ExecuteReadWrite); - LOG_INFO_IF(debug_loader, "====Load Module to Memory ========\n"); - LOG_INFO_IF(debug_loader, "base_virtual_addr ......: {:#018x}\n", m->base_virtual_addr); - LOG_INFO_IF(debug_loader, "base_size ..............: {:#018x}\n", base_size); - LOG_INFO_IF(debug_loader, "aligned_base_size ......: {:#018x}\n", m->aligned_base_size); + LOG_INFO_IF(debug_loader, "====Load Module to Memory ========\n"); + LOG_INFO_IF(debug_loader, "base_virtual_addr ......: {:#018x}\n", m->base_virtual_addr); + LOG_INFO_IF(debug_loader, "base_size ..............: {:#018x}\n", base_size); + LOG_INFO_IF(debug_loader, "aligned_base_size ......: {:#018x}\n", m->aligned_base_size); - for (u16 i = 0; i < elf_header.e_phnum; i++) - { - switch (elf_pheader[i].p_type) - { - case PT_LOAD: - case PT_SCE_RELRO: - if (elf_pheader[i].p_memsz != 0) - { - u64 segment_addr = elf_pheader[i].p_vaddr + m->base_virtual_addr; - u64 segment_file_size = elf_pheader[i].p_filesz; - u64 segment_memory_size = get_aligned_size(elf_pheader[i]); - auto segment_mode = m->elf.ElfPheaderFlagsStr(elf_pheader[i].p_flags); - LOG_INFO_IF(debug_loader, "program header = [{}] type = {}\n",i,m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - LOG_INFO_IF(debug_loader, "segment_addr ..........: {:#018x}\n", segment_addr); - LOG_INFO_IF(debug_loader, "segment_file_size .....: {}\n", segment_file_size); - LOG_INFO_IF(debug_loader, "segment_memory_size ...: {}\n", segment_memory_size); - LOG_INFO_IF(debug_loader, "segment_mode ..........: {}\n", segment_mode); - - m->elf.LoadSegment(segment_addr, elf_pheader[i].p_offset, segment_file_size); + for (u16 i = 0; i < elf_header.e_phnum; i++) { + switch (elf_pheader[i].p_type) { + case PT_LOAD: + case PT_SCE_RELRO: + if (elf_pheader[i].p_memsz != 0) { + u64 segment_addr = elf_pheader[i].p_vaddr + m->base_virtual_addr; + u64 segment_file_size = elf_pheader[i].p_filesz; + u64 segment_memory_size = get_aligned_size(elf_pheader[i]); + auto segment_mode = m->elf.ElfPheaderFlagsStr(elf_pheader[i].p_flags); + LOG_INFO_IF(debug_loader, "program header = [{}] type = {}\n", i, + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + LOG_INFO_IF(debug_loader, "segment_addr ..........: {:#018x}\n", segment_addr); + LOG_INFO_IF(debug_loader, "segment_file_size .....: {}\n", segment_file_size); + LOG_INFO_IF(debug_loader, "segment_memory_size ...: {}\n", segment_memory_size); + LOG_INFO_IF(debug_loader, "segment_mode ..........: {}\n", segment_mode); - if (elf_pheader[i].p_flags & PF_EXEC) { - PatchTLS(segment_addr, segment_file_size); - } - } - else - { - LOG_ERROR_IF(debug_loader, "p_memsz==0 in type {}\n", m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - } - break; - case PT_DYNAMIC: - if (elf_pheader[i].p_filesz != 0) - { - m->m_dynamic.resize(elf_pheader[i].p_filesz); - m->elf.LoadSegment(reinterpret_cast(m->m_dynamic.data()), elf_pheader[i].p_offset, elf_pheader[i].p_filesz); - } - else - { - LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - } - break; - case PT_SCE_DYNLIBDATA: - if (elf_pheader[i].p_filesz != 0) - { - m->m_dynamic_data.resize(elf_pheader[i].p_filesz); - m->elf.LoadSegment(reinterpret_cast(m->m_dynamic_data.data()), elf_pheader[i].p_offset, elf_pheader[i].p_filesz); - } - else - { - LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - } - break; - case PT_TLS: - m->tls.image_virtual_addr = elf_pheader[i].p_vaddr + m->base_virtual_addr; - m->tls.image_size = get_aligned_size(elf_pheader[i]); - LOG_INFO_IF(debug_loader, "tls virtual address ={:#x}\n", m->tls.image_virtual_addr); - LOG_INFO_IF(debug_loader, "tls image size ={}\n", m->tls.image_size); - break; - default: - LOG_ERROR_IF(debug_loader, "Unimplemented type {}\n", m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - } - } - LOG_INFO_IF(debug_loader, "program entry addr ..........: {:#018x}\n", m->elf.GetElfEntry() + m->base_virtual_addr); + m->elf.LoadSegment(segment_addr, elf_pheader[i].p_offset, segment_file_size); + + if (elf_pheader[i].p_flags & PF_EXEC) { + PatchTLS(segment_addr, segment_file_size); + } + } else { + LOG_ERROR_IF(debug_loader, "p_memsz==0 in type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + } + break; + case PT_DYNAMIC: + if (elf_pheader[i].p_filesz != 0) { + m->m_dynamic.resize(elf_pheader[i].p_filesz); + m->elf.LoadSegment(reinterpret_cast(m->m_dynamic.data()), + elf_pheader[i].p_offset, elf_pheader[i].p_filesz); + } else { + LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + } + break; + case PT_SCE_DYNLIBDATA: + if (elf_pheader[i].p_filesz != 0) { + m->m_dynamic_data.resize(elf_pheader[i].p_filesz); + m->elf.LoadSegment(reinterpret_cast(m->m_dynamic_data.data()), + elf_pheader[i].p_offset, elf_pheader[i].p_filesz); + } else { + LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + } + break; + case PT_TLS: + m->tls.image_virtual_addr = elf_pheader[i].p_vaddr + m->base_virtual_addr; + m->tls.image_size = get_aligned_size(elf_pheader[i]); + LOG_INFO_IF(debug_loader, "tls virtual address ={:#x}\n", m->tls.image_virtual_addr); + LOG_INFO_IF(debug_loader, "tls image size ={}\n", m->tls.image_size); + break; + default: + LOG_ERROR_IF(debug_loader, "Unimplemented type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + } + } + LOG_INFO_IF(debug_loader, "program entry addr ..........: {:#018x}\n", + m->elf.GetElfEntry() + m->base_virtual_addr); } -void Linker::LoadDynamicInfo(Module* m) -{ - for (const auto* dyn = reinterpret_cast(m->m_dynamic.data()); dyn->d_tag != DT_NULL; dyn++) - { - switch (dyn->d_tag) - { - case DT_SCE_HASH: //Offset of the hash table. - m->dynamic_info.hash_table = reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); - break; - case DT_SCE_HASHSZ: //Size of the hash table +void Linker::LoadDynamicInfo(Module* m) { + for (const auto* dyn = reinterpret_cast(m->m_dynamic.data()); + dyn->d_tag != DT_NULL; dyn++) { + switch (dyn->d_tag) { + case DT_SCE_HASH: // Offset of the hash table. + m->dynamic_info.hash_table = + reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); + break; + case DT_SCE_HASHSZ: // Size of the hash table m->dynamic_info.hash_table_size = dyn->d_un.d_val; - break; - case DT_SCE_STRTAB://Offset of the string table. - m->dynamic_info.str_table = reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); - break; - case DT_SCE_STRSZ: //Size of the string table. + break; + case DT_SCE_STRTAB: // Offset of the string table. + m->dynamic_info.str_table = + reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); + break; + case DT_SCE_STRSZ: // Size of the string table. m->dynamic_info.str_table_size = dyn->d_un.d_val; - break; - case DT_SCE_SYMTAB://Offset of the symbol table. - m->dynamic_info.symbol_table = reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); - break; - case DT_SCE_SYMTABSZ://Size of the symbol table. + break; + case DT_SCE_SYMTAB: // Offset of the symbol table. + m->dynamic_info.symbol_table = + reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); + break; + case DT_SCE_SYMTABSZ: // Size of the symbol table. m->dynamic_info.symbol_table_total_size = dyn->d_un.d_val; - break; - case DT_INIT: + break; + case DT_INIT: m->dynamic_info.init_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_FINI: + break; + case DT_FINI: m->dynamic_info.fini_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_SCE_PLTGOT: //Offset of the global offset table. + break; + case DT_SCE_PLTGOT: // Offset of the global offset table. m->dynamic_info.pltgot_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_SCE_JMPREL: //Offset of the table containing jump slots. - m->dynamic_info.jmp_relocation_table = reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); - break; - case DT_SCE_PLTRELSZ: //Size of the global offset table. + break; + case DT_SCE_JMPREL: // Offset of the table containing jump slots. + m->dynamic_info.jmp_relocation_table = + reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); + break; + case DT_SCE_PLTRELSZ: // Size of the global offset table. m->dynamic_info.jmp_relocation_table_size = dyn->d_un.d_val; - break; - case DT_SCE_PLTREL: //The type of relocations in the relocation table. Should be DT_RELA + break; + case DT_SCE_PLTREL: // The type of relocations in the relocation table. Should be DT_RELA m->dynamic_info.jmp_relocation_type = dyn->d_un.d_val; - if (m->dynamic_info.jmp_relocation_type != DT_RELA) - { - LOG_WARN_IF(debug_loader, "DT_SCE_PLTREL is NOT DT_RELA should check!"); - } - break; - case DT_SCE_RELA: //Offset of the relocation table. - m->dynamic_info.relocation_table = reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); - break; - case DT_SCE_RELASZ: //Size of the relocation table. + if (m->dynamic_info.jmp_relocation_type != DT_RELA) { + LOG_WARN_IF(debug_loader, "DT_SCE_PLTREL is NOT DT_RELA should check!"); + } + break; + case DT_SCE_RELA: // Offset of the relocation table. + m->dynamic_info.relocation_table = + reinterpret_cast(m->m_dynamic_data.data() + dyn->d_un.d_ptr); + break; + case DT_SCE_RELASZ: // Size of the relocation table. m->dynamic_info.relocation_table_size = dyn->d_un.d_val; - break; - case DT_SCE_RELAENT : //The size of relocation table entries. + break; + case DT_SCE_RELAENT: // The size of relocation table entries. m->dynamic_info.relocation_table_entries_size = dyn->d_un.d_val; - if (m->dynamic_info.relocation_table_entries_size != 0x18) //this value should always be 0x18 - { - LOG_WARN_IF(debug_loader, "DT_SCE_RELAENT is NOT 0x18 should check!"); - } - break; - case DT_INIT_ARRAY:// Address of the array of pointers to initialization functions + if (m->dynamic_info.relocation_table_entries_size != + 0x18) // this value should always be 0x18 + { + LOG_WARN_IF(debug_loader, "DT_SCE_RELAENT is NOT 0x18 should check!"); + } + break; + case DT_INIT_ARRAY: // Address of the array of pointers to initialization functions m->dynamic_info.init_array_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_FINI_ARRAY: // Address of the array of pointers to termination functions + break; + case DT_FINI_ARRAY: // Address of the array of pointers to termination functions m->dynamic_info.fini_array_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_INIT_ARRAYSZ://Size in bytes of the array of initialization functions + break; + case DT_INIT_ARRAYSZ: // Size in bytes of the array of initialization functions m->dynamic_info.init_array_size = dyn->d_un.d_val; - break; - case DT_FINI_ARRAYSZ://Size in bytes of the array of terminationfunctions + break; + case DT_FINI_ARRAYSZ: // Size in bytes of the array of terminationfunctions m->dynamic_info.fini_array_size = dyn->d_un.d_val; - break; - case DT_PREINIT_ARRAY://Address of the array of pointers to pre - initialization functions + break; + case DT_PREINIT_ARRAY: // Address of the array of pointers to pre - initialization functions m->dynamic_info.preinit_array_virtual_addr = dyn->d_un.d_ptr; - break; - case DT_PREINIT_ARRAYSZ://Size in bytes of the array of pre - initialization functions + break; + case DT_PREINIT_ARRAYSZ: // Size in bytes of the array of pre - initialization functions m->dynamic_info.preinit_array_size = dyn->d_un.d_val; - break; - case DT_SCE_SYMENT: //The size of symbol table entries + break; + case DT_SCE_SYMENT: // The size of symbol table entries m->dynamic_info.symbol_table_entries_size = dyn->d_un.d_val; - if (m->dynamic_info.symbol_table_entries_size != 0x18) //this value should always be 0x18 - { - LOG_WARN_IF(debug_loader, "DT_SCE_SYMENT is NOT 0x18 should check!"); - } - break; - case DT_DEBUG: + if (m->dynamic_info.symbol_table_entries_size != + 0x18) // this value should always be 0x18 + { + LOG_WARN_IF(debug_loader, "DT_SCE_SYMENT is NOT 0x18 should check!"); + } + break; + case DT_DEBUG: m->dynamic_info.debug = dyn->d_un.d_val; - break; - case DT_TEXTREL: + break; + case DT_TEXTREL: m->dynamic_info.textrel = dyn->d_un.d_val; - break; - case DT_FLAGS: + break; + case DT_FLAGS: m->dynamic_info.flags = dyn->d_un.d_val; - if (m->dynamic_info.flags != 0x04) //this value should always be DF_TEXTREL (0x04) - { - LOG_WARN_IF(debug_loader, "DT_FLAGS is NOT 0x04 should check!"); - } - break; - case DT_NEEDED://Offset of the library string in the string table to be linked in. - if (m->dynamic_info.str_table != nullptr)//in theory this should already be filled from about just make a test case - { + if (m->dynamic_info.flags != 0x04) // this value should always be DF_TEXTREL (0x04) + { + LOG_WARN_IF(debug_loader, "DT_FLAGS is NOT 0x04 should check!"); + } + break; + case DT_NEEDED: // Offset of the library string in the string table to be linked in. + if (m->dynamic_info.str_table != + nullptr) // in theory this should already be filled from about just make a test case + { m->dynamic_info.needed.push_back(m->dynamic_info.str_table + dyn->d_un.d_val); - } - else - { - LOG_ERROR_IF(debug_loader, "DT_NEEDED str table is not loaded should check!"); - } - break; - case DT_SCE_NEEDED_MODULE: - { - ModuleInfo info{}; - info.value = dyn->d_un.d_val; - info.name = m->dynamic_info.str_table + info.name_offset; - info.enc_id = encodeId(info.id); - m->dynamic_info.import_modules.push_back(info); - } - break; - case DT_SCE_IMPORT_LIB: - { - LibraryInfo info{}; - info.value = dyn->d_un.d_val; - info.name = m->dynamic_info.str_table + info.name_offset; - info.enc_id = encodeId(info.id); - m->dynamic_info.import_libs.push_back(info); - } - break; - case DT_SCE_FINGERPRINT: - //The fingerprint is a 24 byte (0x18) size buffer that contains a unique identifier for the given app. - //How exactly this is generated isn't known, however it is not necessary to have a valid fingerprint. - //While an invalid fingerprint will cause a warning to be printed to the kernel log, the ELF will still load and run. - LOG_INFO_IF(debug_loader, "unsupported DT_SCE_FINGERPRINT value = ..........: {:#018x}\n", dyn->d_un.d_val); - break; - case DT_SCE_IMPORT_LIB_ATTR: - //The upper 32-bits should contain the module index multiplied by 0x10000. The lower 32-bits should be a constant 0x9. - LOG_INFO_IF(debug_loader, "unsupported DT_SCE_IMPORT_LIB_ATTR value = ......: {:#018x}\n", dyn->d_un.d_val); - break; - case DT_SCE_ORIGINAL_FILENAME: + } else { + LOG_ERROR_IF(debug_loader, "DT_NEEDED str table is not loaded should check!"); + } + break; + case DT_SCE_NEEDED_MODULE: { + ModuleInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info.str_table + info.name_offset; + info.enc_id = encodeId(info.id); + m->dynamic_info.import_modules.push_back(info); + } break; + case DT_SCE_IMPORT_LIB: { + LibraryInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info.str_table + info.name_offset; + info.enc_id = encodeId(info.id); + m->dynamic_info.import_libs.push_back(info); + } break; + case DT_SCE_FINGERPRINT: + // The fingerprint is a 24 byte (0x18) size buffer that contains a unique identifier for + // the given app. How exactly this is generated isn't known, however it is not necessary + // to have a valid fingerprint. While an invalid fingerprint will cause a warning to be + // printed to the kernel log, the ELF will still load and run. + LOG_INFO_IF(debug_loader, + "unsupported DT_SCE_FINGERPRINT value = ..........: {:#018x}\n", + dyn->d_un.d_val); + break; + case DT_SCE_IMPORT_LIB_ATTR: + // The upper 32-bits should contain the module index multiplied by 0x10000. The lower + // 32-bits should be a constant 0x9. + LOG_INFO_IF(debug_loader, + "unsupported DT_SCE_IMPORT_LIB_ATTR value = ......: {:#018x}\n", + dyn->d_un.d_val); + break; + case DT_SCE_ORIGINAL_FILENAME: m->dynamic_info.filename = m->dynamic_info.str_table + dyn->d_un.d_val; - break; - case DT_SCE_MODULE_INFO://probably only useable in shared modules - { - ModuleInfo info{}; - info.value = dyn->d_un.d_val; - info.name = m->dynamic_info.str_table + info.name_offset; - info.enc_id = encodeId(info.id); - m->dynamic_info.export_modules.push_back(info); - } - break; - case DT_SCE_MODULE_ATTR: - //TODO? - LOG_INFO_IF(debug_loader, "unsupported DT_SCE_MODULE_ATTR value = ..........: {:#018x}\n", dyn->d_un.d_val); - break; - case DT_SCE_EXPORT_LIB: - { - LibraryInfo info{}; - info.value = dyn->d_un.d_val; - info.name = m->dynamic_info.str_table + info.name_offset; - info.enc_id = encodeId(info.id); - m->dynamic_info.export_libs.push_back(info); - } - break; - default: - LOG_INFO_IF(debug_loader, "unsupported dynamic tag ..........: {:#018x}\n", dyn->d_tag); - } - - } + break; + case DT_SCE_MODULE_INFO: // probably only useable in shared modules + { + ModuleInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info.str_table + info.name_offset; + info.enc_id = encodeId(info.id); + m->dynamic_info.export_modules.push_back(info); + } break; + case DT_SCE_MODULE_ATTR: + // TODO? + LOG_INFO_IF(debug_loader, + "unsupported DT_SCE_MODULE_ATTR value = ..........: {:#018x}\n", + dyn->d_un.d_val); + break; + case DT_SCE_EXPORT_LIB: { + LibraryInfo info{}; + info.value = dyn->d_un.d_val; + info.name = m->dynamic_info.str_table + info.name_offset; + info.enc_id = encodeId(info.id); + m->dynamic_info.export_libs.push_back(info); + } break; + default: + LOG_INFO_IF(debug_loader, "unsupported dynamic tag ..........: {:#018x}\n", dyn->d_tag); + } + } } -const ModuleInfo* Linker::FindModule(const Module& m, const std::string& id) -{ +const ModuleInfo* Linker::FindModule(const Module& m, const std::string& id) { const auto& import_modules = m.dynamic_info.import_modules; - int index = 0; - for (const auto& mod : import_modules) - { - if (mod.enc_id.compare(id) == 0) - { - return &import_modules.at(index); - } - index++; - } + int index = 0; + for (const auto& mod : import_modules) { + if (mod.enc_id.compare(id) == 0) { + return &import_modules.at(index); + } + index++; + } const auto& export_modules = m.dynamic_info.export_modules; - index = 0; - for (const auto& mod : export_modules) - { - if (mod.enc_id.compare(id) == 0) - { - return &export_modules.at(index); - } - index++; - } - return nullptr; + index = 0; + for (const auto& mod : export_modules) { + if (mod.enc_id.compare(id) == 0) { + return &export_modules.at(index); + } + index++; + } + return nullptr; } -const LibraryInfo* Linker::FindLibrary(const Module& m, const std::string& id) -{ +const LibraryInfo* Linker::FindLibrary(const Module& m, const std::string& id) { const auto& import_libs = m.dynamic_info.import_libs; - int index = 0; - for (const auto& lib : import_libs) - { - if (lib.enc_id.compare(id) == 0) - { - return &import_libs.at(index); - } - index++; - } + int index = 0; + for (const auto& lib : import_libs) { + if (lib.enc_id.compare(id) == 0) { + return &import_libs.at(index); + } + index++; + } const auto& export_libs = m.dynamic_info.export_libs; - index = 0; - for (const auto& lib : export_libs) - { - if (lib.enc_id.compare(id) == 0) - { - return &export_libs.at(index); - } - index++; - } - return nullptr; + index = 0; + for (const auto& lib : export_libs) { + if (lib.enc_id.compare(id) == 0) { + return &export_libs.at(index); + } + index++; + } + return nullptr; } -void Linker::LoadSymbols(Module* m) -{ - if (m->dynamic_info.symbol_table == nullptr || m->dynamic_info.str_table == nullptr || m->dynamic_info.symbol_table_total_size==0) - { - LOG_INFO_IF(debug_loader, "Symbol table not found!\n"); - return; - } +void Linker::LoadSymbols(Module* m) { + if (m->dynamic_info.symbol_table == nullptr || m->dynamic_info.str_table == nullptr || + m->dynamic_info.symbol_table_total_size == 0) { + LOG_INFO_IF(debug_loader, "Symbol table not found!\n"); + return; + } for (auto* sym = m->dynamic_info.symbol_table; - reinterpret_cast(sym) < reinterpret_cast(m->dynamic_info.symbol_table) + m->dynamic_info.symbol_table_total_size; - sym++) - { + reinterpret_cast(sym) < + reinterpret_cast(m->dynamic_info.symbol_table) + + m->dynamic_info.symbol_table_total_size; + sym++) { std::string id = std::string(m->dynamic_info.str_table + sym->st_name); const auto ids = Common::SplitString(id, '#'); - if (ids.size() == 3)//symbols are 3 parts name , library , module - { - const auto* library = FindLibrary(*m, ids.at(1)); - const auto* module = FindModule(*m, ids.at(2)); - auto bind = sym->GetBind(); - auto type = sym->GetType(); - auto visibility = sym->GetVisibility(); - if (library != nullptr || module != nullptr) - { - switch (bind) - { - case STB_GLOBAL: - case STB_WEAK: - break; - default: - LOG_INFO_IF(debug_loader, "Unsupported bind {} for name symbol {} \n", bind,ids.at(0)); - continue; - } - switch (type) - { - case STT_OBJECT: - case STT_FUN: - break; - default: - LOG_INFO_IF(debug_loader, "Unsupported type {} for name symbol {} \n", type, ids.at(0)); - continue; - } - switch (visibility) - { - case STV_DEFAULT: - break; - default: - LOG_INFO_IF(debug_loader, "Unsupported visibility {} for name symbol {} \n", visibility, ids.at(0)); - continue; - } - //if st_value!=0 then it's export symbol - bool is_sym_export = sym->st_value != 0; - std::string nidName = ""; + if (ids.size() == 3) // symbols are 3 parts name , library , module + { + const auto* library = FindLibrary(*m, ids.at(1)); + const auto* module = FindModule(*m, ids.at(2)); + auto bind = sym->GetBind(); + auto type = sym->GetType(); + auto visibility = sym->GetVisibility(); + if (library != nullptr || module != nullptr) { + switch (bind) { + case STB_GLOBAL: + case STB_WEAK: + break; + default: + LOG_INFO_IF(debug_loader, "Unsupported bind {} for name symbol {} \n", bind, + ids.at(0)); + continue; + } + switch (type) { + case STT_OBJECT: + case STT_FUN: + break; + default: + LOG_INFO_IF(debug_loader, "Unsupported type {} for name symbol {} \n", type, + ids.at(0)); + continue; + } + switch (visibility) { + case STV_DEFAULT: + break; + default: + LOG_INFO_IF(debug_loader, "Unsupported visibility {} for name symbol {} \n", + visibility, ids.at(0)); + continue; + } + // if st_value!=0 then it's export symbol + bool is_sym_export = sym->st_value != 0; + std::string nidName = ""; auto aeronid = AeroLib::FindByNid(ids.at(0).c_str()); - if (aeronid != nullptr) - { + if (aeronid != nullptr) { nidName = aeronid->name; - } - else - { - nidName = "UNK"; - } + } else { + nidName = "UNK"; + } Loader::SymbolRes sym_r{}; - sym_r.name = ids.at(0); - sym_r.nidName = nidName; - sym_r.library = library->name; - sym_r.library_version = library->version; - sym_r.module = module->name; - sym_r.module_version_major = module->version_major; - sym_r.module_version_minor = module->version_minor; - sym_r.type = type; + sym_r.name = ids.at(0); + sym_r.nidName = nidName; + sym_r.library = library->name; + sym_r.library_version = library->version; + sym_r.module = module->name; + sym_r.module_version_major = module->version_major; + sym_r.module_version_minor = module->version_minor; + sym_r.type = type; - if (is_sym_export) - { + if (is_sym_export) { m->export_sym.AddSymbol(sym_r, sym->st_value + m->base_virtual_addr); - } - else - { - m->import_sym.AddSymbol(sym_r,0); - } - + } else { + m->import_sym.AddSymbol(sym_r, 0); + } - LOG_INFO_IF(debug_loader, "name {} function {} library {} module {} bind {} type {} visibility {}\n", ids.at(0),nidName,library->name, module->name, bind, type, visibility); - } - } - } + LOG_INFO_IF( + debug_loader, + "name {} function {} library {} module {} bind {} type {} visibility {}\n", + ids.at(0), nidName, library->name, module->name, bind, type, visibility); + } + } + } } static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) { auto type = rel->GetType(); @@ -550,86 +535,100 @@ static void relocate(u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) { std::string rel_name; switch (type) { - case R_X86_64_RELATIVE: - if (symbol != 0) // should be always zero - { - //LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, symbol);//found it openorbis but i am not sure it worth logging - } - rel_value = rel_base_virtual_addr + addend; - rel_isResolved = true; - break; - case R_X86_64_64: - case R_X86_64_JUMP_SLOT: // similar but addend is not take into account + case R_X86_64_RELATIVE: + if (symbol != 0) // should be always zero { - auto sym = symbolsTlb[symbol]; - auto sym_bind = sym.GetBind(); - auto sym_type = sym.GetType(); - auto sym_visibility = sym.GetVisibility(); - u64 symbol_vitrual_addr = 0; - Loader::SymbolRecord symrec{}; - switch (sym_type) { - case STT_FUN: rel_sym_type = 2; break; - case STT_OBJECT: rel_sym_type = 1; break; - default: LOG_INFO_IF(debug_loader, "unknown symbol type {}\n", sym_type); - } - if (sym_visibility != 0) // should be zero log if else - { - LOG_INFO_IF(debug_loader, "symbol visilibity !=0\n"); - } - switch (sym_bind) { - case STB_GLOBAL: - rel_name = namesTlb + sym.st_name; - m->linker->Resolve(rel_name, rel_sym_type, m, &symrec); - symbol_vitrual_addr = symrec.virtual_address; - rel_isResolved = (symbol_vitrual_addr != 0); + // LOG_INFO_IF(debug_loader, "R_X86_64_RELATIVE symbol not zero = {:#010x}\n", type, + // symbol);//found it openorbis but i am not sure it worth logging + } + rel_value = rel_base_virtual_addr + addend; + rel_isResolved = true; + break; + case R_X86_64_64: + case R_X86_64_JUMP_SLOT: // similar but addend is not take into account + { + auto sym = symbolsTlb[symbol]; + auto sym_bind = sym.GetBind(); + auto sym_type = sym.GetType(); + auto sym_visibility = sym.GetVisibility(); + u64 symbol_vitrual_addr = 0; + Loader::SymbolRecord symrec{}; + switch (sym_type) { + case STT_FUN: + rel_sym_type = 2; + break; + case STT_OBJECT: + rel_sym_type = 1; + break; + default: + LOG_INFO_IF(debug_loader, "unknown symbol type {}\n", sym_type); + } + if (sym_visibility != 0) // should be zero log if else + { + LOG_INFO_IF(debug_loader, "symbol visilibity !=0\n"); + } + switch (sym_bind) { + case STB_GLOBAL: + rel_name = namesTlb + sym.st_name; + m->linker->Resolve(rel_name, rel_sym_type, m, &symrec); + symbol_vitrual_addr = symrec.virtual_address; + rel_isResolved = (symbol_vitrual_addr != 0); - rel_name = symrec.name; - if (type == R_X86_64_JUMP_SLOT) { - addend = 0; - } - rel_value = (rel_isResolved ? symbol_vitrual_addr + addend : 0); - if (!rel_isResolved) { - LOG_INFO_IF(debug_loader, "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : {:#010x}\n", sym_type, symbol); - } - break; - default: LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind); + rel_name = symrec.name; + if (type == R_X86_64_JUMP_SLOT) { + addend = 0; } + rel_value = (rel_isResolved ? symbol_vitrual_addr + addend : 0); + if (!rel_isResolved) { + LOG_INFO_IF(debug_loader, + "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : " + "{:#010x}\n", + sym_type, symbol); + } + break; + default: + LOG_INFO_IF(debug_loader, "UNK bind {}\n", sym_bind); + } - } break; - default: LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol); + } break; + default: + LOG_INFO_IF(debug_loader, "UNK type {:#010x} rel symbol : {:#010x}\n", type, symbol); } if (rel_isResolved) { VirtualMemory::memory_patch(rel_virtual_addr, rel_value); - } - else - { - LOG_INFO_IF(debug_loader, "function not patched! {}\n",rel_name); - } + } else { + LOG_INFO_IF(debug_loader, "function not patched! {}\n", rel_name); + } } -void Linker::Relocate(Module* m) -{ - u32 idx = 0; - for (auto* rel = m->dynamic_info.relocation_table; reinterpret_cast(rel) < reinterpret_cast(m->dynamic_info.relocation_table) + m->dynamic_info.relocation_table_size; rel++, idx++) - { - relocate(idx, rel, m, false); - } - idx = 0; - for (auto* rel = m->dynamic_info.jmp_relocation_table; reinterpret_cast(rel) < reinterpret_cast(m->dynamic_info.jmp_relocation_table) + m->dynamic_info.jmp_relocation_table_size; rel++, idx++) - { - relocate(idx, rel, m, true); - } +void Linker::Relocate(Module* m) { + u32 idx = 0; + for (auto* rel = m->dynamic_info.relocation_table; + reinterpret_cast(rel) < reinterpret_cast(m->dynamic_info.relocation_table) + + m->dynamic_info.relocation_table_size; + rel++, idx++) { + relocate(idx, rel, m, false); + } + idx = 0; + for (auto* rel = m->dynamic_info.jmp_relocation_table; + reinterpret_cast(rel) < + reinterpret_cast(m->dynamic_info.jmp_relocation_table) + + m->dynamic_info.jmp_relocation_table_size; + rel++, idx++) { + relocate(idx, rel, m, true); + } } -void Linker::Resolve(const std::string& name, int Symtype, Module* m, Loader::SymbolRecord* return_info) { +void Linker::Resolve(const std::string& name, int Symtype, Module* m, + Loader::SymbolRecord* return_info) { const auto ids = Common::SplitString(name, '#'); - if (ids.size() == 3) // symbols are 3 parts name , library , module + if (ids.size() == 3) // symbols are 3 parts name , library , module { const auto* library = FindLibrary(*m, ids.at(1)); const auto* module = FindModule(*m, ids.at(2)); - if (library != nullptr && module != nullptr) { + if (library != nullptr && module != nullptr) { Loader::SymbolRes sr{}; sr.name = ids.at(0); sr.library = library->name; @@ -652,58 +651,53 @@ void Linker::Resolve(const std::string& name, int Symtype, Module* m, Loader::Sy } else { return_info->virtual_address = AeroLib::GetStub(sr.name.c_str()); return_info->name = "Unknown !!!"; - } - LOG_ERROR_IF(debug_loader, "Linker: Stub resolved {} as {} (lib: {}, mod: {}) \n", sr.name, return_info->name, library->name, module->name); + } + LOG_ERROR_IF(debug_loader, "Linker: Stub resolved {} as {} (lib: {}, mod: {}) \n", + sr.name, return_info->name, library->name, module->name); } - } - else - { + } else { //__debugbreak();//den tha prepei na ftasoume edo - } - } - else - { + } + } else { //__debugbreak();//oute edo mallon - } - + } } -using exit_func_t = PS4_SYSV_ABI void (*)(); -using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func); +using exit_func_t = PS4_SYSV_ABI void (*)(); +using entry_func_t = PS4_SYSV_ABI void (*)(EntryParams* params, exit_func_t atexit_func); static PS4_SYSV_ABI void ProgramExitFunc() { fmt::print("exit function called\n"); } static void run_main_entry(u64 addr, EntryParams* params, exit_func_t exit_func) { - //reinterpret_cast(addr)(params, exit_func); // can't be used, stack has to have a specific layout + // reinterpret_cast(addr)(params, exit_func); // can't be used, stack has to have + // a specific layout - asm volatile ( - "andq $-16, %%rsp\n"// Align to 16 bytes - "subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned + asm volatile("andq $-16, %%rsp\n" // Align to 16 bytes + "subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned - // Kernel also pushes some more things here during process init - // at least: environment, auxv, possibly other things + // Kernel also pushes some more things here during process init + // at least: environment, auxv, possibly other things - "pushq 8(%1)\n" // copy EntryParams to top of stack like the kernel does - "pushq 0(%1)\n" // OpenOrbis expects to find it there + "pushq 8(%1)\n" // copy EntryParams to top of stack like the kernel does + "pushq 0(%1)\n" // OpenOrbis expects to find it there - "movq %1, %%rdi\n" // also pass params and exit func - "movq %2, %%rsi\n" // as before + "movq %1, %%rdi\n" // also pass params and exit func + "movq %2, %%rsi\n" // as before - "jmp *%0\n" // can't use call here, as that would mangle the prepared stack. - // there's no coming back - : - : "r"(addr), "r"(params), "r"(exit_func) - : "rax", "rsi", "rdi", "rsp", "rbp" - ); + "jmp *%0\n" // can't use call here, as that would mangle the prepared stack. + // there's no coming back + : + : "r"(addr), "r"(params), "r"(exit_func) + : "rax", "rsi", "rdi", "rsp", "rbp"); } void Linker::Execute() { Core::Libraries::LibKernel::pthreadInitSelfMainThread(); EntryParams p{}; p.argc = 1; - p.argv[0] = "eboot.bin"; //hmm should be ok? + p.argv[0] = "eboot.bin"; // hmm should be ok? const auto& module = m_modules.at(0); run_main_entry(module.elf.GetElfEntry() + module.base_virtual_addr, &p, ProgramExitFunc); diff --git a/src/core/linker.h b/src/core/linker.h index 5f1e9a37..6ecd987a 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include "core/loader/elf.h" #include "core/loader/symbols_resolver.h" @@ -17,30 +17,30 @@ struct EntryParams { }; struct ModuleInfo { - std::string name; + std::string name; union { - u64 value; + u64 value; struct { - u32 name_offset; - u08 version_minor; - u08 version_major; - u16 id; - }; - }; - std::string enc_id; + u32 name_offset; + u08 version_minor; + u08 version_major; + u16 id; + }; + }; + std::string enc_id; }; struct LibraryInfo { - std::string name; + std::string name; union { - u64 value; + u64 value; struct { - u32 name_offset; - u16 version; - u16 id; - }; - }; - std::string enc_id; + u32 name_offset; + u16 version; + u16 id; + }; + }; + std::string enc_id; }; struct PS4ThreadLocal { @@ -110,22 +110,25 @@ struct Module { class Linker { public: - Linker(); - virtual ~Linker(); + Linker(); + virtual ~Linker(); - Module* LoadModule(const std::string& elf_name); - Module* FindModule(/*u32 id*/); - void LoadModuleToMemory(Module* m); - void LoadDynamicInfo(Module* m); - void LoadSymbols(Module* m); - Loader::SymbolsResolver& getHLESymbols() { return m_hle_symbols; } - void Relocate(Module* m); - void Resolve(const std::string& name, int Symtype, Module* m, Loader::SymbolRecord* return_info); + Module* LoadModule(const std::string& elf_name); + Module* FindModule(/*u32 id*/); + void LoadModuleToMemory(Module* m); + void LoadDynamicInfo(Module* m); + void LoadSymbols(Module* m); + Loader::SymbolsResolver& getHLESymbols() { + return m_hle_symbols; + } + void Relocate(Module* m); + void Resolve(const std::string& name, int Symtype, Module* m, + Loader::SymbolRecord* return_info); void Execute(); private: - const ModuleInfo* FindModule(const Module& m, const std::string& id); - const LibraryInfo* FindLibrary(const Module& program, const std::string& id); + const ModuleInfo* FindModule(const Module& m, const std::string& id); + const LibraryInfo* FindLibrary(const Module& program, const std::string& id); std::vector m_modules; Loader::SymbolsResolver m_hle_symbols{}; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index b23f6c6f..8dc6c8ee 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -1,120 +1,185 @@ #include -#include "common/log.h" #include "common/debug.h" +#include "common/log.h" #include "core/loader/elf.h" namespace Core::Loader { -constexpr bool log_file_loader = false; // disable it to disable logging +constexpr bool log_file_loader = false; // disable it to disable logging static std::string_view getProgramTypeName(program_type_es type) { switch (type) { - case PT_FAKE: return "PT_FAKE"; - case PT_NPDRM_EXEC: return "PT_NPDRM_EXEC"; - case PT_NPDRM_DYNLIB: return "PT_NPDRM_DYNLIB"; - case PT_SYSTEM_EXEC: return "PT_SYSTEM_EXEC"; - case PT_SYSTEM_DYNLIB: return "PT_SYSTEM_DYNLIB"; - case PT_HOST_KERNEL: return "PT_HOST_KERNEL"; - case PT_SECURE_MODULE: return "PT_SECURE_MODULE"; - case PT_SECURE_KERNEL: return "PT_SECURE_KERNEL"; - default: return "INVALID"; + case PT_FAKE: + return "PT_FAKE"; + case PT_NPDRM_EXEC: + return "PT_NPDRM_EXEC"; + case PT_NPDRM_DYNLIB: + return "PT_NPDRM_DYNLIB"; + case PT_SYSTEM_EXEC: + return "PT_SYSTEM_EXEC"; + case PT_SYSTEM_DYNLIB: + return "PT_SYSTEM_DYNLIB"; + case PT_HOST_KERNEL: + return "PT_HOST_KERNEL"; + case PT_SECURE_MODULE: + return "PT_SECURE_MODULE"; + case PT_SECURE_KERNEL: + return "PT_SECURE_KERNEL"; + default: + return "INVALID"; } } static std::string_view getIdentClassName(ident_class_es elf_class) { switch (elf_class) { - case ELF_CLASS_NONE: return "ELF_CLASS_NONE"; - case ELF_CLASS_32: return "ELF_CLASS_32"; - case ELF_CLASS_64: return "ELF_CLASS_64"; - case ELF_CLASS_NUM: return "ELF_CLASS_NUM"; - default: return "INVALID"; + case ELF_CLASS_NONE: + return "ELF_CLASS_NONE"; + case ELF_CLASS_32: + return "ELF_CLASS_32"; + case ELF_CLASS_64: + return "ELF_CLASS_64"; + case ELF_CLASS_NUM: + return "ELF_CLASS_NUM"; + default: + return "INVALID"; } } static std::string_view getIdentEndianName(ident_endian_es endian) { switch (endian) { - case ELF_DATA_NONE: return "ELF_DATA_NONE"; - case ELF_DATA_2LSB: return "ELF_DATA_2LSB"; - case ELF_DATA_2MSB: return "ELF_DATA_2MSB"; - case ELF_DATA_NUM: return "ELF_DATA_NUM"; - default: return "INVALID"; + case ELF_DATA_NONE: + return "ELF_DATA_NONE"; + case ELF_DATA_2LSB: + return "ELF_DATA_2LSB"; + case ELF_DATA_2MSB: + return "ELF_DATA_2MSB"; + case ELF_DATA_NUM: + return "ELF_DATA_NUM"; + default: + return "INVALID"; } } static std::string_view getIdentVersionName(ident_version_es version) { switch (version) { - case ELF_VERSION_NONE: return "ELF_VERSION_NONE"; - case ELF_VERSION_CURRENT: return "ELF_VERSION_CURRENT"; - case ELF_VERSION_NUM: return "ELF_VERSION_NUM"; - default: return "INVALID"; + case ELF_VERSION_NONE: + return "ELF_VERSION_NONE"; + case ELF_VERSION_CURRENT: + return "ELF_VERSION_CURRENT"; + case ELF_VERSION_NUM: + return "ELF_VERSION_NUM"; + default: + return "INVALID"; } } static std::string_view getIdentOsabiName(ident_osabi_es osabi) { switch (osabi) { - case ELF_OSABI_NONE: return "ELF_OSABI_NONE"; - case ELF_OSABI_HPUX: return "ELF_OSABI_HPUX"; - case ELF_OSABI_NETBSD: return "ELF_OSABI_NETBSD"; - case ELF_OSABI_LINUX: return "ELF_OSABI_LINUX"; - case ELF_OSABI_SOLARIS: return "ELF_OSABI_SOLARIS"; - case ELF_OSABI_AIX: return "ELF_OSABI_AIX"; - case ELF_OSABI_IRIX: return "ELF_OSABI_IRIX"; - case ELF_OSABI_FREEBSD: return "ELF_OSABI_FREEBSD"; - case ELF_OSABI_TRU64: return "ELF_OSABI_TRU64"; - case ELF_OSABI_MODESTO: return "ELF_OSABI_MODESTO"; - case ELF_OSABI_OPENBSD: return "ELF_OSABI_OPENBSD"; - case ELF_OSABI_OPENVMS: return "ELF_OSABI_OPENVMS"; - case ELF_OSABI_NSK: return "ELF_OSABI_NSK"; - case ELF_OSABI_AROS: return "ELF_OSABI_AROS"; - case ELF_OSABI_ARM_AEABI: return "ELF_OSABI_ARM_AEABI"; - case ELF_OSABI_ARM: return "ELF_OSABI_ARM"; - case ELF_OSABI_STANDALONE: return "ELF_OSABI_STANDALONE"; - default: return "INVALID"; + case ELF_OSABI_NONE: + return "ELF_OSABI_NONE"; + case ELF_OSABI_HPUX: + return "ELF_OSABI_HPUX"; + case ELF_OSABI_NETBSD: + return "ELF_OSABI_NETBSD"; + case ELF_OSABI_LINUX: + return "ELF_OSABI_LINUX"; + case ELF_OSABI_SOLARIS: + return "ELF_OSABI_SOLARIS"; + case ELF_OSABI_AIX: + return "ELF_OSABI_AIX"; + case ELF_OSABI_IRIX: + return "ELF_OSABI_IRIX"; + case ELF_OSABI_FREEBSD: + return "ELF_OSABI_FREEBSD"; + case ELF_OSABI_TRU64: + return "ELF_OSABI_TRU64"; + case ELF_OSABI_MODESTO: + return "ELF_OSABI_MODESTO"; + case ELF_OSABI_OPENBSD: + return "ELF_OSABI_OPENBSD"; + case ELF_OSABI_OPENVMS: + return "ELF_OSABI_OPENVMS"; + case ELF_OSABI_NSK: + return "ELF_OSABI_NSK"; + case ELF_OSABI_AROS: + return "ELF_OSABI_AROS"; + case ELF_OSABI_ARM_AEABI: + return "ELF_OSABI_ARM_AEABI"; + case ELF_OSABI_ARM: + return "ELF_OSABI_ARM"; + case ELF_OSABI_STANDALONE: + return "ELF_OSABI_STANDALONE"; + default: + return "INVALID"; } } static std::string_view getIdentAbiversionName(ident_abiversion_es version) { switch (version) { - case ELF_ABI_VERSION_AMDGPU_HSA_V2: return "ELF_ABI_VERSION_AMDGPU_HSA_V2"; - case ELF_ABI_VERSION_AMDGPU_HSA_V3: return "ELF_ABI_VERSION_AMDGPU_HSA_V3"; - case ELF_ABI_VERSION_AMDGPU_HSA_V4: return "ELF_ABI_VERSION_AMDGPU_HSA_V4"; - case ELF_ABI_VERSION_AMDGPU_HSA_V5: return "ELF_ABI_VERSION_AMDGPU_HSA_V5"; - default: return "INVALID"; + case ELF_ABI_VERSION_AMDGPU_HSA_V2: + return "ELF_ABI_VERSION_AMDGPU_HSA_V2"; + case ELF_ABI_VERSION_AMDGPU_HSA_V3: + return "ELF_ABI_VERSION_AMDGPU_HSA_V3"; + case ELF_ABI_VERSION_AMDGPU_HSA_V4: + return "ELF_ABI_VERSION_AMDGPU_HSA_V4"; + case ELF_ABI_VERSION_AMDGPU_HSA_V5: + return "ELF_ABI_VERSION_AMDGPU_HSA_V5"; + default: + return "INVALID"; } } static std::string_view getVersion(e_version_es version) { switch (version) { - case EV_NONE: return "EV_NONE"; - case EV_CURRENT: return "EV_CURRENT"; - default: return "INVALID"; + case EV_NONE: + return "EV_NONE"; + case EV_CURRENT: + return "EV_CURRENT"; + default: + return "INVALID"; } } static std::string_view getType(e_type_s type) { switch (type) { - case ET_NONE: return "ET_NONE"; - case ET_REL: return "ET_REL"; - case ET_EXEC: return "ET_EXEC"; - case ET_DYN: return "ET_DYN"; - case ET_CORE: return "ET_CORE"; - case ET_SCE_EXEC: return "ET_SCE_EXEC"; - case ET_SCE_STUBLIB: return "ET_SCE_STUBLIB"; - case ET_SCE_DYNEXEC: return "ET_SCE_DYNEXEC"; - case ET_SCE_DYNAMIC: return "ET_SCE_DYNAMIC"; - default: return "INVALID"; + case ET_NONE: + return "ET_NONE"; + case ET_REL: + return "ET_REL"; + case ET_EXEC: + return "ET_EXEC"; + case ET_DYN: + return "ET_DYN"; + case ET_CORE: + return "ET_CORE"; + case ET_SCE_EXEC: + return "ET_SCE_EXEC"; + case ET_SCE_STUBLIB: + return "ET_SCE_STUBLIB"; + case ET_SCE_DYNEXEC: + return "ET_SCE_DYNEXEC"; + case ET_SCE_DYNAMIC: + return "ET_SCE_DYNAMIC"; + default: + return "INVALID"; } } static std::string_view getMachine(e_machine_es machine) { switch (machine) { - case EM_X86_64: return "EM_X86_64"; - default: return "INVALID"; + case EM_X86_64: + return "EM_X86_64"; + default: + return "INVALID"; } } -Elf::~Elf() { Reset(); } +Elf::~Elf() { + Reset(); +} -void Elf::Reset() { m_f.close(); } +void Elf::Reset() { + m_f.close(); +} void Elf::Open(const std::string& file_name) { Reset(); @@ -156,7 +221,7 @@ void Elf::Open(const std::string& file_name) { header_size += m_elf_header.e_phnum * m_elf_header.e_phentsize; header_size += m_elf_header.e_shnum * m_elf_header.e_shentsize; header_size += 15; - header_size &= ~15; // Align + header_size &= ~15; // Align if (m_elf_header.e_ehsize - header_size >= sizeof(elf_program_id_header)) { m_f.seek(header_size, Common::FS::SeekMode::Set); @@ -169,12 +234,14 @@ void Elf::Open(const std::string& file_name) { bool Elf::isSelfFile() const { if (m_self.magic != self_header::signature) [[unlikely]] { - LOG_ERROR_IF(log_file_loader, "Not a SELF file.Magic file mismatched !current = {:#x} required = {:#x}\n ", m_self.magic, - self_header::signature); + LOG_ERROR_IF(log_file_loader, + "Not a SELF file.Magic file mismatched !current = {:#x} required = {:#x}\n ", + m_self.magic, self_header::signature); return false; } - if (m_self.version != 0x00 || m_self.mode != 0x01 || m_self.endian != 0x01 || m_self.attributes != 0x12) [[unlikely]] { + if (m_self.version != 0x00 || m_self.mode != 0x01 || m_self.endian != 0x01 || + m_self.attributes != 0x12) [[unlikely]] { LOG_ERROR_IF(log_file_loader, "Unknown SELF file\n"); return false; } @@ -188,60 +255,74 @@ bool Elf::isSelfFile() const { } bool Elf::isElfFile() const { - if (m_elf_header.e_ident.magic[EI_MAG0] != ELFMAG0 || m_elf_header.e_ident.magic[EI_MAG1] != ELFMAG1 || - m_elf_header.e_ident.magic[EI_MAG2] != ELFMAG2 || m_elf_header.e_ident.magic[EI_MAG3] != ELFMAG3) { + if (m_elf_header.e_ident.magic[EI_MAG0] != ELFMAG0 || + m_elf_header.e_ident.magic[EI_MAG1] != ELFMAG1 || + m_elf_header.e_ident.magic[EI_MAG2] != ELFMAG2 || + m_elf_header.e_ident.magic[EI_MAG3] != ELFMAG3) { LOG_ERROR_IF(log_file_loader, "Not an ELF file magic is wrong!\n"); return false; } if (m_elf_header.e_ident.ei_class != ELF_CLASS_64) { - LOG_ERROR_IF(log_file_loader, "e_ident[EI_CLASS] expected 0x02 is ({:#x})\n", static_cast(m_elf_header.e_ident.ei_class)); + LOG_ERROR_IF(log_file_loader, "e_ident[EI_CLASS] expected 0x02 is ({:#x})\n", + static_cast(m_elf_header.e_ident.ei_class)); return false; } if (m_elf_header.e_ident.ei_data != ELF_DATA_2LSB) { - LOG_ERROR_IF(log_file_loader, "e_ident[EI_DATA] expected 0x01 is ({:#x})\n", static_cast(m_elf_header.e_ident.ei_data)); + LOG_ERROR_IF(log_file_loader, "e_ident[EI_DATA] expected 0x01 is ({:#x})\n", + static_cast(m_elf_header.e_ident.ei_data)); return false; } if (m_elf_header.e_ident.ei_version != ELF_VERSION_CURRENT) { - LOG_ERROR_IF(log_file_loader, "e_ident[EI_VERSION] expected 0x01 is ({:#x})\n", static_cast(m_elf_header.e_ident.ei_version)); + LOG_ERROR_IF(log_file_loader, "e_ident[EI_VERSION] expected 0x01 is ({:#x})\n", + static_cast(m_elf_header.e_ident.ei_version)); return false; } if (m_elf_header.e_ident.ei_osabi != ELF_OSABI_FREEBSD) { - LOG_ERROR_IF(log_file_loader, "e_ident[EI_OSABI] expected 0x09 is ({:#x})\n", static_cast(m_elf_header.e_ident.ei_osabi)); + LOG_ERROR_IF(log_file_loader, "e_ident[EI_OSABI] expected 0x09 is ({:#x})\n", + static_cast(m_elf_header.e_ident.ei_osabi)); return false; } if (m_elf_header.e_ident.ei_abiversion != ELF_ABI_VERSION_AMDGPU_HSA_V2) { - LOG_ERROR_IF(log_file_loader, "e_ident[EI_ABIVERSION] expected 0x00 is ({:#x})\n", static_cast(m_elf_header.e_ident.ei_abiversion)); + LOG_ERROR_IF(log_file_loader, "e_ident[EI_ABIVERSION] expected 0x00 is ({:#x})\n", + static_cast(m_elf_header.e_ident.ei_abiversion)); return false; } - if (m_elf_header.e_type != ET_SCE_DYNEXEC && m_elf_header.e_type != ET_SCE_DYNAMIC && m_elf_header.e_type != ET_SCE_EXEC) { - LOG_ERROR_IF(log_file_loader, "e_type expected 0xFE10 OR 0xFE18 OR 0xfe00 is ({:#x})\n", static_cast(m_elf_header.e_type)); + if (m_elf_header.e_type != ET_SCE_DYNEXEC && m_elf_header.e_type != ET_SCE_DYNAMIC && + m_elf_header.e_type != ET_SCE_EXEC) { + LOG_ERROR_IF(log_file_loader, "e_type expected 0xFE10 OR 0xFE18 OR 0xfe00 is ({:#x})\n", + static_cast(m_elf_header.e_type)); return false; } if (m_elf_header.e_machine != EM_X86_64) { - LOG_ERROR_IF(log_file_loader, "e_machine expected 0x3E is ({:#x})\n", static_cast(m_elf_header.e_machine)); + LOG_ERROR_IF(log_file_loader, "e_machine expected 0x3E is ({:#x})\n", + static_cast(m_elf_header.e_machine)); return false; } if (m_elf_header.e_version != EV_CURRENT) { - LOG_ERROR_IF(log_file_loader, "m_elf_header.e_version expected 0x01 is ({:#x})\n", static_cast(m_elf_header.e_version)); + LOG_ERROR_IF(log_file_loader, "m_elf_header.e_version expected 0x01 is ({:#x})\n", + static_cast(m_elf_header.e_version)); return false; } if (m_elf_header.e_phentsize != sizeof(elf_program_header)) { - LOG_ERROR_IF(log_file_loader, "e_phentsize ({}) != sizeof(elf_program_header)\n", static_cast(m_elf_header.e_phentsize)); + LOG_ERROR_IF(log_file_loader, "e_phentsize ({}) != sizeof(elf_program_header)\n", + static_cast(m_elf_header.e_phentsize)); return false; } if (m_elf_header.e_shentsize > 0 && - m_elf_header.e_shentsize != sizeof(elf_section_header)) // Commercial games doesn't appear to have section headers + m_elf_header.e_shentsize != + sizeof(elf_section_header)) // Commercial games doesn't appear to have section headers { - LOG_ERROR_IF(log_file_loader, "e_shentsize ({}) != sizeof(elf_section_header)\n", m_elf_header.e_shentsize); + LOG_ERROR_IF(log_file_loader, "e_shentsize ({}) != sizeof(elf_section_header)\n", + m_elf_header.e_shentsize); return false; } @@ -249,7 +330,7 @@ bool Elf::isElfFile() const { } void Elf::DebugDump() { - if (is_self) { // If we load elf instead + if (is_self) { // If we load elf instead LOG_INFO_IF(log_file_loader, (SElfHeaderStr())); for (u16 i = 0; i < m_self.segment_count; i++) { LOG_INFO_IF(log_file_loader, SELFSegHeader(i)); @@ -276,7 +357,8 @@ void Elf::DebugDump() { LOG_INFO_IF(log_file_loader, "sh_size ........: {:#018x}\n", m_elf_shdr[i].sh_size); LOG_INFO_IF(log_file_loader, "sh_link ........: {:#010x}\n", m_elf_shdr[i].sh_link); LOG_INFO_IF(log_file_loader, "sh_info ........: {:#010x}\n", m_elf_shdr[i].sh_info); - LOG_INFO_IF(log_file_loader, "sh_addralign ...: {:#018x}\n", m_elf_shdr[i].sh_addralign); + LOG_INFO_IF(log_file_loader, "sh_addralign ...: {:#018x}\n", + m_elf_shdr[i].sh_addralign); LOG_INFO_IF(log_file_loader, "sh_entsize .....: {:#018x}\n", m_elf_shdr[i].sh_entsize); } } @@ -284,7 +366,8 @@ void Elf::DebugDump() { if (is_self) { LOG_INFO_IF(log_file_loader, "SELF info:\n"); LOG_INFO_IF(log_file_loader, "auth id ............: {:#018x}\n", m_self_id_header.authid); - LOG_INFO_IF(log_file_loader, "program type .......: {}\n", getProgramTypeName(m_self_id_header.program_type)); + LOG_INFO_IF(log_file_loader, "program type .......: {}\n", + getProgramTypeName(m_self_id_header.program_type)); LOG_INFO_IF(log_file_loader, "app version ........: {:#018x}\n", m_self_id_header.appver); LOG_INFO_IF(log_file_loader, "fw version .........: {:#018x}\n", m_self_id_header.firmver); std::string digest; @@ -333,11 +416,16 @@ std::string Elf::ElfHeaderStr() { } header += fmt::format("\n"); - header += fmt::format("ident class.......: {}\n", getIdentClassName(m_elf_header.e_ident.ei_class)); - header += fmt::format("ident data .......: {}\n", getIdentEndianName(m_elf_header.e_ident.ei_data)); - header += fmt::format("ident version.....: {}\n", getIdentVersionName(m_elf_header.e_ident.ei_version)); - header += fmt::format("ident osabi .....: {}\n", getIdentOsabiName(m_elf_header.e_ident.ei_osabi)); - header += fmt::format("ident abiversion..: {}\n", getIdentAbiversionName(m_elf_header.e_ident.ei_abiversion)); + header += + fmt::format("ident class.......: {}\n", getIdentClassName(m_elf_header.e_ident.ei_class)); + header += + fmt::format("ident data .......: {}\n", getIdentEndianName(m_elf_header.e_ident.ei_data)); + header += fmt::format("ident version.....: {}\n", + getIdentVersionName(m_elf_header.e_ident.ei_version)); + header += + fmt::format("ident osabi .....: {}\n", getIdentOsabiName(m_elf_header.e_ident.ei_osabi)); + header += fmt::format("ident abiversion..: {}\n", + getIdentAbiversionName(m_elf_header.e_ident.ei_abiversion)); header += fmt::format("ident UNK ........: 0x"); for (auto i : m_elf_header.e_ident.pad) { @@ -363,26 +451,46 @@ std::string Elf::ElfHeaderStr() { std::string Elf::ElfPheaderTypeStr(u32 type) { switch (type) { - case PT_NULL: return "Null"; - case PT_LOAD: return "Loadable"; - case PT_DYNAMIC: return "Dynamic"; - case PT_INTERP: return "Interpreter Path"; - case PT_NOTE: return "Note"; - case PT_SHLIB: return "Section Header Library"; - case PT_PHDR: return "Program Header"; - case PT_TLS: return "Thread-Local Storage"; - case PT_NUM: return "Defined Sections Number"; - case PT_SCE_RELA: return "SCE Relative"; - case PT_SCE_DYNLIBDATA: return "SCE Dynamic Library Data"; - case PT_SCE_PROCPARAM: return "SCE Processor Parameters"; - case PT_SCE_MODULE_PARAM: return "SCE Module Parameters"; - case PT_SCE_RELRO: return "SCE Read-Only After Relocation"; - case PT_GNU_EH_FRAME: return "GNU Entry Header Frame"; - case PT_GNU_STACK: return "GNU Stack (executability)"; - case PT_GNU_RELRO: return "GNU Read-Only After Relocation"; - case PT_SCE_COMMENT: return "SCE Comment"; - case PT_SCE_LIBVERSION: return "SCE Library Version"; - default: return "Unknown Section"; + case PT_NULL: + return "Null"; + case PT_LOAD: + return "Loadable"; + case PT_DYNAMIC: + return "Dynamic"; + case PT_INTERP: + return "Interpreter Path"; + case PT_NOTE: + return "Note"; + case PT_SHLIB: + return "Section Header Library"; + case PT_PHDR: + return "Program Header"; + case PT_TLS: + return "Thread-Local Storage"; + case PT_NUM: + return "Defined Sections Number"; + case PT_SCE_RELA: + return "SCE Relative"; + case PT_SCE_DYNLIBDATA: + return "SCE Dynamic Library Data"; + case PT_SCE_PROCPARAM: + return "SCE Processor Parameters"; + case PT_SCE_MODULE_PARAM: + return "SCE Module Parameters"; + case PT_SCE_RELRO: + return "SCE Read-Only After Relocation"; + case PT_GNU_EH_FRAME: + return "GNU Entry Header Frame"; + case PT_GNU_STACK: + return "GNU Stack (executability)"; + case PT_GNU_RELRO: + return "GNU Read-Only After Relocation"; + case PT_SCE_COMMENT: + return "SCE Comment"; + case PT_SCE_LIBVERSION: + return "SCE Library Version"; + default: + return "Unknown Section"; } } @@ -431,7 +539,7 @@ void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) { } } } - BREAKPOINT(); // Hmm we didn't return something... + BREAKPOINT(); // Hmm we didn't return something... } } // namespace Core::Loader diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 2e72e073..4b8e1713 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -14,7 +14,7 @@ struct self_header { u32 magic; u08 version; u08 mode; - u08 endian; // 1 is little endian + u08 endian; // 1 is little endian u08 attributes; u08 category; u08 program_type; @@ -24,31 +24,33 @@ struct self_header { u32 file_size; u32 padding2; u16 segment_count; - u16 unknown1A; // always 0x22 + u16 unknown1A; // always 0x22 u32 padding3; }; struct self_segment_header { bool IsBlocked() const { - return (flags & 0x800) != 0; // 0 or 0x800 + return (flags & 0x800) != 0; // 0 or 0x800 } - u32 GetId() const { return (flags >> 20u) & 0xFFFu; } + u32 GetId() const { + return (flags >> 20u) & 0xFFFu; + } bool IsOrdered() const { - return (flags & 1) != 0; // 0 or 1 + return (flags & 1) != 0; // 0 or 1 } bool IsEncrypted() const { - return (flags & 2) != 0; // 0 or 2 + return (flags & 2) != 0; // 0 or 2 } bool IsSigned() const { - return (flags & 4) != 0; // 0 or 4 + return (flags & 4) != 0; // 0 or 4 } bool IsCompressed() const { - return (flags & 8) != 0; // 0 or 8 + return (flags & 8) != 0; // 0 or 8 } u64 flags; @@ -181,11 +183,25 @@ typedef enum : u16 { typedef enum : u32 { EV_NONE = 0x0, EV_CURRENT = 0x1 } e_version_es; -typedef enum : u08 { ELF_CLASS_NONE = 0x0, ELF_CLASS_32 = 0x1, ELF_CLASS_64 = 0x2, ELF_CLASS_NUM = 0x3 } ident_class_es; +typedef enum : u08 { + ELF_CLASS_NONE = 0x0, + ELF_CLASS_32 = 0x1, + ELF_CLASS_64 = 0x2, + ELF_CLASS_NUM = 0x3 +} ident_class_es; -typedef enum : u08 { ELF_DATA_NONE = 0x0, ELF_DATA_2LSB = 0x1, ELF_DATA_2MSB = 0x2, ELF_DATA_NUM = 0x3 } ident_endian_es; +typedef enum : u08 { + ELF_DATA_NONE = 0x0, + ELF_DATA_2LSB = 0x1, + ELF_DATA_2MSB = 0x2, + ELF_DATA_NUM = 0x3 +} ident_endian_es; -typedef enum : u08 { ELF_VERSION_NONE = 0x0, ELF_VERSION_CURRENT = 0x1, ELF_VERSION_NUM = 0x2 } ident_version_es; +typedef enum : u08 { + ELF_VERSION_NONE = 0x0, + ELF_VERSION_CURRENT = 0x1, + ELF_VERSION_NUM = 0x2 +} ident_version_es; typedef enum : u08 { ELF_OSABI_NONE = 0x0, /* No extensions or unspecified */ @@ -383,7 +399,7 @@ constexpr u08 STT_FILE = 4; constexpr u08 STT_COMMON = 5; constexpr u08 STT_TLS = 6; constexpr u08 STT_LOOS = 10; -constexpr u08 STT_SCE = 11; // module_start/module_stop +constexpr u08 STT_SCE = 11; // module_start/module_stop constexpr u08 STT_HIOS = 12; constexpr u08 STT_LOPRO = 13; constexpr u08 STT_SPARC_REGISTER = 13; @@ -395,9 +411,15 @@ constexpr u08 STV_HIDDEN = 2; constexpr u08 STV_PROTECTED = 3; struct elf_symbol { - u08 GetBind() const { return st_info >> 4u; } - u08 GetType() const { return st_info & 0xfu; } - u08 GetVisibility() const { return st_other & 3u; } + u08 GetBind() const { + return st_info >> 4u; + } + u08 GetType() const { + return st_info & 0xfu; + } + u08 GetVisibility() const { + return st_other & 3u; + } u32 st_name; u08 st_info; @@ -408,23 +430,27 @@ struct elf_symbol { }; struct elf_relocation { - u32 GetSymbol() const { return static_cast(rel_info >> 32u); } - u32 GetType() const { return static_cast(rel_info & 0xffffffff); } + u32 GetSymbol() const { + return static_cast(rel_info >> 32u); + } + u32 GetType() const { + return static_cast(rel_info & 0xffffffff); + } u64 rel_offset; u64 rel_info; s64 rel_addend; }; -constexpr u32 R_X86_64_64 = 1; // Direct 64 bit +constexpr u32 R_X86_64_64 = 1; // Direct 64 bit constexpr u32 R_X86_64_GLOB_DAT = 6; -constexpr u32 R_X86_64_JUMP_SLOT = 7; // Create PLT entry -constexpr u32 R_X86_64_RELATIVE = 8; // Adjust by program base +constexpr u32 R_X86_64_JUMP_SLOT = 7; // Create PLT entry +constexpr u32 R_X86_64_RELATIVE = 8; // Adjust by program base constexpr u32 R_X86_64_DTPMOD64 = 16; namespace Core::Loader { class Elf { - public: +public: Elf() = default; virtual ~Elf(); @@ -433,15 +459,25 @@ class Elf { bool isElfFile() const; void DebugDump(); - [[nodiscard]] self_header GetSElfHeader() const { return m_self; } + [[nodiscard]] self_header GetSElfHeader() const { + return m_self; + } - [[nodiscard]] elf_header GetElfHeader() const { return m_elf_header; } + [[nodiscard]] elf_header GetElfHeader() const { + return m_elf_header; + } - [[nodiscard]] std::span GetProgramHeader() const { return m_elf_phdr; } + [[nodiscard]] std::span GetProgramHeader() const { + return m_elf_phdr; + } - [[nodiscard]] std::span GetSegmentHeader() const { return m_self_segments; } + [[nodiscard]] std::span GetSegmentHeader() const { + return m_self_segments; + } - [[nodiscard]] u64 GetElfEntry() const { return m_elf_header.e_entry; } + [[nodiscard]] u64 GetElfEntry() const { + return m_elf_header.e_entry; + } std::string SElfHeaderStr(); std::string SELFSegHeader(u16 no); @@ -452,10 +488,10 @@ class Elf { void LoadSegment(u64 virtual_addr, u64 file_offset, u64 size); - private: +private: void Reset(); - private: +private: Common::FS::File m_f{}; bool is_self{}; self_header m_self{}; @@ -466,4 +502,4 @@ class Elf { elf_program_id_header m_self_id_header{}; }; -} // namespace Core::Loader +} // namespace Core::Loader diff --git a/src/core/loader/symbols_resolver.cpp b/src/core/loader/symbols_resolver.cpp index b82495dd..9455059b 100644 --- a/src/core/loader/symbols_resolver.cpp +++ b/src/core/loader/symbols_resolver.cpp @@ -5,20 +5,19 @@ namespace Core::Loader { void SymbolsResolver::AddSymbol(const SymbolRes& s, u64 virtual_addr) { - SymbolRecord r{}; + SymbolRecord r{}; r.name = GenerateName(s); - r.virtual_address = virtual_addr; - m_symbols.push_back(r); + r.virtual_address = virtual_addr; + m_symbols.push_back(r); } std::string SymbolsResolver::GenerateName(const SymbolRes& s) { - return fmt::format("{} lib[{}_v{}]mod[{}_v{}.{}]", - s.name, s.library, s.library_version, + return fmt::format("{} lib[{}_v{}]mod[{}_v{}.{}]", s.name, s.library, s.library_version, s.module, s.module_version_major, s.module_version_minor); } -const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const { - const std::string name = GenerateName(s); +const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const { + const std::string name = GenerateName(s); for (u32 i = 0; i < m_symbols.size(); i++) { if (m_symbols[i].name.compare(name) == 0) { return &m_symbols[i]; @@ -26,7 +25,7 @@ const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const { } LOG_INFO("Unresolved! {}\n", name); - return nullptr; + return nullptr; } } // namespace Core::Loader diff --git a/src/core/loader/symbols_resolver.h b/src/core/loader/symbols_resolver.h index a095f9a5..92fc5387 100644 --- a/src/core/loader/symbols_resolver.h +++ b/src/core/loader/symbols_resolver.h @@ -1,15 +1,15 @@ #pragma once #include -#include #include +#include #include "common/types.h" namespace Core::Loader { struct SymbolRecord { std::string name; - u64 virtual_address; + u64 virtual_address; }; struct SymbolRes { @@ -25,10 +25,10 @@ struct SymbolRes { class SymbolsResolver { public: - SymbolsResolver() = default; - virtual ~SymbolsResolver() = default; + SymbolsResolver() = default; + virtual ~SymbolsResolver() = default; - void AddSymbol(const SymbolRes& s, u64 virtual_addr); + void AddSymbol(const SymbolRes& s, u64 virtual_addr); const SymbolRecord* FindSymbol(const SymbolRes& s) const; static std::string GenerateName(const SymbolRes& s); diff --git a/src/core/virtual_memory.cpp b/src/core/virtual_memory.cpp index cdff12c2..0f6ada46 100644 --- a/src/core/virtual_memory.cpp +++ b/src/core/virtual_memory.cpp @@ -22,35 +22,50 @@ enum PosixPageProtection { namespace VirtualMemory { static u32 convertMemoryMode(MemoryMode mode) { switch (mode) { - case MemoryMode::Read: return PAGE_READONLY; - case MemoryMode::Write: - case MemoryMode::ReadWrite: return PAGE_READWRITE; + case MemoryMode::Read: + return PAGE_READONLY; + case MemoryMode::Write: + case MemoryMode::ReadWrite: + return PAGE_READWRITE; - case MemoryMode::Execute: return PAGE_EXECUTE; - case MemoryMode::ExecuteRead: return PAGE_EXECUTE_READ; - case MemoryMode::ExecuteWrite: - case MemoryMode::ExecuteReadWrite: return PAGE_EXECUTE_READWRITE; + case MemoryMode::Execute: + return PAGE_EXECUTE; + case MemoryMode::ExecuteRead: + return PAGE_EXECUTE_READ; + case MemoryMode::ExecuteWrite: + case MemoryMode::ExecuteReadWrite: + return PAGE_EXECUTE_READWRITE; - case MemoryMode::NoAccess: return PAGE_NOACCESS; - default: return PAGE_NOACCESS; + case MemoryMode::NoAccess: + return PAGE_NOACCESS; + default: + return PAGE_NOACCESS; } } static MemoryMode convertMemoryMode(u32 mode) { switch (mode) { - case PAGE_NOACCESS: return MemoryMode::NoAccess; - case PAGE_READONLY: return MemoryMode::Read; - case PAGE_READWRITE: return MemoryMode::ReadWrite; - case PAGE_EXECUTE: return MemoryMode::Execute; - case PAGE_EXECUTE_READ: return MemoryMode::ExecuteRead; - case PAGE_EXECUTE_READWRITE: return MemoryMode::ExecuteReadWrite; - default: return MemoryMode::NoAccess; + case PAGE_NOACCESS: + return MemoryMode::NoAccess; + case PAGE_READONLY: + return MemoryMode::Read; + case PAGE_READWRITE: + return MemoryMode::ReadWrite; + case PAGE_EXECUTE: + return MemoryMode::Execute; + case PAGE_EXECUTE_READ: + return MemoryMode::ExecuteRead; + case PAGE_EXECUTE_READWRITE: + return MemoryMode::ExecuteReadWrite; + default: + return MemoryMode::NoAccess; } } u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { #ifdef _WIN64 - auto ptr = reinterpret_cast(VirtualAlloc(reinterpret_cast(static_cast(address)), size, - static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), convertMemoryMode(mode))); + auto ptr = reinterpret_cast(VirtualAlloc( + reinterpret_cast(static_cast(address)), size, + static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), convertMemoryMode(mode))); if (ptr == 0) { auto err = static_cast(GetLastError()); @@ -58,7 +73,8 @@ u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { } #else auto ptr = reinterpret_cast( - mmap(reinterpret_cast(static_cast(address)), size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); + mmap(reinterpret_cast(static_cast(address)), size, + PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); if (ptr == reinterpret_cast MAP_FAILED) { LOG_ERROR_IF(true, "mmap() failed: {}\n", std::strerror(errno)); @@ -69,7 +85,8 @@ u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode) { #ifdef _WIN64 DWORD old_protect = 0; - if (VirtualProtect(reinterpret_cast(static_cast(address)), size, convertMemoryMode(mode), &old_protect) == 0) { + if (VirtualProtect(reinterpret_cast(static_cast(address)), size, + convertMemoryMode(mode), &old_protect) == 0) { auto err = static_cast(GetLastError()); LOG_ERROR_IF(true, "VirtualProtect() failed: 0x{:X}\n", err); return false; @@ -86,13 +103,15 @@ bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode bool memory_flush(u64 address, u64 size) { #ifdef _WIN64 - if (::FlushInstructionCache(GetCurrentProcess(), reinterpret_cast(static_cast(address)), size) == 0) { + if (::FlushInstructionCache(GetCurrentProcess(), + reinterpret_cast(static_cast(address)), + size) == 0) { auto err = static_cast(GetLastError()); LOG_ERROR_IF(true, "FlushInstructionCache() failed: 0x{:X}\n", err); return false; } return true; -#else // linux probably doesn't have something similar +#else // linux probably doesn't have something similar return true; #endif } @@ -115,21 +134,27 @@ bool memory_patch(u64 vaddr, u64 value) { return ret; } -static u64 AlignUp(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); } +static u64 AlignUp(u64 pos, u64 align) { + return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); +} u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) { #ifdef _WIN64 // try allocate aligned address inside user area MEM_ADDRESS_REQUIREMENTS req{}; MEM_EXTENDED_PARAMETER param{}; - req.LowestStartingAddress = (address == 0 ? reinterpret_cast(USER_MIN) : reinterpret_cast(AlignUp(address, alignment))); + req.LowestStartingAddress = + (address == 0 ? reinterpret_cast(USER_MIN) + : reinterpret_cast(AlignUp(address, alignment))); req.HighestEndingAddress = reinterpret_cast(USER_MAX); req.Alignment = alignment; param.Type = MemExtendedParameterAddressRequirements; param.Pointer = &req; - auto ptr = reinterpret_cast(VirtualAlloc2( - GetCurrentProcess(), nullptr, size, static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), convertMemoryMode(mode), ¶m, 1)); + auto ptr = reinterpret_cast( + VirtualAlloc2(GetCurrentProcess(), nullptr, size, + static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), + convertMemoryMode(mode), ¶m, 1)); if (ptr == 0) { auto err = static_cast(GetLastError()); @@ -145,4 +170,4 @@ u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) return reinterpret_cast(ptr); #endif } -} // namespace VirtualMemory +} // namespace VirtualMemory diff --git a/src/core/virtual_memory.h b/src/core/virtual_memory.h index ef83a900..5567703e 100644 --- a/src/core/virtual_memory.h +++ b/src/core/virtual_memory.h @@ -27,12 +27,17 @@ bool memory_patch(u64 vaddr, u64 value); inline bool containsExecuteMode(MemoryMode mode) { switch (mode) { - case MemoryMode::Execute: return true; - case MemoryMode::ExecuteRead: return true; - case MemoryMode::ExecuteWrite: return true; - case MemoryMode::ExecuteReadWrite: return true; - default: return false; + case MemoryMode::Execute: + return true; + case MemoryMode::ExecuteRead: + return true; + case MemoryMode::ExecuteWrite: + return true; + case MemoryMode::ExecuteReadWrite: + return true; + default: + return false; } } -} // namespace VirtualMemory \ No newline at end of file +} // namespace VirtualMemory \ No newline at end of file diff --git a/src/emulator.cpp b/src/emulator.cpp index e52cd054..954a6f8e 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -1,12 +1,12 @@ #include #include +#include "Emulator/Host/controller.h" #include "common/singleton.h" #include "common/version.h" -#include "emulator.h" #include "core/PS4/HLE/Graphics/graphics_render.h" -#include "Emulator/Host/controller.h" #include "core/PS4/HLE/Graphics/video_out.h" #include "core/hle/libraries/libpad/pad.h" +#include "emulator.h" namespace Emu { @@ -46,17 +46,19 @@ static void CreateSdlWindow(WindowCtx* ctx) { std::exit(0); } std::string title = "shadps4 v" + std::string(Common::VERSION); - ctx->m_window = SDL_CreateWindowWithPosition(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, - (static_cast(SDL_WINDOW_HIDDEN) | static_cast(SDL_WINDOW_VULKAN))); + ctx->m_window = SDL_CreateWindowWithPosition( + title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, + (static_cast(SDL_WINDOW_HIDDEN) | static_cast(SDL_WINDOW_VULKAN))); - ctx->is_window_hidden = true; // hide window until we need to show something (should draw something in buffers) + ctx->is_window_hidden = + true; // hide window until we need to show something (should draw something in buffers) if (ctx->m_window == nullptr) { fmt::print("{}\n", SDL_GetError()); std::exit(0); } - SDL_SetWindowResizable(ctx->m_window, SDL_FALSE); // we don't support resizable atm + SDL_SetWindowResizable(ctx->m_window, SDL_FALSE); // we don't support resizable atm } static void update() { static double lag = 0.0; @@ -83,7 +85,8 @@ static void calculateFps(double game_time_s) { m_fps_frames_num++; if (m_current_time_seconds - m_fps_start_time > 0.25f) { - m_current_fps = static_cast(m_fps_frames_num) / (m_current_time_seconds - m_fps_start_time); + m_current_fps = + static_cast(m_fps_frames_num) / (m_current_time_seconds - m_fps_start_time); m_fps_frames_num = 0; m_fps_start_time = m_current_time_seconds; } @@ -110,27 +113,35 @@ void emuRun() { SDL_Event event; if (SDL_PollEvent(&event) != 0) { switch (event.type) { - case SDL_EVENT_QUIT: m_emu_needs_exit = true; break; + case SDL_EVENT_QUIT: + m_emu_needs_exit = true; + break; - case SDL_EVENT_TERMINATING: m_emu_needs_exit = true; break; + case SDL_EVENT_TERMINATING: + m_emu_needs_exit = true; + break; - case SDL_EVENT_WILL_ENTER_BACKGROUND: break; + case SDL_EVENT_WILL_ENTER_BACKGROUND: + break; - case SDL_EVENT_DID_ENTER_BACKGROUND: break; + case SDL_EVENT_DID_ENTER_BACKGROUND: + break; - case SDL_EVENT_WILL_ENTER_FOREGROUND: break; + case SDL_EVENT_WILL_ENTER_FOREGROUND: + break; - case SDL_EVENT_DID_ENTER_FOREGROUND: break; + case SDL_EVENT_DID_ENTER_FOREGROUND: + break; - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_KEY_UP: - if (event.type == SDL_EVENT_KEY_DOWN){ - if (event.key.keysym.sym == SDLK_p) { - m_game_is_paused = !m_game_is_paused; - } + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + if (event.type == SDL_EVENT_KEY_DOWN) { + if (event.key.keysym.sym == SDLK_p) { + m_game_is_paused = !m_game_is_paused; } - keyboardEvent(&event); - break; + } + keyboardEvent(&event); + break; } continue; } @@ -138,27 +149,35 @@ void emuRun() { SDL_WaitEvent(&event); switch (event.type) { - case SDL_EVENT_QUIT: m_emu_needs_exit = true; break; + case SDL_EVENT_QUIT: + m_emu_needs_exit = true; + break; - case SDL_EVENT_TERMINATING: m_emu_needs_exit = true; break; + case SDL_EVENT_TERMINATING: + m_emu_needs_exit = true; + break; - case SDL_EVENT_WILL_ENTER_BACKGROUND: break; + case SDL_EVENT_WILL_ENTER_BACKGROUND: + break; - case SDL_EVENT_DID_ENTER_BACKGROUND: break; + case SDL_EVENT_DID_ENTER_BACKGROUND: + break; - case SDL_EVENT_WILL_ENTER_FOREGROUND: break; + case SDL_EVENT_WILL_ENTER_FOREGROUND: + break; - case SDL_EVENT_DID_ENTER_FOREGROUND: break; + case SDL_EVENT_DID_ENTER_FOREGROUND: + break; - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_KEY_UP: - if (event.type == SDL_EVENT_KEY_DOWN) { - if (event.key.keysym.sym == SDLK_p) { - m_game_is_paused = !m_game_is_paused; - } + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + if (event.type == SDL_EVENT_KEY_DOWN) { + if (event.key.keysym.sym == SDLK_p) { + m_game_is_paused = !m_game_is_paused; } - keyboardEvent(&event); - break; + } + keyboardEvent(&event); + break; } exit_loop = m_emu_needs_exit; continue; @@ -169,8 +188,8 @@ void emuRun() { update(); } if (!exit_loop) { - if (HLE::Libs::Graphics::VideoOut::videoOutFlip(100000)) { // flip every 0.1 sec - calculateFps(0); // TODO: Proper fps + if (HLE::Libs::Graphics::VideoOut::videoOutFlip(100000)) { // flip every 0.1 sec + calculateFps(0); // TODO: Proper fps } } } @@ -199,7 +218,8 @@ void DrawBuffer(HLE::Libs::Graphics::VideoOutVulkanImage* image) { window_ctx->swapchain.current_index = static_cast(-1); - auto result = vkAcquireNextImageKHR(window_ctx->m_graphic_ctx.m_device, window_ctx->swapchain.swapchain, UINT64_MAX, nullptr, + auto result = vkAcquireNextImageKHR(window_ctx->m_graphic_ctx.m_device, + window_ctx->swapchain.swapchain, UINT64_MAX, nullptr, VK_NULL_HANDLE, &window_ctx->swapchain.current_index); if (result != VK_SUCCESS) { @@ -241,8 +261,10 @@ void DrawBuffer(HLE::Libs::Graphics::VideoOutVulkanImage* image) { pre_present_barrier.subresourceRange.levelCount = 1; pre_present_barrier.subresourceRange.baseArrayLayer = 0; pre_present_barrier.subresourceRange.layerCount = 1; - pre_present_barrier.image = window_ctx->swapchain.swapchain_images[window_ctx->swapchain.current_index]; - vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, + pre_present_barrier.image = + window_ctx->swapchain.swapchain_images[window_ctx->swapchain.current_index]; + vkCmdPipelineBarrier(vk_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &pre_present_barrier); buffer.end(); @@ -280,22 +302,42 @@ void keyboardEvent(SDL_Event* event) { if (event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_KEY_UP) { u32 button = 0; switch (event->key.keysym.sym) { - case SDLK_UP: button = ScePadButton::UP; break; - case SDLK_DOWN: button = ScePadButton::DOWN; break; - case SDLK_LEFT: button = ScePadButton::LEFT; break; - case SDLK_RIGHT: button = ScePadButton::RIGHT; break; - case SDLK_KP_8: button = ScePadButton ::TRIANGLE; break; - case SDLK_KP_6: button = ScePadButton ::CIRCLE; break; - case SDLK_KP_2: button = ScePadButton ::CROSS; break; - case SDLK_KP_4: button = ScePadButton ::SQUARE; break; - case SDLK_RETURN: button = ScePadButton ::OPTIONS; break; - default: break; + case SDLK_UP: + button = ScePadButton::UP; + break; + case SDLK_DOWN: + button = ScePadButton::DOWN; + break; + case SDLK_LEFT: + button = ScePadButton::LEFT; + break; + case SDLK_RIGHT: + button = ScePadButton::RIGHT; + break; + case SDLK_KP_8: + button = ScePadButton ::TRIANGLE; + break; + case SDLK_KP_6: + button = ScePadButton ::CIRCLE; + break; + case SDLK_KP_2: + button = ScePadButton ::CROSS; + break; + case SDLK_KP_4: + button = ScePadButton ::SQUARE; + break; + case SDLK_RETURN: + button = ScePadButton ::OPTIONS; + break; + default: + break; } if (button != 0) { - auto* controller = Common::Singleton::Instance(); + auto* controller = + Common::Singleton::Instance(); controller->checKButton(0, button, event->type == SDL_EVENT_KEY_DOWN); } } } -} // namespace Emu +} // namespace Emu diff --git a/src/emulator.h b/src/emulator.h index 6f0fe528..72631750 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -1,10 +1,10 @@ #pragma once -#include #include +#include -#include #include +#include #include namespace Emu { @@ -85,4 +85,4 @@ void checkAndWaitForGraphicsInit(); HLE::Libs::Graphics::GraphicCtx* getGraphicCtx(); void DrawBuffer(HLE::Libs::Graphics::VideoOutVulkanImage* image); void keyboardEvent(SDL_Event* event); -} // namespace Emulator +} // namespace Emu diff --git a/src/main.cpp b/src/main.cpp index 84b00ee9..2d3771e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,17 +6,17 @@ #include #include +#include #include "Util/config.h" #include "common/discord.h" #include "common/log.h" #include "common/singleton.h" #include "common/types.h" #include "core/PS4/HLE/Graphics/video_out.h" +#include "core/file_sys/fs.h" #include "core/hle/libraries/libs.h" #include "core/linker.h" #include "emulator.h" -#include -#include "core/file_sys/fs.h" int main(int argc, char* argv[]) { if (argc == 1) { @@ -41,7 +41,8 @@ int main(int argc, char* argv[]) { auto linker = Common::Singleton::Instance(); Core::Libraries::InitHLELibs(&linker->getHLESymbols()); linker->LoadModule(path); - std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); }, nullptr); + std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); }, + nullptr); Discord::RPC discordRPC; discordRPC.init(); discordRPC.update(Discord::RPCStatus::Idling, ""); diff --git a/src/video_core/gpu_memory.cpp b/src/video_core/gpu_memory.cpp index 4b5cfe6d..ba86b075 100644 --- a/src/video_core/gpu_memory.cpp +++ b/src/video_core/gpu_memory.cpp @@ -1,10 +1,11 @@ -#include "gpu_memory.h" #include #include +#include "gpu_memory.h" #include "common/singleton.h" -void* GPU::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, void* todo /*CommandBuffer?*/, u64 virtual_addr, u64 size, +void* GPU::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + void* todo /*CommandBuffer?*/, u64 virtual_addr, u64 size, const GPUObject& info) { auto* gpumemory = Common::Singleton::Instance(); @@ -23,9 +24,12 @@ void GPU::memorySetAllocArea(u64 virtual_addr, u64 size) { gpumemory->m_heaps.push_back(h); } -u64 GPU::calculate_hash(const u08* buf, u64 size) { return (size > 0 && buf != nullptr ? XXH3_64bits(buf, size) : 0); } +u64 GPU::calculate_hash(const u08* buf, u64 size) { + return (size > 0 && buf != nullptr ? XXH3_64bits(buf, size) : 0); +} -bool GPU::vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem) { +bool GPU::vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanMemory* mem) { static std::atomic_uint64_t unique_id = 0; VkPhysicalDeviceMemoryProperties memory_properties{}; @@ -66,7 +70,8 @@ void GPU::flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx) { int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) { int index = 0; for (const auto& heap : m_heaps) { - if ((virtual_addr >= heap.allocated_virtual_addr && virtual_addr < heap.allocated_virtual_addr + heap.allocated_size) || + if ((virtual_addr >= heap.allocated_virtual_addr && + virtual_addr < heap.allocated_virtual_addr + heap.allocated_size) || ((virtual_addr + size - 1) >= heap.allocated_virtual_addr && (virtual_addr + size - 1) < heap.allocated_virtual_addr + heap.allocated_size)) { return index; @@ -76,7 +81,8 @@ int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) { return -1; } -void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, void* todo, const u64* virtual_addr, const u64* size, +void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + void* todo, const u64* virtual_addr, const u64* size, int virtual_addr_num, const GPUObject& info) { auto* gpumemory = Common::Singleton::Instance(); @@ -101,7 +107,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi for (int h = 0; h < virtual_addr_num; h++) { if (info.check_hash) { - objInfo.hash[h] = GPU::calculate_hash(reinterpret_cast(virtual_addr[h]), size[h]); + objInfo.hash[h] = + GPU::calculate_hash(reinterpret_cast(virtual_addr[h]), size[h]); } else { objInfo.hash[h] = 0; } @@ -109,7 +116,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi objInfo.submit_id = submit_id; objInfo.check_hash = info.check_hash; - objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, virtual_addr_num, &objInfo.mem); + objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, + virtual_addr_num, &objInfo.mem); objInfo.update_func = info.getUpdateFunc(); int index = static_cast(heap.objects.size()); @@ -123,7 +131,8 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi return objInfo.gpu_object.obj; } -GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id) { +GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u64* size, + int virtual_addr_num, int heap_id, int obj_id) { auto& heap = m_heaps[heap_id]; GPU::HeapBlock heapBlock{}; @@ -135,7 +144,8 @@ GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u6 return heapBlock; } -void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id) { +void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, + int obj_id) { auto& heap = m_heaps[heap_id]; auto& heapObj = heap.objects[obj_id]; @@ -147,7 +157,9 @@ void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, for (int i = 0; i < heapObj.block.virtual_addr_num; i++) { if (objInfo.check_hash) { - hash[i] = GPU::calculate_hash(reinterpret_cast(heapObj.block.virtual_addr[i]), heapObj.block.size[i]); + hash[i] = GPU::calculate_hash( + reinterpret_cast(heapObj.block.virtual_addr[i]), + heapObj.block.size[i]); } else { hash[i] = 0; } @@ -166,7 +178,8 @@ void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, } if (need_update) { - objInfo.update_func(ctx, objInfo.obj_params, objInfo.gpu_object.obj, heapObj.block.virtual_addr, heapObj.block.size, + objInfo.update_func(ctx, objInfo.obj_params, objInfo.gpu_object.obj, + heapObj.block.virtual_addr, heapObj.block.size, heapObj.block.virtual_addr_num); } } diff --git a/src/video_core/gpu_memory.h b/src/video_core/gpu_memory.h index 87095ec7..82705125 100644 --- a/src/video_core/gpu_memory.h +++ b/src/video_core/gpu_memory.h @@ -1,8 +1,8 @@ #pragma once -#include "common/types.h" #include #include +#include "common/types.h" namespace VideoCore { @@ -65,9 +65,11 @@ public: GPUMemory() {} virtual ~GPUMemory() {} int getHeapId(u64 vaddr, u64 size); - void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr, + void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr, const u64* size, int virtual_addr_num, const GPUObject& info); - HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id); + HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, + int heap_id, int obj_id); void update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id); void flushAllHeaps(HLE::Libs::Graphics::GraphicCtx* ctx); @@ -77,10 +79,12 @@ private: }; void memorySetAllocArea(u64 virtual_addr, u64 size); -void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size, +void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, + /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size, const GPUObject& info); u64 calculate_hash(const u08* buf, u64 size); -bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem); +bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanMemory* mem); void flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx); -} // namespace VideoCore +} // namespace VideoCore diff --git a/src/video_core/tile_manager.cpp b/src/video_core/tile_manager.cpp index c0d4ed3b..a1a8d0f0 100644 --- a/src/video_core/tile_manager.cpp +++ b/src/video_core/tile_manager.cpp @@ -5,7 +5,7 @@ namespace VideoCore { class TileManager32 { - public: +public: u32 m_macro_tile_height = 0; u32 m_bank_height = 0; u32 m_num_banks = 0; @@ -60,25 +60,26 @@ class TileManager32 { return pipe; } - static u32 GetBankIndex(u32 x, u32 y, u32 bank_width, u32 bank_height, u32 num_banks, u32 num_pipes) { + static u32 GetBankIndex(u32 x, u32 y, u32 bank_width, u32 bank_height, u32 num_banks, + u32 num_pipes) { const u32 x_shift_offset = std::bit_width(bank_width * num_pipes); const u32 y_shift_offset = std::bit_width(bank_height); const u32 xs = x >> x_shift_offset; const u32 ys = y >> y_shift_offset; u32 bank = 0; switch (num_banks) { - case 8: - bank |= (((xs >> 3u) ^ (ys >> 5u)) & 0x1u) << 0u; - bank |= (((xs >> 4u) ^ (ys >> 4u) ^ (ys >> 5u)) & 0x1u) << 1u; - bank |= (((xs >> 5u) ^ (ys >> 3u)) & 0x1u) << 2u; - break; - case 16: - bank |= (((xs >> 3u) ^ (ys >> 6u)) & 0x1u) << 0u; - bank |= (((xs >> 4u) ^ (ys >> 5u) ^ (ys >> 6u)) & 0x1u) << 1u; - bank |= (((xs >> 5u) ^ (ys >> 4u)) & 0x1u) << 2u; - bank |= (((xs >> 6u) ^ (ys >> 3u)) & 0x1u) << 3u; - break; - default:; + case 8: + bank |= (((xs >> 3u) ^ (ys >> 5u)) & 0x1u) << 0u; + bank |= (((xs >> 4u) ^ (ys >> 4u) ^ (ys >> 5u)) & 0x1u) << 1u; + bank |= (((xs >> 5u) ^ (ys >> 3u)) & 0x1u) << 2u; + break; + case 16: + bank |= (((xs >> 3u) ^ (ys >> 6u)) & 0x1u) << 0u; + bank |= (((xs >> 4u) ^ (ys >> 5u) ^ (ys >> 6u)) & 0x1u) << 1u; + bank |= (((xs >> 5u) ^ (ys >> 4u)) & 0x1u) << 2u; + bank |= (((xs >> 6u) ^ (ys >> 3u)) & 0x1u) << 3u; + break; + default:; } return bank; @@ -101,11 +102,13 @@ class TileManager32 { tile_bytes = 512; } - u64 macro_tile_bytes = (128 / 8) * (m_macro_tile_height / 8) * tile_bytes / (m_num_pipes * m_num_banks); + u64 macro_tile_bytes = + (128 / 8) * (m_macro_tile_height / 8) * tile_bytes / (m_num_pipes * m_num_banks); u64 macro_tiles_per_row = m_padded_width / 128; u64 macro_tile_row_index = y / m_macro_tile_height; u64 macro_tile_column_index = x / 128; - u64 macro_tile_index = (macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index; + u64 macro_tile_index = + (macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index; u64 macro_tile_offset = macro_tile_index * macro_tile_bytes; u64 macro_tiles_per_slice = macro_tiles_per_row * (m_padded_height / m_macro_tile_height); u64 slice_bytes = macro_tiles_per_slice * macro_tile_bytes; @@ -124,13 +127,14 @@ class TileManager32 { u64 pipe_interleave_offset = total_offset & 0xffu; u64 offset = total_offset >> 8u; - u64 byte_offset = pipe_interleave_offset | (pipe << (8u)) | (bank << (8u + m_pipe_bits)) | (offset << (8u + m_pipe_bits + m_bank_bits)); + u64 byte_offset = pipe_interleave_offset | (pipe << (8u)) | (bank << (8u + m_pipe_bits)) | + (offset << (8u + m_pipe_bits + m_bank_bits)); return ((byte_offset << 3u) | bit_offset) / 8; } }; -void ConvertTileToLinear(u08* dst, const u08* src,u32 width, u32 height, bool is_neo) { +void ConvertTileToLinear(u08* dst, const u08* src, u32 width, u32 height, bool is_neo) { const TileManager32 t{width, height, is_neo}; for (u32 y = 0; y < height; y++) { u32 x = 0; diff --git a/src/vulkan_util.cpp b/src/vulkan_util.cpp index 1c2bc5b0..a2c10233 100644 --- a/src/vulkan_util.cpp +++ b/src/vulkan_util.cpp @@ -1,16 +1,16 @@ -#include "vulkan_util.h" -#include -#include #include -#include "common/singleton.h" -#include "common/log.h" -#include "common/debug.h" +#include +#include #include #include +#include "common/debug.h" +#include "common/log.h" +#include "common/singleton.h" +#include "vulkan_util.h" #include -constexpr bool log_file_vulkanutil = true; // disable it to disable logging +constexpr bool log_file_vulkanutil = true; // disable it to disable logging void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { Emu::VulkanExt ext; @@ -44,18 +44,21 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { std::exit(0); } - if (SDL_Vulkan_CreateSurface(ctx->m_window, ctx->m_graphic_ctx.m_instance, &ctx->m_surface) == SDL_FALSE) { + if (SDL_Vulkan_CreateSurface(ctx->m_window, ctx->m_graphic_ctx.m_instance, &ctx->m_surface) == + SDL_FALSE) { LOG_CRITICAL_IF(log_file_vulkanutil, "Can't create an vulkan surface\n"); std::exit(0); } // TODO i am not sure if it's that it is neccesary or if it needs more - std::vector device_extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, - VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME, "VK_KHR_maintenance1"}; + std::vector device_extensions = { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, + VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME, "VK_KHR_maintenance1"}; Emu::VulkanQueues queues; - vulkanFindCompatiblePhysicalDevice(ctx->m_graphic_ctx.m_instance, ctx->m_surface, device_extensions, &ctx->m_surface_capabilities, + vulkanFindCompatiblePhysicalDevice(ctx->m_graphic_ctx.m_instance, ctx->m_surface, + device_extensions, &ctx->m_surface_capabilities, &ctx->m_graphic_ctx.m_physical_device, &queues); if (ctx->m_graphic_ctx.m_physical_device == nullptr) { @@ -68,7 +71,8 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { LOG_INFO_IF(log_file_vulkanutil, "GFX device to be used : {}\n", device_properties.deviceName); - ctx->m_graphic_ctx.m_device = vulkanCreateDevice(ctx->m_graphic_ctx.m_physical_device, ctx->m_surface, &ext, queues, device_extensions); + ctx->m_graphic_ctx.m_device = vulkanCreateDevice( + ctx->m_graphic_ctx.m_physical_device, ctx->m_surface, &ext, queues, device_extensions); if (ctx->m_graphic_ctx.m_device == nullptr) { LOG_CRITICAL_IF(log_file_vulkanutil, "Can't create vulkan device\n"); std::exit(0); @@ -78,7 +82,8 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { ctx->swapchain = vulkanCreateSwapchain(&ctx->m_graphic_ctx, 2); } -Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics::GraphicCtx* ctx, u32 image_count) { +Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics::GraphicCtx* ctx, + u32 image_count) { auto window_ctx = Common::Singleton::Instance(); const auto& capabilities = window_ctx->m_surface_capabilities.capabilities; Emu::VulkanSwapchain s{}; @@ -128,7 +133,8 @@ Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics vkGetSwapchainImagesKHR(ctx->m_device, s.swapchain, &s.swapchain_images_count, nullptr); s.swapchain_images.resize(s.swapchain_images_count); - vkGetSwapchainImagesKHR(ctx->m_device, s.swapchain, &s.swapchain_images_count, s.swapchain_images.data()); + vkGetSwapchainImagesKHR(ctx->m_device, s.swapchain, &s.swapchain_images_count, + s.swapchain_images.data()); s.swapchain_image_views.resize(s.swapchain_images_count); for (uint32_t i = 0; i < s.swapchain_images_count; i++) { @@ -163,7 +169,8 @@ Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics present_complete_info.pNext = nullptr; present_complete_info.flags = 0; - auto result = vkCreateSemaphore(ctx->m_device, &present_complete_info, nullptr, &s.present_complete_semaphore); + auto result = vkCreateSemaphore(ctx->m_device, &present_complete_info, nullptr, + &s.present_complete_semaphore); VkFenceCreateInfo fence_info{}; fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; @@ -179,11 +186,13 @@ Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics return s; } -void Graphics::Vulkan::vulkanCreateQueues(HLE::Libs::Graphics::GraphicCtx* ctx, const Emu::VulkanQueues& queues) { +void Graphics::Vulkan::vulkanCreateQueues(HLE::Libs::Graphics::GraphicCtx* ctx, + const Emu::VulkanQueues& queues) { auto get_queue = [ctx](int id, const Emu::VulkanQueueInfo& info, bool with_mutex = false) { ctx->queues[id].family = info.family; ctx->queues[id].index = info.index; - vkGetDeviceQueue(ctx->m_device, ctx->queues[id].family, ctx->queues[id].index, &ctx->queues[id].vk_queue); + vkGetDeviceQueue(ctx->m_device, ctx->queues[id].family, ctx->queues[id].index, + &ctx->queues[id].vk_queue); if (with_mutex) { ctx->queues[id].mutex = std::make_unique(); } @@ -199,8 +208,10 @@ void Graphics::Vulkan::vulkanCreateQueues(HLE::Libs::Graphics::GraphicCtx* ctx, } } -VkDevice Graphics::Vulkan::vulkanCreateDevice(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const Emu::VulkanExt* r, - const Emu::VulkanQueues& queues, const std::vector& device_extensions) { +VkDevice Graphics::Vulkan::vulkanCreateDevice(VkPhysicalDevice physical_device, + VkSurfaceKHR surface, const Emu::VulkanExt* r, + const Emu::VulkanQueues& queues, + const std::vector& device_extensions) { std::vector queue_create_info(queues.family_count); std::vector> queue_priority(queues.family_count); uint32_t queue_create_info_num = 0; @@ -211,12 +222,14 @@ VkDevice Graphics::Vulkan::vulkanCreateDevice(VkPhysicalDevice physical_device, queue_priority[queue_create_info_num].push_back(1.0f); } - queue_create_info[queue_create_info_num].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info[queue_create_info_num].sType = + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queue_create_info[queue_create_info_num].pNext = nullptr; queue_create_info[queue_create_info_num].flags = 0; queue_create_info[queue_create_info_num].queueFamilyIndex = i; queue_create_info[queue_create_info_num].queueCount = queues.family_used[i]; - queue_create_info[queue_create_info_num].pQueuePriorities = queue_priority[queue_create_info_num].data(); + queue_create_info[queue_create_info_num].pQueuePriorities = + queue_priority[queue_create_info_num].data(); queue_create_info_num++; } @@ -251,13 +264,15 @@ void Graphics::Vulkan::vulkanGetInstanceExtensions(Emu::VulkanExt* ext) { ext->required_extensions = std::vector(required_extensions_count); - result = SDL_Vulkan_GetInstanceExtensions(&required_extensions_count, ext->required_extensions.data()); + result = SDL_Vulkan_GetInstanceExtensions(&required_extensions_count, + ext->required_extensions.data()); vkEnumerateInstanceExtensionProperties(nullptr, &available_extensions_count, nullptr); ext->available_extensions = std::vector(available_extensions_count); - vkEnumerateInstanceExtensionProperties(nullptr, &available_extensions_count, ext->available_extensions.data()); + vkEnumerateInstanceExtensionProperties(nullptr, &available_extensions_count, + ext->available_extensions.data()); vkEnumerateInstanceLayerProperties(&available_layers_count, nullptr); ext->available_layers = std::vector(available_layers_count); @@ -268,19 +283,21 @@ void Graphics::Vulkan::vulkanGetInstanceExtensions(Emu::VulkanExt* ext) { } for (const auto& ext : ext->available_extensions) { - LOG_INFO_IF(log_file_vulkanutil, "Vulkan available extension: {}, version = {}\n", ext.extensionName, ext.specVersion); + LOG_INFO_IF(log_file_vulkanutil, "Vulkan available extension: {}, version = {}\n", + ext.extensionName, ext.specVersion); } for (const auto& l : ext->available_layers) { - LOG_INFO_IF(log_file_vulkanutil, "Vulkan available layer: {}, specVersion = {}, implVersion = {}, {}\n", l.layerName, l.specVersion, - l.implementationVersion, l.description); + LOG_INFO_IF(log_file_vulkanutil, + "Vulkan available layer: {}, specVersion = {}, implVersion = {}, {}\n", + l.layerName, l.specVersion, l.implementationVersion, l.description); } } -void Graphics::Vulkan::vulkanFindCompatiblePhysicalDevice(VkInstance instance, VkSurfaceKHR surface, - const std::vector& device_extensions, - Emu::VulkanSurfaceCapabilities* out_capabilities, VkPhysicalDevice* out_device, - Emu::VulkanQueues* out_queues) { +void Graphics::Vulkan::vulkanFindCompatiblePhysicalDevice( + VkInstance instance, VkSurfaceKHR surface, const std::vector& device_extensions, + Emu::VulkanSurfaceCapabilities* out_capabilities, VkPhysicalDevice* out_device, + Emu::VulkanQueues* out_queues) { u32 count_devices = 0; vkEnumeratePhysicalDevices(instance, &count_devices, nullptr); @@ -297,7 +314,8 @@ void Graphics::Vulkan::vulkanFindCompatiblePhysicalDevice(VkInstance instance, V vkGetPhysicalDeviceProperties(device, &device_properties); vkGetPhysicalDeviceFeatures2(device, &device_features2); if (device_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { - continue; // we don't want integrated gpu for now .Later we will check the requirements and see what we can support (TODO fix me) + continue; // we don't want integrated gpu for now .Later we will check the requirements + // and see what we can support (TODO fix me) } LOG_INFO_IF(log_file_vulkanutil, "Vulkan device: {}\n", device_properties.deviceName); @@ -312,7 +330,8 @@ void Graphics::Vulkan::vulkanFindCompatiblePhysicalDevice(VkInstance instance, V *out_queues = found_best_queues; } -Emu::VulkanQueues Graphics::Vulkan::vulkanFindQueues(VkPhysicalDevice device, VkSurfaceKHR surface) { +Emu::VulkanQueues Graphics::Vulkan::vulkanFindQueues(VkPhysicalDevice device, + VkSurfaceKHR surface) { Emu::VulkanQueues qs; u32 queue_family_count = 0; @@ -327,7 +346,8 @@ Emu::VulkanQueues Graphics::Vulkan::vulkanFindQueues(VkPhysicalDevice device, Vk VkBool32 presentation_supported = VK_FALSE; vkGetPhysicalDeviceSurfaceSupportKHR(device, family, surface, &presentation_supported); - LOG_INFO_IF(log_file_vulkanutil, "queue family: {}, count = {}, present = {}\n", string_VkQueueFlags(f.queueFlags).c_str(), f.queueCount, + LOG_INFO_IF(log_file_vulkanutil, "queue family: {}, count = {}, present = {}\n", + string_VkQueueFlags(f.queueFlags).c_str(), f.queueCount, (presentation_supported == VK_TRUE ? "true" : "false")); for (uint32_t i = 0; i < f.queueCount; i++) { Emu::VulkanQueueInfo info; @@ -396,7 +416,8 @@ Emu::VulkanQueues Graphics::Vulkan::vulkanFindQueues(VkPhysicalDevice device, Vk return qs; } -void Graphics::Vulkan::vulkanGetSurfaceCapabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface, +void Graphics::Vulkan::vulkanGetSurfaceCapabilities(VkPhysicalDevice physical_device, + VkSurfaceKHR surface, Emu::VulkanSurfaceCapabilities* surfaceCap) { vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surfaceCap->capabilities); @@ -404,28 +425,34 @@ void Graphics::Vulkan::vulkanGetSurfaceCapabilities(VkPhysicalDevice physical_de vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &formats_count, nullptr); surfaceCap->formats = std::vector(formats_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &formats_count, surfaceCap->formats.data()); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &formats_count, + surfaceCap->formats.data()); uint32_t present_modes_count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &present_modes_count, nullptr); + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &present_modes_count, + nullptr); surfaceCap->present_modes = std::vector(present_modes_count); - vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &present_modes_count, surfaceCap->present_modes.data()); + vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &present_modes_count, + surfaceCap->present_modes.data()); for (const auto& f : surfaceCap->formats) { - if (f.format == VK_FORMAT_B8G8R8A8_SRGB && f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + if (f.format == VK_FORMAT_B8G8R8A8_SRGB && + f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { surfaceCap->is_format_srgb_bgra32 = true; break; } - if (f.format == VK_FORMAT_B8G8R8A8_UNORM && f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + if (f.format == VK_FORMAT_B8G8R8A8_UNORM && + f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { surfaceCap->is_format_unorm_bgra32 = true; break; } } } -static void set_image_layout(VkCommandBuffer buffer, HLE::Libs::Graphics::VulkanImage* dst_image, uint32_t base_level, uint32_t levels, - VkImageAspectFlags aspect_mask, VkImageLayout old_image_layout, VkImageLayout new_image_layout) { +static void set_image_layout(VkCommandBuffer buffer, HLE::Libs::Graphics::VulkanImage* dst_image, + uint32_t base_level, uint32_t levels, VkImageAspectFlags aspect_mask, + VkImageLayout old_image_layout, VkImageLayout new_image_layout) { VkImageMemoryBarrier imageMemoryBarrier{}; imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; imageMemoryBarrier.pNext = nullptr; @@ -478,12 +505,14 @@ static void set_image_layout(VkCommandBuffer buffer, HLE::Libs::Graphics::Vulkan VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - vkCmdPipelineBarrier(buffer, src_stages, dest_stages, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); + vkCmdPipelineBarrier(buffer, src_stages, dest_stages, 0, 0, nullptr, 0, nullptr, 1, + &imageMemoryBarrier); dst_image->layout = new_image_layout; } -void Graphics::Vulkan::vulkanBlitImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanImage* src_image, +void Graphics::Vulkan::vulkanBlitImage(GPU::CommandBuffer* buffer, + HLE::Libs::Graphics::VulkanImage* src_image, Emu::VulkanSwapchain* dst_swapchain) { auto* vk_buffer = buffer->getPool()->buffers[buffer->getIndex()]; @@ -492,9 +521,11 @@ void Graphics::Vulkan::vulkanBlitImage(GPU::CommandBuffer* buffer, HLE::Libs::Gr swapchain_image.image = dst_swapchain->swapchain_images[dst_swapchain->current_index]; swapchain_image.layout = VK_IMAGE_LAYOUT_UNDEFINED; - set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - set_image_layout(vk_buffer, &swapchain_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + set_image_layout(vk_buffer, &swapchain_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkImageBlit region{}; region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -518,22 +549,28 @@ void Graphics::Vulkan::vulkanBlitImage(GPU::CommandBuffer* buffer, HLE::Libs::Gr region.dstOffsets[1].y = static_cast(dst_swapchain->swapchain_extent.height); region.dstOffsets[1].z = 1; - vkCmdBlitImage(vk_buffer, src_image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchain_image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, - ®ion, VK_FILTER_LINEAR); + vkCmdBlitImage(vk_buffer, src_image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + swapchain_image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion, + VK_FILTER_LINEAR); - set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + set_image_layout(vk_buffer, src_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } -void Graphics::Vulkan::vulkanFillImage(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanImage* dst_image, const void* src_data, - u64 size, u32 src_pitch, u64 dst_layout) { +void Graphics::Vulkan::vulkanFillImage(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanImage* dst_image, + const void* src_data, u64 size, u32 src_pitch, + u64 dst_layout) { HLE::Libs::Graphics::VulkanBuffer staging_buffer{}; staging_buffer.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - staging_buffer.memory.property = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + staging_buffer.memory.property = + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; vulkanCreateBuffer(ctx, size, &staging_buffer); void* data = nullptr; - vkMapMemory(ctx->m_device, staging_buffer.memory.memory, staging_buffer.memory.offset, staging_buffer.memory.requirements.size, 0, &data); + vkMapMemory(ctx->m_device, staging_buffer.memory.memory, staging_buffer.memory.offset, + staging_buffer.memory.requirements.size, 0, &data); std::memcpy(data, src_data, size); vkUnmapMemory(ctx->m_device, staging_buffer.memory.memory); @@ -548,11 +585,15 @@ void Graphics::Vulkan::vulkanFillImage(HLE::Libs::Graphics::GraphicCtx* ctx, HLE vulkanDeleteBuffer(ctx, &staging_buffer); } -void Graphics::Vulkan::vulkanBufferToImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanBuffer* src_buffer, u32 src_pitch, - HLE::Libs::Graphics::VulkanImage* dst_image, u64 dst_layout) { +void Graphics::Vulkan::vulkanBufferToImage(GPU::CommandBuffer* buffer, + HLE::Libs::Graphics::VulkanBuffer* src_buffer, + u32 src_pitch, + HLE::Libs::Graphics::VulkanImage* dst_image, + u64 dst_layout) { auto* vk_buffer = buffer->getPool()->buffers[buffer->getIndex()]; - set_image_layout(vk_buffer, dst_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + set_image_layout(vk_buffer, dst_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -567,13 +608,15 @@ void Graphics::Vulkan::vulkanBufferToImage(GPU::CommandBuffer* buffer, HLE::Libs region.imageOffset = {0, 0, 0}; region.imageExtent = {dst_image->extent.width, dst_image->extent.height, 1}; - vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkCmdCopyBufferToImage(vk_buffer, src_buffer->buffer, dst_image->image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - set_image_layout(vk_buffer, dst_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(dst_layout)); + set_image_layout(vk_buffer, dst_image, 0, 1, VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast(dst_layout)); } -void Graphics::Vulkan::vulkanCreateBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, u64 size, HLE::Libs::Graphics::VulkanBuffer* buffer) { +void Graphics::Vulkan::vulkanCreateBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, u64 size, + HLE::Libs::Graphics::VulkanBuffer* buffer) { VkBufferCreateInfo buffer_info{}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = size; @@ -592,7 +635,8 @@ void Graphics::Vulkan::vulkanCreateBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, vkBindBufferMemory(ctx->m_device, buffer->buffer, buffer->memory.memory, buffer->memory.offset); } -void Graphics::Vulkan::vulkanDeleteBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanBuffer* buffer) { +void Graphics::Vulkan::vulkanDeleteBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanBuffer* buffer) { vkDestroyBuffer(ctx->m_device, buffer->buffer, nullptr); vkFreeMemory(ctx->m_device, buffer->memory.memory, nullptr); buffer->memory.memory = nullptr; diff --git a/src/vulkan_util.h b/src/vulkan_util.h index 550b9b00..2cd32c88 100644 --- a/src/vulkan_util.h +++ b/src/vulkan_util.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #include #include @@ -9,7 +9,7 @@ namespace Graphics::Vulkan { -constexpr int VULKAN_QUEUES_NUM = 11; // Total of the above +constexpr int VULKAN_QUEUES_NUM = 11; // Total of the above constexpr int VULKAN_QUEUE_GRAPHICS_NUM = 1; constexpr int VULKAN_QUEUE_TRANSFER_NUM = 1; constexpr int VULKAN_QUEUE_PRESENT_NUM = 1; @@ -21,20 +21,29 @@ constexpr int VULKAN_QUEUE_PRESENT = 10; void vulkanCreate(Emu::WindowCtx* ctx); void vulkanGetInstanceExtensions(Emu::VulkanExt* ext); -void vulkanFindCompatiblePhysicalDevice(VkInstance instance, VkSurfaceKHR surface, const std::vector& device_extensions, - Emu::VulkanSurfaceCapabilities* out_capabilities, VkPhysicalDevice* out_device, +void vulkanFindCompatiblePhysicalDevice(VkInstance instance, VkSurfaceKHR surface, + const std::vector& device_extensions, + Emu::VulkanSurfaceCapabilities* out_capabilities, + VkPhysicalDevice* out_device, Emu::VulkanQueues* out_queues); -VkDevice vulkanCreateDevice(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const Emu::VulkanExt* r, - const Emu::VulkanQueues& queues, const std::vector& device_extensions); +VkDevice vulkanCreateDevice(VkPhysicalDevice physical_device, VkSurfaceKHR surface, + const Emu::VulkanExt* r, const Emu::VulkanQueues& queues, + const std::vector& device_extensions); Emu::VulkanQueues vulkanFindQueues(VkPhysicalDevice device, VkSurfaceKHR surface); -void vulkanGetSurfaceCapabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface, Emu::VulkanSurfaceCapabilities* surfaceCap); +void vulkanGetSurfaceCapabilities(VkPhysicalDevice physical_device, VkSurfaceKHR surface, + Emu::VulkanSurfaceCapabilities* surfaceCap); void vulkanCreateQueues(HLE::Libs::Graphics::GraphicCtx* ctx, const Emu::VulkanQueues& queues); Emu::VulkanSwapchain vulkanCreateSwapchain(HLE::Libs::Graphics::GraphicCtx* ctx, u32 image_count); -void vulkanBlitImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanImage* src_image, Emu::VulkanSwapchain* dst_swapchain); -void vulkanFillImage(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanImage* dst_image, const void* src_data, u64 size, u32 src_pitch, - u64 dst_layout); -void vulkanBufferToImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanBuffer* src_buffer, u32 src_pitch, - HLE::Libs::Graphics::VulkanImage* dst_image, u64 dst_layout); -void vulkanCreateBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, u64 size, HLE::Libs::Graphics::VulkanBuffer* buffer); -void vulkanDeleteBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanBuffer* buffer); -}; // namespace Graphics::Vulkan +void vulkanBlitImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanImage* src_image, + Emu::VulkanSwapchain* dst_swapchain); +void vulkanFillImage(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanImage* dst_image, const void* src_data, u64 size, + u32 src_pitch, u64 dst_layout); +void vulkanBufferToImage(GPU::CommandBuffer* buffer, HLE::Libs::Graphics::VulkanBuffer* src_buffer, + u32 src_pitch, HLE::Libs::Graphics::VulkanImage* dst_image, + u64 dst_layout); +void vulkanCreateBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, u64 size, + HLE::Libs::Graphics::VulkanBuffer* buffer); +void vulkanDeleteBuffer(HLE::Libs::Graphics::GraphicCtx* ctx, + HLE::Libs::Graphics::VulkanBuffer* buffer); +}; // namespace Graphics::Vulkan