From eb09c4ccce4ca6ab8ed08f9e53926c52dd52d8a5 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Thu, 1 May 2025 20:10:42 -0700 Subject: [PATCH 1/6] vk_presenter: Use correct format for output frame image and view. (#2871) --- .../renderer_vulkan/vk_presenter.cpp | 22 +++++++++++++++++-- src/video_core/renderer_vulkan/vk_presenter.h | 8 ++++--- src/video_core/texture_cache/image_info.cpp | 7 +++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index 6bd4b26fa..09dd23cb6 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -270,7 +270,25 @@ Frame* Presenter::PrepareLastFrame() { return frame; } -Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) { +static vk::Format GetFrameViewFormat(const Libraries::VideoOut::PixelFormat format) { + switch (format) { + case Libraries::VideoOut::PixelFormat::A8B8G8R8Srgb: + return vk::Format::eR8G8B8A8Srgb; + case Libraries::VideoOut::PixelFormat::A8R8G8B8Srgb: + return vk::Format::eB8G8R8A8Srgb; + case Libraries::VideoOut::PixelFormat::A2R10G10B10: + case Libraries::VideoOut::PixelFormat::A2R10G10B10Srgb: + case Libraries::VideoOut::PixelFormat::A2R10G10B10Bt2020Pq: + return vk::Format::eA2R10G10B10UnormPack32; + default: + break; + } + UNREACHABLE_MSG("Unknown format={}", static_cast(format)); + return {}; +} + +Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, + const Libraries::VideoOut::PixelFormat format, bool is_eop) { // Request a free presentation frame. Frame* frame = GetRenderFrame(); @@ -324,7 +342,7 @@ Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) cmdbuf); VideoCore::ImageViewInfo info{}; - info.format = image.info.pixel_format; + info.format = GetFrameViewFormat(format); // Exclude alpha from output frame to avoid blending with UI. info.mapping = vk::ComponentMapping{ .r = vk::ComponentSwizzle::eIdentity, diff --git a/src/video_core/renderer_vulkan/vk_presenter.h b/src/video_core/renderer_vulkan/vk_presenter.h index ad2708474..8ed2052ee 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.h +++ b/src/video_core/renderer_vulkan/vk_presenter.h @@ -70,11 +70,12 @@ public: auto desc = VideoCore::TextureCache::VideoOutDesc{attribute, cpu_address}; const auto image_id = texture_cache.FindImage(desc); texture_cache.UpdateImage(image_id, is_eop ? nullptr : &flip_scheduler); - return PrepareFrameInternal(image_id, is_eop); + return PrepareFrameInternal(image_id, attribute.attrib.pixel_format, is_eop); } Frame* PrepareBlankFrame(bool is_eop) { - return PrepareFrameInternal(VideoCore::NULL_IMAGE_ID, is_eop); + return PrepareFrameInternal(VideoCore::NULL_IMAGE_ID, + Libraries::VideoOut::PixelFormat::Unknown, is_eop); } VideoCore::Image& RegisterVideoOutSurface( @@ -119,7 +120,8 @@ public: } private: - Frame* PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop = true); + Frame* PrepareFrameInternal(VideoCore::ImageId image_id, + Libraries::VideoOut::PixelFormat format, bool is_eop = true); Frame* GetRenderFrame(); void SetExpectedGameSize(s32 width, s32 height); diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 26928eaf7..39322f449 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -16,14 +16,15 @@ using VideoOutFormat = Libraries::VideoOut::PixelFormat; static vk::Format ConvertPixelFormat(const VideoOutFormat format) { switch (format) { - case VideoOutFormat::A8R8G8B8Srgb: - return vk::Format::eB8G8R8A8Srgb; case VideoOutFormat::A8B8G8R8Srgb: + // Remaining formats are mapped to RGBA for internal consistency and changed to BGRA in the + // frame image view. + case VideoOutFormat::A8R8G8B8Srgb: return vk::Format::eR8G8B8A8Srgb; case VideoOutFormat::A2R10G10B10: case VideoOutFormat::A2R10G10B10Srgb: case VideoOutFormat::A2R10G10B10Bt2020Pq: - return vk::Format::eA2R10G10B10UnormPack32; + return vk::Format::eA2B10G10R10UnormPack32; default: break; } From 0ba9ea6a3b98d6454164ac12a29baef30f1ef595 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Fri, 2 May 2025 13:22:05 -0500 Subject: [PATCH 2/6] Only perform early read-write open when truncating is needed (#2874) Should stop some fs error spam when games open files from /app0, as this open call would fail from reduced permissions. --- src/core/libraries/kernel/file_system.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index cb1fd14a2..ad372325c 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -181,10 +181,6 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) { return -1; } } else { - // Start by opening as read-write so we can truncate regardless of flags. - // Since open starts by closing the file, this won't interfere with later open calls. - e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite); - file->type = Core::FileSys::FileType::Regular; if (truncate && read_only) { @@ -192,9 +188,14 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) { h->DeleteHandle(handle); *__Error() = POSIX_EROFS; return -1; - } else if (truncate && e == 0) { - // If the file was opened successfully and truncate was enabled, reduce size to 0 - file->f.SetSize(0); + } else if (truncate) { + // Open the file as read-write so we can truncate regardless of flags. + // Since open starts by closing the file, this won't interfere with later open calls. + e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite); + if (e == 0) { + // If the file was opened successfully, reduce size to 0 + file->f.SetSize(0); + } } if (read) { From d542d952f4bbff97ef71ed61beac6da0813ac84a Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Sat, 3 May 2025 12:51:10 -0300 Subject: [PATCH 3/6] Savefixes VIII (#2851) * savedata dialog: fix SaveDialogUi move semantics fix possible dangling points * savedata dialog: removed unnecessary firmware version checks --- .../save_data/dialog/savedatadialog_ui.cpp | 23 ++++++++++--------- .../save_data/dialog/savedatadialog_ui.h | 3 ++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp index a6ca8744d..edb5caa07 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp +++ b/src/core/libraries/save_data/dialog/savedatadialog_ui.cpp @@ -49,13 +49,11 @@ void SaveDialogResult::CopyTo(OrbisSaveDataDialogResult& result) const { result.mode = this->mode; result.result = this->result; result.buttonId = this->button_id; - if (mode == SaveDataDialogMode::LIST || ElfInfo::Instance().FirmwareVer() >= ElfInfo::FW_45) { - if (result.dirName != nullptr) { - result.dirName->data.FromString(this->dir_name); - } - if (result.param != nullptr && this->param.GetString(SaveParams::MAINTITLE).has_value()) { - result.param->FromSFO(this->param); - } + if (result.dirName != nullptr) { + result.dirName->data.FromString(this->dir_name); + } + if (result.param != nullptr && this->param.GetString(SaveParams::MAINTITLE).has_value()) { + result.param->FromSFO(this->param); } result.userData = this->user_data; } @@ -345,12 +343,15 @@ SaveDialogUi::SaveDialogUi(SaveDialogUi&& other) noexcept } } -SaveDialogUi& SaveDialogUi::operator=(SaveDialogUi other) { +SaveDialogUi& SaveDialogUi::operator=(SaveDialogUi&& other) noexcept { std::scoped_lock lock(draw_mutex, other.draw_mutex); using std::swap; - swap(state, other.state); - swap(status, other.status); - swap(result, other.result); + state = other.state; + other.state = nullptr; + status = other.status; + other.status = nullptr; + result = other.result; + other.result = nullptr; if (status && *status == Status::RUNNING) { first_render = true; AddLayer(this); diff --git a/src/core/libraries/save_data/dialog/savedatadialog_ui.h b/src/core/libraries/save_data/dialog/savedatadialog_ui.h index aa67e1f5f..dc97268f4 100644 --- a/src/core/libraries/save_data/dialog/savedatadialog_ui.h +++ b/src/core/libraries/save_data/dialog/savedatadialog_ui.h @@ -300,7 +300,8 @@ public: ~SaveDialogUi() override; SaveDialogUi(const SaveDialogUi& other) = delete; SaveDialogUi(SaveDialogUi&& other) noexcept; - SaveDialogUi& operator=(SaveDialogUi other); + SaveDialogUi& operator=(SaveDialogUi& other) = delete; + SaveDialogUi& operator=(SaveDialogUi&& other) noexcept; void Finish(ButtonId buttonId, CommonDialog::Result r = CommonDialog::Result::OK); From 17b6343f18a39bbd6436a94956fb6cb90f8f554c Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 3 May 2025 13:47:03 -0700 Subject: [PATCH 4/6] emulator: Fix log initialization order. (#2878) --- src/emulator.cpp | 184 ++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 89 deletions(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index 448b8aad4..ebb34054b 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -10,7 +10,6 @@ #include "common/logging/log.h" #ifdef ENABLE_QT_GUI #include -#include "common/memory_patcher.h" #endif #include "common/assert.h" #ifdef ENABLE_DISCORD_RPC @@ -20,6 +19,7 @@ #include #endif #include "common/elf_info.h" +#include "common/memory_patcher.h" #include "common/ntapi.h" #include "common/path_util.h" #include "common/polyfill_thread.h" @@ -54,27 +54,6 @@ Emulator::Emulator() { WSADATA wsaData; WSAStartup(versionWanted, &wsaData); #endif - - // Create stdin/stdout/stderr - Common::Singleton::Instance()->CreateStdHandles(); - - // Defer until after logging is initialized. - memory = Core::Memory::Instance(); - controller = Common::Singleton::Instance(); - linker = Common::Singleton::Instance(); - - // Load renderdoc module. - VideoCore::LoadRenderDoc(); - - // Start the timer (Play Time) -#ifdef ENABLE_QT_GUI - start_time = std::chrono::steady_clock::now(); - const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); - QString filePath = QString::fromStdString((user_dir / "play_time.txt").string()); - QFile file(filePath); - ASSERT_MSG(file.open(QIODevice::ReadWrite | QIODevice::Text), - "Error opening or creating play_time.txt"); -#endif } Emulator::~Emulator() { @@ -102,54 +81,89 @@ void Emulator::Run(const std::filesystem::path& file, const std::vectorMount(game_folder, "/hostapp", true); - auto& game_info = Common::ElfInfo::Instance(); + const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo"); + const auto param_sfo_exists = std::filesystem::exists(param_sfo_path); - // Loading param.sfo file if exists + // Load param.sfo details if it exists std::string id; std::string title; std::string app_version; u32 fw_version; Common::PSFAttributes psf_attributes{}; - - const auto param_sfo_path = mnt->GetHostPath("/app0/sce_sys/param.sfo"); - if (!std::filesystem::exists(param_sfo_path) || !Config::getSeparateLogFilesEnabled()) { - Common::Log::Initialize(); - Common::Log::Start(); - } - - if (std::filesystem::exists(param_sfo_path)) { + if (param_sfo_exists) { auto* param_sfo = Common::Singleton::Instance(); - const bool success = param_sfo->Open(param_sfo_path); - ASSERT_MSG(success, "Failed to open param.sfo"); + ASSERT_MSG(param_sfo->Open(param_sfo_path), "Failed to open param.sfo"); + const auto content_id = param_sfo->GetString("CONTENT_ID"); ASSERT_MSG(content_id.has_value(), "Failed to get CONTENT_ID"); + id = std::string(*content_id, 7, 9); - - if (Config::getSeparateLogFilesEnabled()) { - Common::Log::Initialize(id + ".log"); - Common::Log::Start(); + title = param_sfo->GetString("TITLE").value_or("Unknown title"); + fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); + app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); + if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) { + psf_attributes.raw = *raw_attributes; } - LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::g_version); - LOG_INFO(Loader, "Revision {}", Common::g_scm_rev); - LOG_INFO(Loader, "Branch {}", Common::g_scm_branch); - LOG_INFO(Loader, "Description {}", Common::g_scm_desc); - LOG_INFO(Loader, "Remote {}", Common::g_scm_remote_url); + } - LOG_INFO(Config, "General LogType: {}", Config::getLogType()); - LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole()); - LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu()); - LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders()); - LOG_INFO(Config, "GPU vblankDivider: {}", Config::vblankDiv()); - LOG_INFO(Config, "Vulkan gpuId: {}", Config::getGpuId()); - LOG_INFO(Config, "Vulkan vkValidation: {}", Config::vkValidationEnabled()); - LOG_INFO(Config, "Vulkan vkValidationSync: {}", Config::vkValidationSyncEnabled()); - LOG_INFO(Config, "Vulkan vkValidationGpu: {}", Config::vkValidationGpuEnabled()); - LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::getVkCrashDiagnosticEnabled()); - LOG_INFO(Config, "Vulkan hostMarkers: {}", Config::getVkHostMarkersEnabled()); - LOG_INFO(Config, "Vulkan guestMarkers: {}", Config::getVkGuestMarkersEnabled()); - LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled()); + // Initialize logging as soon as possible + if (!id.empty() && Config::getSeparateLogFilesEnabled()) { + Common::Log::Initialize(id + ".log"); + } else { + Common::Log::Initialize(); + } + Common::Log::Start(); + LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::g_version); + LOG_INFO(Loader, "Revision {}", Common::g_scm_rev); + LOG_INFO(Loader, "Branch {}", Common::g_scm_branch); + LOG_INFO(Loader, "Description {}", Common::g_scm_desc); + LOG_INFO(Loader, "Remote {}", Common::g_scm_remote_url); + + LOG_INFO(Config, "General LogType: {}", Config::getLogType()); + LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole()); + LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu()); + LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders()); + LOG_INFO(Config, "GPU vblankDivider: {}", Config::vblankDiv()); + LOG_INFO(Config, "Vulkan gpuId: {}", Config::getGpuId()); + LOG_INFO(Config, "Vulkan vkValidation: {}", Config::vkValidationEnabled()); + LOG_INFO(Config, "Vulkan vkValidationSync: {}", Config::vkValidationSyncEnabled()); + LOG_INFO(Config, "Vulkan vkValidationGpu: {}", Config::vkValidationGpuEnabled()); + LOG_INFO(Config, "Vulkan crashDiagnostics: {}", Config::getVkCrashDiagnosticEnabled()); + LOG_INFO(Config, "Vulkan hostMarkers: {}", Config::getVkHostMarkersEnabled()); + LOG_INFO(Config, "Vulkan guestMarkers: {}", Config::getVkGuestMarkersEnabled()); + LOG_INFO(Config, "Vulkan rdocEnable: {}", Config::isRdocEnabled()); + + if (param_sfo_exists) { + LOG_INFO(Loader, "Game id: {} Title: {}", id, title); + LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); + } + if (!args.empty()) { + const auto argc = std::min(args.size(), 32); + for (auto i = 0; i < argc; i++) { + LOG_INFO(Loader, "Game argument {}: {}", i, args[i]); + } + if (args.size() > 32) { + LOG_ERROR(Loader, "Too many game arguments, only passing the first 32"); + } + } + + // Create stdin/stdout/stderr + Common::Singleton::Instance()->CreateStdHandles(); + + // Initialize components + memory = Core::Memory::Instance(); + controller = Common::Singleton::Instance(); + linker = Common::Singleton::Instance(); + + // Load renderdoc module + VideoCore::LoadRenderDoc(); + + // Initialize patcher and trophies + if (!id.empty()) { + MemoryPatcher::g_game_serial = id; Libraries::NpTrophy::game_serial = id; + const auto trophyDir = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / id / "TrophyFiles"; if (!std::filesystem::exists(trophyDir)) { @@ -158,41 +172,9 @@ void Emulator::Run(const std::filesystem::path& file, const std::vectorstart(60000); // 60000 ms = 1 minute -#endif - title = param_sfo->GetString("TITLE").value_or("Unknown title"); - LOG_INFO(Loader, "Game id: {} Title: {}", id, title); - fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); - app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); - LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); - if (const auto raw_attributes = param_sfo->GetInteger("ATTRIBUTE")) { - psf_attributes.raw = *raw_attributes; - } - if (!args.empty()) { - int argc = std::min(args.size(), 32); - for (int i = 0; i < argc; i++) { - LOG_INFO(Loader, "Game argument {}: {}", i, args[i]); - } - if (args.size() > 32) { - LOG_ERROR(Loader, "Too many game arguments, only passing the first 32"); - } - } - } - - const auto pic1_path = mnt->GetHostPath("/app0/sce_sys/pic1.png"); - if (std::filesystem::exists(pic1_path)) { - game_info.splash_path = pic1_path; } + auto& game_info = Common::ElfInfo::Instance(); game_info.initialized = true; game_info.game_serial = id; game_info.title = title; @@ -201,6 +183,11 @@ void Emulator::Run(const std::filesystem::path& file, const std::vectorGetHostPath("/app0/sce_sys/pic1.png"); + if (std::filesystem::exists(pic1_path)) { + game_info.splash_path = pic1_path; + } + std::string game_title = fmt::format("{} - {} <{}>", id, title, app_version); std::string window_title = ""; if (Common::g_is_release) { @@ -284,6 +271,25 @@ void Emulator::Run(const std::filesystem::path& file, const std::vectorstart(60000); // 60000 ms = 1 minute + + start_time = std::chrono::steady_clock::now(); + const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + QString filePath = QString::fromStdString((user_dir / "play_time.txt").string()); + QFile file(filePath); + ASSERT_MSG(file.open(QIODevice::ReadWrite | QIODevice::Text), + "Error opening or creating play_time.txt"); + } +#endif + linker->Execute(args); window->InitTimers(); From 9a22185ab780ce7362b7a587b7defd16b456c460 Mon Sep 17 00:00:00 2001 From: oltolm Date: Sun, 4 May 2025 12:11:02 +0200 Subject: [PATCH 5/6] vulkan: do not use VK_EXT_extended_dynamic_state (#2880) fixes Bloodborne crashing on RX 580 --- src/video_core/buffer_cache/buffer_cache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index cdf736a89..fb9fd755e 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -177,8 +177,8 @@ void BufferCache::BindVertexBuffers(const Vulkan::GraphicsPipeline& pipeline) { if (instance.IsVertexInputDynamicState()) { cmdbuf.bindVertexBuffers(0, num_buffers, host_buffers.data(), host_offsets.data()); } else { - cmdbuf.bindVertexBuffers2EXT(0, num_buffers, host_buffers.data(), host_offsets.data(), - host_sizes.data(), host_strides.data()); + cmdbuf.bindVertexBuffers2(0, num_buffers, host_buffers.data(), host_offsets.data(), + host_sizes.data(), host_strides.data()); } } From fed064931ad599f2de628cd9ad72c640da3f061b Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Mon, 5 May 2025 05:24:08 -0500 Subject: [PATCH 6/6] Core: Fix module load addresses (#2879) * Fix module map addresses Most modules are mapped starting at 0x800000000, with no gaps between mappings. * Hardcode hardware accurate base address Looking at our address space, all platforms will have this base address mapped, so there shouldn't be any problem in using it. * Clang * Swap module mapping to NoFlags, remove offset code Since real hardware has no gap between module mappings, the Fixed flag is just an annoyance to work around, and has no impact on the actual mappings. Swapping the module mappings to use flags NoFlags instead simplifies our code slightly. * Fix module mapping names On real hardware, the file extension is part of the mapping name. Easiest way to manage this is to swap the name to be `file.filename().string()` instead of `file.stem().string()` * Fix patches Completely missed this, whoops. --- src/core/address_space.h | 2 -- src/core/module.cpp | 13 +++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/core/address_space.h b/src/core/address_space.h index 7ccc2cd1e..d7f3efc75 100644 --- a/src/core/address_space.h +++ b/src/core/address_space.h @@ -19,8 +19,6 @@ enum class MemoryPermission : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission) -constexpr VAddr CODE_BASE_OFFSET = 0x100000000ULL; - constexpr VAddr SYSTEM_MANAGED_MIN = 0x00000400000ULL; constexpr VAddr SYSTEM_MANAGED_MAX = 0x07FFFFBFFFULL; constexpr VAddr SYSTEM_RESERVED_MIN = 0x07FFFFC000ULL; diff --git a/src/core/module.cpp b/src/core/module.cpp index cbe44457c..f31bbed6c 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -19,8 +19,7 @@ namespace Core { using EntryFunc = PS4_SYSV_ABI int (*)(size_t args, const void* argp, void* param); -static u64 LoadOffset = CODE_BASE_OFFSET; -static constexpr u64 CODE_BASE_INCR = 0x010000000u; +static constexpr u64 ModuleLoadBase = 0x800000000; static u64 GetAlignedSize(const elf_program_header& phdr) { return (phdr.p_align != 0 ? (phdr.p_memsz + (phdr.p_align - 1)) & ~(phdr.p_align - 1) @@ -84,7 +83,7 @@ static std::string StringToNid(std::string_view symbol) { } Module::Module(Core::MemoryManager* memory_, const std::filesystem::path& file_, u32& max_tls_index) - : memory{memory_}, file{file_}, name{file.stem().string()} { + : memory{memory_}, file{file_}, name{file.filename().string()} { elf.Open(file); if (elf.IsElfFile()) { LoadModuleToMemory(max_tls_index); @@ -113,10 +112,8 @@ void Module::LoadModuleToMemory(u32& max_tls_index) { // Map module segments (and possible TLS trampolines) void** out_addr = reinterpret_cast(&base_virtual_addr); - memory->MapMemory(out_addr, memory->SystemReservedVirtualBase() + LoadOffset, - aligned_base_size + TrampolineSize, MemoryProt::CpuReadWrite, - MemoryMapFlags::Fixed, VMAType::Code, name, true); - LoadOffset += CODE_BASE_INCR * (1 + aligned_base_size / CODE_BASE_INCR); + memory->MapMemory(out_addr, ModuleLoadBase, aligned_base_size + TrampolineSize, + MemoryProt::CpuReadWrite, MemoryMapFlags::NoFlags, VMAType::Code, name, true); LOG_INFO(Core_Linker, "Loading module {} to {}", name, fmt::ptr(*out_addr)); #ifdef ARCH_X86_64 @@ -229,7 +226,7 @@ void Module::LoadModuleToMemory(u32& max_tls_index) { LOG_INFO(Core_Linker, "program entry addr ..........: {:#018x}", entry_addr); if (MemoryPatcher::g_eboot_address == 0) { - if (name == "eboot") { + if (name == "eboot.bin") { MemoryPatcher::g_eboot_address = base_virtual_addr; MemoryPatcher::g_eboot_image_size = base_size; MemoryPatcher::OnGameLoaded();