mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 06:45:29 +03:00
Dynamic Guest Memory Base Allocation
This commit is contained in:
parent
cffbfc8034
commit
369bd469f6
@ -68,9 +68,6 @@ namespace skyline {
|
||||
};
|
||||
|
||||
namespace constant {
|
||||
// Memory
|
||||
constexpr u64 BaseAddress{0x8000000}; //!< The address space base
|
||||
constexpr u64 DefaultStackSize{0x1E8480}; //!< The default amount of stack: 2 MB
|
||||
// Display
|
||||
constexpr u16 HandheldResolutionW{1280}; //!< The width component of the handheld resolution
|
||||
constexpr u16 HandheldResolutionH{720}; //!< The height component of the handheld resolution
|
||||
@ -140,12 +137,12 @@ namespace skyline {
|
||||
template<class T>
|
||||
T PointerValue(T item) {
|
||||
return item;
|
||||
};
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t PointerValue(T *item) {
|
||||
return reinterpret_cast<size_t>(item);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value aligned up to the next multiple
|
||||
@ -210,7 +207,7 @@ namespace skyline {
|
||||
return object;
|
||||
}
|
||||
|
||||
constexpr u8 HexDigitToByte(char digit) {
|
||||
constexpr u8 HexDigitToNibble(char digit) {
|
||||
if (digit >= '0' && digit <= '9')
|
||||
return digit - '0';
|
||||
else if (digit >= 'a' && digit <= 'f')
|
||||
@ -221,17 +218,35 @@ namespace skyline {
|
||||
}
|
||||
|
||||
template<size_t Size>
|
||||
constexpr std::array<u8, Size> HexStringToArray(std::string_view hexString) {
|
||||
if (hexString.size() != Size * 2)
|
||||
constexpr std::array<u8, Size> HexStringToArray(std::string_view string) {
|
||||
if (string.size() != Size * 2)
|
||||
throw exception("Invalid size");
|
||||
std::array<u8, Size> result;
|
||||
for (size_t i{}; i < Size; i++) {
|
||||
size_t hexStrIndex{i * 2};
|
||||
result[i] = (HexDigitToByte(hexString[hexStrIndex]) << 4) | HexDigitToByte(hexString[hexStrIndex + 1]);
|
||||
size_t index{i * 2};
|
||||
result[i] = (HexDigitToNibble(string[index]) << 4) | HexDigitToNibble(string[index + 1]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
constexpr Type HexStringToInt(std::string_view string) {
|
||||
Type result{};
|
||||
size_t offset{(sizeof(Type) * 8) - 4};
|
||||
for (size_t index{}; index < std::min(sizeof(Type) * 2, string.size()); index++, offset -= 4) {
|
||||
char digit{string[index]};
|
||||
if (digit >= '0' && digit <= '9')
|
||||
result |= static_cast<Type>(digit - '0') << offset;
|
||||
else if (digit >= 'a' && digit <= 'f')
|
||||
result |= static_cast<Type>(digit - 'a' + 10) << offset;
|
||||
else if (digit >= 'A' && digit <= 'F')
|
||||
result |= static_cast<Type>(digit - 'A' + 10) << offset;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return result >> (offset + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A compile-time hash function as std::hash isn't constexpr
|
||||
*/
|
||||
|
@ -15,16 +15,14 @@ namespace skyline::kernel {
|
||||
case memory::AddressSpaceType::AddressSpace36Bit: {
|
||||
addressSpace.address = 0;
|
||||
addressSpace.size = 1UL << 36;
|
||||
base.address = constant::BaseAddress;
|
||||
base.size = 0xFF8000000;
|
||||
base.size = 0x78000000 + 0x180000000 + 0x180000000 + 0x180000000;
|
||||
break;
|
||||
}
|
||||
|
||||
case memory::AddressSpaceType::AddressSpace39Bit: {
|
||||
addressSpace.address = 0;
|
||||
addressSpace.size = 1UL << 39;
|
||||
base.address = constant::BaseAddress;
|
||||
base.size = 0x7FF8000000;
|
||||
base.size = 0x78000000 + 0x1000000000 + 0x180000000 + 0x80000000 + 0x1000000000;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -32,6 +30,27 @@ namespace skyline::kernel {
|
||||
throw exception("VMM initialization with unknown address space");
|
||||
}
|
||||
|
||||
std::ifstream mapsFile("/proc/self/maps");
|
||||
std::string maps((std::istreambuf_iterator<char>(mapsFile)), std::istreambuf_iterator<char>());
|
||||
size_t line{}, start{}, alignedStart{};
|
||||
do {
|
||||
auto end{util::HexStringToInt<u64>(std::string_view(maps.data() + line, sizeof(u64) * 2))};
|
||||
if (end - start > base.size + (alignedStart - start)) { // We don't want to overflow if alignedStart > start
|
||||
base.address = alignedStart;
|
||||
break;
|
||||
}
|
||||
|
||||
start = util::HexStringToInt<u64>(std::string_view(maps.data() + maps.find_first_of('-', line) + 1, sizeof(u64) * 2));
|
||||
alignedStart = util::AlignUp(start, 1ULL << 21);
|
||||
if (alignedStart + base.size > addressSpace.size)
|
||||
break;
|
||||
} while ((line = maps.find_first_of('\n', line)) != std::string::npos && line++);
|
||||
|
||||
if (!base.address)
|
||||
throw exception("Cannot find a suitable carveout for the guest address space");
|
||||
|
||||
mmap(reinterpret_cast<void*>(base.address), base.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
|
||||
chunks = {ChunkDescriptor{
|
||||
.ptr = reinterpret_cast<u8 *>(addressSpace.address),
|
||||
.size = addressSpace.size,
|
||||
@ -50,7 +69,7 @@ namespace skyline::kernel {
|
||||
alias.address = code.address + code.size;
|
||||
alias.size = 0x180000000;
|
||||
stack.address = alias.address;
|
||||
stack.size = alias.size;
|
||||
stack.size = 0x180000000;
|
||||
heap.address = alias.address + alias.size;
|
||||
heap.size = 0x180000000;
|
||||
tlsIo.address = code.address;
|
||||
@ -59,8 +78,8 @@ namespace skyline::kernel {
|
||||
}
|
||||
|
||||
case 1UL << 39: {
|
||||
code.address = util::AlignDown(address, 0x200000);
|
||||
code.size = util::AlignUp(address + size, 0x200000) - code.address;
|
||||
code.address = base.address;
|
||||
code.size = 0x78000000;
|
||||
alias.address = code.address + code.size;
|
||||
alias.size = 0x1000000000;
|
||||
heap.address = alias.address + alias.size;
|
||||
@ -76,7 +95,10 @@ namespace skyline::kernel {
|
||||
throw exception("Regions initialized without VMM initialization");
|
||||
}
|
||||
|
||||
state.logger->Debug("Region Map:\nCode Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nAlias Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nHeap Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nStack Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nTLS/IO Region: 0x{:X} - 0x{:X} (Size: 0x{:X})", code.address, code.address + code.size, code.size, alias.address, alias.address + alias.size, alias.size, heap.address, heap
|
||||
if (size > code.size)
|
||||
throw exception("Code region ({}) is smaller than mapped code size ({})", code.size, size);
|
||||
|
||||
state.logger->Debug("Region Map:\nVMM Base: 0x{:X}\nCode Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nAlias Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nHeap Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nStack Region: 0x{:X} - 0x{:X} (Size: 0x{:X})\nTLS/IO Region: 0x{:X} - 0x{:X} (Size: 0x{:X})", base.address, code.address, code.address + code.size, code.size, alias.address, alias.address + alias.size, alias.size, heap.address, heap
|
||||
.address + heap.size, heap.size, stack.address, stack.address + stack.size, stack.size, tlsIo.address, tlsIo.address + tlsIo.size, tlsIo.size);
|
||||
}
|
||||
|
||||
|
@ -674,15 +674,15 @@ namespace skyline::kernel::svc {
|
||||
break;
|
||||
|
||||
case constant::infoState::TotalMemoryUsage:
|
||||
out = state.process->heap->size + constant::DefaultStackSize + state.process->memory.GetProgramSize();
|
||||
out = state.process->heap->size + state.thread->stack->size + state.process->memory.GetProgramSize();
|
||||
break;
|
||||
|
||||
case constant::infoState::AddressSpaceBaseAddr:
|
||||
out = state.process->memory.base.address;
|
||||
out = state.process->memory.addressSpace.address;
|
||||
break;
|
||||
|
||||
case constant::infoState::AddressSpaceSize:
|
||||
out = state.process->memory.base.size;
|
||||
out = state.process->memory.addressSpace.size;
|
||||
break;
|
||||
|
||||
case constant::infoState::StackRegionBaseAddr:
|
||||
@ -698,7 +698,7 @@ namespace skyline::kernel::svc {
|
||||
break;
|
||||
|
||||
case constant::infoState::PersonalMmHeapUsage:
|
||||
out = state.process->heap->size + constant::DefaultStackSize;
|
||||
out = state.process->heap->size + state.thread->stack->size;
|
||||
break;
|
||||
|
||||
case constant::infoState::TotalMemoryAvailableWithoutMmHeap:
|
||||
@ -706,7 +706,7 @@ namespace skyline::kernel::svc {
|
||||
break;
|
||||
|
||||
case constant::infoState::TotalMemoryUsedWithoutMmHeap:
|
||||
out = state.process->heap->size + constant::DefaultStackSize; // TODO: Same as above
|
||||
out = state.process->heap->size + state.thread->stack->size; // TODO: Same as above
|
||||
break;
|
||||
|
||||
case constant::infoState::UserExceptionContextAddr:
|
||||
|
@ -8,16 +8,17 @@
|
||||
#include "KProcess.h"
|
||||
|
||||
namespace skyline::kernel::type {
|
||||
KPrivateMemory::KPrivateMemory(const DeviceState &state, u8* ptr, size_t size, memory::Permission permission, memory::MemoryState memState) : size(size), permission(permission), memState(memState), KMemory(state, KType::KPrivateMemory) {
|
||||
if (ptr && !util::PageAligned(ptr))
|
||||
KPrivateMemory::KPrivateMemory(const DeviceState &state, u8* ptr, size_t size, memory::Permission permission, memory::MemoryState memState) : ptr(ptr), size(size), permission(permission), memState(memState), KMemory(state, KType::KPrivateMemory) {
|
||||
if (!state.process->memory.base.IsInside(ptr) || !state.process->memory.base.IsInside(ptr + size))
|
||||
throw exception("KPrivateMemory allocation isn't inside guest address space: 0x{:X} - 0x{:X}", ptr, ptr + size);
|
||||
if (!util::PageAligned(ptr))
|
||||
throw exception("KPrivateMemory was created with non-page-aligned address: 0x{:X}", ptr);
|
||||
|
||||
this->ptr = reinterpret_cast<u8*>(mmap(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, (ptr ? MAP_FIXED : 0) | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
|
||||
if (this->ptr == MAP_FAILED)
|
||||
if (mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) // We only need to reprotect as the allocation has already been reserved by the MemoryManager
|
||||
throw exception("An occurred while mapping private memory: {} with 0x{:X} @ 0x{:X}", strerror(errno), ptr, size);
|
||||
|
||||
state.process->memory.InsertChunk(ChunkDescriptor{
|
||||
.ptr = this->ptr,
|
||||
.ptr = ptr,
|
||||
.size = size,
|
||||
.permission = permission,
|
||||
.state = memState,
|
||||
@ -25,8 +26,7 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
void KPrivateMemory::Resize(size_t nSize) {
|
||||
ptr = reinterpret_cast<u8*>(mremap(ptr, size, nSize, 0));
|
||||
if (ptr == MAP_FAILED)
|
||||
if (mprotect(ptr, nSize, PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
|
||||
throw exception("An occurred while resizing private memory: {}", strerror(errno));
|
||||
|
||||
if (nSize < size) {
|
||||
@ -48,6 +48,9 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
void KPrivateMemory::UpdatePermission(u8* ptr, size_t size, memory::Permission permission) {
|
||||
ptr = std::clamp(ptr, this->ptr, this->ptr + this->size);
|
||||
size = std::min(size, static_cast<size_t>((this->ptr + this->size) - ptr));
|
||||
|
||||
if (ptr && !util::PageAligned(ptr))
|
||||
throw exception("KPrivateMemory permission updated with a non-page-aligned address: 0x{:X}", ptr);
|
||||
|
||||
@ -64,7 +67,7 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
KPrivateMemory::~KPrivateMemory() {
|
||||
munmap(ptr, size);
|
||||
mprotect(ptr, size, PROT_NONE);
|
||||
state.process->memory.InsertChunk(ChunkDescriptor{
|
||||
.ptr = ptr,
|
||||
.size = size,
|
||||
|
@ -17,8 +17,8 @@ namespace skyline::kernel::type {
|
||||
memory::MemoryState memState;
|
||||
|
||||
/**
|
||||
* @param ptr The address to map to (If NULL then an arbitrary address is picked)
|
||||
* @param permission The permissions for the allocated memory (As reported to the application, host memory permissions aren't reflected by this)
|
||||
* @note 'ptr' needs to be in guest-reserved address space
|
||||
*/
|
||||
KPrivateMemory(const DeviceState &state, u8* ptr, size_t size, memory::Permission permission, memory::MemoryState memState);
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace skyline::kernel::type {
|
||||
if (fd < 0)
|
||||
throw exception("An error occurred while creating shared memory: {}", fd);
|
||||
|
||||
kernel.ptr = reinterpret_cast<u8*>(mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0));
|
||||
kernel.ptr = reinterpret_cast<u8 *>(mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, 0));
|
||||
if (kernel.ptr == MAP_FAILED)
|
||||
throw exception("An occurred while mapping shared memory: {}", strerror(errno));
|
||||
|
||||
@ -21,10 +21,12 @@ namespace skyline::kernel::type {
|
||||
}
|
||||
|
||||
u8 *KSharedMemory::Map(u8 *ptr, u64 size, memory::Permission permission) {
|
||||
if (!state.process->memory.base.IsInside(ptr) || !state.process->memory.base.IsInside(ptr + size))
|
||||
throw exception("KPrivateMemory allocation isn't inside guest address space: 0x{:X} - 0x{:X}", ptr, ptr + size);
|
||||
if (ptr && !util::PageAligned(ptr))
|
||||
throw exception("KSharedMemory was mapped to a non-page-aligned address: 0x{:X}", ptr);
|
||||
|
||||
guest.ptr = reinterpret_cast<u8*>(mmap(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | (ptr ? MAP_FIXED_NOREPLACE : 0), fd, 0));
|
||||
guest.ptr = reinterpret_cast<u8 *>(mmap(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | (ptr ? MAP_FIXED_NOREPLACE : 0), fd, 0));
|
||||
if (guest.ptr == MAP_FAILED)
|
||||
throw exception("An error occurred while mapping shared memory in guest");
|
||||
guest.size = size;
|
||||
@ -39,7 +41,7 @@ namespace skyline::kernel::type {
|
||||
return guest.ptr;
|
||||
}
|
||||
|
||||
void KSharedMemory::UpdatePermission(u8* ptr, size_t size, memory::Permission permission) {
|
||||
void KSharedMemory::UpdatePermission(u8 *ptr, size_t size, memory::Permission permission) {
|
||||
if (ptr && !util::PageAligned(ptr))
|
||||
throw exception("KSharedMemory permission updated with a non-page-aligned address: 0x{:X}", ptr);
|
||||
|
||||
@ -63,7 +65,7 @@ namespace skyline::kernel::type {
|
||||
munmap(kernel.ptr, kernel.size);
|
||||
|
||||
if (guest.Valid()) {
|
||||
munmap(guest.ptr, guest.size);
|
||||
mmap(guest.ptr, guest.size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
state.process->memory.InsertChunk(ChunkDescriptor{
|
||||
.ptr = guest.ptr,
|
||||
.size = guest.size,
|
||||
|
@ -27,8 +27,7 @@ namespace skyline::kernel::type {
|
||||
KSharedMemory(const DeviceState &state, size_t size, memory::MemoryState memState = memory::states::SharedMemory, KType type = KType::KSharedMemory);
|
||||
|
||||
/**
|
||||
* @param ptr The address to map to (If NULL an arbitrary address is picked, it may be outside of the HOS address space)
|
||||
* @return The address of the allocation
|
||||
* @note 'ptr' needs to be in guest-reserved address space
|
||||
*/
|
||||
u8 *Map(u8 *ptr, u64 size, memory::Permission permission);
|
||||
|
||||
|
@ -123,7 +123,8 @@ namespace skyline::kernel::type {
|
||||
state.logger->Debug("Starting thread #{}", id);
|
||||
|
||||
if (!stack) {
|
||||
stack = stack.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), constant::DefaultStackSize, memory::Permission{true, true, false}, memory::states::Stack);
|
||||
constexpr u64 DefaultStackSize{0x1E8480}; //!< The default amount of stack: 2 MB
|
||||
stack = stack.make_shared(state, reinterpret_cast<u8 *>(state.process->memory.stack.address), DefaultStackSize, memory::Permission{true, true, false}, memory::states::Stack);
|
||||
if (mprotect(stack->ptr, PAGE_SIZE, PROT_NONE))
|
||||
throw exception("Failed to create guard page for thread stack at 0x{:X}", stack->ptr);
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ namespace skyline::kernel::type {
|
||||
*/
|
||||
class KTransferMemory : public KSharedMemory {
|
||||
public:
|
||||
/**
|
||||
* @note 'ptr' needs to be in guest-reserved address space
|
||||
*/
|
||||
KTransferMemory(const DeviceState &state, u8 *ptr, size_t size, memory::Permission permission, memory::MemoryState memState = memory::states::TransferMemory) : KSharedMemory(state, size, memState, KType::KTransferMemory) {
|
||||
std::memcpy(kernel.ptr, ptr, size);
|
||||
Map(ptr, size, permission);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
namespace skyline::loader {
|
||||
Loader::ExecutableLoadInfo Loader::LoadExecutable(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, Executable &executable, size_t offset) {
|
||||
u8 *base{reinterpret_cast<u8 *>(constant::BaseAddress + offset)};
|
||||
u8 *base{reinterpret_cast<u8 *>(process->memory.base.address + offset)};
|
||||
|
||||
u64 textSize{executable.text.contents.size()};
|
||||
u64 roSize{executable.ro.contents.size()};
|
||||
@ -45,6 +45,6 @@ namespace skyline::loader {
|
||||
std::memcpy(base + executable.data.offset, executable.data.contents.data(), dataSize - executable.bssSize);
|
||||
std::memcpy(base + patchOffset, patch.data(), patchSize);
|
||||
|
||||
return {base, patchOffset + patchSize + padding};
|
||||
return {base, patchOffset + patchSize + padding, base};
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ namespace skyline::loader {
|
||||
struct ExecutableLoadInfo {
|
||||
u8* base; //!< The base of the loaded executable
|
||||
size_t size; //!< The total size of the loaded executable
|
||||
void* entry; //!< The entry point of the loaded executable
|
||||
};
|
||||
|
||||
/**
|
||||
@ -74,6 +75,9 @@ namespace skyline::loader {
|
||||
return std::vector<u8>();
|
||||
}
|
||||
|
||||
virtual void LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) = 0;
|
||||
/**
|
||||
* @return Entry point to the start of the main executable in the ROM
|
||||
*/
|
||||
virtual void* LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) = 0;
|
||||
};
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace skyline::loader {
|
||||
throw exception("Only NCAs with an ExeFS can be loaded directly");
|
||||
}
|
||||
|
||||
void NcaLoader::LoadExeFs(const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void* NcaLoader::LoadExeFs(const std::shared_ptr<vfs::FileSystem> &exeFs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
if (exeFs == nullptr)
|
||||
throw exception("Cannot load a null ExeFS");
|
||||
|
||||
@ -25,6 +25,7 @@ namespace skyline::loader {
|
||||
auto loadInfo{NsoLoader::LoadNso(nsoFile, process, state)};
|
||||
u64 offset{loadInfo.size};
|
||||
u8* base{loadInfo.base};
|
||||
void* entry{loadInfo.entry};
|
||||
|
||||
state.logger->Info("Loaded nso 'rtld' at 0x{:X}", base);
|
||||
|
||||
@ -40,9 +41,11 @@ namespace skyline::loader {
|
||||
}
|
||||
|
||||
state.process->memory.InitializeRegions(base, offset);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
void NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
LoadExeFs(nca.exeFs, process, state);
|
||||
void* NcaLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
return LoadExeFs(nca.exeFs, process, state);
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ namespace skyline::loader {
|
||||
* @param exefs A filesystem object containing the ExeFS filesystem to load into memory
|
||||
* @param process The process to load the ExeFS into
|
||||
*/
|
||||
static void LoadExeFs(const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
static void* LoadExeFs(const std::shared_ptr<vfs::FileSystem> &exefs, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
|
||||
void LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void* LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
};
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace skyline::loader {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void* NroLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
Executable nroExecutable{};
|
||||
|
||||
nroExecutable.text.contents = GetSegment(header.text);
|
||||
@ -61,5 +61,7 @@ namespace skyline::loader {
|
||||
state.process->memory.InitializeVmm(memory::AddressSpaceType::AddressSpace39Bit);
|
||||
auto loadInfo{LoadExecutable(process, state, nroExecutable)};
|
||||
state.process->memory.InitializeRegions(loadInfo.base, loadInfo.size);
|
||||
|
||||
return loadInfo.entry;
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,6 @@ namespace skyline::loader {
|
||||
|
||||
std::vector<u8> GetIcon();
|
||||
|
||||
void LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void* LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
};
|
||||
}
|
||||
|
@ -54,9 +54,10 @@ namespace skyline::loader {
|
||||
return LoadExecutable(process, state, nsoExecutable, offset);
|
||||
}
|
||||
|
||||
void NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
void* NsoLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
state.process->memory.InitializeVmm(memory::AddressSpaceType::AddressSpace39Bit);
|
||||
auto loadInfo{LoadNso(backing, process, state)};
|
||||
state.process->memory.InitializeRegions(loadInfo.base, loadInfo.size);
|
||||
return loadInfo.entry;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,6 @@ namespace skyline::loader {
|
||||
*/
|
||||
static ExecutableLoadInfo LoadNso(const std::shared_ptr<vfs::Backing> &backing, const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state, size_t offset = 0);
|
||||
|
||||
void LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void* LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
};
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ namespace skyline::loader {
|
||||
nacp = std::make_shared<vfs::NACP>(controlRomFs->OpenFile("control.nacp"));
|
||||
}
|
||||
|
||||
void NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
NcaLoader::LoadExeFs(programNca->exeFs, process, state);
|
||||
void* NspLoader::LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state) {
|
||||
return NcaLoader::LoadExeFs(programNca->exeFs, process, state);
|
||||
}
|
||||
|
||||
std::vector<u8> NspLoader::GetIcon() {
|
||||
|
@ -26,6 +26,6 @@ namespace skyline::loader {
|
||||
|
||||
std::vector<u8> GetIcon();
|
||||
|
||||
void LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
void* LoadProcessData(const std::shared_ptr<kernel::type::KProcess> process, const DeviceState &state);
|
||||
};
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ namespace skyline::kernel {
|
||||
throw exception("Unsupported ROM extension.");
|
||||
|
||||
process = std::make_shared<kernel::type::KProcess>(state);
|
||||
state.loader->LoadProcessData(process, state);
|
||||
auto entry{state.loader->LoadProcessData(process, state)};
|
||||
process->InitializeHeap();
|
||||
process->CreateThread(reinterpret_cast<void*>(constant::BaseAddress))->Start();
|
||||
process->CreateThread(entry)->Start();
|
||||
|
||||
state.nce->Execute();
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ namespace skyline::service::fssrv {
|
||||
|
||||
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch" + saveDataPath), state, manager), session, response);
|
||||
return {};
|
||||
|
||||
}
|
||||
|
||||
Result IFileSystemProxy::OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
|
Loading…
Reference in New Issue
Block a user