mirror of
https://github.com/Atmosphere-NX/Atmosphere-libs.git
synced 2025-06-28 05:52:39 +02:00
strat: remove map namespace, svc: add address space defs
This commit is contained in:
parent
4ce6273f2b
commit
782e449543
@ -22,19 +22,19 @@ namespace ams::kern {
|
|||||||
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
|
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
|
||||||
|
|
||||||
constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
|
constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
|
||||||
{ 32, 2_MB, 1_GB - 2_MB, KAddressSpaceInfo::Type_MapSmall, },
|
{ 32, ams::svc::AddressSmallMap32Start, ams::svc::AddressSmallMap32Size, KAddressSpaceInfo::Type_MapSmall, },
|
||||||
{ 32, 1_GB, 4_GB - 1_GB, KAddressSpaceInfo::Type_MapLarge, },
|
{ 32, ams::svc::AddressLargeMap32Start, ams::svc::AddressLargeMap32Size, KAddressSpaceInfo::Type_MapLarge, },
|
||||||
{ 32, Invalid, 1_GB, KAddressSpaceInfo::Type_Heap, },
|
{ 32, Invalid, ams::svc::AddressMemoryRegionHeap32Size, KAddressSpaceInfo::Type_Heap, },
|
||||||
{ 32, Invalid, 1_GB, KAddressSpaceInfo::Type_Alias, },
|
{ 32, Invalid, ams::svc::AddressMemoryRegionAlias32Size, KAddressSpaceInfo::Type_Alias, },
|
||||||
{ 36, 128_MB, 2_GB - 128_MB, KAddressSpaceInfo::Type_MapSmall, },
|
{ 36, ams::svc::AddressSmallMap36Start, ams::svc::AddressSmallMap36Size, KAddressSpaceInfo::Type_MapSmall, },
|
||||||
{ 36, 2_GB, 64_GB - 2_GB, KAddressSpaceInfo::Type_MapLarge, },
|
{ 36, ams::svc::AddressLargeMap36Start, ams::svc::AddressLargeMap36Size, KAddressSpaceInfo::Type_MapLarge, },
|
||||||
{ 36, Invalid, 6_GB, KAddressSpaceInfo::Type_Heap, },
|
{ 36, Invalid, ams::svc::AddressMemoryRegionHeap36Size, KAddressSpaceInfo::Type_Heap, },
|
||||||
{ 36, Invalid, 6_GB, KAddressSpaceInfo::Type_Alias, },
|
{ 36, Invalid, ams::svc::AddressMemoryRegionAlias36Size, KAddressSpaceInfo::Type_Alias, },
|
||||||
{ 39, 128_MB, 512_GB - 128_MB, KAddressSpaceInfo::Type_Map39Bit, },
|
{ 39, ams::svc::AddressMap39Start, ams::svc::AddressMap39Size, KAddressSpaceInfo::Type_Map39Bit, },
|
||||||
{ 39, Invalid, 64_GB, KAddressSpaceInfo::Type_MapSmall, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionSmall39Size, KAddressSpaceInfo::Type_MapSmall, },
|
||||||
{ 39, Invalid, 6_GB, KAddressSpaceInfo::Type_Heap, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionHeap39Size, KAddressSpaceInfo::Type_Heap, },
|
||||||
{ 39, Invalid, 64_GB, KAddressSpaceInfo::Type_Alias, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionAlias39Size, KAddressSpaceInfo::Type_Alias, },
|
||||||
{ 39, Invalid, 2_GB, KAddressSpaceInfo::Type_Stack, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool IsAllowedIndexForAddress(size_t index) {
|
constexpr bool IsAllowedIndexForAddress(size_t index) {
|
||||||
|
@ -66,7 +66,6 @@
|
|||||||
#include <stratosphere/ldr.hpp>
|
#include <stratosphere/ldr.hpp>
|
||||||
#include <stratosphere/lr.hpp>
|
#include <stratosphere/lr.hpp>
|
||||||
#include <stratosphere/lm.hpp>
|
#include <stratosphere/lm.hpp>
|
||||||
#include <stratosphere/map.hpp>
|
|
||||||
#include <stratosphere/ncm.hpp>
|
#include <stratosphere/ncm.hpp>
|
||||||
#include <stratosphere/nim.hpp>
|
#include <stratosphere/nim.hpp>
|
||||||
#include <stratosphere/ns.hpp>
|
#include <stratosphere/ns.hpp>
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stratosphere/map/map_types.hpp>
|
|
||||||
#include <stratosphere/map/map_api.hpp>
|
|
@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stratosphere/map/map_types.hpp>
|
|
||||||
|
|
||||||
namespace ams::map {
|
|
||||||
|
|
||||||
/* Public API. */
|
|
||||||
Result GetProcessAddressSpaceInfo(AddressSpaceInfo *out, os::NativeHandle process_h);
|
|
||||||
Result LocateMappableSpace(uintptr_t *out_address, size_t size);
|
|
||||||
Result MapCodeMemoryInProcess(MappedCodeMemory &out_mcm, os::NativeHandle process_handle, uintptr_t base_address, size_t size);
|
|
||||||
bool CanAddGuardRegionsInProcess(os::NativeHandle process_handle, uintptr_t address, size_t size);
|
|
||||||
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <vapours.hpp>
|
|
||||||
#include <stratosphere/os/os_native_handle.hpp>
|
|
||||||
|
|
||||||
namespace ams::map {
|
|
||||||
|
|
||||||
/* Types. */
|
|
||||||
struct AddressSpaceInfo {
|
|
||||||
uintptr_t heap_base;
|
|
||||||
size_t heap_size;
|
|
||||||
uintptr_t heap_end;
|
|
||||||
uintptr_t alias_base;
|
|
||||||
size_t alias_size;
|
|
||||||
uintptr_t alias_end;
|
|
||||||
uintptr_t aslr_base;
|
|
||||||
size_t aslr_size;
|
|
||||||
uintptr_t aslr_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr uintptr_t AslrBase32Bit = 0x0000200000ul;
|
|
||||||
static constexpr size_t AslrSize32Bit = 0x003FE00000ul;
|
|
||||||
static constexpr uintptr_t AslrBase64BitDeprecated = 0x0008000000ul;
|
|
||||||
static constexpr size_t AslrSize64BitDeprecated = 0x0078000000ul;
|
|
||||||
static constexpr uintptr_t AslrBase64Bit = 0x0008000000ul;
|
|
||||||
static constexpr size_t AslrSize64Bit = 0x7FF8000000ul;
|
|
||||||
|
|
||||||
class AutoCloseMap {
|
|
||||||
private:
|
|
||||||
os::NativeHandle process_handle;
|
|
||||||
Result result;
|
|
||||||
uintptr_t mapped_address;
|
|
||||||
uintptr_t base_address;
|
|
||||||
size_t size;
|
|
||||||
public:
|
|
||||||
AutoCloseMap(uintptr_t mp, os::NativeHandle p_h, uintptr_t ba, size_t sz) : process_handle(p_h), mapped_address(mp), base_address(ba), size(sz) {
|
|
||||||
this->result = svc::MapProcessMemory(this->mapped_address, this->process_handle, this->base_address, this->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoCloseMap() {
|
|
||||||
if (this->process_handle != os::InvalidNativeHandle && R_SUCCEEDED(this->result)) {
|
|
||||||
R_ABORT_UNLESS(svc::UnmapProcessMemory(this->mapped_address, this->process_handle, this->base_address, this->size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetResult() const {
|
|
||||||
return this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSuccess() const {
|
|
||||||
return R_SUCCEEDED(this->result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Invalidate() {
|
|
||||||
this->process_handle = os::InvalidNativeHandle;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MappedCodeMemory {
|
|
||||||
private:
|
|
||||||
os::NativeHandle process_handle;
|
|
||||||
Result result;
|
|
||||||
uintptr_t dst_address;
|
|
||||||
uintptr_t src_address;
|
|
||||||
size_t size;
|
|
||||||
public:
|
|
||||||
MappedCodeMemory(Result init_res) : process_handle(os::InvalidNativeHandle), result(init_res), dst_address(0), src_address(0), size(0) {
|
|
||||||
/* ... */
|
|
||||||
}
|
|
||||||
|
|
||||||
MappedCodeMemory(os::NativeHandle p_h, uintptr_t dst, uintptr_t src, size_t sz) : process_handle(p_h), dst_address(dst), src_address(src), size(sz) {
|
|
||||||
this->result = svc::MapProcessCodeMemory(this->process_handle, this->dst_address, this->src_address, this->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~MappedCodeMemory() {
|
|
||||||
if (this->process_handle != os::InvalidNativeHandle && R_SUCCEEDED(this->result) && this->size > 0) {
|
|
||||||
R_ABORT_UNLESS(svc::UnmapProcessCodeMemory(this->process_handle, this->dst_address, this->src_address, this->size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t GetDstAddress() const {
|
|
||||||
return this->dst_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result GetResult() const {
|
|
||||||
return this->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSuccess() const {
|
|
||||||
return R_SUCCEEDED(this->result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Invalidate() {
|
|
||||||
this->process_handle = os::InvalidNativeHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
MappedCodeMemory &operator=(MappedCodeMemory &&o) {
|
|
||||||
this->process_handle = o.process_handle;
|
|
||||||
this->result = o.result;
|
|
||||||
this->dst_address = o.dst_address;
|
|
||||||
this->src_address = o.src_address;
|
|
||||||
this->size = o.size;
|
|
||||||
o.Invalidate();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include <stratosphere.hpp>
|
|
||||||
|
|
||||||
namespace ams::map {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/* Convenience defines. */
|
|
||||||
constexpr size_t GuardRegionSize = 0x4000;
|
|
||||||
constexpr size_t LocateRetryCount = 0x200;
|
|
||||||
|
|
||||||
/* Deprecated/Modern implementations. */
|
|
||||||
Result LocateMappableSpaceDeprecated(uintptr_t *out_address, size_t size) {
|
|
||||||
svc::MemoryInfo mem_info;
|
|
||||||
svc::PageInfo page_info;
|
|
||||||
uintptr_t cur_base = 0;
|
|
||||||
|
|
||||||
AddressSpaceInfo address_space;
|
|
||||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, dd::GetCurrentProcessHandle()));
|
|
||||||
cur_base = address_space.aslr_base;
|
|
||||||
|
|
||||||
do {
|
|
||||||
R_TRY(svc::QueryMemory(&mem_info, &page_info, cur_base));
|
|
||||||
|
|
||||||
if (mem_info.state == svc::MemoryState_Free && mem_info.addr - cur_base + mem_info.size >= size) {
|
|
||||||
*out_address = cur_base;
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
const uintptr_t mem_end = mem_info.addr + mem_info.size;
|
|
||||||
R_UNLESS(mem_info.state != svc::MemoryState_Inaccessible, svc::ResultOutOfMemory());
|
|
||||||
R_UNLESS(cur_base <= mem_end, svc::ResultOutOfMemory());
|
|
||||||
R_UNLESS(mem_end <= static_cast<uintptr_t>(std::numeric_limits<s32>::max()), svc::ResultOutOfMemory());
|
|
||||||
|
|
||||||
cur_base = mem_end;
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result LocateMappableSpaceModern(uintptr_t *out_address, size_t size) {
|
|
||||||
svc::MemoryInfo mem_info;
|
|
||||||
svc::PageInfo page_info;
|
|
||||||
uintptr_t cur_base = 0, cur_end = 0;
|
|
||||||
|
|
||||||
AddressSpaceInfo address_space;
|
|
||||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, dd::GetCurrentProcessHandle()));
|
|
||||||
cur_base = address_space.aslr_base;
|
|
||||||
cur_end = cur_base + size;
|
|
||||||
|
|
||||||
R_UNLESS(cur_base < cur_end, svc::ResultOutOfMemory());
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (address_space.heap_size && (address_space.heap_base <= cur_end - 1 && cur_base <= address_space.heap_end - 1)) {
|
|
||||||
/* If we overlap the heap region, go to the end of the heap region. */
|
|
||||||
R_UNLESS(cur_base != address_space.heap_end, svc::ResultOutOfMemory());
|
|
||||||
cur_base = address_space.heap_end;
|
|
||||||
} else if (address_space.alias_size && (address_space.alias_base <= cur_end - 1 && cur_base <= address_space.alias_end - 1)) {
|
|
||||||
/* If we overlap the alias region, go to the end of the alias region. */
|
|
||||||
R_UNLESS(cur_base != address_space.alias_end, svc::ResultOutOfMemory());
|
|
||||||
cur_base = address_space.alias_end;
|
|
||||||
} else {
|
|
||||||
R_ABORT_UNLESS(svc::QueryMemory(&mem_info, &page_info, cur_base));
|
|
||||||
if (mem_info.state == svc::MemoryState_Free && mem_info.addr - cur_base + mem_info.size >= size) {
|
|
||||||
*out_address = cur_base;
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
R_UNLESS(cur_base < mem_info.addr + mem_info.size, svc::ResultOutOfMemory());
|
|
||||||
|
|
||||||
cur_base = mem_info.addr + mem_info.size;
|
|
||||||
R_UNLESS(cur_base < address_space.aslr_end, svc::ResultOutOfMemory());
|
|
||||||
}
|
|
||||||
cur_end = cur_base + size;
|
|
||||||
R_UNLESS(cur_base < cur_base + size, svc::ResultOutOfMemory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result MapCodeMemoryInProcessDeprecated(MappedCodeMemory &out_mcm, os::NativeHandle process_handle, uintptr_t base_address, size_t size) {
|
|
||||||
AddressSpaceInfo address_space;
|
|
||||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle));
|
|
||||||
|
|
||||||
R_UNLESS(size <= address_space.aslr_size, ro::ResultOutOfAddressSpace());
|
|
||||||
|
|
||||||
uintptr_t try_address;
|
|
||||||
for (unsigned int i = 0; i < LocateRetryCount; i++) {
|
|
||||||
try_address = address_space.aslr_base + (os::GenerateRandomU64(static_cast<u64>(address_space.aslr_size - size) / os::MemoryPageSize) * os::MemoryPageSize);
|
|
||||||
|
|
||||||
MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size);
|
|
||||||
R_TRY_CATCH(tmp_mcm.GetResult()) {
|
|
||||||
R_CATCH(svc::ResultInvalidCurrentMemory) { continue; }
|
|
||||||
} R_END_TRY_CATCH;
|
|
||||||
|
|
||||||
if (!CanAddGuardRegionsInProcess(process_handle, try_address, size)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We're done searching. */
|
|
||||||
out_mcm = std::move(tmp_mcm);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ro::ResultOutOfAddressSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result MapCodeMemoryInProcessModern(MappedCodeMemory &out_mcm, os::NativeHandle process_handle, uintptr_t base_address, size_t size) {
|
|
||||||
AddressSpaceInfo address_space;
|
|
||||||
R_TRY(GetProcessAddressSpaceInfo(&address_space, process_handle));
|
|
||||||
|
|
||||||
R_UNLESS(size <= address_space.aslr_size, ro::ResultOutOfAddressSpace());
|
|
||||||
|
|
||||||
uintptr_t try_address;
|
|
||||||
for (unsigned int i = 0; i < LocateRetryCount; i++) {
|
|
||||||
while (true) {
|
|
||||||
try_address = address_space.aslr_base + (os::GenerateRandomU64(static_cast<u64>(address_space.aslr_size - size) / os::MemoryPageSize) * os::MemoryPageSize);
|
|
||||||
if (address_space.heap_size && (address_space.heap_base <= try_address + size - 1 && try_address <= address_space.heap_end - 1)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (address_space.alias_size && (address_space.alias_base <= try_address + size - 1 && try_address <= address_space.alias_end - 1)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MappedCodeMemory tmp_mcm(process_handle, try_address, base_address, size);
|
|
||||||
R_TRY_CATCH(tmp_mcm.GetResult()) {
|
|
||||||
R_CATCH(svc::ResultInvalidCurrentMemory) { continue; }
|
|
||||||
} R_END_TRY_CATCH;
|
|
||||||
|
|
||||||
if (!CanAddGuardRegionsInProcess(process_handle, try_address, size)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We're done searching. */
|
|
||||||
out_mcm = std::move(tmp_mcm);
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ro::ResultOutOfAddressSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Public API. */
|
|
||||||
Result GetProcessAddressSpaceInfo(AddressSpaceInfo *out, os::NativeHandle process_h) {
|
|
||||||
/* Clear output. */
|
|
||||||
std::memset(out, 0, sizeof(*out));
|
|
||||||
|
|
||||||
/* Retrieve info from kernel. */
|
|
||||||
R_TRY(svc::GetInfo(&out->heap_base, svc::InfoType_HeapRegionAddress, process_h, 0));
|
|
||||||
R_TRY(svc::GetInfo(&out->heap_size, svc::InfoType_HeapRegionSize, process_h, 0));
|
|
||||||
R_TRY(svc::GetInfo(&out->alias_base, svc::InfoType_AliasRegionAddress, process_h, 0));
|
|
||||||
R_TRY(svc::GetInfo(&out->alias_size, svc::InfoType_AliasRegionSize, process_h, 0));
|
|
||||||
R_TRY(svc::GetInfo(&out->aslr_base, svc::InfoType_AslrRegionAddress, process_h, 0));
|
|
||||||
R_TRY(svc::GetInfo(&out->aslr_size, svc::InfoType_AslrRegionSize, process_h, 0));
|
|
||||||
|
|
||||||
out->heap_end = out->heap_base + out->heap_size;
|
|
||||||
out->alias_end = out->alias_base + out->alias_size;
|
|
||||||
out->aslr_end = out->aslr_base + out->aslr_size;
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result LocateMappableSpace(uintptr_t *out_address, size_t size) {
|
|
||||||
if (hos::GetVersion() >= hos::Version_2_0_0) {
|
|
||||||
return LocateMappableSpaceModern(out_address, size);
|
|
||||||
} else {
|
|
||||||
return LocateMappableSpaceDeprecated(out_address, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result MapCodeMemoryInProcess(MappedCodeMemory &out_mcm, os::NativeHandle process_handle, uintptr_t base_address, size_t size) {
|
|
||||||
if (hos::GetVersion() >= hos::Version_2_0_0) {
|
|
||||||
return MapCodeMemoryInProcessModern(out_mcm, process_handle, base_address, size);
|
|
||||||
} else {
|
|
||||||
return MapCodeMemoryInProcessDeprecated(out_mcm, process_handle, base_address, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CanAddGuardRegionsInProcess(os::NativeHandle process_handle, uintptr_t address, size_t size) {
|
|
||||||
svc::MemoryInfo mem_info;
|
|
||||||
svc::PageInfo page_info;
|
|
||||||
|
|
||||||
/* Nintendo doesn't validate SVC return values at all. */
|
|
||||||
/* TODO: Should we allow these to fail? */
|
|
||||||
R_ABORT_UNLESS(svc::QueryProcessMemory(&mem_info, &page_info, process_handle, address - 1));
|
|
||||||
if (mem_info.state == svc::MemoryState_Free && address - GuardRegionSize >= mem_info.addr) {
|
|
||||||
R_ABORT_UNLESS(svc::QueryProcessMemory(&mem_info, &page_info, process_handle, address + size));
|
|
||||||
return mem_info.state == svc::MemoryState_Free && address + size + GuardRegionSize <= mem_info.addr + mem_info.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -21,5 +21,6 @@
|
|||||||
|
|
||||||
#include <vapours/svc/svc_types.hpp>
|
#include <vapours/svc/svc_types.hpp>
|
||||||
#include <vapours/svc/svc_definitions.hpp>
|
#include <vapours/svc/svc_definitions.hpp>
|
||||||
|
#include <vapours/svc/svc_memory_map.hpp>
|
||||||
#include <vapours/svc/svc_version.hpp>
|
#include <vapours/svc/svc_version.hpp>
|
||||||
#include <vapours/svc/ipc/svc_message_buffer.hpp>
|
#include <vapours/svc/ipc/svc_message_buffer.hpp>
|
||||||
|
100
libvapours/include/vapours/svc/svc_memory_map.hpp
Normal file
100
libvapours/include/vapours/svc/svc_memory_map.hpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <vapours/common.hpp>
|
||||||
|
|
||||||
|
namespace ams::svc {
|
||||||
|
|
||||||
|
#if defined(ATMOSPHERE_ARCH_ARM64)
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall32Size = 1_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionLarge32Size = 4_GB - AddressMemoryRegionSmall32Size;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap32Size = 1_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias32Size = 1_GB;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall36Size = 2_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionLarge36Size = 64_GB - AddressMemoryRegionSmall36Size;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap36Size = 6_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias36Size = 6_GB;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall39Size = 64_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap39Size = 6_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias39Size = 64_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionStack39Size = 2_GB;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegion39Size = 512_GB;
|
||||||
|
|
||||||
|
#elif defined(ATMOSPHERE_ARCH_ARM)
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall32Size = 512_MB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionLarge32Size = 2_GB - AddressMemoryRegionSmall32Size;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap32Size = 1_GB;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias32Size = 512_MB;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall36Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionLarge36Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap36Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias36Size = 0;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegionSmall39Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionHeap39Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionAlias39Size = 0;
|
||||||
|
constexpr inline size_t AddressMemoryRegionStack39Size = 0;
|
||||||
|
|
||||||
|
constexpr inline size_t AddressMemoryRegion39Size = 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error "Unknown architecture for svc::AddressMemoryRegion*Size"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
constexpr inline size_t AddressNullGuard32Size = 2_MB;
|
||||||
|
constexpr inline size_t AddressNullGuard64Size = 128_MB;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionSmall32Start = 0;
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionSmall32End = AddressMemoryRegionSmall32Start + AddressMemoryRegionSmall32Size;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionLarge32Start = AddressMemoryRegionSmall32End;
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionLarge32End = AddressMemoryRegionLarge32Start + AddressMemoryRegionLarge32Size;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressSmallMap32Start = AddressMemoryRegionSmall32Start + AddressNullGuard32Size;
|
||||||
|
constexpr inline uintptr_t AddressSmallMap32End = AddressMemoryRegionSmall32End;
|
||||||
|
constexpr inline size_t AddressSmallMap32Size = AddressSmallMap32End - AddressSmallMap32Start;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressLargeMap32Start = AddressMemoryRegionLarge32Start;
|
||||||
|
constexpr inline uintptr_t AddressLargeMap32End = AddressMemoryRegionLarge32End;
|
||||||
|
constexpr inline size_t AddressLargeMap32Size = AddressLargeMap32End - AddressLargeMap32Start;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionSmall36Start = 0;
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionSmall36End = AddressMemoryRegionSmall36Start + AddressMemoryRegionSmall36Size;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionLarge36Start = AddressMemoryRegionSmall36End;
|
||||||
|
constexpr inline uintptr_t AddressMemoryRegionLarge36End = AddressMemoryRegionLarge36Start + AddressMemoryRegionLarge36Size;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressSmallMap36Start = AddressMemoryRegionSmall36Start + AddressNullGuard64Size;
|
||||||
|
constexpr inline uintptr_t AddressSmallMap36End = AddressMemoryRegionSmall36End;
|
||||||
|
constexpr inline size_t AddressSmallMap36Size = AddressSmallMap36End - AddressSmallMap36Start;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressLargeMap36Start = AddressMemoryRegionLarge36Start;
|
||||||
|
constexpr inline uintptr_t AddressLargeMap36End = AddressMemoryRegionLarge36End;
|
||||||
|
constexpr inline size_t AddressLargeMap36Size = AddressLargeMap36End - AddressLargeMap36Start;
|
||||||
|
|
||||||
|
constexpr inline uintptr_t AddressMap39Start = 0 + AddressNullGuard64Size;
|
||||||
|
constexpr inline uintptr_t AddressMap39End = AddressMemoryRegion39Size;
|
||||||
|
constexpr inline size_t AddressMap39Size = AddressMap39End - AddressMap39Start;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user