mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 04:11:18 +00:00
kern: KAddressSpaceInfo now takes CreateProcessFlags in getters
This commit is contained in:
parent
a0ad3ef949
commit
70bf833070
5 changed files with 52 additions and 31 deletions
|
@ -37,8 +37,8 @@ namespace ams::kern {
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
Type m_type;
|
Type m_type;
|
||||||
public:
|
public:
|
||||||
static uintptr_t GetAddressSpaceStart(size_t width, Type type);
|
static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type);
|
||||||
static size_t GetAddressSpaceSize(size_t width, Type type);
|
static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type);
|
||||||
|
|
||||||
static void SetAddressSpaceSize(size_t width, Type type, size_t size);
|
static void SetAddressSpaceSize(size_t width, Type type, size_t size);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,24 @@ namespace ams::kern {
|
||||||
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr u8 FlagsToAddressSpaceWidthTable[4] = {
|
||||||
|
32, 36, 32, 39
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag flags) {
|
||||||
|
/* Convert the input flags to an array index. */
|
||||||
|
const size_t idx = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask) >> ams::svc::CreateProcessFlag_AddressSpaceShift;
|
||||||
|
MESOSPHERE_ABORT_UNLESS(idx < sizeof(FlagsToAddressSpaceWidthTable));
|
||||||
|
|
||||||
|
/* Return the width. */
|
||||||
|
return FlagsToAddressSpaceWidthTable[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32Bit) == 32);
|
||||||
|
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated) == 36);
|
||||||
|
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) == 32);
|
||||||
|
static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64Bit) == 39);
|
||||||
|
|
||||||
KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
|
KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
|
||||||
for (auto &info : AddressSpaceInfos) {
|
for (auto &info : AddressSpaceInfos) {
|
||||||
if (info.GetWidth() == width && info.GetType() == type) {
|
if (info.GetWidth() == width && info.GetType() == type) {
|
||||||
|
@ -48,12 +66,12 @@ namespace ams::kern {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
|
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||||
return GetAddressSpaceInfo(width, type).GetAddress();
|
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
|
size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) {
|
||||||
return GetAddressSpaceInfo(width, type).GetSize();
|
return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
||||||
|
|
|
@ -193,40 +193,25 @@ namespace ams::kern {
|
||||||
R_UNLESS(this->Is64Bit(), svc::ResultInvalidCombination());
|
R_UNLESS(this->Is64Bit(), svc::ResultInvalidCombination());
|
||||||
}
|
}
|
||||||
|
|
||||||
using ASType = KAddressSpaceInfo::Type;
|
|
||||||
|
|
||||||
const uintptr_t start_address = rx_address;
|
const uintptr_t start_address = rx_address;
|
||||||
const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size;
|
const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size;
|
||||||
const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32;
|
|
||||||
const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall;
|
|
||||||
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type);
|
|
||||||
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type);
|
|
||||||
const uintptr_t map_end = map_start + map_size;
|
|
||||||
MESOSPHERE_ABORT_UNLESS(start_address == 0);
|
MESOSPHERE_ABORT_UNLESS(start_address == 0);
|
||||||
|
|
||||||
/* Default fields in parameter to zero. */
|
/* Default fields in parameter to zero. */
|
||||||
*out = {};
|
*out = {};
|
||||||
|
|
||||||
/* Set fields in parameter. */
|
/* Set fields in parameter. */
|
||||||
out->code_address = map_start + start_address;
|
out->code_address = 0;
|
||||||
out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize;
|
out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize;
|
||||||
out->program_id = m_kip_header.GetProgramId();
|
out->program_id = m_kip_header.GetProgramId();
|
||||||
out->version = m_kip_header.GetVersion();
|
out->version = m_kip_header.GetVersion();
|
||||||
out->flags = 0;
|
out->flags = 0;
|
||||||
out->reslimit = ams::svc::InvalidHandle;
|
out->reslimit = ams::svc::InvalidHandle;
|
||||||
out->system_resource_num_pages = 0;
|
out->system_resource_num_pages = 0;
|
||||||
MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize));
|
|
||||||
|
|
||||||
/* Copy name field. */
|
/* Copy name field. */
|
||||||
m_kip_header.GetName(out->name, sizeof(out->name));
|
m_kip_header.GetName(out->name, sizeof(out->name));
|
||||||
|
|
||||||
/* Apply ASLR, if needed. */
|
|
||||||
if (enable_aslr) {
|
|
||||||
const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment);
|
|
||||||
out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment;
|
|
||||||
out->flags |= ams::svc::CreateProcessFlag_EnableAslr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply other flags. */
|
/* Apply other flags. */
|
||||||
if (this->Is64Bit()) {
|
if (this->Is64Bit()) {
|
||||||
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
|
out->flags |= ams::svc::CreateProcessFlag_Is64Bit;
|
||||||
|
@ -236,10 +221,28 @@ namespace ams::kern {
|
||||||
} else {
|
} else {
|
||||||
out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit;
|
out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit;
|
||||||
}
|
}
|
||||||
|
if (enable_aslr) {
|
||||||
|
out->flags |= ams::svc::CreateProcessFlag_EnableAslr;
|
||||||
|
}
|
||||||
|
|
||||||
/* All initial processes should disable device address space merge. */
|
/* All initial processes should disable device address space merge. */
|
||||||
out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge;
|
out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge;
|
||||||
|
|
||||||
|
/* Set and check code address. */
|
||||||
|
using ASType = KAddressSpaceInfo::Type;
|
||||||
|
const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall;
|
||||||
|
const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
|
||||||
|
const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(out->flags), as_type);
|
||||||
|
const uintptr_t map_end = map_start + map_size;
|
||||||
|
out->code_address = map_start + start_address;
|
||||||
|
MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize));
|
||||||
|
|
||||||
|
/* Apply ASLR, if needed. */
|
||||||
|
if (enable_aslr) {
|
||||||
|
const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment);
|
||||||
|
out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,10 +141,10 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Define helpers. */
|
/* Define helpers. */
|
||||||
auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
||||||
return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
|
return KAddressSpaceInfo::GetAddressSpaceStart(flags, type);
|
||||||
};
|
};
|
||||||
auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA {
|
||||||
return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type);
|
return KAddressSpaceInfo::GetAddressSpaceSize(flags, type);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Default to zero alias region extra size. */
|
/* Default to zero alias region extra size. */
|
||||||
|
|
|
@ -110,8 +110,8 @@ namespace ams::kern::svc {
|
||||||
case ams::svc::CreateProcessFlag_AddressSpace32Bit:
|
case ams::svc::CreateProcessFlag_AddressSpace32Bit:
|
||||||
case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias:
|
case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias:
|
||||||
{
|
{
|
||||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(32, KAddressSpaceInfo::Type_MapSmall);
|
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(32, KAddressSpaceInfo::Type_MapSmall);
|
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||||
map_end = map_start + map_size;
|
map_end = map_start + map_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -120,8 +120,8 @@ namespace ams::kern::svc {
|
||||||
/* 64-bit address space requires 64-bit process. */
|
/* 64-bit address space requires 64-bit process. */
|
||||||
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
||||||
|
|
||||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(36, KAddressSpaceInfo::Type_MapSmall);
|
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(36, KAddressSpaceInfo::Type_MapSmall);
|
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_MapSmall);
|
||||||
map_end = map_start + map_size;
|
map_end = map_start + map_size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -130,10 +130,10 @@ namespace ams::kern::svc {
|
||||||
/* 64-bit address space requires 64-bit process. */
|
/* 64-bit address space requires 64-bit process. */
|
||||||
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
R_UNLESS(is_64_bit, svc::ResultInvalidCombination());
|
||||||
|
|
||||||
map_start = KAddressSpaceInfo::GetAddressSpaceStart(39, KAddressSpaceInfo::Type_Map39Bit);
|
map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
|
||||||
map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Map39Bit);
|
map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Map39Bit);
|
||||||
|
|
||||||
map_size = KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Heap);
|
map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast<ams::svc::CreateProcessFlag>(params.flags), KAddressSpaceInfo::Type_Heap);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue