From 1ac19f1b08296e41ec0b93b8fe9a8f362bad1b7b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 27 Jun 2015 18:02:20 -0700 Subject: [PATCH] Replacing vfs memory mapping with base memory mapping. Progress on #294. --- src/xenia/base/mapped_memory.h | 17 ++++++++----- src/xenia/kernel/kernel_state.cc | 16 +++++++------ src/xenia/kernel/objects/xuser_module.cc | 4 ++-- src/xenia/kernel/util/xex2.cc | 2 +- src/xenia/vfs/devices/disc_image_entry.cc | 29 ++++++++--------------- src/xenia/vfs/devices/disc_image_entry.h | 9 +++---- src/xenia/vfs/devices/host_path_entry.cc | 28 +++++----------------- src/xenia/vfs/devices/host_path_entry.h | 9 +++---- src/xenia/vfs/entry.cc | 5 ---- src/xenia/vfs/entry.h | 28 +++++++--------------- 10 files changed, 57 insertions(+), 90 deletions(-) diff --git a/src/xenia/base/mapped_memory.h b/src/xenia/base/mapped_memory.h index 95eeb0430..951d6a1b8 100644 --- a/src/xenia/base/mapped_memory.h +++ b/src/xenia/base/mapped_memory.h @@ -22,21 +22,26 @@ class MappedMemory { kReadWrite, }; - virtual ~MappedMemory() = default; - static std::unique_ptr Open(const std::wstring& path, Mode mode, size_t offset = 0, size_t length = 0); + MappedMemory(const std::wstring& path, Mode mode) + : path_(path), mode_(mode), data_(nullptr), size_(0) {} + MappedMemory(const std::wstring& path, Mode mode, void* data, size_t size) + : path_(path), mode_(mode), data_(data), size_(size) {} + virtual ~MappedMemory() = default; + + std::unique_ptr Slice(Mode mode, size_t offset, size_t length) { + return std::make_unique(path_, mode, data() + offset, length); + } + uint8_t* data() const { return reinterpret_cast(data_); } size_t size() const { return size_; } - virtual void Flush() = 0; + virtual void Flush() {} protected: - MappedMemory(const std::wstring& path, Mode mode) - : path_(path), mode_(mode), data_(nullptr), size_(0) {} - std::wstring path_; Mode mode_; void* data_; diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 3a56e8a88..a43189102 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -180,13 +180,15 @@ void KernelState::SetExecutableModule(object_ref module) { } executable_module_ = std::move(module); - auto header = executable_module_->xex_header(); - if (header) { - auto pib = memory_->TranslateVirtual( - process_info_block_address_); - pib->tls_data_size = header->tls_info.data_size; - pib->tls_raw_data_size = header->tls_info.raw_data_size; - pib->tls_slot_size = header->tls_info.slot_count * 4; + if (executable_module_) { + auto header = executable_module_->xex_header(); + if (header) { + auto pib = memory_->TranslateVirtual( + process_info_block_address_); + pib->tls_data_size = header->tls_info.data_size; + pib->tls_raw_data_size = header->tls_info.raw_data_size; + pib->tls_slot_size = header->tls_info.slot_count * 4; + } } } diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index a8b533e2b..8e82db820 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -51,13 +51,13 @@ X_STATUS XUserModule::LoadFromFile(std::string path) { // If the FS supports mapping, map the file in and load from that. if (fs_entry->can_map()) { // Map. - auto mmap = fs_entry->CreateMemoryMapping(vfs::Mode::READ, 0, 0); + auto mmap = fs_entry->OpenMapped(MappedMemory::Mode::kRead); if (!mmap) { return result; } // Load the module. - result = LoadFromMemory(mmap->address(), mmap->length()); + result = LoadFromMemory(mmap->data(), mmap->size()); } else { X_FILE_NETWORK_OPEN_INFORMATION file_info = {0}; result = fs_entry->QueryInfo(&file_info); diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index ab8d594e4..2c816f312 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -976,7 +976,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, info->thunk_address = record; } break; default: - // assert_always(); + assert_always(); break; } } diff --git a/src/xenia/vfs/devices/disc_image_entry.cc b/src/xenia/vfs/devices/disc_image_entry.cc index 5838e5b3f..36238dbc5 100644 --- a/src/xenia/vfs/devices/disc_image_entry.cc +++ b/src/xenia/vfs/devices/disc_image_entry.cc @@ -17,14 +17,6 @@ namespace xe { namespace vfs { -class DiscImageMemoryMapping : public MemoryMapping { - public: - DiscImageMemoryMapping(uint8_t* address, size_t length) - : MemoryMapping(address, length) {} - - ~DiscImageMemoryMapping() override = default; -}; - DiscImageEntry::DiscImageEntry(Device* device, const char* path, MappedMemory* mmap, GDFXEntry* gdfx_entry) : Entry(device, path), @@ -97,9 +89,15 @@ X_STATUS DiscImageEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, return X_STATUS_SUCCESS; } -std::unique_ptr DiscImageEntry::CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length) { - if (map_mode != Mode::READ) { +X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) { + *out_file = new DiscImageFile(kernel_state, mode, this); + return X_STATUS_SUCCESS; +} + +std::unique_ptr DiscImageEntry::OpenMapped( + MappedMemory::Mode mode, size_t offset, size_t length) { + if (mode != MappedMemory::Mode::kRead) { // Only allow reads. return nullptr; } @@ -107,14 +105,7 @@ std::unique_ptr DiscImageEntry::CreateMemoryMapping( size_t real_offset = gdfx_entry_->offset + offset; size_t real_length = length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size; - return std::make_unique(mmap_->data() + real_offset, - real_length); -} - -X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, bool async, - XFile** out_file) { - *out_file = new DiscImageFile(kernel_state, mode, this); - return X_STATUS_SUCCESS; + return mmap_->Slice(mode, real_offset, real_length); } } // namespace vfs diff --git a/src/xenia/vfs/devices/disc_image_entry.h b/src/xenia/vfs/devices/disc_image_entry.h index 2b68e2446..e7f94c2c3 100644 --- a/src/xenia/vfs/devices/disc_image_entry.h +++ b/src/xenia/vfs/devices/disc_image_entry.h @@ -33,13 +33,14 @@ class DiscImageEntry : public Entry { X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, const char* file_name, bool restart) override; - bool can_map() override { return true; } - std::unique_ptr CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length) override; - X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, XFile** out_file) override; + bool can_map() const override { return true; } + std::unique_ptr OpenMapped(MappedMemory::Mode mode, + size_t offset, + size_t length) override; + private: MappedMemory* mmap_; GDFXEntry* gdfx_entry_; diff --git a/src/xenia/vfs/devices/host_path_entry.cc b/src/xenia/vfs/devices/host_path_entry.cc index 2b7401215..8660c9f63 100644 --- a/src/xenia/vfs/devices/host_path_entry.cc +++ b/src/xenia/vfs/devices/host_path_entry.cc @@ -17,15 +17,6 @@ namespace xe { namespace vfs { -class HostPathMemoryMapping : public MemoryMapping { - public: - HostPathMemoryMapping(std::unique_ptr mmap) - : MemoryMapping(mmap->data(), mmap->size()), mmap_(std::move(mmap)) {} - - private: - std::unique_ptr mmap_; -}; - HostPathEntry::HostPathEntry(Device* device, const char* path, const std::wstring& local_path) : Entry(device, path), @@ -125,19 +116,6 @@ X_STATUS HostPathEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, return X_STATUS_SUCCESS; } -std::unique_ptr HostPathEntry::CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length) { - auto mmap = MappedMemory::Open( - local_path_, map_mode == Mode::READ ? MappedMemory::Mode::kRead - : MappedMemory::Mode::kReadWrite, - offset, length); - if (!mmap) { - return nullptr; - } - - return std::make_unique(std::move(mmap)); -} - X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async, XFile** out_file) { // TODO(benvanik): plumb through proper disposition/access mode. @@ -176,5 +154,11 @@ X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async, return X_STATUS_SUCCESS; } +std::unique_ptr HostPathEntry::OpenMapped(MappedMemory::Mode mode, + size_t offset, + size_t length) { + return MappedMemory::Open(local_path_, mode, offset, length); +} + } // namespace vfs } // namespace xe diff --git a/src/xenia/vfs/devices/host_path_entry.h b/src/xenia/vfs/devices/host_path_entry.h index 2d2a365e0..fb38074e1 100644 --- a/src/xenia/vfs/devices/host_path_entry.h +++ b/src/xenia/vfs/devices/host_path_entry.h @@ -27,13 +27,14 @@ class HostPathEntry : public Entry { X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, const char* file_name, bool restart) override; - bool can_map() override { return true; } - std::unique_ptr CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length) override; - X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, XFile** out_file) override; + bool can_map() const override { return true; } + std::unique_ptr OpenMapped(MappedMemory::Mode mode, + size_t offset, + size_t length) override; + private: std::wstring local_path_; HANDLE find_file_; diff --git a/src/xenia/vfs/entry.cc b/src/xenia/vfs/entry.cc index 99cef3d68..e03f5b24e 100644 --- a/src/xenia/vfs/entry.cc +++ b/src/xenia/vfs/entry.cc @@ -15,11 +15,6 @@ namespace xe { namespace vfs { -MemoryMapping::MemoryMapping(uint8_t* address, size_t length) - : address_(address), length_(length) {} - -MemoryMapping::~MemoryMapping() {} - Entry::Entry(Device* device, const std::string& path) : device_(device), path_(path) { assert_not_null(device); diff --git a/src/xenia/vfs/entry.h b/src/xenia/vfs/entry.h index 32b44e3df..e04a9f3c2 100644 --- a/src/xenia/vfs/entry.h +++ b/src/xenia/vfs/entry.h @@ -13,6 +13,7 @@ #include #include +#include "xenia/base/mapped_memory.h" #include "xenia/xbox.h" namespace xe { @@ -37,19 +38,6 @@ enum class Mode { READ_APPEND, }; -class MemoryMapping { - public: - MemoryMapping(uint8_t* address, size_t length); - virtual ~MemoryMapping(); - - uint8_t* address() const { return address_; } - size_t length() const { return length_; } - - private: - uint8_t* address_; - size_t length_; -}; - class Entry { public: Entry(Device* device, const std::string& path); @@ -67,16 +55,16 @@ class Entry { size_t length, const char* file_name, bool restart) = 0; - virtual bool can_map() { return false; } - - virtual std::unique_ptr CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length) { - return NULL; - } - virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, XFile** out_file) = 0; + virtual bool can_map() const { return false; } + virtual std::unique_ptr OpenMapped(MappedMemory::Mode mode, + size_t offset = 0, + size_t length = 0) { + return nullptr; + } + private: Device* device_; std::string path_;