Replacing vfs memory mapping with base memory mapping.

Progress on #294.
This commit is contained in:
Ben Vanik 2015-06-27 18:02:20 -07:00
parent 23f91b58f3
commit 1ac19f1b08
10 changed files with 57 additions and 90 deletions

View File

@ -22,21 +22,26 @@ class MappedMemory {
kReadWrite, kReadWrite,
}; };
virtual ~MappedMemory() = default;
static std::unique_ptr<MappedMemory> Open(const std::wstring& path, Mode mode, static std::unique_ptr<MappedMemory> Open(const std::wstring& path, Mode mode,
size_t offset = 0, size_t offset = 0,
size_t length = 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<MappedMemory> Slice(Mode mode, size_t offset, size_t length) {
return std::make_unique<MappedMemory>(path_, mode, data() + offset, length);
}
uint8_t* data() const { return reinterpret_cast<uint8_t*>(data_); } uint8_t* data() const { return reinterpret_cast<uint8_t*>(data_); }
size_t size() const { return size_; } size_t size() const { return size_; }
virtual void Flush() = 0; virtual void Flush() {}
protected: protected:
MappedMemory(const std::wstring& path, Mode mode)
: path_(path), mode_(mode), data_(nullptr), size_(0) {}
std::wstring path_; std::wstring path_;
Mode mode_; Mode mode_;
void* data_; void* data_;

View File

@ -180,6 +180,7 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
} }
executable_module_ = std::move(module); executable_module_ = std::move(module);
if (executable_module_) {
auto header = executable_module_->xex_header(); auto header = executable_module_->xex_header();
if (header) { if (header) {
auto pib = memory_->TranslateVirtual<ProcessInfoBlock*>( auto pib = memory_->TranslateVirtual<ProcessInfoBlock*>(
@ -189,6 +190,7 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
pib->tls_slot_size = header->tls_info.slot_count * 4; pib->tls_slot_size = header->tls_info.slot_count * 4;
} }
} }
}
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) { void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
std::lock_guard<xe::recursive_mutex> lock(object_mutex_); std::lock_guard<xe::recursive_mutex> lock(object_mutex_);

View File

@ -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 the FS supports mapping, map the file in and load from that.
if (fs_entry->can_map()) { if (fs_entry->can_map()) {
// Map. // Map.
auto mmap = fs_entry->CreateMemoryMapping(vfs::Mode::READ, 0, 0); auto mmap = fs_entry->OpenMapped(MappedMemory::Mode::kRead);
if (!mmap) { if (!mmap) {
return result; return result;
} }
// Load the module. // Load the module.
result = LoadFromMemory(mmap->address(), mmap->length()); result = LoadFromMemory(mmap->data(), mmap->size());
} else { } else {
X_FILE_NETWORK_OPEN_INFORMATION file_info = {0}; X_FILE_NETWORK_OPEN_INFORMATION file_info = {0};
result = fs_entry->QueryInfo(&file_info); result = fs_entry->QueryInfo(&file_info);

View File

@ -976,7 +976,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex,
info->thunk_address = record; info->thunk_address = record;
} break; } break;
default: default:
// assert_always(); assert_always();
break; break;
} }
} }

View File

@ -17,14 +17,6 @@
namespace xe { namespace xe {
namespace vfs { 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, DiscImageEntry::DiscImageEntry(Device* device, const char* path,
MappedMemory* mmap, GDFXEntry* gdfx_entry) MappedMemory* mmap, GDFXEntry* gdfx_entry)
: Entry(device, path), : Entry(device, path),
@ -97,9 +89,15 @@ X_STATUS DiscImageEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info,
return X_STATUS_SUCCESS; return X_STATUS_SUCCESS;
} }
std::unique_ptr<MemoryMapping> DiscImageEntry::CreateMemoryMapping( X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, bool async,
Mode map_mode, const size_t offset, const size_t length) { XFile** out_file) {
if (map_mode != Mode::READ) { *out_file = new DiscImageFile(kernel_state, mode, this);
return X_STATUS_SUCCESS;
}
std::unique_ptr<MappedMemory> DiscImageEntry::OpenMapped(
MappedMemory::Mode mode, size_t offset, size_t length) {
if (mode != MappedMemory::Mode::kRead) {
// Only allow reads. // Only allow reads.
return nullptr; return nullptr;
} }
@ -107,14 +105,7 @@ std::unique_ptr<MemoryMapping> DiscImageEntry::CreateMemoryMapping(
size_t real_offset = gdfx_entry_->offset + offset; size_t real_offset = gdfx_entry_->offset + offset;
size_t real_length = size_t real_length =
length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size; length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size;
return std::make_unique<DiscImageMemoryMapping>(mmap_->data() + real_offset, return mmap_->Slice(mode, real_offset, real_length);
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;
} }
} // namespace vfs } // namespace vfs

View File

@ -33,13 +33,14 @@ class DiscImageEntry : public Entry {
X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length,
const char* file_name, bool restart) override; const char* file_name, bool restart) override;
bool can_map() override { return true; }
std::unique_ptr<MemoryMapping> CreateMemoryMapping(
Mode map_mode, const size_t offset, const size_t length) override;
X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, X_STATUS Open(KernelState* kernel_state, Mode mode, bool async,
XFile** out_file) override; XFile** out_file) override;
bool can_map() const override { return true; }
std::unique_ptr<MappedMemory> OpenMapped(MappedMemory::Mode mode,
size_t offset,
size_t length) override;
private: private:
MappedMemory* mmap_; MappedMemory* mmap_;
GDFXEntry* gdfx_entry_; GDFXEntry* gdfx_entry_;

View File

@ -17,15 +17,6 @@
namespace xe { namespace xe {
namespace vfs { namespace vfs {
class HostPathMemoryMapping : public MemoryMapping {
public:
HostPathMemoryMapping(std::unique_ptr<MappedMemory> mmap)
: MemoryMapping(mmap->data(), mmap->size()), mmap_(std::move(mmap)) {}
private:
std::unique_ptr<MappedMemory> mmap_;
};
HostPathEntry::HostPathEntry(Device* device, const char* path, HostPathEntry::HostPathEntry(Device* device, const char* path,
const std::wstring& local_path) const std::wstring& local_path)
: Entry(device, path), : Entry(device, path),
@ -125,19 +116,6 @@ X_STATUS HostPathEntry::QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info,
return X_STATUS_SUCCESS; return X_STATUS_SUCCESS;
} }
std::unique_ptr<MemoryMapping> 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<HostPathMemoryMapping>(std::move(mmap));
}
X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async, X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async,
XFile** out_file) { XFile** out_file) {
// TODO(benvanik): plumb through proper disposition/access mode. // 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; return X_STATUS_SUCCESS;
} }
std::unique_ptr<MappedMemory> HostPathEntry::OpenMapped(MappedMemory::Mode mode,
size_t offset,
size_t length) {
return MappedMemory::Open(local_path_, mode, offset, length);
}
} // namespace vfs } // namespace vfs
} // namespace xe } // namespace xe

View File

@ -27,13 +27,14 @@ class HostPathEntry : public Entry {
X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length, X_STATUS QueryDirectory(X_FILE_DIRECTORY_INFORMATION* out_info, size_t length,
const char* file_name, bool restart) override; const char* file_name, bool restart) override;
bool can_map() override { return true; }
std::unique_ptr<MemoryMapping> CreateMemoryMapping(
Mode map_mode, const size_t offset, const size_t length) override;
X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, X_STATUS Open(KernelState* kernel_state, Mode mode, bool async,
XFile** out_file) override; XFile** out_file) override;
bool can_map() const override { return true; }
std::unique_ptr<MappedMemory> OpenMapped(MappedMemory::Mode mode,
size_t offset,
size_t length) override;
private: private:
std::wstring local_path_; std::wstring local_path_;
HANDLE find_file_; HANDLE find_file_;

View File

@ -15,11 +15,6 @@
namespace xe { namespace xe {
namespace vfs { namespace vfs {
MemoryMapping::MemoryMapping(uint8_t* address, size_t length)
: address_(address), length_(length) {}
MemoryMapping::~MemoryMapping() {}
Entry::Entry(Device* device, const std::string& path) Entry::Entry(Device* device, const std::string& path)
: device_(device), path_(path) { : device_(device), path_(path) {
assert_not_null(device); assert_not_null(device);

View File

@ -13,6 +13,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "xenia/base/mapped_memory.h"
#include "xenia/xbox.h" #include "xenia/xbox.h"
namespace xe { namespace xe {
@ -37,19 +38,6 @@ enum class Mode {
READ_APPEND, 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 { class Entry {
public: public:
Entry(Device* device, const std::string& path); Entry(Device* device, const std::string& path);
@ -67,16 +55,16 @@ class Entry {
size_t length, const char* file_name, size_t length, const char* file_name,
bool restart) = 0; bool restart) = 0;
virtual bool can_map() { return false; }
virtual std::unique_ptr<MemoryMapping> 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, virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async,
XFile** out_file) = 0; XFile** out_file) = 0;
virtual bool can_map() const { return false; }
virtual std::unique_ptr<MappedMemory> OpenMapped(MappedMemory::Mode mode,
size_t offset = 0,
size_t length = 0) {
return nullptr;
}
private: private:
Device* device_; Device* device_;
std::string path_; std::string path_;