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,
|
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_;
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
Loading…
Reference in New Issue