Replacing vfs memory mapping with base memory mapping.
Progress on #294.
This commit is contained in:
parent
23f91b58f3
commit
1ac19f1b08
|
@ -22,21 +22,26 @@ class MappedMemory {
|
|||
kReadWrite,
|
||||
};
|
||||
|
||||
virtual ~MappedMemory() = default;
|
||||
|
||||
static std::unique_ptr<MappedMemory> 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<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_); }
|
||||
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_;
|
||||
|
|
|
@ -180,6 +180,7 @@ void KernelState::SetExecutableModule(object_ref<XUserModule> module) {
|
|||
}
|
||||
executable_module_ = std::move(module);
|
||||
|
||||
if (executable_module_) {
|
||||
auto header = executable_module_->xex_header();
|
||||
if (header) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KernelState::LoadKernelModule(object_ref<XKernelModule> kernel_module) {
|
||||
std::lock_guard<xe::recursive_mutex> lock(object_mutex_);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<MemoryMapping> 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<MappedMemory> 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<MemoryMapping> 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<DiscImageMemoryMapping>(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
|
||||
|
|
|
@ -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<MemoryMapping> 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<MappedMemory> OpenMapped(MappedMemory::Mode mode,
|
||||
size_t offset,
|
||||
size_t length) override;
|
||||
|
||||
private:
|
||||
MappedMemory* mmap_;
|
||||
GDFXEntry* gdfx_entry_;
|
||||
|
|
|
@ -17,15 +17,6 @@
|
|||
namespace xe {
|
||||
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,
|
||||
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<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,
|
||||
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<MappedMemory> HostPathEntry::OpenMapped(MappedMemory::Mode mode,
|
||||
size_t offset,
|
||||
size_t length) {
|
||||
return MappedMemory::Open(local_path_, mode, offset, length);
|
||||
}
|
||||
|
||||
} // namespace vfs
|
||||
} // namespace xe
|
||||
|
|
|
@ -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<MemoryMapping> 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<MappedMemory> OpenMapped(MappedMemory::Mode mode,
|
||||
size_t offset,
|
||||
size_t length) override;
|
||||
|
||||
private:
|
||||
std::wstring local_path_;
|
||||
HANDLE find_file_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#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<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,
|
||||
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:
|
||||
Device* device_;
|
||||
std::string path_;
|
||||
|
|
Loading…
Reference in New Issue