diff --git a/.gitmodules b/.gitmodules index e15f953e..6d889ed6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ [submodule "externals/zlib-ng-win"] path = externals/zlib-ng-win url = https://github.com/shadps4-emu/ext-zlib-ng-win.git +[submodule "third-party/spdlog"] + path = third-party/spdlog + url = https://github.com/gabime/spdlog diff --git a/CMakeLists.txt b/CMakeLists.txt index 0eb4ca75..a5201a0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,21 +172,7 @@ qt_add_resources(RESOURCE_FILES src/shadps4.qrc) ) endif() -set(COMMON src/common/logging/backend.cpp - src/common/logging/backend.h - src/common/logging/filter.cpp - src/common/logging/filter.h - src/common/logging/formatter.h - src/common/logging/log_entry.h - src/common/logging/log.h - src/common/logging/text_formatter.cpp - src/common/logging/text_formatter.h - src/common/logging/types.h - src/common/assert.cpp - src/common/assert.h - src/common/bounded_threadsafe_queue.h - src/common/concepts.h - src/common/debug.h +set(COMMON src/common/debug.h src/common/disassembler.cpp src/common/disassembler.h src/common/discord.cpp @@ -194,22 +180,22 @@ set(COMMON src/common/logging/backend.cpp src/common/endian.h src/common/io_file.cpp src/common/io_file.h - src/common/error.cpp - src/common/error.h src/common/native_clock.cpp src/common/native_clock.h - src/common/path_util.cpp - src/common/path_util.h src/common/rdtsc.cpp src/common/rdtsc.h src/common/singleton.h src/common/string_util.cpp src/common/string_util.h - src/common/thread.cpp - src/common/thread.h src/common/types.h src/common/uint128.h src/common/version.h + src/common/fs_file.cpp + src/common/fs_file.h + src/common/log.cpp + src/common/log.h + src/common/io_file.cpp + src/common/io_file.h ) set(CORE src/core/loader.cpp @@ -302,8 +288,6 @@ add_executable(shadps4 src/core/PS4/GPU/tile_manager.h src/core/hle/libraries/libkernel/time_management.cpp src/core/hle/libraries/libkernel/time_management.h - src/core/tls.cpp - src/core/tls.h ${COMMON} ${CORE} ${CRYPTO} @@ -314,7 +298,7 @@ endif() create_target_directory_groups(shadps4) -target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11) +target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 spdlog::spdlog) target_link_libraries(shadps4 PRIVATE discord-rpc vulkan-1 xxhash Zydis) if(NOT ENABLE_QT_GUI) diff --git a/src/Util/config.cpp b/src/Util/config.cpp index 3d202742..5c0d2803 100644 --- a/src/Util/config.cpp +++ b/src/Util/config.cpp @@ -12,22 +12,19 @@ namespace Config { bool isNeo = false; u32 screenWidth = 1280; u32 screenHeight = 720; -std::string logFilter; +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; } - -std::string getLogFilter() { - return logFilter; +u32 getLogLevel() { + return logLevel; } void load(const std::filesystem::path& path) { @@ -53,7 +50,7 @@ void load(const std::filesystem::path& path) { auto general = generalResult.unwrap(); isNeo = toml::find_or(general, "isPS4Pro", false); - logFilter = toml::find_or(general, "logFilter", ""); + logLevel = toml::find_or(general, "logLevel", false); } } if (data.contains("GPU")) { @@ -65,6 +62,7 @@ void load(const std::filesystem::path& path) { screenHeight = toml::find_or(general, "screenHeight", false); } } + int k = 0; } void save(const std::filesystem::path& path) { toml::basic_value data; @@ -86,7 +84,7 @@ void save(const std::filesystem::path& path) { } data["General"]["isPS4Pro"] = isNeo; - data["General"]["logFilter"] = logFilter; + data["General"]["logLevel"] = logLevel; data["GPU"]["screenWidth"] = screenWidth; data["GPU"]["screenHeight"] = screenHeight; diff --git a/src/Util/config.h b/src/Util/config.h index c2869049..9cd2e0c0 100644 --- a/src/Util/config.h +++ b/src/Util/config.h @@ -11,7 +11,7 @@ void load(const std::filesystem::path& path); void save(const std::filesystem::path& path); bool isNeoMode(); -std::string getLogFilter(); +u32 getLogLevel(); u32 getScreenWidth(); u32 getScreenHeight(); diff --git a/src/common/assert.cpp b/src/common/assert.cpp deleted file mode 100644 index 43b094c8..00000000 --- a/src/common/assert.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/logging/backend.h" - -#define Crash() __asm__ __volatile__("int $3") - -void assert_fail_impl() { - Common::Log::Stop(); - Crash(); -} - -[[noreturn]] void unreachable_impl() { - Common::Log::Stop(); - Crash(); - throw std::runtime_error("Unreachable code"); -} diff --git a/src/common/assert.h b/src/common/assert.h deleted file mode 100644 index dabeb111..00000000 --- a/src/common/assert.h +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/logging/log.h" - -// Sometimes we want to try to continue even after hitting an assert. -// However touching this file yields a global recompilation as this header is included almost -// everywhere. So let's just move the handling of the failed assert to a single cpp file. - -void assert_fail_impl(); -[[noreturn]] void unreachable_impl(); - -#ifdef _MSC_VER -#define SHAD_NO_INLINE __declspec(noinline) -#else -#define SHAD_NO_INLINE __attribute__((noinline)) -#endif - -#define ASSERT(_a_) \ - ([&]() SHAD_NO_INLINE { \ - if (!(_a_)) [[unlikely]] { \ - LOG_CRITICAL(Debug, "Assertion Failed!"); \ - assert_fail_impl(); \ - } \ - }()) - -#define ASSERT_MSG(_a_, ...) \ - ([&]() SHAD_NO_INLINE { \ - if (!(_a_)) [[unlikely]] { \ - LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ - assert_fail_impl(); \ - } \ - }()) - -#define UNREACHABLE() \ - do { \ - LOG_CRITICAL(Debug, "Unreachable code!"); \ - unreachable_impl(); \ - } while (0) - -#define UNREACHABLE_MSG(...) \ - do { \ - LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \ - unreachable_impl(); \ - } while (0) - -#ifdef _DEBUG -#define DEBUG_ASSERT(_a_) ASSERT(_a_) -#define DEBUG_ASSERT_MSG(_a_, ...) ASSERT_MSG(_a_, __VA_ARGS__) -#else // not debug -#define DEBUG_ASSERT(_a_) \ - do { \ - } while (0) -#define DEBUG_ASSERT_MSG(_a_, _desc_, ...) \ - do { \ - } while (0) -#endif - -#define UNIMPLEMENTED() ASSERT_MSG(false, "Unimplemented code!") -#define UNIMPLEMENTED_MSG(...) ASSERT_MSG(false, __VA_ARGS__) - -#define UNIMPLEMENTED_IF(cond) ASSERT_MSG(!(cond), "Unimplemented code!") -#define UNIMPLEMENTED_IF_MSG(cond, ...) ASSERT_MSG(!(cond), __VA_ARGS__) - -// If the assert is ignored, execute _b_ -#define ASSERT_OR_EXECUTE(_a_, _b_) \ - do { \ - ASSERT(_a_); \ - if (!(_a_)) [[unlikely]] { \ - _b_ \ - } \ - } while (0) - -// If the assert is ignored, execute _b_ -#define ASSERT_OR_EXECUTE_MSG(_a_, _b_, ...) \ - do { \ - ASSERT_MSG(_a_, __VA_ARGS__); \ - if (!(_a_)) [[unlikely]] { \ - _b_ \ - } \ - } while (0) diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h deleted file mode 100644 index 46e382f0..00000000 --- a/src/common/bounded_threadsafe_queue.h +++ /dev/null @@ -1,248 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace Common { - -namespace detail { -constexpr std::size_t DefaultCapacity = 0x1000; -} // namespace detail - -template -class SPSCQueue { - static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of two."); - -public: - template - bool TryEmplace(Args&&... args) { - return Emplace(std::forward(args)...); - } - - template - void EmplaceWait(Args&&... args) { - Emplace(std::forward(args)...); - } - - bool TryPop(T& t) { - return Pop(t); - } - - void PopWait(T& t) { - Pop(t); - } - - void PopWait(T& t, std::stop_token stop_token) { - Pop(t, stop_token); - } - - T PopWait() { - T t; - Pop(t); - return t; - } - - T PopWait(std::stop_token stop_token) { - T t; - Pop(t, stop_token); - return t; - } - -private: - enum class PushMode { - Try, - Wait, - Count, - }; - - enum class PopMode { - Try, - Wait, - WaitWithStopToken, - Count, - }; - - template - bool Emplace(Args&&... args) { - const std::size_t write_index = m_write_index.load(std::memory_order::relaxed); - - if constexpr (Mode == PushMode::Try) { - // Check if we have free slots to write to. - if ((write_index - m_read_index.load(std::memory_order::acquire)) == Capacity) { - return false; - } - } else if constexpr (Mode == PushMode::Wait) { - // Wait until we have free slots to write to. - std::unique_lock lock{producer_cv_mutex}; - producer_cv.wait(lock, [this, write_index] { - return (write_index - m_read_index.load(std::memory_order::acquire)) < Capacity; - }); - } else { - static_assert(Mode < PushMode::Count, "Invalid PushMode."); - } - - // Determine the position to write to. - const std::size_t pos = write_index % Capacity; - - // Emplace into the queue. - new (std::addressof(m_data[pos])) T(std::forward(args)...); - - // Increment the write index. - ++m_write_index; - - // Notify the consumer that we have pushed into the queue. - std::scoped_lock lock{consumer_cv_mutex}; - consumer_cv.notify_one(); - - return true; - } - - template - bool Pop(T& t, [[maybe_unused]] std::stop_token stop_token = {}) { - const std::size_t read_index = m_read_index.load(std::memory_order::relaxed); - - if constexpr (Mode == PopMode::Try) { - // Check if the queue is empty. - if (read_index == m_write_index.load(std::memory_order::acquire)) { - return false; - } - } else if constexpr (Mode == PopMode::Wait) { - // Wait until the queue is not empty. - std::unique_lock lock{consumer_cv_mutex}; - consumer_cv.wait(lock, [this, read_index] { - return read_index != m_write_index.load(std::memory_order::acquire); - }); - } else if constexpr (Mode == PopMode::WaitWithStopToken) { - // Wait until the queue is not empty. - std::unique_lock lock{consumer_cv_mutex}; - consumer_cv.wait(lock, stop_token, [this, read_index] { - return read_index != m_write_index.load(std::memory_order::acquire); - }); - if (stop_token.stop_requested()) { - return false; - } - } else { - static_assert(Mode < PopMode::Count, "Invalid PopMode."); - } - - // Determine the position to read from. - const std::size_t pos = read_index % Capacity; - - // Pop the data off the queue, moving it. - t = std::move(m_data[pos]); - - // Increment the read index. - ++m_read_index; - - // Notify the producer that we have popped off the queue. - std::scoped_lock lock{producer_cv_mutex}; - producer_cv.notify_one(); - - return true; - } - - alignas(128) std::atomic_size_t m_read_index{0}; - alignas(128) std::atomic_size_t m_write_index{0}; - - std::array m_data; - - std::condition_variable_any producer_cv; - std::mutex producer_cv_mutex; - std::condition_variable_any consumer_cv; - std::mutex consumer_cv_mutex; -}; - -template -class MPSCQueue { -public: - template - bool TryEmplace(Args&&... args) { - std::scoped_lock lock{write_mutex}; - return spsc_queue.TryEmplace(std::forward(args)...); - } - - template - void EmplaceWait(Args&&... args) { - std::scoped_lock lock{write_mutex}; - spsc_queue.EmplaceWait(std::forward(args)...); - } - - bool TryPop(T& t) { - return spsc_queue.TryPop(t); - } - - void PopWait(T& t) { - spsc_queue.PopWait(t); - } - - void PopWait(T& t, std::stop_token stop_token) { - spsc_queue.PopWait(t, stop_token); - } - - T PopWait() { - return spsc_queue.PopWait(); - } - - T PopWait(std::stop_token stop_token) { - return spsc_queue.PopWait(stop_token); - } - -private: - SPSCQueue spsc_queue; - std::mutex write_mutex; -}; - -template -class MPMCQueue { -public: - template - bool TryEmplace(Args&&... args) { - std::scoped_lock lock{write_mutex}; - return spsc_queue.TryEmplace(std::forward(args)...); - } - - template - void EmplaceWait(Args&&... args) { - std::scoped_lock lock{write_mutex}; - spsc_queue.EmplaceWait(std::forward(args)...); - } - - bool TryPop(T& t) { - std::scoped_lock lock{read_mutex}; - return spsc_queue.TryPop(t); - } - - void PopWait(T& t) { - std::scoped_lock lock{read_mutex}; - spsc_queue.PopWait(t); - } - - void PopWait(T& t, std::stop_token stop_token) { - std::scoped_lock lock{read_mutex}; - spsc_queue.PopWait(t, stop_token); - } - - T PopWait() { - std::scoped_lock lock{read_mutex}; - return spsc_queue.PopWait(); - } - - T PopWait(std::stop_token stop_token) { - std::scoped_lock lock{read_mutex}; - return spsc_queue.PopWait(stop_token); - } - -private: - SPSCQueue spsc_queue; - std::mutex write_mutex; - std::mutex read_mutex; -}; - -} // namespace Common diff --git a/src/common/error.cpp b/src/common/error.cpp deleted file mode 100644 index a1125b6e..00000000 --- a/src/common/error.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#ifdef _WIN32 -#include -#else -#include -#include -#endif - -#include "common/error.h" - -namespace Common { - -std::string NativeErrorToString(int e) { -#ifdef _WIN32 - LPSTR err_str; - - DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast(&err_str), 1, nullptr); - if (!res) { - return "(FormatMessageA failed to format error)"; - } - std::string ret(err_str); - LocalFree(err_str); - return ret; -#else - char err_str[255]; -#if defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) || \ - defined(ANDROID) - // Thread safe (GNU-specific) - const char* str = strerror_r(e, err_str, sizeof(err_str)); - return std::string(str); -#else - // Thread safe (XSI-compliant) - int second_err = strerror_r(e, err_str, sizeof(err_str)); - if (second_err != 0) { - return "(strerror_r failed to format error)"; - } - return std::string(err_str); -#endif // GLIBC etc. -#endif // _WIN32 -} - -std::string GetLastErrorMsg() { -#ifdef _WIN32 - return NativeErrorToString(GetLastError()); -#else - return NativeErrorToString(errno); -#endif -} - -} // namespace Common diff --git a/src/common/error.h b/src/common/error.h deleted file mode 100644 index 62a3bd83..00000000 --- a/src/common/error.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -namespace Common { - -// Generic function to get last error message. -// Call directly after the command or use the error num. -// This function might change the error code. -// Defined in error.cpp. -[[nodiscard]] std::string GetLastErrorMsg(); - -// Like GetLastErrorMsg(), but passing an explicit error code. -// Defined in error.cpp. -[[nodiscard]] std::string NativeErrorToString(int e); - -} // namespace Common diff --git a/src/common/fs_file.cpp b/src/common/fs_file.cpp new file mode 100644 index 00000000..3875b9ac --- /dev/null +++ b/src/common/fs_file.cpp @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/fs_file.h" + +namespace Common::FS { + +File::File() = default; + +File::File(const std::string& path, OpenMode mode) { + open(path, mode); +} + +File::~File() { + close(); +} + +bool File::open(const std::string& path, OpenMode mode) { + close(); +#ifdef _WIN64 + fopen_s(&m_file, path.c_str(), getOpenMode(mode)); +#else + m_file = std::fopen(path.c_str(), getOpenMode(mode)); +#endif + return isOpen(); +} + +bool File::close() { + if (!isOpen() || std::fclose(m_file) != 0) [[unlikely]] { + m_file = nullptr; + return false; + } + + m_file = nullptr; + return true; +} + +bool File::write(std::span data) { + return isOpen() && std::fwrite(data.data(), 1, data.size(), m_file) == data.size(); +} + +bool File::read(void* data, u64 size) const { + return isOpen() && std::fread(data, 1, size, m_file) == size; +} + +bool File::seek(s64 offset, SeekMode mode) { +#ifdef _WIN64 + if (!isOpen() || _fseeki64(m_file, offset, getSeekMode(mode)) != 0) { + return false; + } +#else + if (!isOpen() || fseeko64(m_file, offset, getSeekMode(mode)) != 0) { + return false; + } +#endif + return true; +} + +u64 File::tell() const { + if (isOpen()) [[likely]] { +#ifdef _WIN64 + return _ftelli64(m_file); +#else + return ftello64(m_file); +#endif + } + + return -1; +} + +u64 File::getFileSize() { +#ifdef _WIN64 + const u64 pos = _ftelli64(m_file); + if (_fseeki64(m_file, 0, SEEK_END) != 0) { + return 0; + } + + const u64 size = _ftelli64(m_file); + if (_fseeki64(m_file, pos, SEEK_SET) != 0) { + return 0; + } +#else + const u64 pos = ftello64(m_file); + if (fseeko64(m_file, 0, SEEK_END) != 0) { + return 0; + } + + const u64 size = ftello64(m_file); + if (fseeko64(m_file, pos, SEEK_SET) != 0) { + return 0; + } +#endif + return size; +} + +} // namespace Common::FS diff --git a/src/common/fs_file.h b/src/common/fs_file.h new file mode 100644 index 00000000..d6a63db9 --- /dev/null +++ b/src/common/fs_file.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#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 SeekMode : u32 { + Set, + Cur, + End, +}; + +class File { +public: + File(); + explicit File(const std::string& path, OpenMode mode = OpenMode::Read); + ~File(); + + bool open(const std::string& path, OpenMode mode = OpenMode::Read); + bool close(); + bool read(void* data, u64 size) const; + bool write(std::span data); + bool seek(s64 offset, SeekMode mode); + u64 getFileSize(); + u64 tell() const; + + template + bool read(T& data) const { + return read(&data, sizeof(T)); + } + + template + bool read(std::vector& data) const { + return read(data.data(), data.size() * sizeof(T)); + } + + bool isOpen() const { + return m_file != nullptr; + } + + 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"; + } + } + + 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; + } + } + + [[nodiscard]] std::FILE* fileDescr() const { + return m_file; + } + +private: + std::FILE* m_file{}; +}; + +} // namespace Common::FS diff --git a/src/common/io_file.cpp b/src/common/io_file.cpp index fda3353e..b7fd8838 100644 --- a/src/common/io_file.cpp +++ b/src/common/io_file.cpp @@ -4,8 +4,8 @@ #include #include "common/io_file.h" -#include "common/logging/log.h" -#include "common/path_util.h" +// #include "common/logging/log.h" +// #include "common/path_util.h" #ifdef _WIN32 #include @@ -184,8 +184,8 @@ void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, File if (!IsOpen()) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, ec_message={}", - PathToUTF8String(file_path), ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, ec_message={}", + // PathToUTF8String(file_path), ec.message()); } } @@ -200,8 +200,8 @@ void IOFile::Close() { if (!close_result) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, "Failed to close the file at path={}, ec_message={}", - PathToUTF8String(file_path), ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to close the file at path={}, ec_message={}", + // PathToUTF8String(file_path), ec.message()); } file = nullptr; @@ -231,8 +231,8 @@ bool IOFile::Flush() const { if (!flush_result) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}", - PathToUTF8String(file_path), ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}", + // PathToUTF8String(file_path), ec.message()); } return flush_result; @@ -253,8 +253,8 @@ bool IOFile::Commit() const { if (!commit_result) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, "Failed to commit the file at path={}, ec_message={}", - PathToUTF8String(file_path), ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to commit the file at path={}, ec_message={}", + // PathToUTF8String(file_path), ec.message()); } return commit_result; @@ -275,8 +275,9 @@ bool IOFile::SetSize(u64 size) const { if (!set_size_result) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, "Failed to resize the file at path={}, size={}, ec_message={}", - PathToUTF8String(file_path), size, ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to resize the file at path={}, size={}, + // ec_message={}", + // PathToUTF8String(file_path), size, ec.message()); } return set_size_result; @@ -295,8 +296,9 @@ u64 IOFile::GetSize() const { const auto file_size = fs::file_size(file_path, ec); if (ec) { - LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}", - PathToUTF8String(file_path), ec.message()); + // LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, + // ec_message={}", + // PathToUTF8String(file_path), ec.message()); return 0; } @@ -314,9 +316,9 @@ bool IOFile::Seek(s64 offset, SeekOrigin origin) const { if (!seek_result) { const auto ec = std::error_code{errno, std::generic_category()}; - LOG_ERROR(Common_Filesystem, - "Failed to seek the file at path={}, offset={}, origin={}, ec_message={}", - PathToUTF8String(file_path), offset, static_cast(origin), ec.message()); + // LOG_ERROR(Common_Filesystem, + // "Failed to seek the file at path={}, offset={}, origin={}, ec_message={}", + // PathToUTF8String(file_path), offset, static_cast(origin), ec.message()); } return seek_result; diff --git a/src/common/log.cpp b/src/common/log.cpp new file mode 100644 index 00000000..3ad797ba --- /dev/null +++ b/src/common/log.cpp @@ -0,0 +1,159 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include +#include +#include "common/log.h" +#ifdef _WIN64 +#include +#endif + +namespace Common::Log { + +std::vector sinks; +constexpr bool log_file_exceptions = true; + +void Flush() { + spdlog::details::registry::instance().flush_all(); +} + +thread_local uint8_t TLS[1024]; + +uint64_t tls_access(int64_t tls_offset) { + if (tls_offset == 0) { + return (uint64_t)TLS; + } +} + +#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++; + + 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); + else + 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; + + return EXCEPTION_CONTINUE_EXECUTION; + } + + 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; + } + 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) { + sinks.push_back(std::make_shared()); + } +#ifdef _WIN64 + sinks.push_back(std::make_shared(L"shadps4.txt", true)); +#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_formatter(std::move(f)); + spdlog::set_level(static_cast(Config::getLogLevel())); + +#ifdef _WIN64 + if (!AddVectoredExceptionHandler(0, ExceptionHandler)) { + LOG_CRITICAL_IF(log_file_exceptions, "Failed to register an exception handler"); + } +#endif + + static std::terminate_handler old_terminate = nullptr; + old_terminate = std::set_terminate([]() { + try { + std::rethrow_exception(std::current_exception()); + } 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(); + }); + + return 0; +} + +void SetLevel(spdlog::level::level_enum log_level) { + spdlog::set_level(log_level); +} + +} // namespace Common::Log diff --git a/src/common/log.h b/src/common/log.h new file mode 100644 index 00000000..089cdcbd --- /dev/null +++ b/src/common/log.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE + +#include + +namespace Common::Log { + +#define LOG_TRACE SPDLOG_TRACE +#define LOG_DEBUG SPDLOG_DEBUG +#define LOG_INFO SPDLOG_INFO +#define LOG_WARN SPDLOG_WARN +#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__) + +int Init(bool use_stdout); + +void SetLevel(spdlog::level::level_enum log_level); + +} // namespace Common::Log diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp deleted file mode 100644 index 50d18c98..00000000 --- a/src/common/logging/backend.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include - -#include -#include "Util/config.h" - -#ifdef _WIN32 -#include // For OutputDebugStringW -#endif - -#include "common/bounded_threadsafe_queue.h" -#include "common/io_file.h" -#include "common/logging/backend.h" -#include "common/logging/log.h" -#include "common/logging/log_entry.h" -#include "common/logging/text_formatter.h" -#include "common/path_util.h" -#include "common/string_util.h" -#include "common/thread.h" - -namespace Common::Log { - -using namespace Common::FS; - -namespace { - -/** - * Backend that writes to stderr and with color - */ -class ColorConsoleBackend { -public: - explicit ColorConsoleBackend() = default; - - ~ColorConsoleBackend() = default; - - void Write(const Entry& entry) { - if (enabled.load(std::memory_order_relaxed)) { - PrintColoredMessage(entry); - } - } - - void Flush() { - // stderr shouldn't be buffered - } - - void SetEnabled(bool enabled_) { - enabled = enabled_; - } - -private: - std::atomic_bool enabled{true}; -}; - -/** - * Backend that writes to a file passed into the constructor - */ -class FileBackend { -public: - explicit FileBackend(const std::filesystem::path& filename) - : file{filename, FS::FileAccessMode::Write, FS::FileType::TextFile} {} - - ~FileBackend() = default; - - void Write(const Entry& entry) { - if (!enabled) { - return; - } - - bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n')); - - // Prevent logs from exceeding a set maximum size in the event that log entries are spammed. - const auto write_limit = 100_MB; - const bool write_limit_exceeded = bytes_written > write_limit; - if (entry.log_level >= Level::Error || write_limit_exceeded) { - if (write_limit_exceeded) { - // Stop writing after the write limit is exceeded. - // Don't close the file so we can print a stacktrace if necessary - enabled = false; - } - file.Flush(); - } - } - - void Flush() { - file.Flush(); - } - -private: - Common::FS::IOFile file; - bool enabled = true; - std::size_t bytes_written = 0; -}; - -/** - * Backend that writes to Visual Studio's output window - */ -class DebuggerBackend { -public: - explicit DebuggerBackend() = default; - - ~DebuggerBackend() = default; - - void Write(const Entry& entry) { -#ifdef _WIN32 - ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); -#endif - } - - void Flush() {} - - void EnableForStacktrace() {} -}; - -bool initialization_in_progress_suppress_logging = true; - -/** - * Static state as a singleton. - */ -class Impl { -public: - static Impl& Instance() { - if (!instance) { - throw std::runtime_error("Using Logging instance before its initialization"); - } - return *instance; - } - - static void Initialize(std::string_view log_file) { - if (instance) { - LOG_WARNING(Log, "Reinitializing logging backend"); - return; - } - const auto& log_dir = GetUserPath(PathType::LogDir); - std::filesystem::create_directory(log_dir); - Filter filter; - filter.ParseFilterString(Config::getLogFilter()); - instance = std::unique_ptr(new Impl(log_dir / LOG_FILE, filter), - Deleter); - initialization_in_progress_suppress_logging = false; - } - - static void Start() { - instance->StartBackendThread(); - } - - static void Stop() { - instance->StopBackendThread(); - } - - Impl(const Impl&) = delete; - Impl& operator=(const Impl&) = delete; - - Impl(Impl&&) = delete; - Impl& operator=(Impl&&) = delete; - - void SetGlobalFilter(const Filter& f) { - filter = f; - } - - void SetColorConsoleBackendEnabled(bool enabled) { - color_console_backend.SetEnabled(enabled); - } - - void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, std::string message) { - if (!filter.CheckMessage(log_class, log_level)) { - return; - } - - using std::chrono::duration_cast; - using std::chrono::microseconds; - using std::chrono::steady_clock; - - message_queue.EmplaceWait(Entry{ - .timestamp = duration_cast(steady_clock::now() - time_origin), - .log_class = log_class, - .log_level = log_level, - .filename = filename, - .line_num = line_num, - .function = function, - .message = std::move(message), - }); - } - -private: - Impl(const std::filesystem::path& file_backend_filename, const Filter& filter_) - : filter{filter_}, file_backend{file_backend_filename} {} - - ~Impl() = default; - - void StartBackendThread() { - backend_thread = std::jthread([this](std::stop_token stop_token) { - Common::SetCurrentThreadName("shadPS4:Log"); - Entry entry; - const auto write_logs = [this, &entry]() { - ForEachBackend([&entry](auto& backend) { backend.Write(entry); }); - }; - while (!stop_token.stop_requested()) { - message_queue.PopWait(entry, stop_token); - if (entry.filename != nullptr) { - write_logs(); - } - } - // Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a - // case where a system is repeatedly spamming logs even on close. - int max_logs_to_write = filter.IsDebug() ? std::numeric_limits::max() : 100; - while (max_logs_to_write-- && message_queue.TryPop(entry)) { - write_logs(); - } - }); - } - - void StopBackendThread() { - backend_thread.request_stop(); - if (backend_thread.joinable()) { - backend_thread.join(); - } - - ForEachBackend([](auto& backend) { backend.Flush(); }); - } - - void ForEachBackend(auto lambda) { - lambda(debugger_backend); - lambda(color_console_backend); - lambda(file_backend); - } - - static void Deleter(Impl* ptr) { - delete ptr; - } - - static inline std::unique_ptr instance{nullptr, Deleter}; - - Filter filter; - DebuggerBackend debugger_backend{}; - ColorConsoleBackend color_console_backend{}; - FileBackend file_backend; - - MPSCQueue message_queue{}; - std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; - std::jthread backend_thread; -}; -} // namespace - -void Initialize(std::string_view log_file) { - Impl::Initialize(log_file.empty() ? LOG_FILE : log_file); -} - -void Start() { - Impl::Start(); -} - -void Stop() { - Impl::Stop(); -} - -void SetGlobalFilter(const Filter& filter) { - Impl::Instance().SetGlobalFilter(filter); -} - -void SetColorConsoleBackendEnabled(bool enabled) { - Impl::Instance().SetColorConsoleBackendEnabled(enabled); -} - -void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, - unsigned int line_num, const char* function, const char* format, - const fmt::format_args& args) { - if (!initialization_in_progress_suppress_logging) [[likely]] { - Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function, - fmt::vformat(format, args)); - } -} -} // namespace Common::Log diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h deleted file mode 100644 index 91c9da83..00000000 --- a/src/common/logging/backend.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "common/logging/filter.h" - -namespace Common::Log { - -class Filter; - -/// Initializes the logging system. This should be the first thing called in main. -void Initialize(std::string_view log_file = ""); - -/// Starts the logging threads. -void Start(); - -/// Explictily stops the logger thread and flushes the buffers -void Stop(); - -/// The global filter will prevent any messages from even being processed if they are filtered. -void SetGlobalFilter(const Filter& filter); - -void SetColorConsoleBackendEnabled(bool enabled); - -} // namespace Common::Log diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp deleted file mode 100644 index 04c5d7ef..00000000 --- a/src/common/logging/filter.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include "common/assert.h" -#include "common/logging/filter.h" - -namespace Common::Log { -namespace { -template -Level GetLevelByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Level::Count); ++i) { - const char* level_name = GetLevelName(static_cast(i)); - if (std::string_view(begin, end).compare(level_name) == 0) { - return static_cast(i); - } - } - return Level::Count; -} - -template -Class GetClassByName(const It begin, const It end) { - for (u8 i = 0; i < static_cast(Class::Count); ++i) { - const char* level_name = GetLogClassName(static_cast(i)); - if (std::string_view(begin, end).compare(level_name) == 0) { - return static_cast(i); - } - } - return Class::Count; -} - -template -bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { - auto level_separator = std::find(begin, end, ':'); - if (level_separator == end) { - LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}", - std::string_view(begin, end)); - return false; - } - - const Level level = GetLevelByName(level_separator + 1, end); - if (level == Level::Count) { - LOG_ERROR(Log, "Unknown log level in filter: {}", std::string_view(begin, end)); - return false; - } - - if (std::string_view(begin, level_separator).compare("*") == 0) { - instance.ResetAll(level); - return true; - } - - const Class log_class = GetClassByName(begin, level_separator); - if (log_class == Class::Count) { - LOG_ERROR(Log, "Unknown log class in filter: {}", std::string(begin, end)); - return false; - } - - instance.SetClassLevel(log_class, level); - return true; -} -} // Anonymous namespace - -/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. -#define ALL_LOG_CLASSES() \ - CLS(Log) \ - CLS(Common) \ - SUB(Common, Filesystem) \ - SUB(Common, Memory) \ - CLS(Core) \ - SUB(Core, Linker) \ - CLS(Config) \ - CLS(Debug) \ - CLS(Kernel) \ - SUB(Kernel, Pthread) \ - SUB(Kernel, Vmm) \ - SUB(Kernel, Fs) \ - SUB(Kernel, Event) \ - SUB(Kernel, Sce) \ - CLS(Lib) \ - SUB(Lib, LibC) \ - SUB(Lib, Kernel) \ - SUB(Lib, Pad) \ - SUB(Lib, GnmDriver) \ - SUB(Lib, SystemService) \ - SUB(Lib, UserService) \ - SUB(Lib, VideoOut) \ - CLS(Frontend) \ - CLS(Render) \ - SUB(Render, Vulkan) \ - CLS(Input) \ - CLS(Loader) - -// GetClassName is a macro defined by Windows.h, grrr... -const char* GetLogClassName(Class log_class) { - switch (log_class) { -#define CLS(x) \ - case Class::x: \ - return #x; -#define SUB(x, y) \ - case Class::x##_##y: \ - return #x "." #y; - ALL_LOG_CLASSES() -#undef CLS -#undef SUB - case Class::Count: - default: - break; - } - UNREACHABLE(); -} - -const char* GetLevelName(Level log_level) { -#define LVL(x) \ - case Level::x: \ - return #x - switch (log_level) { - LVL(Trace); - LVL(Debug); - LVL(Info); - LVL(Warning); - LVL(Error); - LVL(Critical); - case Level::Count: - default: - break; - } -#undef LVL - UNREACHABLE(); -} - -Filter::Filter(Level default_level) { - ResetAll(default_level); -} - -void Filter::ResetAll(Level level) { - class_levels.fill(level); -} - -void Filter::SetClassLevel(Class log_class, Level level) { - class_levels[static_cast(log_class)] = level; -} - -void Filter::ParseFilterString(std::string_view filter_view) { - auto clause_begin = filter_view.cbegin(); - while (clause_begin != filter_view.cend()) { - auto clause_end = std::find(clause_begin, filter_view.cend(), ' '); - - // If clause isn't empty - if (clause_end != clause_begin) { - ParseFilterRule(*this, clause_begin, clause_end); - } - - if (clause_end != filter_view.cend()) { - // Skip over the whitespace - ++clause_end; - } - clause_begin = clause_end; - } -} - -bool Filter::CheckMessage(Class log_class, Level level) const { - return static_cast(level) >= - static_cast(class_levels[static_cast(log_class)]); -} - -bool Filter::IsDebug() const { - return std::any_of(class_levels.begin(), class_levels.end(), [](const Level& l) { - return static_cast(l) <= static_cast(Level::Debug); - }); -} - -} // namespace Common::Log diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h deleted file mode 100644 index 7c46fd82..00000000 --- a/src/common/logging/filter.h +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include "common/logging/types.h" - -namespace Common::Log { - -/** - * Returns the name of the passed log class as a C-string. Subclasses are separated by periods - * instead of underscores as in the enumeration. - */ -const char* GetLogClassName(Class log_class); - -/** - * Returns the name of the passed log level as a C-string. - */ -const char* GetLevelName(Level log_level); - -/** - * Implements a log message filter which allows different log classes to have different minimum - * severity levels. The filter can be changed at runtime and can be parsed from a string to allow - * editing via the interface or loading from a configuration file. - */ -class Filter { -public: - /// Initializes the filter with all classes having `default_level` as the minimum level. - explicit Filter(Level default_level = Level::Info); - - /// Resets the filter so that all classes have `level` as the minimum displayed level. - void ResetAll(Level level); - - /// Sets the minimum level of `log_class` (and not of its subclasses) to `level`. - void SetClassLevel(Class log_class, Level level); - - /** - * Parses a filter string and applies it to this filter. - * - * A filter string consists of a space-separated list of filter rules, each of the format - * `:`. `` is a log class name, with subclasses separated using periods. - * `*` is allowed as a class name and will reset all filters to the specified level. `` - * a severity level name which will be set as the minimum logging level of the matched classes. - * Rules are applied left to right, with each rule overriding previous ones in the sequence. - * - * A few examples of filter rules: - * - `*:Info` -- Resets the level of all classes to Info. - * - `Service:Info` -- Sets the level of Service to Info. - * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. - */ - void ParseFilterString(std::string_view filter_view); - - /// Matches class/level combination against the filter, returning true if it passed. - bool CheckMessage(Class log_class, Level level) const; - - /// Returns true if any logging classes are set to debug - bool IsDebug() const; - -private: - std::array(Class::Count)> class_levels; -}; - -} // namespace Common::Log diff --git a/src/common/logging/formatter.h b/src/common/logging/formatter.h deleted file mode 100644 index f80905cc..00000000 --- a/src/common/logging/formatter.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -// Adapted from https://github.com/fmtlib/fmt/issues/2704 -// a generic formatter for enum classes -#if FMT_VERSION >= 80100 -template -struct fmt::formatter, char>> - : formatter> { - template - auto format(const T& value, FormatContext& ctx) -> decltype(ctx.out()) { - return fmt::formatter>::format( - static_cast>(value), ctx); - } -}; -#endif diff --git a/src/common/logging/log.h b/src/common/logging/log.h deleted file mode 100644 index 5fa43034..00000000 --- a/src/common/logging/log.h +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include - -#include "common/logging/formatter.h" -#include "common/logging/types.h" - -namespace Common::Log { - -constexpr const char* TrimSourcePath(std::string_view source) { - const auto rfind = [source](const std::string_view match) { - return source.rfind(match) == source.npos ? 0 : (source.rfind(match) + match.size()); - }; - auto idx = std::max({rfind("/"), rfind("\\")}); - return source.data() + idx; -} - -/// Logs a message to the global logger, using fmt -void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, - unsigned int line_num, const char* function, const char* format, - const fmt::format_args& args); - -template -void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num, - const char* function, const char* format, const Args&... args) { - FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format, - fmt::make_format_args(args...)); -} - -} // namespace Common::Log - -// Define the fmt lib macros -#define LOG_GENERIC(log_class, log_level, ...) \ - Common::Log::FmtLogMessage(log_class, log_level, Common::Log::TrimSourcePath(__FILE__), \ - __LINE__, __func__, __VA_ARGS__) - -#ifdef _DEBUG -#define LOG_TRACE(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) -#else -#define LOG_TRACE(log_class, fmt, ...) (void(0)) -#endif - -#define LOG_DEBUG(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) -#define LOG_INFO(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) -#define LOG_WARNING(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) -#define LOG_ERROR(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) -#define LOG_CRITICAL(log_class, ...) \ - Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \ - Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \ - __VA_ARGS__) diff --git a/src/common/logging/log_entry.h b/src/common/logging/log_entry.h deleted file mode 100644 index cd4ae935..00000000 --- a/src/common/logging/log_entry.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -#include "common/logging/types.h" - -namespace Common::Log { - -/** - * A log entry. Log entries are store in a structured format to permit more varied output - * formatting on different frontends, as well as facilitating filtering and aggregation. - */ -struct Entry { - std::chrono::microseconds timestamp; - Class log_class{}; - Level log_level{}; - const char* filename = nullptr; - u32 line_num = 0; - std::string function; - std::string message; -}; - -} // namespace Common::Log diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp deleted file mode 100644 index 5f6c2172..00000000 --- a/src/common/logging/text_formatter.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include "common/assert.h" -#include "common/logging/filter.h" -#include "common/logging/log.h" -#include "common/logging/log_entry.h" -#include "common/logging/text_formatter.h" - -namespace Common::Log { - -std::string FormatLogMessage(const Entry& entry) { - const u32 time_seconds = static_cast(entry.timestamp.count() / 1000000); - const u32 time_fractional = static_cast(entry.timestamp.count() % 1000000); - - const char* class_name = GetLogClassName(entry.log_class); - const char* level_name = GetLevelName(entry.log_level); - - return fmt::format("[{}] <{}> {}:{}:{}: {}", class_name, level_name, entry.filename, - entry.function, entry.line_num, entry.message); -} - -void PrintMessage(const Entry& entry) { - const auto str = FormatLogMessage(entry).append(1, '\n'); - fputs(str.c_str(), stdout); -} - -void PrintColoredMessage(const Entry& entry) { -#ifdef _WIN32 - HANDLE console_handle = GetStdHandle(STD_ERROR_HANDLE); - if (console_handle == INVALID_HANDLE_VALUE) { - return; - } - - CONSOLE_SCREEN_BUFFER_INFO original_info{}; - GetConsoleScreenBufferInfo(console_handle, &original_info); - - WORD color = 0; - switch (entry.log_level) { - case Level::Trace: // Grey - color = FOREGROUND_INTENSITY; - break; - case Level::Debug: // Cyan - color = FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Info: // Bright gray - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - break; - case Level::Warning: // Bright yellow - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - break; - case Level::Error: // Bright red - color = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case Level::Critical: // Bright magenta - color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case Level::Count: - UNREACHABLE(); - } - - SetConsoleTextAttribute(console_handle, color); -#else -#define ESC "\x1b" - const char* color = ""; - switch (entry.log_level) { - case Level::Trace: // Grey - color = ESC "[1;30m"; - break; - case Level::Debug: // Cyan - color = ESC "[0;36m"; - break; - case Level::Info: // Bright gray - color = ESC "[0;37m"; - break; - case Level::Warning: // Bright yellow - color = ESC "[1;33m"; - break; - case Level::Error: // Bright red - color = ESC "[1;31m"; - break; - case Level::Critical: // Bright magenta - color = ESC "[1;35m"; - break; - case Level::Count: - UNREACHABLE(); - } - - fputs(color, stdout); -#endif - - PrintMessage(entry); - -#ifdef _WIN32 - SetConsoleTextAttribute(console_handle, original_info.wAttributes); -#else - fputs(ESC "[0m", stdout); -#undef ESC -#endif -} - -} // namespace Common::Log diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h deleted file mode 100644 index 504d8639..00000000 --- a/src/common/logging/text_formatter.h +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include - -namespace Common::Log { - -struct Entry; - -/// Formats a log entry into the provided text buffer. -std::string FormatLogMessage(const Entry& entry); - -/// Formats and prints a log entry to stderr. -void PrintMessage(const Entry& entry); - -/// Prints the same message as `PrintMessage`, but colored according to the severity level. -void PrintColoredMessage(const Entry& entry); - -} // namespace Common::Log diff --git a/src/common/logging/types.h b/src/common/logging/types.h deleted file mode 100644 index f9ee22fb..00000000 --- a/src/common/logging/types.h +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/types.h" - -namespace Common::Log { - -/// Specifies the severity or level of detail of the log message. -enum class Level : u8 { - Trace, ///< Extremely detailed and repetitive debugging information that is likely to - ///< pollute logs. - Debug, ///< Less detailed debugging information. - Info, ///< Status information from important points during execution. - Warning, ///< Minor or potential problems found during execution of a task. - Error, ///< Major problems found during execution of a task that prevent it from being - ///< completed. - Critical, ///< Major problems during execution that threaten the stability of the entire - ///< application. - - Count, ///< Total number of logging levels -}; - -/** - * Specifies the sub-system that generated the log message. - * - * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in - * backend.cpp. - */ -enum class Class : u8 { - Log, ///< Messages about the log system itself - Common, ///< Library routines - Common_Filesystem, ///< Filesystem interface library - Common_Memory, ///< Memory mapping and management functions - Core, ///< LLE emulation core - Core_Linker, ///< The module linker - Config, ///< Emulator configuration (including commandline) - Debug, ///< Debugging tools - Kernel, ///< The HLE implementation of the PS4 kernel. - Kernel_Pthread, ///< The pthread implementation of the kernel. - Kernel_Fs, ///< The filesystem implementation of the kernel. - Kernel_Vmm, ///< The virtual memory implementation of the kernel. - Kernel_Event, ///< The event management implementation of the kernel. - Kernel_Sce, ///< The sony specific interfaces provided by the kernel. - Lib, ///< HLE implementation of system library. Each major library - ///< should have its own subclass. - Lib_LibC, ///< The LibC implementation. - Lib_Kernel, ///< The LibKernel implementation. - Lib_Pad, ///< The LibScePad implementation. - Lib_GnmDriver, ///< The LibSceGnmDriver implementation. - Lib_SystemService, ///< The LibSceSystemService implementation. - Lib_UserService, ///< The LibSceUserService implementation. - Lib_VideoOut, ///< The LibSceVideoOut implementation. - Frontend, ///< Emulator UI - Render, ///< Video Core - Render_Vulkan, ///< Vulkan backend - Loader, ///< ROM loader - Input, ///< Input emulation - Count ///< Total number of logging classes -}; - -} // namespace Common::Log diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp deleted file mode 100644 index 16ece313..00000000 --- a/src/common/path_util.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include - -#include "common/logging/log.h" -#include "common/path_util.h" - -#ifndef MAX_PATH -#ifdef _WIN32 -// This is the maximum number of UTF-16 code units permissible in Windows file paths -#define MAX_PATH 260 -#else -// This is the maximum number of UTF-8 code units permissible in all other OSes' file paths -#define MAX_PATH 1024 -#endif -#endif - -namespace Common::FS { - -namespace fs = std::filesystem; - -static auto UserPaths = [] { - std::unordered_map paths; - const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR; - - const auto create_path = [&](PathType shad_path, const fs::path& new_path) { - std::filesystem::create_directory(new_path); - paths.insert_or_assign(shad_path, new_path); - }; - - create_path(PathType::UserDir, user_dir); - create_path(PathType::LogDir, user_dir / LOG_DIR); - create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR); - create_path(PathType::ShaderDir, user_dir / SHADER_DIR); - create_path(PathType::App0, user_dir / APP0_DIR); - - return paths; -}(); - -bool ValidatePath(const fs::path& path) { - if (path.empty()) { - LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path)); - return false; - } - -#ifdef _WIN32 - if (path.u16string().size() >= MAX_PATH) { - LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); - return false; - } -#else - if (path.u8string().size() >= MAX_PATH) { - LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path)); - return false; - } -#endif - - return true; -} - -std::string PathToUTF8String(const std::filesystem::path& path) { - const auto u8_string = path.u8string(); - return std::string{u8_string.begin(), u8_string.end()}; -} - -const fs::path& GetUserPath(PathType shad_path) { - return UserPaths.at(shad_path); -} - -std::string GetUserPathString(PathType shad_path) { - return PathToUTF8String(GetUserPath(shad_path)); -} - -void SetUserPath(PathType shad_path, const fs::path& new_path) { - if (!std::filesystem::is_directory(new_path)) { - LOG_ERROR(Common_Filesystem, "Filesystem object at new_path={} is not a directory", - PathToUTF8String(new_path)); - return; - } - - UserPaths.insert_or_assign(shad_path, new_path); -} - -} // namespace Common::FS diff --git a/src/common/path_util.h b/src/common/path_util.h deleted file mode 100644 index 1836a3ac..00000000 --- a/src/common/path_util.h +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -namespace Common::FS { - -enum class PathType { - UserDir, // Where shadPS4 stores its data. - LogDir, // Where log files are stored. - ScreenshotsDir, // Where screenshots are stored. - ShaderDir, // Where shaders are stored. - App0, // Where guest application data is stored. -}; - -constexpr auto PORTABLE_DIR = "user"; - -// Sub-directories contained within a user data directory -constexpr auto LOG_DIR = "log"; -constexpr auto SCREENSHOTS_DIR = "screenshots"; -constexpr auto SHADER_DIR = "shader"; -constexpr auto APP0_DIR = "app0"; - -// Filenames -constexpr auto LOG_FILE = "shad_log.txt"; - -/** - * Validates a given path. - * - * A given path is valid if it meets these conditions: - * - The path is not empty - * - The path is not too long - * - * @param path Filesystem path - * - * @returns True if the path is valid, false otherwise. - */ -[[nodiscard]] bool ValidatePath(const std::filesystem::path& path); - -/** - * Converts a filesystem path to a UTF-8 encoded std::string. - * - * @param path Filesystem path - * - * @returns UTF-8 encoded std::string. - */ -[[nodiscard]] std::string PathToUTF8String(const std::filesystem::path& path); - -/** - * Gets the filesystem path associated with the PathType enum. - * - * @param user_path PathType enum - * - * @returns The filesystem path associated with the PathType enum. - */ -[[nodiscard]] const std::filesystem::path& GetUserPath(PathType user_path); - -/** - * Gets the filesystem path associated with the PathType enum as a UTF-8 encoded std::string. - * - * @param user_path PathType enum - * - * @returns The filesystem path associated with the PathType enum as a UTF-8 encoded std::string. - */ -[[nodiscard]] std::string GetUserPathString(PathType user_path); - -/** - * Sets a new filesystem path associated with the PathType enum. - * If the filesystem object at new_path is not a directory, this function will not do anything. - * - * @param user_path PathType enum - * @param new_path New filesystem path - */ -void SetUserPath(PathType user_path, const std::filesystem::path& new_path); - -} // namespace Common::FS diff --git a/src/common/thread.cpp b/src/common/thread.cpp deleted file mode 100644 index 13db7eb5..00000000 --- a/src/common/thread.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include "common/error.h" -#include "common/logging/log.h" -#include "common/thread.h" -#ifdef __APPLE__ -#include -#elif defined(_WIN32) -#include -#include "common/string_util.h" -#else -#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#include -#else -#include -#endif -#include -#endif -#ifndef _WIN32 -#include -#endif - -#ifdef __FreeBSD__ -#define cpu_set_t cpuset_t -#endif - -namespace Common { - -#ifdef _WIN32 - -void SetCurrentThreadPriority(ThreadPriority new_priority) { - auto handle = GetCurrentThread(); - int windows_priority = 0; - switch (new_priority) { - case ThreadPriority::Low: - windows_priority = THREAD_PRIORITY_BELOW_NORMAL; - break; - case ThreadPriority::Normal: - windows_priority = THREAD_PRIORITY_NORMAL; - break; - case ThreadPriority::High: - windows_priority = THREAD_PRIORITY_ABOVE_NORMAL; - break; - case ThreadPriority::VeryHigh: - windows_priority = THREAD_PRIORITY_HIGHEST; - break; - case ThreadPriority::Critical: - windows_priority = THREAD_PRIORITY_TIME_CRITICAL; - break; - default: - windows_priority = THREAD_PRIORITY_NORMAL; - break; - } - SetThreadPriority(handle, windows_priority); -} - -#else - -void SetCurrentThreadPriority(ThreadPriority new_priority) { - pthread_t this_thread = pthread_self(); - - const auto scheduling_type = SCHED_OTHER; - s32 max_prio = sched_get_priority_max(scheduling_type); - s32 min_prio = sched_get_priority_min(scheduling_type); - u32 level = std::max(static_cast(new_priority) + 1, 4U); - - struct sched_param params; - if (max_prio > min_prio) { - params.sched_priority = min_prio + ((max_prio - min_prio) * level) / 4; - } else { - params.sched_priority = min_prio - ((min_prio - max_prio) * level) / 4; - } - - pthread_setschedparam(this_thread, scheduling_type, ¶ms); -} - -#endif - -#ifdef _MSC_VER - -// Sets the debugger-visible name of the current thread. -void SetCurrentThreadName(const char* name) { - SetThreadDescription(GetCurrentThread(), UTF8ToUTF16W(name).data()); -} - -#else // !MSVC_VER, so must be POSIX threads - -// MinGW with the POSIX threading model does not support pthread_setname_np -#if !defined(_WIN32) || defined(_MSC_VER) -void SetCurrentThreadName(const char* name) { -#ifdef __APPLE__ - pthread_setname_np(name); -#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(pthread_self(), name); -#elif defined(__NetBSD__) - pthread_setname_np(pthread_self(), "%s", (void*)name); -#elif defined(__linux__) - // Linux limits thread names to 15 characters and will outright reject any - // attempt to set a longer name with ERANGE. - std::string truncated(name, std::min(strlen(name), static_cast(15))); - if (int e = pthread_setname_np(pthread_self(), truncated.c_str())) { - errno = e; - LOG_ERROR(Common, "Failed to set thread name to '{}': {}", truncated, GetLastErrorMsg()); - } -#else - pthread_setname_np(pthread_self(), name); -#endif -} -#endif - -#if defined(_WIN32) -void SetCurrentThreadName(const char*) { - // Do Nothing on MingW -} -#endif - -#endif - -} // namespace Common diff --git a/src/common/thread.h b/src/common/thread.h deleted file mode 100644 index 39acc1db..00000000 --- a/src/common/thread.h +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project -// SPDX-FileCopyrightText: 2014 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/types.h" - -namespace Common { - -enum class ThreadPriority : u32 { - Low = 0, - Normal = 1, - High = 2, - VeryHigh = 3, - Critical = 4, -}; - -void SetCurrentThreadPriority(ThreadPriority new_priority); - -void SetCurrentThreadName(const char* name); - -} // namespace Common diff --git a/src/core/PS4/GPU/video_out_buffer.cpp b/src/core/PS4/GPU/video_out_buffer.cpp index 87283997..b0a5493f 100644 --- a/src/core/PS4/GPU/video_out_buffer.cpp +++ b/src/core/PS4/GPU/video_out_buffer.cpp @@ -1,12 +1,14 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" #include "core/PS4/GPU/tile_manager.h" #include "core/PS4/GPU/video_out_buffer.h" #include "vulkan_util.h" +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) { @@ -53,7 +55,8 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params vk_format = VK_FORMAT_B8G8R8A8_SRGB; break; default: - UNREACHABLE_MSG("Unknown pixelFormat = {}", pixel_format); + LOG_CRITICAL_IF(log_file_videoOutBuffer, "unknown pixelFormat = {}\n", pixel_format); + std::exit(0); } vk_obj->extent.width = width; @@ -88,7 +91,8 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params vkCreateImage(ctx->m_device, &image_info, nullptr, &vk_obj->image); if (vk_obj->image == nullptr) { - UNREACHABLE_MSG("vk_obj->image is null"); + LOG_CRITICAL_IF(log_file_videoOutBuffer, "vk_obj->image is null\n"); + std::exit(0); } vkGetImageMemoryRequirements(ctx->m_device, vk_obj->image, &mem->requirements); @@ -98,15 +102,19 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params bool allocated = GPU::vulkanAllocateMemory(ctx, mem); if (!allocated) { - UNREACHABLE_MSG("Can't allocate vulkan memory"); + LOG_CRITICAL_IF(log_file_videoOutBuffer, "can't allocate vulkan memory\n"); + std::exit(0); } vkBindImageMemory(ctx->m_device, vk_obj->image, mem->memory, mem->offset); vk_obj->memory = *mem; - LOG_INFO(Lib_VideoOut, "videoOutBuffer create object width = {}, height = {}, size = {}", width, - height, *size); + LOG_INFO_IF(log_file_videoOutBuffer, "videoOutBuffer create object\n"); + LOG_INFO_IF(log_file_videoOutBuffer, "mem requirements.size = {}\n", mem->requirements.size); + LOG_INFO_IF(log_file_videoOutBuffer, "width = {}\n", width); + LOG_INFO_IF(log_file_videoOutBuffer, "height = {}\n", height); + LOG_INFO_IF(log_file_videoOutBuffer, "size = {}\n", *size); update_func(ctx, params, vk_obj, virtual_addr, size, virtual_addr_num); @@ -131,7 +139,8 @@ static void* create_func(HLE::Libs::Graphics::GraphicCtx* ctx, const u64* params &vk_obj->image_view[HLE::Libs::Graphics::VulkanImage::VIEW_DEFAULT]); if (vk_obj->image_view[HLE::Libs::Graphics::VulkanImage::VIEW_DEFAULT] == nullptr) { - UNREACHABLE_MSG("vk_obj->image_view is null"); + LOG_CRITICAL_IF(log_file_videoOutBuffer, "vk_obj->image_view is null\n"); + std::exit(0); } return vk_obj; diff --git a/src/core/PS4/HLE/Graphics/video_out.cpp b/src/core/PS4/HLE/Graphics/video_out.cpp index 259d0568..05a18db3 100644 --- a/src/core/PS4/HLE/Graphics/video_out.cpp +++ b/src/core/PS4/HLE/Graphics/video_out.cpp @@ -3,10 +3,11 @@ #include #include +#include #include "Objects/video_out_ctx.h" #include "Util/config.h" #include "common/debug.h" -#include "common/logging/log.h" +#include "common/log.h" #include "common/singleton.h" #include "core/PS4/GPU/gpu_memory.h" #include "core/PS4/GPU/video_out_buffer.h" @@ -57,11 +58,17 @@ std::string getPixelFormatString(s32 format) { void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(SceVideoOutBufferAttribute* attribute, u32 pixelFormat, u32 tilingMode, u32 aspectRatio, u32 width, u32 height, u32 pitchInPixel) { - LOG_INFO(Lib_VideoOut, - "pixelFormat = {}, tilingMode = {}, aspectRatio = {}, width = {}, height = {}, " - "pitchInPixel = {}", - getPixelFormatString(pixelFormat), tilingMode, aspectRatio, width, height, - pitchInPixel); + PRINT_FUNCTION_NAME(); + + auto tileMode = magic_enum::enum_cast(tilingMode); + auto aspectR = magic_enum::enum_cast(aspectRatio); + + LOG_INFO_IF(log_file_videoout, "pixelFormat = {}\n", getPixelFormatString(pixelFormat)); + LOG_INFO_IF(log_file_videoout, "tilingMode = {}\n", magic_enum::enum_name(tileMode.value())); + LOG_INFO_IF(log_file_videoout, "aspectRatio = {}\n", magic_enum::enum_name(aspectR.value())); + LOG_INFO_IF(log_file_videoout, "width = {}\n", width); + LOG_INFO_IF(log_file_videoout, "height = {}\n", height); + LOG_INFO_IF(log_file_videoout, "pitchInPixel = {}\n", pitchInPixel); std::memset(attribute, 0, sizeof(SceVideoOutBufferAttribute)); @@ -93,8 +100,7 @@ static void flip_delete_event_func(Core::Kernel::SceKernelEqueue eq, s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 handle, void* udata) { - LOG_INFO(Lib_VideoOut, "handle = {}", handle); - + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); auto* ctx = videoOut->getCtx(handle); @@ -130,43 +136,46 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Core::Kernel::SceKernelEqueue eq, s32 h 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 (startIndex < 0 || startIndex > 15) { - LOG_ERROR(Lib_VideoOut, "Invalid startIndex = {}", startIndex); + LOG_TRACE_IF(log_file_videoout, "invalid startIndex = {}\n", startIndex); return SCE_VIDEO_OUT_ERROR_INVALID_VALUE; } if (bufferNum < 1 || bufferNum > 16) { - LOG_ERROR(Lib_VideoOut, "Invalid bufferNum = {}", bufferNum); + LOG_TRACE_IF(log_file_videoout, "invalid bufferNum = {}\n", bufferNum); return SCE_VIDEO_OUT_ERROR_INVALID_VALUE; } } if (addresses == nullptr) { - LOG_ERROR(Lib_VideoOut, "Addresses are null"); + LOG_TRACE_IF(log_file_videoout, "addresses are null\n"); return SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS; } if (attribute == nullptr) { - LOG_ERROR(Lib_VideoOut, "Attribute is null"); + LOG_TRACE_IF(log_file_videoout, "attribute is null\n"); return SCE_VIDEO_OUT_ERROR_INVALID_OPTION; } if (attribute->aspectRatio != 0) { - LOG_ERROR(Lib_VideoOut, "Invalid aspect ratio = {}", attribute->aspectRatio); + LOG_TRACE_IF(log_file_videoout, "invalid aspect ratio = {}\n", attribute->aspectRatio); return SCE_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO; } if (attribute->tilingMode < 0 || attribute->tilingMode > 1) { - LOG_ERROR(Lib_VideoOut, "Invalid tilingMode = {}", attribute->tilingMode); + LOG_TRACE_IF(log_file_videoout, "invalid tilingMode = {}\n", attribute->tilingMode); return SCE_VIDEO_OUT_ERROR_INVALID_TILING_MODE; } - - LOG_INFO(Lib_VideoOut, - "handle = {}, startIndex = {}, bufferNum = {}, pixelFormat = {:#x}, aspectRatio = {}, " - "tilingMode = {}, width = {}, height = {}, pitchInPixel = {}, option = {:#x}", - handle, startIndex, bufferNum, attribute->pixelFormat, attribute->aspectRatio, - attribute->tilingMode, attribute->width, attribute->height, attribute->pitchInPixel, - attribute->option); + LOG_INFO_IF(log_file_videoout, "startIndex = {}\n", startIndex); + LOG_INFO_IF(log_file_videoout, "bufferNum = {}\n", bufferNum); + LOG_INFO_IF(log_file_videoout, "pixelFormat = {:#x}\n", attribute->pixelFormat); + LOG_INFO_IF(log_file_videoout, "tilingMode = {}\n", attribute->tilingMode); + LOG_INFO_IF(log_file_videoout, "aspectRatio = {}\n", attribute->aspectRatio); + LOG_INFO_IF(log_file_videoout, "width = {}\n", attribute->width); + LOG_INFO_IF(log_file_videoout, "height = {}\n", attribute->height); + LOG_INFO_IF(log_file_videoout, "pitchInPixel = {}\n", attribute->pitchInPixel); + LOG_INFO_IF(log_file_videoout, "option = {}\n", attribute->option); int registration_index = ctx->buffers_registration_index++; @@ -205,7 +214,7 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co for (int i = 0; i < bufferNum; i++) { if (ctx->buffers[i + startIndex].buffer != nullptr) { - LOG_ERROR(Lib_VideoOut, "Buffer slot {} is occupied!", i + startIndex); + LOG_TRACE_IF(log_file_videoout, "buffer slot {} is occupied!\n", i + startIndex); return SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED; } @@ -218,49 +227,51 @@ s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* co 0, videoOut->getGraphicCtx(), nullptr, reinterpret_cast(addresses[i]), buffer_size, buffer_info)); - LOG_INFO(Lib_VideoOut, "buffers[{}] = {:#x}", i + startIndex, - reinterpret_cast(addresses[i])); + LOG_INFO_IF(log_file_videoout, "buffers[{}] = {:#x}\n", i + startIndex, + reinterpret_cast(addresses[i])); } return registration_index; } s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate) { - LOG_INFO(Lib_VideoOut, "called"); + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); videoOut->getCtx(handle)->m_flip_rate = rate; return SCE_OK; } s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) { - LOG_INFO(Lib_VideoOut, "called"); + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); s32 pending = videoOut->getCtx(handle)->m_flip_status.flipPendingNum; return pending; } s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg) { + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); auto* ctx = videoOut->getCtx(handle); if (flipMode != 1) { // BREAKPOINT(); // only flipmode==1 is supported - LOG_WARNING(Lib_VideoOut, "flipmode = {}", - flipMode); // openBOR needs 2 but seems to work + 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 } if (bufferIndex < -1 || bufferIndex > 15) { - LOG_ERROR(Lib_VideoOut, "Invalid bufferIndex = {}", bufferIndex); + LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip invalid bufferIndex {}\n", + bufferIndex); return SCE_VIDEO_OUT_ERROR_INVALID_INDEX; } - - LOG_INFO(Lib_VideoOut, "bufferIndex = {}, flipMode = {}, flipArg = {}", bufferIndex, flipMode, - flipArg); + LOG_INFO_IF(log_file_videoout, "bufferIndex = {}\n", bufferIndex); + LOG_INFO_IF(log_file_videoout, "flipMode = {}\n", flipMode); + LOG_INFO_IF(log_file_videoout, "flipArg = {}\n", flipArg); if (!videoOut->getFlipQueue().submitFlip(ctx, bufferIndex, flipArg)) { - LOG_ERROR(Lib_VideoOut, "Flip queue is full"); + 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 @@ -269,20 +280,24 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode } s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, SceVideoOutFlipStatus* status) { + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); auto* ctx = videoOut->getCtx(handle); videoOut->getFlipQueue().getFlipStatus(ctx, status); - LOG_INFO(Lib_VideoOut, - "count = {}, processTime = {}, tsc = {}, submitTsc = {}, flipArg = {}, gcQueueNum = " - "{}, flipPendingNum = {}, currentBuffer = {}", - status->count, status->processTime, status->tsc, status->submitTsc, status->flipArg, - status->gcQueueNum, status->flipPendingNum, status->currentBuffer); + LOG_INFO_IF(log_file_videoout, "count = {}\n", status->count); + LOG_INFO_IF(log_file_videoout, "processTime = {}\n", status->processTime); + LOG_INFO_IF(log_file_videoout, "tsc = {}\n", status->tsc); + LOG_INFO_IF(log_file_videoout, "submitTsc = {}\n", status->submitTsc); + LOG_INFO_IF(log_file_videoout, "flipArg = {}\n", status->flipArg); + LOG_INFO_IF(log_file_videoout, "gcQueueNum = {}\n", status->gcQueueNum); + LOG_INFO_IF(log_file_videoout, "flipPendingNum = {}\n", status->flipPendingNum); + LOG_INFO_IF(log_file_videoout, "currentBuffer = {}\n", status->currentBuffer); return 0; } s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status) { - LOG_INFO(Lib_VideoOut, "called"); + PRINT_FUNCTION_NAME(); auto* videoOut = Common::Singleton::Instance(); *status = videoOut->getCtx(handle)->m_resolution; return SCE_OK; @@ -290,7 +305,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutio s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, const void* param) { - LOG_INFO(Lib_VideoOut, "called"); + PRINT_FUNCTION_NAME(); if (userId != SCE_USER_SERVICE_USER_ID_SYSTEM && userId != 0) { BREAKPOINT(); } @@ -298,7 +313,7 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 i BREAKPOINT(); } if (index != 0) { - LOG_ERROR(Lib_VideoOut, "Index != 0"); + LOG_TRACE_IF(log_file_videoout, "sceVideoOutOpen index!=0\n"); return SCE_VIDEO_OUT_ERROR_INVALID_VALUE; } if (param != nullptr) { @@ -308,7 +323,7 @@ s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 i int handle = videoOut->Open(); if (handle < 0) { - LOG_ERROR(Lib_VideoOut, "All available handles are open"); + LOG_TRACE_IF(log_file_videoout, "sceVideoOutOpen all available handles are open\n"); return SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY; // it is alreadyOpened } @@ -327,6 +342,7 @@ 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("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutSubmitFlip); diff --git a/src/core/aerolib/stubs.cpp b/src/core/aerolib/stubs.cpp index 5a797548..34db7a94 100644 --- a/src/core/aerolib/stubs.cpp +++ b/src/core/aerolib/stubs.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/log.h" #include "core/aerolib/aerolib.h" #include "core/aerolib/stubs.h" @@ -22,12 +22,13 @@ namespace Core::AeroLib { constexpr u32 MAX_STUBS = 128; u64 UnresolvedStub() { - LOG_ERROR(Core, "Returning zero to {}", __builtin_return_address(0)); + LOG_ERROR("Unresolved Stub: called, returning zero to {}\n", __builtin_return_address(0)); return 0; } static u64 UnknownStub() { - LOG_ERROR(Core, "Returning zero to {}", __builtin_return_address(0)); + LOG_ERROR("Stub: Unknown (nid: Unknown) called, returning zero to {}\n", + __builtin_return_address(0)); return 0; } @@ -38,10 +39,10 @@ template static u64 CommonStub() { auto entry = stub_nids[stub_index]; if (entry) { - LOG_ERROR(Core, "Stub: {} (nid: {}) called, returning zero to {}", entry->name, entry->nid, + LOG_ERROR("Stub: {} (nid: {}) called, returning zero to {}\n", entry->name, entry->nid, __builtin_return_address(0)); } else { - LOG_ERROR(Core, "Stub: Unknown (nid: {}) called, returning zero to {}", + LOG_ERROR("Stub: Unknown (nid: {}) called, returning zero to {}\n", stub_nids_unknown[stub_index], __builtin_return_address(0)); } return 0; diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 6a99a808..5e8f8312 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -8,24 +8,21 @@ namespace Core::FileSys { constexpr int RESERVED_HANDLES = 3; // First 3 handles are stdin,stdout,stderr -void MntPoints::Mount(const std::filesystem::path& host_folder, const std::string& guest_folder) { +void MntPoints::mount(const std::string& host_folder, const std::string& guest_folder) { std::scoped_lock lock{m_mutex}; MntPair pair; - pair.host_path = host_folder.string(); + pair.host_path = host_folder; pair.guest_path = guest_folder; m_mnt_pairs.push_back(pair); } - -void MntPoints::Unmount(const std::string& path) {} // TODO! - -void MntPoints::UnmountAll() { +void MntPoints::unmount(const std::string& path) {} // TODO! +void MntPoints::unmountAll() { std::scoped_lock lock{m_mutex}; m_mnt_pairs.clear(); } - -std::string MntPoints::GetHostDirectory(const std::string& guest_directory) { +std::string MntPoints::getHostDirectory(const std::string& guest_directory) { std::scoped_lock lock{m_mutex}; for (auto& pair : m_mnt_pairs) { if (pair.guest_path.starts_with(guest_directory)) { @@ -41,8 +38,7 @@ std::string MntPoints::GetHostDirectory(const std::string& guest_directory) { } return ""; } - -std::string MntPoints::GetHostFile(const std::string& guest_file) { +std::string MntPoints::getHostFile(const std::string& guest_file) { std::scoped_lock lock{m_mutex}; for (auto& pair : m_mnt_pairs) { @@ -56,13 +52,11 @@ std::string MntPoints::GetHostFile(const std::string& guest_file) { } return ""; } - -int HandleTable::CreateHandle() { +int HandleTable::createHandle() { std::scoped_lock lock{m_mutex}; - auto* file = new File{}; - file->is_directory = false; - file->is_opened = false; + file->isDirectory = false; + file->isOpened = false; int existingFilesNum = m_files.size(); @@ -74,20 +68,19 @@ int HandleTable::CreateHandle() { } m_files.push_back(file); + return m_files.size() + RESERVED_HANDLES - 1; } - -void HandleTable::DeleteHandle(int d) { +void HandleTable::deleteHandle(int d) { std::scoped_lock lock{m_mutex}; delete m_files.at(d - RESERVED_HANDLES); m_files[d - RESERVED_HANDLES] = nullptr; } -File* HandleTable::GetFile(int d) { +File* HandleTable::getFile(int d) { std::scoped_lock lock{m_mutex}; return m_files.at(d - RESERVED_HANDLES); } - File* HandleTable::getFile(const std::string& host_name) { std::scoped_lock lock{m_mutex}; for (auto* file : m_files) { diff --git a/src/core/file_sys/fs.h b/src/core/file_sys/fs.h index 7d7b9985..8ac80e3d 100644 --- a/src/core/file_sys/fs.h +++ b/src/core/file_sys/fs.h @@ -7,6 +7,7 @@ #include #include #include +#include "common/fs_file.h" #include "common/io_file.h" namespace Core::FileSys { @@ -20,12 +21,11 @@ public: MntPoints() = default; virtual ~MntPoints() = default; - - void Mount(const std::filesystem::path& host_folder, const std::string& guest_folder); - void Unmount(const std::string& path); - void UnmountAll(); - std::string GetHostDirectory(const std::string& guest_directory); - std::string GetHostFile(const std::string& guest_file); + void mount(const std::string& host_folder, const std::string& guest_folder); + void unmount(const std::string& path); + void unmountAll(); + std::string getHostDirectory(const std::string& guest_directory); + std::string getHostFile(const std::string& guest_file); private: std::vector m_mnt_pairs; @@ -33,8 +33,8 @@ private: }; struct File { - std::atomic_bool is_opened{}; - std::atomic_bool is_directory{}; + std::atomic_bool isOpened; + std::atomic_bool isDirectory; std::string m_host_name; std::string m_guest_name; Common::FS::IOFile f; @@ -42,15 +42,13 @@ struct File { u32 dirents_index; std::mutex m_mutex; }; - class HandleTable { public: - HandleTable() = default; - virtual ~HandleTable() = default; - - int CreateHandle(); - void DeleteHandle(int d); - File* GetFile(int d); + HandleTable() {} + virtual ~HandleTable() {} + int createHandle(); + void deleteHandle(int d); + File* getFile(int d); File* getFile(const std::string& host_name); private: diff --git a/src/core/hle/kernel/cpu_management.cpp b/src/core/hle/kernel/cpu_management.cpp index 81c3b3fe..bd483e84 100644 --- a/src/core/hle/kernel/cpu_management.cpp +++ b/src/core/hle/kernel/cpu_management.cpp @@ -2,13 +2,14 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "Util/config.h" -#include "common/logging/log.h" +#include "common/log.h" #include "core/hle/kernel/cpu_management.h" +#include "core/hle/libraries/libs.h" namespace Core::Kernel { int PS4_SYSV_ABI sceKernelIsNeoMode() { - LOG_INFO(Kernel_Sce, "called"); + PRINT_FUNCTION_NAME(); return Config::isNeoMode(); } diff --git a/src/core/hle/kernel/event_queues.cpp b/src/core/hle/kernel/event_queues.cpp index 9c198fc3..ca3264d4 100644 --- a/src/core/hle/kernel/event_queues.cpp +++ b/src/core/hle/kernel/event_queues.cpp @@ -1,44 +1,51 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.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 + int PS4_SYSV_ABI sceKernelCreateEqueue(SceKernelEqueue* eq, const char* name) { + PRINT_FUNCTION_NAME(); + if (eq == nullptr) { - LOG_ERROR(Kernel_Event, "Event queue is null!"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL eq invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (name == nullptr) { - LOG_ERROR(Kernel_Event, "Event queue name is invalid!"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EFAULT name invalid\n"); return SCE_KERNEL_ERROR_EFAULT; } if (name == NULL) { - LOG_ERROR(Kernel_Event, "Event queue name is null!"); + LOG_TRACE_IF(log_file_equeues, + "sceKernelCreateEqueue returned SCE_KERNEL_ERROR_EINVAL name is null\n"); return SCE_KERNEL_ERROR_EINVAL; } - // Maximum is 32 including null terminator - static constexpr size_t MaxEventQueueNameSize = 32; - if (std::strlen(name) > MaxEventQueueNameSize) { - LOG_ERROR(Kernel_Event, "Event queue name exceeds 32 bytes!"); + 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; } - - LOG_INFO(Kernel_Event, "name = {}", name); - *eq = new EqueueInternal; (*eq)->setName(std::string(name)); + + LOG_INFO_IF(log_file_equeues, "sceKernelCreateEqueue created with name \"{}\"\n", name); return SCE_OK; } int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int num, int* out, SceKernelUseconds* timo) { - LOG_INFO(Kernel_Event, "num = {}", num); + PRINT_FUNCTION_NAME(); if (eq == nullptr) { return SCE_KERNEL_ERROR_EBADF; @@ -59,10 +66,10 @@ int PS4_SYSV_ABI sceKernelWaitEqueue(SceKernelEqueue eq, SceKernelEvent* ev, int if (timo != nullptr) { // Only events that have already arrived at the time of this function call can be received if (*timo == 0) { - UNREACHABLE(); + BREAKPOINT(); } else { // Wait until an event arrives with timing out - UNREACHABLE(); + BREAKPOINT(); } } diff --git a/src/core/hle/kernel/memory_management.cpp b/src/core/hle/kernel/memory_management.cpp index 9491b4a3..7cb23e8f 100644 --- a/src/core/hle/kernel/memory_management.cpp +++ b/src/core/hle/kernel/memory_management.cpp @@ -2,85 +2,106 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "common/assert.h" -#include "common/logging/log.h" +#include +#include "common/debug.h" +#include "common/log.h" #include "common/singleton.h" #include "core/PS4/GPU/gpu_memory.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/virtual_memory.h" namespace Core::Kernel { +constexpr bool log_file_memory = true; // disable it to disable logging + bool is16KBAligned(u64 n) { return ((n % (16ull * 1024) == 0)); } u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() { - LOG_WARNING(Kernel_Vmm, "(STUBBED) called"); + PRINT_FUNCTION_NAME(); return SCE_KERNEL_MAIN_DMEM_SIZE; } int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, u64 alignment, int memoryType, s64* physAddrOut) { - LOG_INFO(Kernel_Vmm, - "searchStart = {:#x}, searchEnd = {:#x}, len = {:#x}, alignment = {:#x}, memoryType = " - "{:#x}", - searchStart, searchEnd, len, alignment, memoryType); + PRINT_FUNCTION_NAME(); if (searchStart < 0 || searchEnd <= searchStart) { - LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); + LOG_TRACE_IF(log_file_memory, "sceKernelAllocateDirectMemory returned " + "SCE_KERNEL_ERROR_EINVAL searchStart,searchEnd invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } - const bool is_in_range = (searchStart < len && searchEnd > len); - if (len <= 0 || !is16KBAligned(len) || !is_in_range) { - LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); + 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"); return SCE_KERNEL_ERROR_EINVAL; } if ((alignment != 0 || is16KBAligned(alignment)) && !std::has_single_bit(alignment)) { - LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); + LOG_TRACE_IF( + log_file_memory, + "sceKernelAllocateDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (physAddrOut == nullptr) { - LOG_ERROR(Kernel_Vmm, "Result physical address pointer is null!"); + 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); + + LOG_INFO_IF(log_file_memory, "search_start = {:#x}\n", searchStart); + LOG_INFO_IF(log_file_memory, "search_end = {:#x}\n", searchEnd); + LOG_INFO_IF(log_file_memory, "len = {:#x}\n", len); + LOG_INFO_IF(log_file_memory, "alignment = {:#x}\n", alignment); + LOG_INFO_IF(log_file_memory, "memory_type = {}\n", magic_enum::enum_name(memtype.value())); u64 physical_addr = 0; auto* physical_memory = Common::Singleton::Instance(); if (!physical_memory->Alloc(searchStart, searchEnd, len, alignment, &physical_addr, memoryType)) { - LOG_CRITICAL(Kernel_Vmm, "Unable to allocate physical memory"); + 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); - LOG_INFO(Kernel_Vmm, "physAddrOut = {:#x}", physical_addr); + LOG_INFO_IF(true, "physAddrOut = {:#x}\n", physical_addr); return SCE_OK; } int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment) { - LOG_INFO( - Kernel_Vmm, - "len = {:#x}, prot = {:#x}, flags = {:#x}, directMemoryStart = {:#x}, alignment = {:#x}", - len, prot, flags, directMemoryStart, alignment); - + PRINT_FUNCTION_NAME(); if (len == 0 || !is16KBAligned(len)) { - LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!"); + LOG_TRACE_IF(log_file_memory, + "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL len invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } if (!is16KBAligned(directMemoryStart)) { - LOG_ERROR(Kernel_Vmm, "Start address is not 16KB aligned!"); + 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_ERROR(Kernel_Vmm, "Alignment value is invalid!"); + LOG_TRACE_IF( + log_file_memory, + "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n"); return SCE_KERNEL_ERROR_EINVAL; } } + LOG_INFO_IF(log_file_memory, "len = {:#x}\n", len); + LOG_INFO_IF(log_file_memory, "prot = {:#x}\n", prot); + LOG_INFO_IF(log_file_memory, "flags = {:#x}\n", flags); + LOG_INFO_IF(log_file_memory, "directMemoryStart = {:#x}\n", directMemoryStart); + LOG_INFO_IF(log_file_memory, "alignment = {:#x}\n", alignment); + VirtualMemory::MemoryMode cpu_mode = VirtualMemory::MemoryMode::NoAccess; GPU::MemoryMode gpu_mode = GPU::MemoryMode::NoAccess; @@ -91,7 +112,7 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl gpu_mode = GPU::MemoryMode::ReadWrite; break; default: - UNREACHABLE(); + BREAKPOINT(); } auto in_addr = reinterpret_cast(*addr); @@ -100,7 +121,8 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl if (flags == 0) { out_addr = VirtualMemory::memory_alloc_aligned(in_addr, len, cpu_mode, alignment); } - LOG_INFO(Kernel_Vmm, "in_addr = {:#x}, out_addr = {:#x}", in_addr, out_addr); + 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 @@ -110,7 +132,7 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl auto* physical_memory = Common::Singleton::Instance(); if (!physical_memory->Map(out_addr, directMemoryStart, len, prot, cpu_mode, gpu_mode)) { - UNREACHABLE(); + BREAKPOINT(); } if (gpu_mode != GPU::MemoryMode::NoAccess) { diff --git a/src/core/hle/libraries/libc/libc.cpp b/src/core/hle/libraries/libc/libc.cpp index 127c3eb9..d3a90b22 100644 --- a/src/core/hle/libraries/libc/libc.cpp +++ b/src/core/hle/libraries/libc/libc.cpp @@ -3,7 +3,7 @@ #include #include "common/debug.h" -#include "common/logging/log.h" +#include "common/log.h" #include "common/singleton.h" #include "core/hle/libraries/libc/libc.h" #include "core/hle/libraries/libc/libc_cxa.h" @@ -49,15 +49,15 @@ void PS4_SYSV_ABI ps4___cxa_pure_virtual() { } static PS4_SYSV_ABI void ps4_init_env() { - LOG_INFO(Lib_LibC, "called"); + PRINT_DUMMY_FUNCTION_NAME(); } static PS4_SYSV_ABI void ps4_catchReturnFromMain(int status) { - LOG_INFO(Lib_LibC, "returned = {}", status); + LOG_INFO_IF(log_file_libc, "catchReturnFromMain returned ={}\n", status); } static PS4_SYSV_ABI void ps4__Assert() { - LOG_INFO(Lib_LibC, "called"); + PRINT_DUMMY_FUNCTION_NAME(); BREAKPOINT(); } @@ -66,18 +66,18 @@ PS4_SYSV_ABI void ps4__ZdlPv(void* ptr) { } PS4_SYSV_ABI void ps4__ZSt11_Xbad_allocv() { - LOG_INFO(Lib_LibC, "called"); + PRINT_DUMMY_FUNCTION_NAME(); BREAKPOINT(); } PS4_SYSV_ABI void ps4__ZSt14_Xlength_errorPKc() { - LOG_INFO(Lib_LibC, "called"); + PRINT_DUMMY_FUNCTION_NAME(); BREAKPOINT(); } PS4_SYSV_ABI void* ps4__Znwm(u64 count) { if (count == 0) { - LOG_INFO(Lib_LibC, "_Znwm count ={}", count); + LOG_ERROR_IF(log_file_libc, "_Znwm count ={}\n", count); BREAKPOINT(); } void* ptr = std::malloc(count); @@ -457,7 +457,6 @@ void libcSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("8zTFvBIAIN8", "libc", 1, "libc", 1, 1, ps4_memset); // stdio functions - LIB_FUNCTION("xeYO4u7uyJ0", "libc", 1, "libc", 1, 1, ps4_fopen); LIB_FUNCTION("hcuQgD53UxM", "libc", 1, "libc", 1, 1, ps4_printf); LIB_FUNCTION("Q2V+iqvjgC0", "libc", 1, "libc", 1, 1, ps4_vsnprintf); LIB_FUNCTION("YQ0navp+YIc", "libc", 1, "libc", 1, 1, ps4_puts); diff --git a/src/core/hle/libraries/libc/libc_cxa.cpp b/src/core/hle/libraries/libc/libc_cxa.cpp index e1e693ae..6d5dc7f8 100644 --- a/src/core/hle/libraries/libc/libc_cxa.cpp +++ b/src/core/hle/libraries/libc/libc_cxa.cpp @@ -1,7 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" #include "core/hle/libraries/libc/libc_cxa.h" // adapted from @@ -9,6 +10,8 @@ namespace Core::Libraries::LibC { +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 // @@ -100,7 +103,8 @@ int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) { int result = ::pthread_mutex_lock(guard_mutex()); if (result != 0) { - LOG_ERROR(Lib_LibC, "pthread_mutex_lock failed with {}", 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() @@ -108,7 +112,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_ERROR(Lib_LibC, "pthread_mutex_lock failed with {}", result); + LOG_TRACE_IF(log_file_cxa, + "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", result); } return 0; } @@ -118,8 +123,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_ERROR(Lib_LibC, - "initializer for function local static variable called enclosing function"); + 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 @@ -141,7 +146,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_ERROR(Lib_LibC, "pthread_mutex_unlock failed with {}", result); + LOG_TRACE_IF(log_file_cxa, "__cxa_guard_acquire(): pthread_mutex_unlock failed with {}\n", + result); } } @@ -151,7 +157,8 @@ 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_ERROR(Lib_LibC, "pthread_mutex_unlock failed with {}", 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 diff --git a/src/core/hle/libraries/libc/libc_stdio.cpp b/src/core/hle/libraries/libc/libc_stdio.cpp index 67568e29..72c14e3d 100644 --- a/src/core/hle/libraries/libc/libc_stdio.cpp +++ b/src/core/hle/libraries/libc/libc_stdio.cpp @@ -1,17 +1,13 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/singleton.h" -#include "core/file_sys/fs.h" +#include "common/debug.h" +#include "common/log.h" #include "core/hle/libraries/libc/libc_stdio.h" namespace Core::Libraries::LibC { -std::FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode) { - auto* mnt = Common::Singleton::Instance(); - return std::fopen(mnt->GetHostFile(filename).c_str(), mode); -} +constexpr bool log_file_libc = true; // disable it to disable logging int PS4_SYSV_ABI ps4_printf(VA_ARGS) { VA_CTX(ctx); @@ -24,8 +20,8 @@ int PS4_SYSV_ABI ps4_fprintf(FILE* file, VA_ARGS) { VA_CTX(ctx); return printf_ctx(&ctx); } - - UNREACHABLE_MSG("Unimplemented fprintf case"); + LOG_ERROR_IF(log_file_libc, "libc:Unimplemented fprintf case\n"); + BREAKPOINT(); return 0; } diff --git a/src/core/hle/libraries/libc/libc_stdio.h b/src/core/hle/libraries/libc/libc_stdio.h index c2911f36..f4308213 100644 --- a/src/core/hle/libraries/libc/libc_stdio.h +++ b/src/core/hle/libraries/libc/libc_stdio.h @@ -8,7 +8,6 @@ namespace Core::Libraries::LibC { -std::FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode); int PS4_SYSV_ABI ps4_printf(VA_ARGS); int PS4_SYSV_ABI ps4_vsnprintf(char* s, size_t n, const char* format, VaList* arg); int PS4_SYSV_ABI ps4_puts(const char* s); diff --git a/src/core/hle/libraries/libc/libc_stdlib.cpp b/src/core/hle/libraries/libc/libc_stdlib.cpp index 0ec3de08..f055ae58 100644 --- a/src/core/hle/libraries/libc/libc_stdlib.cpp +++ b/src/core/hle/libraries/libc/libc_stdlib.cpp @@ -2,18 +2,24 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "common/assert.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 + void PS4_SYSV_ABI ps4_exit(int code) { std::exit(code); } int PS4_SYSV_ABI ps4_atexit(void (*func)()) { int rt = std::atexit(func); - ASSERT_MSG(rt == 0, "atexit returned {}", rt); + if (rt != 0) { + LOG_ERROR_IF(log_file_libc, "atexit returned {}\n", rt); + BREAKPOINT(); + } return rt; } diff --git a/src/core/hle/libraries/libc/printf.h b/src/core/hle/libraries/libc/printf.h index 8bf98ada..e2560879 100644 --- a/src/core/hle/libraries/libc/printf.h +++ b/src/core/hle/libraries/libc/printf.h @@ -59,7 +59,6 @@ #include #include #include -#include #include #include "va_ctx.h" diff --git a/src/core/hle/libraries/libkernel/file_system.cpp b/src/core/hle/libraries/libkernel/file_system.cpp index 6d4c6162..f67fbc94 100644 --- a/src/core/hle/libraries/libkernel/file_system.cpp +++ b/src/core/hle/libraries/libkernel/file_system.cpp @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" #include "common/singleton.h" #include "core/file_sys/fs.h" #include "core/hle/error_codes.h" @@ -11,37 +11,41 @@ namespace Core::Libraries::LibKernel { +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(Kernel_Fs, "path = {} flags = {:#x} mode = {:#x}", 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(); // only open files support! - u32 handle = h->CreateHandle(); - auto* file = h->GetFile(handle); + u32 handle = h->createHandle(); + auto* file = h->getFile(handle); file->m_guest_name = path; - file->m_host_name = mnt->GetHostFile(file->m_guest_name); + file->m_host_name = mnt->getHostFile(file->m_guest_name); file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read); if (!file->f.IsOpen()) { - h->DeleteHandle(handle); + h->deleteHandle(handle); return SCE_KERNEL_ERROR_EACCES; } - file->is_opened = true; + file->isOpened = true; return handle; } int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) { - LOG_INFO(Kernel_Fs, "posix open redirect to sceKernelOpen\n"); + LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n"); int result = sceKernelOpen(path, flags, mode); - // Posix calls different only for their return values - ASSERT(result >= 0); + if (result < 0) { + BREAKPOINT(); // posix calls different only for their return values + } return result; } size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) { auto* h = Common::Singleton::Instance(); - auto* file = h->GetFile(d); + auto* file = h->getFile(d); size_t total_read = 0; file->m_mutex.lock(); for (int i = 0; i < iovcnt; i++) { diff --git a/src/core/hle/libraries/libkernel/file_system.h b/src/core/hle/libraries/libkernel/file_system.h index a6319da5..1648904e 100644 --- a/src/core/hle/libraries/libkernel/file_system.h +++ b/src/core/hle/libraries/libkernel/file_system.h @@ -13,7 +13,7 @@ namespace Core::Libraries::LibKernel { struct SceKernelIovec { void* iov_base; - std::size_t iov_len; + size_t iov_len; }; int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, /* SceKernelMode*/ u16 mode); diff --git a/src/core/hle/libraries/libkernel/libkernel.cpp b/src/core/hle/libraries/libkernel/libkernel.cpp index 8fbeb2d0..1e244d2b 100644 --- a/src/core/hle/libraries/libkernel/libkernel.cpp +++ b/src/core/hle/libraries/libkernel/libkernel.cpp @@ -1,8 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" +#include "common/singleton.h" +#include "core/hle/kernel/Objects/physical_memory.h" #include "core/hle/kernel/cpu_management.h" #include "core/hle/kernel/event_queues.h" #include "core/hle/kernel/memory_management.h" @@ -22,19 +24,21 @@ namespace Core::Libraries::LibKernel { +constexpr bool log_libkernel_file = true; // disable it to disable logging + static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len) { - UNREACHABLE(); + BREAKPOINT(); return 0; } static PS4_SYSV_ABI void stack_chk_fail() { - UNREACHABLE(); + BREAKPOINT(); } int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { - UNREACHABLE(); + BREAKPOINT(); } void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) { @@ -67,9 +71,10 @@ int* PS4_SYSV_ABI __Error() { int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, off_t offset, void** res) { #ifdef _WIN64 - LOG_INFO(Kernel_Vmm, "called"); - if (prot > 3) { - LOG_ERROR(Kernel_Vmm, "prot = {} not supported", prot); + PRINT_FUNCTION_NAME(); + if (prot > 3) // READ,WRITE or bitwise READ | WRITE supported + { + LOG_ERROR_IF(log_libkernel_file, "sceKernelMmap prot ={} not supported\n", prot); } DWORD flProtect; if (prot & PROT_WRITE) { @@ -109,11 +114,13 @@ 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(Kernel_Vmm, "posix mmap redirect to sceKernelMmap\n"); + 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 int result = sceKernelMmap(addr, len, prot, flags, fd, offset, &ptr); - ASSERT(result == 0); + if (result != 0) { + BREAKPOINT(); + } return ptr; } diff --git a/src/core/hle/libraries/libkernel/thread_management.cpp b/src/core/hle/libraries/libkernel/thread_management.cpp index 343a64a8..782351cb 100644 --- a/src/core/hle/libraries/libkernel/thread_management.cpp +++ b/src/core/hle/libraries/libkernel/thread_management.cpp @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" #include "core/hle/error_codes.h" #include "core/hle/libraries/libkernel/thread_management.h" #include "core/hle/libraries/libs.h" @@ -12,6 +12,8 @@ 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 + void init_pthreads() { g_pthread_cxt = new PThreadCxt{}; // default mutex init @@ -71,7 +73,9 @@ int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachst pstate = PTHREAD_CREATE_DETACHED; break; default: - UNREACHABLE_MSG("Invalid detachstate: {}", detachstate); + 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 @@ -97,7 +101,9 @@ int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inherit pinherit_sched = PTHREAD_INHERIT_SCHED; break; default: - UNREACHABLE_MSG("Invalid inheritSched: {}", inheritSched); + LOG_TRACE_IF(log_pthread_file, "scePthreadAttrSetinheritsched invalid inheritSched: {}\n", + inheritSched); + std::exit(0); } int result = pthread_attr_setinheritsched(&(*attr)->pth_attr, pinherit_sched); @@ -132,7 +138,9 @@ int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy) int ppolicy = SCHED_OTHER; // winpthreads only supports SCHED_OTHER if (policy != SCHED_OTHER) { - LOG_ERROR(Kernel_Pthread, "policy={} not supported by winpthreads\n", policy); + LOG_TRACE_IF(log_pthread_file, + "scePthreadAttrSetschedpolicy policy={} not supported by winpthreads\n", + policy); } (*attr)->policy = policy; @@ -146,7 +154,7 @@ ScePthread PS4_SYSV_ABI scePthreadSelf() { int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, const /*SceKernelCpumask*/ u64 mask) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); if (pattr == nullptr || *pattr == nullptr) { return SCE_KERNEL_ERROR_EINVAL; @@ -158,7 +166,7 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr, } int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); if (thread == nullptr) { return SCE_KERNEL_ERROR_ESRCH; @@ -170,10 +178,12 @@ int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpuma } int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr, pthreadEntryFunc start_routine, void* arg, const char* name) { - LOG_INFO(Kernel_Pthread, "(STUBBED) called"); + PRINT_DUMMY_FUNCTION_NAME(); return 0; } - +/**** + * Mutex calls + */ void* createMutex(void* addr) { if (addr == nullptr || *static_cast(addr) != nullptr) { return addr; @@ -187,7 +197,7 @@ void* createMutex(void* addr) { int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr, const char* name) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); if (mutex == nullptr) { return SCE_KERNEL_ERROR_EINVAL; } @@ -205,7 +215,7 @@ int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMut int result = pthread_mutex_init(&(*mutex)->pth_mutex, &(*attr)->pth_mutex_attr); if (name != nullptr) { - LOG_INFO(Kernel_Pthread, "name={}, result={}", name, result); + LOG_INFO_IF(log_pthread_file, "mutex_init name={},result={}\n", name, result); } switch (result) { @@ -254,7 +264,8 @@ int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) ptype = PTHREAD_MUTEX_NORMAL; break; default: - UNREACHABLE_MSG("Invalid type: {}", type); + LOG_TRACE_IF(log_pthread_file, "scePthreadMutexattrSettype invalid type: {}\n", type); + std::exit(0); } int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype); @@ -275,7 +286,9 @@ int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int p pprotocol = PTHREAD_PRIO_PROTECT; break; default: - UNREACHABLE_MSG("Invalid protocol: {}", protocol); + 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 @@ -285,7 +298,7 @@ int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int p return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL; } int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); mutex = static_cast(createMutex(mutex)); if (mutex == nullptr) { @@ -293,7 +306,8 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { } int result = pthread_mutex_lock(&(*mutex)->pth_mutex); - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result); + LOG_INFO_IF(log_pthread_file, "scePthreadMutexLock name={} result={}\n", (*mutex)->name, + result); switch (result) { case 0: return SCE_OK; @@ -308,14 +322,15 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) { } } int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); mutex = static_cast(createMutex(mutex)); if (mutex == nullptr) { return SCE_KERNEL_ERROR_EINVAL; } int result = pthread_mutex_unlock(&(*mutex)->pth_mutex); - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result); + LOG_INFO_IF(log_pthread_file, "scePthreadMutexUnlock name={} result={}\n", (*mutex)->name, + result); switch (result) { case 0: return SCE_OK; @@ -329,6 +344,9 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) { } } +/**** + * Cond calls + */ void* createCond(void* addr) { if (addr == nullptr || *static_cast(addr) != nullptr) { return addr; @@ -361,7 +379,7 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat int result = pthread_cond_init(&(*cond)->cond, &(*attr)->cond_attr); if (name != nullptr) { - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*cond)->name, result); + LOG_INFO_IF(log_pthread_file, "cond init name={},result={}\n", (*cond)->name, result); } switch (result) { @@ -394,7 +412,7 @@ int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr) { } int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) { - LOG_INFO(Kernel_Pthread, "called"); + PRINT_FUNCTION_NAME(); cond = static_cast(createCond(cond)); if (cond == nullptr) { @@ -403,13 +421,15 @@ int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond) { int result = pthread_cond_broadcast(&(*cond)->cond); - LOG_INFO(Kernel_Pthread, "name={}, result={}", (*cond)->name, result); + LOG_INFO_IF(log_pthread_file, "cond broadcast name={},result={}\n", (*cond)->name, result); return (result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL); } - +/**** + * Posix calls + */ int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr) { - LOG_INFO(Kernel_Pthread, "posix pthread_mutex_init redirect to scePthreadMutexInit"); + 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 @@ -421,7 +441,7 @@ int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthre } int PS4_SYSV_ABI posix_pthread_mutex_lock(ScePthreadMutex* mutex) { - LOG_INFO(Kernel_Pthread, "posix pthread_mutex_lock redirect to scePthreadMutexLock"); + 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 @@ -433,7 +453,7 @@ int PS4_SYSV_ABI posix_pthread_mutex_lock(ScePthreadMutex* mutex) { } int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex) { - LOG_INFO(Kernel_Pthread, "posix pthread_mutex_unlock redirect to scePthreadMutexUnlock"); + 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 @@ -445,8 +465,8 @@ int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex) { } int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond) { - LOG_INFO(Kernel_Pthread, - "posix posix_pthread_cond_broadcast redirect to scePthreadCondBroadcast"); + 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 @@ -490,4 +510,4 @@ void pthreadSymbolsRegister(Loader::SymbolsResolver* sym) { LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast); } -} // namespace Core::Libraries::LibKernel +} // namespace Core::Libraries::LibKernel \ No newline at end of file diff --git a/src/core/hle/libraries/libpad/pad.cpp b/src/core/hle/libraries/libpad/pad.cpp index b9bdd8ee..d9588b9e 100644 --- a/src/core/hle/libraries/libpad/pad.cpp +++ b/src/core/hle/libraries/libpad/pad.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "Emulator/Host/controller.h" -#include "common/logging/log.h" +#include "common/log.h" #include "common/singleton.h" #include "core/hle/error_codes.h" #include "core/hle/libraries/libpad/pad.h" @@ -10,14 +10,15 @@ namespace Core::Libraries::LibPad { +constexpr bool log_file_pad = true; // disable it to disable logging + int PS4_SYSV_ABI scePadInit() { - LOG_WARNING(Lib_Pad, "(STUBBED) called"); return SCE_OK; } -int PS4_SYSV_ABI scePadOpen(Core::Libraries::LibUserService::SceUserServiceUserId user_id, s32 type, +int PS4_SYSV_ABI scePadOpen(Core::Libraries::LibUserService::SceUserServiceUserId userId, s32 type, s32 index, const ScePadOpenParam* pParam) { - LOG_INFO(Lib_Pad, "(STUBBED) called user_id = {} type = {} index = {}", user_id, type, index); + LOG_INFO_IF(log_file_pad, "scePadOpen userid = {} type = {} index = {}\n", userId, type, index); return 1; // dummy } diff --git a/src/core/hle/libraries/libs.h b/src/core/hle/libraries/libs.h index 56c90f13..a0f56283 100644 --- a/src/core/hle/libraries/libs.h +++ b/src/core/hle/libraries/libs.h @@ -34,6 +34,15 @@ sym->AddSymbol(sr, func); \ } +#define PRINT_FUNCTION_NAME() \ + { LOG_INFO_IF(true, "{}()\n", __func__); } + +#define PRINT_DUMMY_FUNCTION_NAME() \ + { LOG_WARN_IF(true, "dummy {}()\n", __func__); } + +#define PRINT_UNIMPLEMENTED_FUNCTION_NAME() \ + { LOG_ERROR_IF(true, "{}()\n", __func__); } + namespace Core::Libraries { void InitHLELibs(Loader::SymbolsResolver* sym); diff --git a/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp b/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp index 9f24c280..98aad084 100644 --- a/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp +++ b/src/core/hle/libraries/libscegnmdriver/libscegnmdriver.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/log.h" #include "core/PS4/GPU/gpu_memory.h" #include "core/hle/libraries/libs.h" #include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h" @@ -10,12 +10,12 @@ namespace Core::Libraries::LibSceGnmDriver { int32_t sceGnmSubmitDone() { - LOG_WARNING(Lib_GnmDriver, "(STUBBED) called"); + PRINT_DUMMY_FUNCTION_NAME(); return 0; } void sceGnmFlushGarlic() { - LOG_WARNING(Lib_GnmDriver, "(STUBBED) called"); + PRINT_FUNCTION_NAME(); GPU::flushGarlic(Emu::getGraphicCtx()); } diff --git a/src/core/hle/libraries/libsystemservice/system_service.cpp b/src/core/hle/libraries/libsystemservice/system_service.cpp index b25be615..dfffa3e3 100644 --- a/src/core/hle/libraries/libsystemservice/system_service.cpp +++ b/src/core/hle/libraries/libsystemservice/system_service.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/log.h" #include "core/hle/error_codes.h" #include "core/hle/libraries/libs.h" #include "core/hle/libraries/libsystemservice/system_service.h" @@ -9,7 +9,7 @@ namespace Core::Libraries::LibSystemService { s32 PS4_SYSV_ABI sceSystemServiceHideSplashScreen() { - LOG_WARNING(Lib_SystemService, "(STUBBED) called"); + PRINT_DUMMY_FUNCTION_NAME(); return SCE_OK; } diff --git a/src/core/hle/libraries/libuserservice/libuserservice.cpp b/src/core/hle/libraries/libuserservice/libuserservice.cpp index 0fe3905a..55bf2355 100644 --- a/src/core/hle/libraries/libuserservice/libuserservice.cpp +++ b/src/core/hle/libraries/libuserservice/libuserservice.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/log.h" #include "core/hle/error_codes.h" #include "core/hle/libraries/libs.h" #include "core/hle/libraries/libuserservice/libuserservice.h" @@ -9,12 +9,12 @@ namespace Core::Libraries::LibUserService { s32 PS4_SYSV_ABI sceUserServiceInitialize(const SceUserServiceInitializeParams* initParams) { - LOG_WARNING(Lib_UserService, "(STUBBED) called"); + PRINT_DUMMY_FUNCTION_NAME(); return SCE_OK; } s32 PS4_SYSV_ABI sceUserServiceGetLoginUserIdList(SceUserServiceLoginUserIdList* userIdList) { - LOG_WARNING(Lib_UserService, "(STUBBED) called"); + PRINT_DUMMY_FUNCTION_NAME(); userIdList->user_id[0] = 1; userIdList->user_id[1] = -1; userIdList->user_id[2] = -1; diff --git a/src/core/libraries/libscegnmdriver.cpp b/src/core/libraries/libscegnmdriver.cpp index 3cb81292..4b389ab3 100644 --- a/src/core/libraries/libscegnmdriver.cpp +++ b/src/core/libraries/libscegnmdriver.cpp @@ -2,1264 +2,1264 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Generated By moduleGenerator -#include "common/logging/log.h" +#include "common/log.h" #include "error_codes.h" #include "libscegnmdriver.h" namespace Libraries::GnmDriver { int PS4_SYSV_ABI sceGnmAddEqEvent() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmAreSubmitsAllowed() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmBeginWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmComputeWaitOnAddress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmComputeWaitSemaphore() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmCreateWorkloadStream() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerGetAddressWatch() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerHaltWavefront() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerReadGds() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerReadSqIndirectRegister() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerResumeWavefront() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerResumeWavefrontCreation() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerSetAddressWatch() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerWriteGds() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebuggerWriteSqIndirectRegister() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebugHardwareStatus() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDeleteEqEvent() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDestroyWorkloadStream() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDingDong() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDingDongForWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDisableMipStatsReport() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDispatchDirect() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDispatchIndirect() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDispatchIndirectOnMec() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndex() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexAuto() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexIndirect() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndexOffset() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndirect() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawIndirectMulti() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawOpaqueAuto() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverCaptureInProgress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterface() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuDebugger() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForGpuException() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForHDRScopes() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForReplay() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForResourceRegistration() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterfaceForValidation() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverInternalVirtualQuery() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverTraceInProgress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDriverTriggerCapture() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmEndWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmFindResourcesPublic() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmFlushGarlic() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetCoredumpAddress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetCoredumpMode() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetCoredumpProtectionFaultTimestamp() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetDbgGcHandle() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetDebugTimestamp() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetEqEventType() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetEqTimeStamp() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetGpuBlockStatus() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetGpuCoreClockFrequency() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetGpuInfoStatus() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetLastWaitedAddress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetNumTcaUnits() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetOffChipTessellationBufferSize() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetOwnerName() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetPhysicalCounterFromVirtualized() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetProtectionFaultTimeStamp() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceBaseAddressAndSizeInBytes() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceName() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceShaderGuid() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceType() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceUserData() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetShaderProgramBaseAddress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetShaderStatus() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGpuPaDebugEnter() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGpuPaDebugLeave() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertDingDongMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertPopMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertPushColorMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertPushMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertSetColorMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertSetMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertThreadTraceMarker() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmInsertWaitFlipDone() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmIsCoredumpValid() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmIsUserPaEnabled() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmLogicalCuIndexToPhysicalCuIndex() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmLogicalCuMaskToPhysicalCuMask() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmLogicalTcaUnitToPhysical() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmMapComputeQueue() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmPaDisableFlipCallbacks() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmPaEnableFlipCallbacks() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmPaHeartbeat() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmQueryResourceRegistrationUserMemoryRequirements() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRaiseUserExceptionEvent() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRegisterGdsResource() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRegisterGnmLiveCallbackConfig() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRegisterOwner() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRegisterResource() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDone() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRequestFlipAndSubmitDoneForWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRequestMipStatsReportAndReset() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmResetVgtControl() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaClose() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaConstFill() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaCopyLinear() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaCopyTiled() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaCopyWindow() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaFlush() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaGetMinCmdSize() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSdmaOpen() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetCsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetCsShaderWithModifier() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetEmbeddedPsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetEmbeddedVsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetEsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetGsRingSizes() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetGsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetHsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetLsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetPsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetPsShader350() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetResourceRegistrationUserMemory() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetResourceUserData() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetSpiEnableSqCounters() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetSpiEnableSqCountersForUnitInstance() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetupMipStatsReport() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetVgtControl() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetVsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetWaveLimitMultiplier() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSetWaveLimitMultipliers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmEndSpm() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmInit() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmInit2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetDelay() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetMuxRam() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetMuxRam2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetSelectCounter() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetSpmSelects() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmSetSpmSelects2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSpmStartSpm() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttFini() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttFinishTrace() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetBcInfo() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetGpuClocks() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetHiWater() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetStatus() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetTraceCounter() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetTraceWptr() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetWrapCounts() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetWrapCounts2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttGetWritebackLabels() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttInit() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSelectMode() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSelectTarget() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSelectTokens() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetCuPerfMask() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetDceEventWrite() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetHiWater() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetTraceBuffer2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetTraceBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetUserData() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSetUserdataTimer() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttStartTrace() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttStopTrace() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttSwitchTraceBuffer2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSqttWaitForEvent() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSubmitCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSubmitCommandBuffersForWorkload() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmSubmitDone() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUnmapComputeQueue() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUnregisterAllResourcesForOwner() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUnregisterOwnerAndResources() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUnregisterResource() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUpdateGsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUpdateHsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUpdatePsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUpdatePsShader350() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmUpdateVsShader() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateDisableDiagnostics2() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateDispatchCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateDrawCommandBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateGetDiagnosticInfo() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateGetDiagnostics() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateGetVersion() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateOnSubmitEnabled() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidateResetState() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmValidationRegisterMemoryCheckCallback() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlyImmediate() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceRazorCaptureCommandBuffersOnlySinceLastFlip() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceRazorCaptureImmediate() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceRazorCaptureSinceLastFlip() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceRazorIsLoaded() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_063D065A2D6359C3() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_0CABACAFB258429D() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_150CF336FC2E99A3() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_17CA687F9EE52D49() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_1870B89F759C6B45() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_26F9029EF68A955E() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_301E3DBBAB092DB0() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_30BAFE172AF17FEF() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_3E6A3E8203D95317() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_40FEEF0C6534C434() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_416B9079DE4CBACE() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_4774D83BB4DDBF9A() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_50678F1CCEEB9A00() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_54A2EC5FA4C62413() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_5A9C52C83138AE6B() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_5D22193A31EA1142() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_725A36DEBB60948D() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_8021A502FA61B9BB() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_9D002FE0FA40F0E6() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_9D297F36A7028B71() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_A2D7EC7A7BCF79B3() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_AA12A3CB8990854A() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_ADC8DDC005020BC6() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_B0A8688B679CB42D() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_B489020B5157A5FF() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_BADE7B4C199140DD() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_D1511B9DCFFB3DD9() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_D53446649B02E58E() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_D8B6E8E28E1EF0A3() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_D93D733A19DD7454() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_DE995443BC2A8317() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_DF6E9528150C23FF() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_ECB4C6BA41FE3350() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebugModuleReset() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDebugReset() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_C4C328B7CF3B4171() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalCommand() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextStateInternalSize() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmFindResources() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmGetResourceRegistrationBuffers() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI sceGnmRegisterOwnerForSystem() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_1C43886B16EE5530() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_81037019ECCD0E01() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_BFB41C057478F0BF() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_E51D44DB8151238C() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } int PS4_SYSV_ABI Func_F916890425496553() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); + PRINT_UNIMPLEMENTED_FUNCTION_NAME(); return ORBIS_OK; } @@ -1735,4 +1735,4 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { Func_BADE7B4C199140DD); }; -} // namespace Libraries::GnmDriver +} // namespace Libraries::GnmDriver \ No newline at end of file diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 0cbeb4c7..7bf7691e 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -2,29 +2,31 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "common/logging/log.h" +#include +#include "common/log.h" #include "common/string_util.h" #include "core/aerolib/aerolib.h" #include "core/aerolib/stubs.h" #include "core/hle/libraries/libkernel/thread_management.h" #include "core/linker.h" -#include "core/tls.h" #include "core/virtual_memory.h" namespace Core { -static constexpr u64 LoadAddress = SYSTEM_RESERVED + CODE_BASE_OFFSET; +constexpr bool debug_loader = true; -static u64 GetAlignedSize(const elf_program_header& phdr) { +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 CalculateBaseSize(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)) { - u64 last_addr = phdr[i].p_vaddr + GetAlignedSize(phdr[i]); + u64 last_addr = phdr[i].p_vaddr + get_aligned_size(phdr[i]); if (last_addr > base_size) { base_size = last_addr; } @@ -33,7 +35,7 @@ static u64 CalculateBaseSize(const elf_header& ehdr, std::span(); - m->elf.Open(elf_name); + m.linker = this; + m.elf.Open(elf_name); - if (m->elf.IsElfFile()) { - LoadModuleToMemory(m.get()); - LoadDynamicInfo(m.get()); - LoadSymbols(m.get()); - Relocate(m.get()); + if (m.elf.isElfFile()) { + LoadModuleToMemory(&m); + LoadDynamicInfo(&m); + LoadSymbols(&m); + Relocate(&m); } else { m_modules.pop_back(); return nullptr; // It is not a valid elf file //TODO check it why! } - return m.get(); + 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; } - return m_modules[0].get(); + return &m_modules[0]; +} + +struct TLSPattern { + uint8_t pattern[5]; + uint8_t pattern_size; + uint8_t imm_size; + uint8_t target_reg; +}; + +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, 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) { + uint8_t* code = (uint8_t*)segment_addr; + auto remaining_size = segment_size; + + while (remaining_size) { + for (auto& tls_pattern : tls_patterns) { + auto total_size = tls_pattern.pattern_size + tls_pattern.imm_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)); + else + 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); + code += total_size - 1; + remaining_size -= total_size - 1; + break; + } + } + } + code++; + remaining_size--; + } } void Linker::LoadModuleToMemory(Module* m) { @@ -93,18 +155,18 @@ void Linker::LoadModuleToMemory(Module* m) { const auto elf_header = m->elf.GetElfHeader(); const auto elf_pheader = m->elf.GetProgramHeader(); - u64 base_size = CalculateBaseSize(elf_header, elf_pheader); + 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(LoadAddress, m->aligned_base_size, + m->base_virtual_addr = VirtualMemory::memory_alloc(g_load_addr, m->aligned_base_size, VirtualMemory::MemoryMode::ExecuteReadWrite); - LOG_INFO(Core_Linker, "====Load Module to Memory ========"); - LOG_INFO(Core_Linker, "base_virtual_addr ......: {:#018x}", m->base_virtual_addr); - LOG_INFO(Core_Linker, "base_size ..............: {:#018x}", base_size); - LOG_INFO(Core_Linker, "aligned_base_size ......: {:#018x}", 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) { @@ -113,14 +175,14 @@ void Linker::LoadModuleToMemory(Module* m) { 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 = GetAlignedSize(elf_pheader[i]); + u64 segment_memory_size = get_aligned_size(elf_pheader[i]); auto segment_mode = m->elf.ElfPheaderFlagsStr(elf_pheader[i].p_flags); - LOG_INFO(Core_Linker, "program header = [{}] type = {}", i, - m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); - LOG_INFO(Core_Linker, "segment_addr ..........: {:#018x}", segment_addr); - LOG_INFO(Core_Linker, "segment_file_size .....: {}", segment_file_size); - LOG_INFO(Core_Linker, "segment_memory_size ...: {}", segment_memory_size); - LOG_INFO(Core_Linker, "segment_mode ..........: {}", segment_mode); + 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); @@ -128,8 +190,8 @@ void Linker::LoadModuleToMemory(Module* m) { PatchTLS(segment_addr, segment_file_size); } } else { - LOG_ERROR(Core_Linker, "p_memsz==0 in type {}", - m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + LOG_ERROR_IF(debug_loader, "p_memsz==0 in type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); } break; case PT_DYNAMIC: @@ -138,8 +200,8 @@ void Linker::LoadModuleToMemory(Module* m) { m->elf.LoadSegment(reinterpret_cast(m->m_dynamic.data()), elf_pheader[i].p_offset, elf_pheader[i].p_filesz); } else { - LOG_ERROR(Core_Linker, "p_filesz==0 in type {}", - m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + LOG_ERROR_IF(debug_loader, "p_filesz==0 in type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); } break; case PT_SCE_DYNLIBDATA: @@ -148,23 +210,23 @@ void Linker::LoadModuleToMemory(Module* m) { m->elf.LoadSegment(reinterpret_cast(m->m_dynamic_data.data()), elf_pheader[i].p_offset, elf_pheader[i].p_filesz); } else { - LOG_ERROR(Core_Linker, "p_filesz==0 in type {}", - m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + 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 = GetAlignedSize(elf_pheader[i]); - LOG_INFO(Core_Linker, "tls virtual address ={:#x}", m->tls.image_virtual_addr); - LOG_INFO(Core_Linker, "tls image size ={}", m->tls.image_size); + 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(Core_Linker, "Unimplemented type {}", - m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); + LOG_ERROR_IF(debug_loader, "Unimplemented type {}\n", + m->elf.ElfPheaderTypeStr(elf_pheader[i].p_type)); } } - LOG_INFO(Core_Linker, "program entry addr ..........: {:#018x}", - m->elf.GetElfEntry() + m->base_virtual_addr); + LOG_INFO_IF(debug_loader, "program entry addr ..........: {:#018x}\n", + m->elf.GetElfEntry() + m->base_virtual_addr); } void Linker::LoadDynamicInfo(Module* m) { @@ -211,7 +273,7 @@ void Linker::LoadDynamicInfo(Module* m) { 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_WARNING(Core_Linker, "DT_SCE_PLTREL is NOT DT_RELA should check!"); + LOG_WARN_IF(debug_loader, "DT_SCE_PLTREL is NOT DT_RELA should check!"); } break; case DT_SCE_RELA: // Offset of the relocation table. @@ -226,7 +288,7 @@ void Linker::LoadDynamicInfo(Module* m) { if (m->dynamic_info.relocation_table_entries_size != 0x18) // this value should always be 0x18 { - LOG_WARNING(Core_Linker, "DT_SCE_RELAENT is NOT 0x18 should check!"); + 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 @@ -252,7 +314,7 @@ void Linker::LoadDynamicInfo(Module* m) { if (m->dynamic_info.symbol_table_entries_size != 0x18) // this value should always be 0x18 { - LOG_WARNING(Core_Linker, "DT_SCE_SYMENT is NOT 0x18 should check!"); + LOG_WARN_IF(debug_loader, "DT_SCE_SYMENT is NOT 0x18 should check!"); } break; case DT_DEBUG: @@ -265,7 +327,7 @@ void Linker::LoadDynamicInfo(Module* m) { m->dynamic_info.flags = dyn->d_un.d_val; if (m->dynamic_info.flags != 0x04) // this value should always be DF_TEXTREL (0x04) { - LOG_WARNING(Core_Linker, "DT_FLAGS is NOT 0x04 should check!"); + 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. @@ -274,21 +336,21 @@ void Linker::LoadDynamicInfo(Module* m) { { m->dynamic_info.needed.push_back(m->dynamic_info.str_table + dyn->d_un.d_val); } else { - LOG_ERROR(Core_Linker, "DT_NEEDED str table is not loaded should check!"); + 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); + 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); + info.enc_id = encodeId(info.id); m->dynamic_info.import_libs.push_back(info); } break; case DT_SCE_FINGERPRINT: @@ -296,14 +358,16 @@ void Linker::LoadDynamicInfo(Module* m) { // 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(Core_Linker, "unsupported DT_SCE_FINGERPRINT value = ..........: {:#018x}", - dyn->d_un.d_val); + 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(Core_Linker, "unsupported DT_SCE_IMPORT_LIB_ATTR value = ......: {:#018x}", - dyn->d_un.d_val); + 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; @@ -313,23 +377,24 @@ void Linker::LoadDynamicInfo(Module* m) { 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); + info.enc_id = encodeId(info.id); m->dynamic_info.export_modules.push_back(info); } break; case DT_SCE_MODULE_ATTR: // TODO? - LOG_INFO(Core_Linker, "unsupported DT_SCE_MODULE_ATTR value = ..........: {:#018x}", - dyn->d_un.d_val); + 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); + info.enc_id = encodeId(info.id); m->dynamic_info.export_libs.push_back(info); } break; default: - LOG_INFO(Core_Linker, "unsupported dynamic tag ..........: {:#018x}", dyn->d_tag); + LOG_INFO_IF(debug_loader, "unsupported dynamic tag ..........: {:#018x}\n", dyn->d_tag); } } } @@ -377,7 +442,7 @@ const LibraryInfo* Linker::FindLibrary(const Module& m, const std::string& id) { 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(Core_Linker, "Symbol table not found!"); + LOG_INFO_IF(debug_loader, "Symbol table not found!\n"); return; } @@ -401,8 +466,8 @@ void Linker::LoadSymbols(Module* m) { case STB_WEAK: break; default: - LOG_INFO(Core_Linker, "Unsupported bind {} for name symbol {}", bind, - ids.at(0)); + LOG_INFO_IF(debug_loader, "Unsupported bind {} for name symbol {} \n", bind, + ids.at(0)); continue; } switch (type) { @@ -410,16 +475,16 @@ void Linker::LoadSymbols(Module* m) { case STT_FUN: break; default: - LOG_INFO(Core_Linker, "Unsupported type {} for name symbol {}", type, - ids.at(0)); + 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(Core_Linker, "Unsupported visibility {} for name symbol {}", - visibility, ids.at(0)); + 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 @@ -450,98 +515,97 @@ void Linker::LoadSymbols(Module* m) { m->import_sym.AddSymbol(sym_r, 0); } - LOG_INFO(Core_Linker, - "name = {}, function = {}, library = {}, module = {}, bind = {}, type = " - "{}, visibility = {}", - 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(); + auto symbol = rel->GetSymbol(); + auto addend = rel->rel_addend; + auto* symbolsTlb = m->dynamic_info.symbol_table; + auto* namesTlb = m->dynamic_info.str_table; + + u64 rel_value = 0; + u64 rel_base_virtual_addr = m->base_virtual_addr; + u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset; + bool rel_isResolved = false; + u8 rel_sym_type = 0; + 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 + { + 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); + } + + } 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); + } +} void Linker::Relocate(Module* m) { - const auto relocate = [this](u32 idx, elf_relocation* rel, Module* m, bool isJmpRel) { - auto type = rel->GetType(); - auto symbol = rel->GetSymbol(); - auto addend = rel->rel_addend; - auto* symbolsTlb = m->dynamic_info.symbol_table; - auto* namesTlb = m->dynamic_info.str_table; - - u64 rel_value = 0; - u64 rel_base_virtual_addr = m->base_virtual_addr; - u64 rel_virtual_addr = m->base_virtual_addr + rel->rel_offset; - bool rel_isResolved = false; - u8 rel_sym_type = 0; - std::string rel_name; - - switch (type) { - case R_X86_64_RELATIVE: - if (symbol != 0) // should be always zero - { - // LOG_INFO(Core_Linker, "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(Core_Linker, "unknown symbol type {}", sym_type); - } - if (sym_visibility != 0) // should be zero log if else - { - LOG_INFO(Core_Linker, "symbol visilibity !=0"); - } - switch (sym_bind) { - case STB_GLOBAL: - rel_name = namesTlb + sym.st_name; - 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(Core_Linker, - "R_X86_64_64-R_X86_64_JUMP_SLOT sym_type {} bind STB_GLOBAL symbol : " - "{:#010x}", - sym_type, symbol); - } - break; - default: - LOG_INFO(Core_Linker, "UNK bind {}", sym_bind); - } - - } break; - default: - LOG_INFO(Core_Linker, "UNK type {:#010x} rel symbol : {:#010x}", type, symbol); - } - - if (rel_isResolved) { - VirtualMemory::memory_patch(rel_virtual_addr, rel_value); - } else { - LOG_INFO(Core_Linker, "function not patched! {}", rel_name); - } - }; - u32 idx = 0; for (auto* rel = m->dynamic_info.relocation_table; reinterpret_cast(rel) < reinterpret_cast(m->dynamic_info.relocation_table) + @@ -590,8 +654,8 @@ void Linker::Resolve(const std::string& name, int Symtype, Module* m, return_info->virtual_address = AeroLib::GetStub(sr.name.c_str()); return_info->name = "Unknown !!!"; } - LOG_ERROR(Core_Linker, "Linker: Stub resolved {} as {} (lib: {}, mod: {})", 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 { //__debugbreak();//den tha prepei na ftasoume edo @@ -608,7 +672,7 @@ static PS4_SYSV_ABI void ProgramExitFunc() { fmt::print("exit function called\n"); } -static void RunMainEntry(u64 addr, EntryParams* params, exit_func_t exit_func) { +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 @@ -638,7 +702,7 @@ void Linker::Execute() { p.argv[0] = "eboot.bin"; // hmm should be ok? const auto& module = m_modules.at(0); - RunMainEntry(module->elf.GetElfEntry() + module->base_virtual_addr, &p, ProgramExitFunc); + run_main_entry(module.elf.GetElfEntry() + module.base_virtual_addr, &p, ProgramExitFunc); } } // namespace Core diff --git a/src/core/linker.h b/src/core/linker.h index 89d556b2..5ee28f59 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -51,7 +51,6 @@ struct PS4ThreadLocal { u64 image_size = 0; u64 handler_virtual_addr = 0; }; - struct DynamicModuleInfo { void* hash_table = nullptr; u64 hash_table_size = 0; @@ -98,7 +97,9 @@ struct DynamicModuleInfo { struct Module { Loader::Elf elf; u64 aligned_base_size = 0; - u64 base_virtual_addr = 0; + u64 base_virtual_addr = 0; // Base virtual address + + Linker* linker = nullptr; std::vector m_dynamic; std::vector m_dynamic_data; @@ -115,8 +116,8 @@ public: Linker(); virtual ~Linker(); - Module* LoadModule(const std::filesystem::path& elf_name); - Module* FindModule(u32 id = 0); + Module* LoadModule(const std::string& elf_name); + Module* FindModule(/*u32 id*/); void LoadModuleToMemory(Module* m); void LoadDynamicInfo(Module* m); void LoadSymbols(Module* m); @@ -132,7 +133,7 @@ private: const ModuleInfo* FindModule(const Module& m, const std::string& id); const LibraryInfo* FindLibrary(const Module& program, const std::string& id); - std::vector> m_modules; + std::vector m_modules; Loader::SymbolsResolver m_hle_symbols{}; std::mutex m_mutex; }; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 2e6dd60d..a10cf999 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -2,15 +2,15 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "common/assert.h" -#include "common/logging/log.h" +#include "common/debug.h" +#include "common/log.h" #include "core/loader/elf.h" namespace Core::Loader { -using namespace Common::FS; +constexpr bool log_file_loader = false; // disable it to disable logging -static std::string_view GetProgramTypeName(program_type_es type) { +static std::string_view getProgramTypeName(program_type_es type) { switch (type) { case PT_FAKE: return "PT_FAKE"; @@ -33,7 +33,7 @@ static std::string_view GetProgramTypeName(program_type_es type) { } } -static std::string_view GetIdentClassName(ident_class_es elf_class) { +static std::string_view getIdentClassName(ident_class_es elf_class) { switch (elf_class) { case ELF_CLASS_NONE: return "ELF_CLASS_NONE"; @@ -48,7 +48,7 @@ static std::string_view GetIdentClassName(ident_class_es elf_class) { } } -static std::string_view GetIdentEndianName(ident_endian_es endian) { +static std::string_view getIdentEndianName(ident_endian_es endian) { switch (endian) { case ELF_DATA_NONE: return "ELF_DATA_NONE"; @@ -63,7 +63,7 @@ static std::string_view GetIdentEndianName(ident_endian_es endian) { } } -static std::string_view GetIdentVersionName(ident_version_es version) { +static std::string_view getIdentVersionName(ident_version_es version) { switch (version) { case ELF_VERSION_NONE: return "ELF_VERSION_NONE"; @@ -76,7 +76,7 @@ static std::string_view GetIdentVersionName(ident_version_es version) { } } -static std::string_view GetIdentOsabiName(ident_osabi_es osabi) { +static std::string_view getIdentOsabiName(ident_osabi_es osabi) { switch (osabi) { case ELF_OSABI_NONE: return "ELF_OSABI_NONE"; @@ -117,7 +117,7 @@ static std::string_view GetIdentOsabiName(ident_osabi_es osabi) { } } -static std::string_view GetIdentAbiversionName(ident_abiversion_es version) { +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"; @@ -131,7 +131,7 @@ static std::string_view GetIdentAbiversionName(ident_abiversion_es version) { return "INVALID"; } } -static std::string_view GetVersion(e_version_es version) { +static std::string_view getVersion(e_version_es version) { switch (version) { case EV_NONE: return "EV_NONE"; @@ -142,7 +142,7 @@ static std::string_view GetVersion(e_version_es version) { } } -static std::string_view GetType(e_type_s type) { +static std::string_view getType(e_type_s type) { switch (type) { case ET_NONE: return "ET_NONE"; @@ -167,7 +167,7 @@ static std::string_view GetType(e_type_s type) { } } -static std::string_view GetMachine(e_machine_es machine) { +static std::string_view getMachine(e_machine_es machine) { switch (machine) { case EM_X86_64: return "EM_X86_64"; @@ -176,25 +176,30 @@ static std::string_view GetMachine(e_machine_es machine) { } } -Elf::~Elf() = default; +Elf::~Elf() { + Reset(); +} -void Elf::Open(const std::filesystem::path& file_name) { - m_f.Open(file_name, FileAccessMode::Read); - if (!m_f.ReadObject(m_self)) { - LOG_ERROR(Loader, "Unable to read self header!"); - return; - } +void Elf::Reset() { + m_f.close(); +} - if (is_self = IsSelfFile(); !is_self) { - m_f.Seek(0, SeekOrigin::SetOrigin); +void Elf::Open(const std::string& file_name) { + Reset(); + + m_f.open(file_name, Common::FS::OpenMode::Read); + m_f.read(m_self); + + if (is_self = isSelfFile(); !is_self) { + m_f.seek(0, Common::FS::SeekMode::Set); } else { m_self_segments.resize(m_self.segment_count); - m_f.Read(m_self_segments); + m_f.read(m_self_segments); } - const u64 elf_header_pos = m_f.Tell(); - m_f.Read(m_elf_header); - if (!IsElfFile()) { + const u64 elf_header_pos = m_f.tell(); + m_f.read(m_elf_header); + if (!isElfFile()) { return; } @@ -204,8 +209,8 @@ void Elf::Open(const std::filesystem::path& file_name) { } out.resize(num); - m_f.Seek(offset, SeekOrigin::SetOrigin); - m_f.Read(out); + m_f.seek(offset, Common::FS::SeekMode::Set); + m_f.read(out); }; load_headers(m_elf_phdr, elf_header_pos + m_elf_header.e_phoff, m_elf_header.e_phnum); @@ -222,95 +227,96 @@ void Elf::Open(const std::filesystem::path& file_name) { header_size &= ~15; // Align if (m_elf_header.e_ehsize - header_size >= sizeof(elf_program_id_header)) { - m_f.Seek(header_size, SeekOrigin::SetOrigin); - m_f.ReadObject(m_self_id_header); + m_f.seek(header_size, Common::FS::SeekMode::Set); + m_f.read(m_self_id_header); } } DebugDump(); } -bool Elf::IsSelfFile() const { +bool Elf::isSelfFile() const { if (m_self.magic != self_header::signature) [[unlikely]] { - LOG_INFO(Loader, "Not a SELF file. Magic mismatch current = {:#x} expected = {:#x}", - 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]] { - LOG_INFO(Loader, "Unknown SELF file"); + LOG_ERROR_IF(log_file_loader, "Unknown SELF file\n"); return false; } if (m_self.category != 0x01 || m_self.program_type != 0x01) [[unlikely]] { - LOG_INFO(Loader, "Unknown SELF file"); + LOG_ERROR_IF(log_file_loader, "Unknown SELF file\n"); return false; } return true; } -bool Elf::IsElfFile() 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) { - LOG_INFO(Loader, "Not an ELF file magic is wrong!"); + 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_INFO(Loader, "e_ident[EI_CLASS] expected 0x02 is ({:#x})", - 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_INFO(Loader, "e_ident[EI_DATA] expected 0x01 is ({:#x})", - 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_INFO(Loader, "e_ident[EI_VERSION] expected 0x01 is ({:#x})", - 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_INFO(Loader, "e_ident[EI_OSABI] expected 0x09 is ({:#x})", - 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_INFO(Loader, "e_ident[EI_ABIVERSION] expected 0x00 is ({:#x})", - 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_INFO(Loader, "e_type expected 0xFE10 OR 0xFE18 OR 0xfe00 is ({:#x})", - static_cast(m_elf_header.e_type)); + 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_INFO(Loader, "e_machine expected 0x3E is ({:#x})", - 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_INFO(Loader, "m_elf_header.e_version expected 0x01 is ({:#x})", - 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_INFO(Loader, "e_phentsize ({}) != sizeof(elf_program_header)", - 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; } @@ -318,8 +324,8 @@ bool Elf::IsElfFile() const { m_elf_header.e_shentsize != sizeof(elf_section_header)) // Commercial games doesn't appear to have section headers { - LOG_INFO(Loader, "e_shentsize ({}) != sizeof(elf_section_header)", - 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; } @@ -328,49 +334,50 @@ bool Elf::IsElfFile() const { void Elf::DebugDump() { if (is_self) { // If we load elf instead - LOG_INFO(Loader, "{}", SElfHeaderStr()); + LOG_INFO_IF(log_file_loader, (SElfHeaderStr())); for (u16 i = 0; i < m_self.segment_count; i++) { - LOG_INFO(Loader, "{}", SELFSegHeader(i)); + LOG_INFO_IF(log_file_loader, SELFSegHeader(i)); } } - LOG_INFO(Loader, "{}", ElfHeaderStr()); + LOG_INFO_IF(log_file_loader, ElfHeaderStr()); if (m_elf_header.e_phentsize > 0) { - LOG_INFO(Loader, "Program headers:"); + LOG_INFO_IF(log_file_loader, "Program headers:\n"); for (u16 i = 0; i < m_elf_header.e_phnum; i++) { - LOG_INFO(Loader, "{}", ElfPHeaderStr(i)); + LOG_INFO_IF(log_file_loader, ElfPHeaderStr(i)); } } if (m_elf_header.e_shentsize > 0) { - LOG_INFO(Loader, "Section headers:"); + LOG_INFO_IF(log_file_loader, "Section headers:\n"); for (u16 i = 0; i < m_elf_header.e_shnum; i++) { - LOG_INFO(Loader, "--- shdr {} --", i); - LOG_INFO(Loader, "sh_name ........: {}", m_elf_shdr[i].sh_name); - LOG_INFO(Loader, "sh_type ........: {:#010x}", m_elf_shdr[i].sh_type); - LOG_INFO(Loader, "sh_flags .......: {:#018x}", m_elf_shdr[i].sh_flags); - LOG_INFO(Loader, "sh_addr ........: {:#018x}", m_elf_shdr[i].sh_addr); - LOG_INFO(Loader, "sh_offset ......: {:#018x}", m_elf_shdr[i].sh_offset); - LOG_INFO(Loader, "sh_size ........: {:#018x}", m_elf_shdr[i].sh_size); - LOG_INFO(Loader, "sh_link ........: {:#010x}", m_elf_shdr[i].sh_link); - LOG_INFO(Loader, "sh_info ........: {:#010x}", m_elf_shdr[i].sh_info); - LOG_INFO(Loader, "sh_addralign ...: {:#018x}", m_elf_shdr[i].sh_addralign); - LOG_INFO(Loader, "sh_entsize .....: {:#018x}", m_elf_shdr[i].sh_entsize); + LOG_INFO_IF(log_file_loader, "--- shdr {} --\n", i); + LOG_INFO_IF(log_file_loader, "sh_name ........: {}\n", m_elf_shdr[i].sh_name); + LOG_INFO_IF(log_file_loader, "sh_type ........: {:#010x}\n", m_elf_shdr[i].sh_type); + LOG_INFO_IF(log_file_loader, "sh_flags .......: {:#018x}\n", m_elf_shdr[i].sh_flags); + LOG_INFO_IF(log_file_loader, "sh_addr ........: {:#018x}\n", m_elf_shdr[i].sh_addr); + LOG_INFO_IF(log_file_loader, "sh_offset ......: {:#018x}\n", m_elf_shdr[i].sh_offset); + 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_entsize .....: {:#018x}\n", m_elf_shdr[i].sh_entsize); } } if (is_self) { - LOG_INFO(Loader, "SELF info:"); - LOG_INFO(Loader, "auth id ............: {:#018x}", m_self_id_header.authid); - LOG_INFO(Loader, "program type .......: {}", - GetProgramTypeName(m_self_id_header.program_type)); - LOG_INFO(Loader, "app version ........: {:#018x}", m_self_id_header.appver); - LOG_INFO(Loader, "fw version .........: {:#018x}", m_self_id_header.firmver); + 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, "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; for (int i = 0; i < 32; i++) { digest += fmt::format("{:02X}", m_self_id_header.digest[i]); } - LOG_INFO(Loader, "digest..............: 0x{}", digest); + LOG_INFO_IF(log_file_loader, "digest..............: 0x{}\n", digest); } } @@ -413,15 +420,15 @@ std::string Elf::ElfHeaderStr() { header += fmt::format("\n"); header += - fmt::format("ident class.......: {}\n", GetIdentClassName(m_elf_header.e_ident.ei_class)); + 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)); + 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)); + getIdentVersionName(m_elf_header.e_ident.ei_version)); header += - fmt::format("ident osabi .....: {}\n", GetIdentOsabiName(m_elf_header.e_ident.ei_osabi)); + 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)); + getIdentAbiversionName(m_elf_header.e_ident.ei_abiversion)); header += fmt::format("ident UNK ........: 0x"); for (auto i : m_elf_header.e_ident.pad) { @@ -429,9 +436,9 @@ std::string Elf::ElfHeaderStr() { } header += fmt::format("\n"); - header += fmt::format("type ............: {}\n", GetType(m_elf_header.e_type)); - header += fmt::format("machine ..........: {}\n", GetMachine(m_elf_header.e_machine)); - header += fmt::format("version ..........: {}\n", GetVersion(m_elf_header.e_version)); + header += fmt::format("type ............: {}\n", getType(m_elf_header.e_type)); + header += fmt::format("machine ..........: {}\n", getMachine(m_elf_header.e_machine)); + header += fmt::format("version ..........: {}\n", getVersion(m_elf_header.e_version)); header += fmt::format("entry ............: {:#018x}\n", m_elf_header.e_entry); header += fmt::format("phoff ............: {:#018x}\n", m_elf_header.e_phoff); header += fmt::format("shoff ............: {:#018x}\n", m_elf_header.e_shoff); @@ -515,8 +522,8 @@ std::string Elf::ElfPHeaderStr(u16 no) { void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) { if (!is_self) { // It's elf file - m_f.Seek(file_offset, SeekOrigin::SetOrigin); - m_f.ReadRaw(reinterpret_cast(virtual_addr), size); + m_f.seek(file_offset, Common::FS::SeekMode::Set); + m_f.read(reinterpret_cast(static_cast(virtual_addr)), size); return; } @@ -529,13 +536,13 @@ void Elf::LoadSegment(u64 virtual_addr, u64 file_offset, u64 size) { if (file_offset >= phdr.p_offset && file_offset < phdr.p_offset + phdr.p_filesz) { auto offset = file_offset - phdr.p_offset; - m_f.Seek(offset + seg.file_offset, SeekOrigin::SetOrigin); - m_f.ReadRaw(reinterpret_cast(virtual_addr), size); + m_f.seek(offset + seg.file_offset, Common::FS::SeekMode::Set); + m_f.read(reinterpret_cast(static_cast(virtual_addr)), size); return; } } } - UNREACHABLE(); + 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 3a8df6be..9a570f28 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -8,11 +8,11 @@ #include #include -#include "common/io_file.h" +#include "common/fs_file.h" #include "common/types.h" struct self_header { - static constexpr u32 signature = 0x1D3D154Fu; + static const u32 signature = 0x1D3D154Fu; u32 magic; u8 version; @@ -455,11 +455,11 @@ namespace Core::Loader { class Elf { public: Elf() = default; - ~Elf(); + virtual ~Elf(); - void Open(const std::filesystem::path& file_name); - bool IsSelfFile() const; - bool IsElfFile() const; + void Open(const std::string& file_name); + bool isSelfFile() const; + bool isElfFile() const; void DebugDump(); [[nodiscard]] self_header GetSElfHeader() const { @@ -492,7 +492,10 @@ public: void LoadSegment(u64 virtual_addr, u64 file_offset, u64 size); private: - Common::FS::IOFile m_f{}; + void Reset(); + +private: + Common::FS::File m_f{}; bool is_self{}; self_header m_self{}; std::vector m_self_segments; diff --git a/src/core/loader/symbols_resolver.cpp b/src/core/loader/symbols_resolver.cpp index 9c90875b..221e764e 100644 --- a/src/core/loader/symbols_resolver.cpp +++ b/src/core/loader/symbols_resolver.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/logging/log.h" +#include "common/log.h" #include "common/types.h" #include "core/loader/symbols_resolver.h" @@ -27,7 +27,7 @@ const SymbolRecord* SymbolsResolver::FindSymbol(const SymbolRes& s) const { } } - LOG_INFO(Core_Linker, "Unresolved! {}", name); + LOG_INFO("Unresolved! {}\n", name); return nullptr; } diff --git a/src/core/tls.cpp b/src/core/tls.cpp deleted file mode 100644 index 6291d1ab..00000000 --- a/src/core/tls.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/types.h" -#include "core/tls.h" - -#ifdef _WIN32 -#include -#endif - -namespace Core { - -thread_local u8 TLS[1024]; - -struct TLSPattern { - uint8_t pattern[5]; - uint8_t pattern_size; - uint8_t imm_size; - uint8_t target_reg; -}; - -constexpr static TLSPattern TlsPatterns[] = { - {{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 -}; - -uintptr_t GetGuestTls(s64 tls_offset) { - if (tls_offset == 0) { - return reinterpret_cast(TLS); - } - UNREACHABLE_MSG("Unimplemented offset info tls"); -} - -#ifdef _WIN64 -static LONG WINAPI ExceptionHandler(PEXCEPTION_POINTERS pExp) noexcept { - auto orig_rip = pExp->ContextRecord->Rip; - while (*(u8*)pExp->ContextRecord->Rip == 0x66) { - pExp->ContextRecord->Rip++; - } - - if (*(u8*)pExp->ContextRecord->Rip == 0xcd) { - int reg = *(u8*)(pExp->ContextRecord->Rip + 1) - 0x80; - int sizes = *(u8*)(pExp->ContextRecord->Rip + 2); - int pattern_size = sizes & 0xF; - int imm_size = sizes >> 4; - - int64_t tls_offset; - if (imm_size == 4) { - tls_offset = *(s32*)(pExp->ContextRecord->Rip + pattern_size); - } else { - tls_offset = *(s64*)(pExp->ContextRecord->Rip + pattern_size); - } - - (&pExp->ContextRecord->Rax)[reg] = GetGuestTls(tls_offset); /* GetGuestTls */ - pExp->ContextRecord->Rip += pattern_size + imm_size; - - return EXCEPTION_CONTINUE_EXECUTION; - } - - pExp->ContextRecord->Rip = orig_rip; - const u32 ec = pExp->ExceptionRecord->ExceptionCode; - switch (ec) { - case EXCEPTION_ACCESS_VIOLATION: { - LOG_CRITICAL(Core, "Exception EXCEPTION_ACCESS_VIOLATION ({:#x})", ec); - const auto info = pExp->ExceptionRecord->ExceptionInformation; - switch (info[0]) { - case 0: - LOG_CRITICAL(Core, "Read violation at address {:#x}", info[1]); - break; - case 1: - LOG_CRITICAL(Core, "Write violation at address {:#x}", info[1]); - break; - case 8: - LOG_CRITICAL(Core, "DEP violation at address {:#x}", info[1]); - break; - default: - break; - } - break; - } - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - LOG_CRITICAL(Core, "Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({:#x})", ec); - break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - LOG_CRITICAL(Core, "Exception EXCEPTION_DATATYPE_MISALIGNMENT ({:#x})", ec); - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - LOG_CRITICAL(Core, "Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({:#x})", ec); - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - LOG_CRITICAL(Core, "Exception EXCEPTION_ILLEGAL_INSTRUCTION ({:#x})", ec); - break; - case EXCEPTION_IN_PAGE_ERROR: - LOG_CRITICAL(Core, "Exception EXCEPTION_IN_PAGE_ERROR ({:#x})", ec); - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - LOG_CRITICAL(Core, "Exception EXCEPTION_INT_DIVIDE_BY_ZERO ({:#x})", ec); - break; - case EXCEPTION_PRIV_INSTRUCTION: - LOG_CRITICAL(Core, "Exception EXCEPTION_PRIV_INSTRUCTION ({:#x})", ec); - break; - case EXCEPTION_STACK_OVERFLOW: - LOG_CRITICAL(Core, "Exception EXCEPTION_STACK_OVERFLOW ({:#x})", ec); - break; - default: - return EXCEPTION_CONTINUE_SEARCH; - } - return EXCEPTION_CONTINUE_SEARCH; -} -#endif - -void InstallTlsHandler() { -#ifdef _WIN64 - if (!AddVectoredExceptionHandler(0, ExceptionHandler)) { - LOG_CRITICAL(Core, "Failed to register an exception handler"); - } -#endif -} - -void PatchTLS(u64 segment_addr, u64 segment_size) { - u8* code = reinterpret_cast(segment_addr); - auto remaining_size = segment_size; - - while (remaining_size) { - for (const auto& tls_pattern : TlsPatterns) { - const auto total_size = tls_pattern.pattern_size + tls_pattern.imm_size; - if (remaining_size < total_size) { - continue; - } - if (std::memcmp(code, tls_pattern.pattern, tls_pattern.pattern_size) != 0) { - continue; - } - if (tls_pattern.imm_size == 4) { - LOG_INFO(Core_Linker, "PATTERN32 FOUND at {}, reg: {} offset: {:#x}", - fmt::ptr(code), tls_pattern.target_reg, - *(u32*)(code + tls_pattern.pattern_size)); - } else { - LOG_INFO(Core_Linker, "PATTERN64 FOUND at {}, reg: {} offset: {:#x}", - fmt::ptr(code), tls_pattern.target_reg, - *(u32*)(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); - code += total_size - 1; - remaining_size -= total_size - 1; - break; - } - code++; - remaining_size--; - } -} - -} // namespace Core diff --git a/src/core/tls.h b/src/core/tls.h deleted file mode 100644 index aa001178..00000000 --- a/src/core/tls.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/types.h" - -namespace Core { - -/// Installs a host exception handler to handle guest TLS access. -void InstallTlsHandler(); - -/// Patches any instructions that access TLS to trigger the exception handler. -void PatchTLS(u64 segment_addr, u64 segment_size); - -} // namespace Core diff --git a/src/core/virtual_memory.cpp b/src/core/virtual_memory.cpp index 3c9c2e20..9f3aacc1 100644 --- a/src/core/virtual_memory.cpp +++ b/src/core/virtual_memory.cpp @@ -1,11 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "common/error.h" -#include "common/logging/log.h" #include "core/virtual_memory.h" +#include "common/log.h" + #ifdef _WIN64 #include #else @@ -73,7 +72,7 @@ u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { if (ptr == 0) { auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualAlloc() failed: 0x{:X}", err); + LOG_ERROR_IF(true, "VirtualAlloc() failed: 0x{:X}\n", err); } #else auto ptr = reinterpret_cast( @@ -81,7 +80,7 @@ u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); if (ptr == reinterpret_cast MAP_FAILED) { - LOG_ERROR(Common_Memory, "mmap() failed: {}", std::strerror(errno)); + LOG_ERROR_IF(true, "mmap() failed: {}\n", std::strerror(errno)); } #endif return ptr; @@ -92,7 +91,7 @@ bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode if (VirtualProtect(reinterpret_cast(static_cast(address)), size, convertMemoryMode(mode), &old_protect) == 0) { auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualProtect() failed: 0x{:X}", err); + LOG_ERROR_IF(true, "VirtualProtect() failed: 0x{:X}\n", err); return false; } if (old_mode != nullptr) { @@ -101,10 +100,6 @@ bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode return true; #else int ret = mprotect(reinterpret_cast(address), size, convertMemoryMode(mode)); - if (ret != 0) { - const auto error = Common::GetLastErrorMsg(); - ASSERT(false); - } return true; #endif } @@ -115,7 +110,7 @@ bool memory_flush(u64 address, u64 size) { reinterpret_cast(static_cast(address)), size) == 0) { auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "FlushInstructionCache() failed: 0x{:X}", err); + LOG_ERROR_IF(true, "FlushInstructionCache() failed: 0x{:X}\n", err); return false; } return true; @@ -125,7 +120,7 @@ bool memory_flush(u64 address, u64 size) { } bool memory_patch(u64 vaddr, u64 value) { MemoryMode old_mode{}; - // memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode); + memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode); auto* ptr = reinterpret_cast(vaddr); @@ -133,7 +128,7 @@ bool memory_patch(u64 vaddr, u64 value) { *ptr = value; - // memory_protect(vaddr, 8, old_mode, nullptr); + memory_protect(vaddr, 8, old_mode, nullptr); // if mode is executable flush it so insure that cpu finds it if (containsExecuteMode(old_mode)) { @@ -166,13 +161,15 @@ u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) if (ptr == 0) { auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualAlloc2() failed: 0x{:X}", err); + LOG_ERROR_IF(true, "VirtualAlloc2() failed: 0x{:X}\n", err); } return ptr; #else void* hint_address = reinterpret_cast(AlignUp(address, alignment)); void* ptr = mmap(hint_address, size, convertMemoryMode(mode), MAP_ANON | MAP_PRIVATE, -1, 0); - ASSERT(ptr != MAP_FAILED); + if (ptr == MAP_FAILED) { + std::abort(); + } return reinterpret_cast(ptr); #endif } diff --git a/src/emulator.cpp b/src/emulator.cpp index 8962a5bb..77e07f7c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -197,6 +197,7 @@ void emuRun() { } } } + std::exit(0); } HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { diff --git a/src/main.cpp b/src/main.cpp index 10255db8..05c6a26a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,26 +12,22 @@ #include #include "Util/config.h" #include "common/discord.h" -#include "common/logging/backend.h" -#include "common/path_util.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 "core/tls.h" #include "emulator.h" int main(int argc, char* argv[]) { - if (argc == 1) { + /* if (argc == 1) { fmt::print("Usage: {} \n", argv[0]); return -1; - } - const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - Config::load(config_dir / "config.toml"); - Common::Log::Initialize(); - Common::Log::Start(); + }*/ + Config::load("config.toml"); + Common::Log::Init(true); Core::Libraries::LibKernel::init_pthreads(); auto width = Config::getScreenWidth(); auto height = Config::getScreenHeight(); @@ -39,15 +35,15 @@ int main(int argc, char* argv[]) { HLE::Libs::Graphics::VideoOut::videoOutInit(width, height); // Argument 1 is the path of self file to boot - const char* const path = argv[1]; + // const char* const path = argv[1]; + const char* const path = "C://ps4//games//CUSA11712//eboot.bin"; auto* mnt = Common::Singleton::Instance(); std::filesystem::path p = std::string(path); - mnt->Mount(p.parent_path(), "/app0"); + mnt->mount(p.parent_path().string(), "/app0"); auto linker = Common::Singleton::Instance(); Core::Libraries::InitHLELibs(&linker->getHLESymbols()); - Core::InstallTlsHandler(); linker->LoadModule(path); std::jthread mainthread([linker](std::stop_token stop_token, void*) { linker->Execute(); }, nullptr); diff --git a/src/vulkan_util.cpp b/src/vulkan_util.cpp index 7190d7d8..326ec81e 100644 --- a/src/vulkan_util.cpp +++ b/src/vulkan_util.cpp @@ -6,14 +6,15 @@ #include #include #include -#include "common/assert.h" #include "common/debug.h" -#include "common/logging/log.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 + void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { Emu::VulkanExt ext; vulkanGetInstanceExtensions(&ext); @@ -37,12 +38,19 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { inst_info.enabledLayerCount = 0; inst_info.ppEnabledLayerNames = nullptr; - const VkResult result = vkCreateInstance(&inst_info, nullptr, &ctx->m_graphic_ctx.m_instance); - ASSERT_MSG(result == VK_SUCCESS, "Can't create an vulkan instance"); + VkResult result = vkCreateInstance(&inst_info, nullptr, &ctx->m_graphic_ctx.m_instance); + if (result == VK_ERROR_INCOMPATIBLE_DRIVER) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Can't find an compatiblie vulkan driver\n"); + std::exit(0); + } else if (result != VK_SUCCESS) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Can't create an vulkan instance\n"); + std::exit(0); + } if (SDL_Vulkan_CreateSurface(ctx->m_window, ctx->m_graphic_ctx.m_instance, &ctx->m_surface) == SDL_FALSE) { - UNREACHABLE_MSG("Can't create an vulkan surface"); + 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 @@ -56,16 +64,22 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { device_extensions, &ctx->m_surface_capabilities, &ctx->m_graphic_ctx.m_physical_device, &queues); - ASSERT_MSG(ctx->m_graphic_ctx.m_physical_device, "Can't find compatible vulkan device"); + if (ctx->m_graphic_ctx.m_physical_device == nullptr) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Can't find compatible vulkan device\n"); + std::exit(0); + } VkPhysicalDeviceProperties device_properties{}; vkGetPhysicalDeviceProperties(ctx->m_graphic_ctx.m_physical_device, &device_properties); - LOG_INFO(Render_Vulkan, "GFX device to be used : {}", device_properties.deviceName); + 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); - ASSERT_MSG(ctx->m_graphic_ctx.m_device, "Can't create vulkan device"); + if (ctx->m_graphic_ctx.m_device == nullptr) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Can't create vulkan device\n"); + std::exit(0); + } vulkanCreateQueues(&ctx->m_graphic_ctx, queues); ctx->swapchain = vulkanCreateSwapchain(&ctx->m_graphic_ctx, 2); @@ -146,8 +160,11 @@ Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics vkCreateImageView(ctx->m_device, &create_info, nullptr, &s.swapchain_image_views[i]); } + if (s.swapchain == nullptr) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Could not create swapchain\n"); + std::exit(0); + } - ASSERT_MSG(s.swapchain, "Could not create swapchain"); s.current_index = static_cast(-1); VkSemaphoreCreateInfo present_complete_info{}; @@ -164,7 +181,10 @@ Emu::VulkanSwapchain Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics fence_info.flags = 0; result = vkCreateFence(ctx->m_device, &fence_info, nullptr, &s.present_complete_fence); - ASSERT_MSG(result == VK_SUCCESS, "Can't create vulkan fence"); + if (result != VK_SUCCESS) { + LOG_CRITICAL_IF(log_file_vulkanutil, "Can't create vulkan fence\n"); + std::exit(0); + } return s; } @@ -262,18 +282,18 @@ void Graphics::Vulkan::vulkanGetInstanceExtensions(Emu::VulkanExt* ext) { vkEnumerateInstanceLayerProperties(&available_layers_count, ext->available_layers.data()); for (const char* ext : ext->required_extensions) { - LOG_INFO(Render_Vulkan, "Vulkan required extension = {}", ext); + LOG_INFO_IF(log_file_vulkanutil, "Vulkan required extension = {}\n", ext); } for (const auto& ext : ext->available_extensions) { - LOG_INFO(Render_Vulkan, "Vulkan available extension: {}, version = {}", 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(Render_Vulkan, - "Vulkan available layer: {}, specVersion = {}, implVersion = {}, {}", 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); } } @@ -300,7 +320,7 @@ void Graphics::Vulkan::vulkanFindCompatiblePhysicalDevice( 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(Render_Vulkan, "Vulkan device: {}", device_properties.deviceName); + LOG_INFO_IF(log_file_vulkanutil, "Vulkan device: {}\n", device_properties.deviceName); auto qs = vulkanFindQueues(device, surface); @@ -329,9 +349,9 @@ Emu::VulkanQueues Graphics::Vulkan::vulkanFindQueues(VkPhysicalDevice device, VkBool32 presentation_supported = VK_FALSE; vkGetPhysicalDeviceSurfaceSupportKHR(device, family, surface, &presentation_supported); - LOG_INFO(Render_Vulkan, "queue family: {}, count = {}, present = {}", - string_VkQueueFlags(f.queueFlags).c_str(), f.queueCount, - (presentation_supported == VK_TRUE ? "true" : "false")); + 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; info.family = family; diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 2c9f843f..c640ab74 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -12,10 +12,16 @@ add_subdirectory(fmt EXCLUDE_FROM_ALL) # MagicEnum add_subdirectory(magic_enum EXCLUDE_FROM_ALL) -if(NOT ENABLE_QT_GUI) +# Spdlog +set(SPDLOG_WCHAR_FILENAMES ON CACHE BOOL "") +set(SPDLOG_NO_THREAD_ID ON CACHE BOOL "") +set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "") +add_subdirectory(spdlog EXCLUDE_FROM_ALL) +add_library(stb INTERFACE) +target_include_directories(stb INTERFACE ./stb) + # SDL3 add_subdirectory(SDL EXCLUDE_FROM_ALL) -endif() # Toml11 add_subdirectory(toml11 EXCLUDE_FROM_ALL) diff --git a/third-party/spdlog b/third-party/spdlog new file mode 160000 index 00000000..5532231b --- /dev/null +++ b/third-party/spdlog @@ -0,0 +1 @@ +Subproject commit 5532231bbc31bbdf95ac15febdac0413ee1d07ad