mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-14 23:24:26 -04:00
kern: load initial process binary from user pool, rather than from pt heap
This commit is contained in:
parent
a1e137cc1c
commit
0f8b7be2d2
13 changed files with 350 additions and 184 deletions
|
@ -77,14 +77,14 @@ namespace ams::kern {
|
|||
|
||||
Result KInitialProcessReader::MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const {
|
||||
/* Get and validate addresses/sizes. */
|
||||
const uintptr_t rx_address = m_kip_header->GetRxAddress();
|
||||
const size_t rx_size = m_kip_header->GetRxSize();
|
||||
const uintptr_t ro_address = m_kip_header->GetRoAddress();
|
||||
const size_t ro_size = m_kip_header->GetRoSize();
|
||||
const uintptr_t rw_address = m_kip_header->GetRwAddress();
|
||||
const size_t rw_size = m_kip_header->GetRwSize();
|
||||
const uintptr_t bss_address = m_kip_header->GetBssAddress();
|
||||
const size_t bss_size = m_kip_header->GetBssSize();
|
||||
const uintptr_t rx_address = m_kip_header.GetRxAddress();
|
||||
const size_t rx_size = m_kip_header.GetRxSize();
|
||||
const uintptr_t ro_address = m_kip_header.GetRoAddress();
|
||||
const size_t ro_size = m_kip_header.GetRoSize();
|
||||
const uintptr_t rw_address = m_kip_header.GetRwAddress();
|
||||
const size_t rw_size = m_kip_header.GetRwSize();
|
||||
const uintptr_t bss_address = m_kip_header.GetBssAddress();
|
||||
const size_t bss_size = m_kip_header.GetBssSize();
|
||||
R_UNLESS(util::IsAligned(rx_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(ro_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(rw_address, PageSize), svc::ResultInvalidAddress());
|
||||
|
@ -115,13 +115,13 @@ namespace ams::kern {
|
|||
/* Set fields in parameter. */
|
||||
out->code_address = map_start + start_address;
|
||||
out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize;
|
||||
out->program_id = m_kip_header->GetProgramId();
|
||||
out->version = m_kip_header->GetVersion();
|
||||
out->program_id = m_kip_header.GetProgramId();
|
||||
out->version = m_kip_header.GetVersion();
|
||||
out->flags = 0;
|
||||
MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize));
|
||||
|
||||
/* 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) {
|
||||
|
@ -146,39 +146,36 @@ namespace ams::kern {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result KInitialProcessReader::Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms) const {
|
||||
/* Clear memory at the address. */
|
||||
std::memset(GetVoidPointer(address), 0, params.code_num_pages * PageSize);
|
||||
|
||||
Result KInitialProcessReader::Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms, KProcessAddress src) const {
|
||||
/* Prepare to layout the data. */
|
||||
const KProcessAddress rx_address = address + m_kip_header->GetRxAddress();
|
||||
const KProcessAddress ro_address = address + m_kip_header->GetRoAddress();
|
||||
const KProcessAddress rw_address = address + m_kip_header->GetRwAddress();
|
||||
const u8 *rx_binary = reinterpret_cast<const u8 *>(m_kip_header + 1);
|
||||
const u8 *ro_binary = rx_binary + m_kip_header->GetRxCompressedSize();
|
||||
const u8 *rw_binary = ro_binary + m_kip_header->GetRoCompressedSize();
|
||||
const KProcessAddress rx_address = address + m_kip_header.GetRxAddress();
|
||||
const KProcessAddress ro_address = address + m_kip_header.GetRoAddress();
|
||||
const KProcessAddress rw_address = address + m_kip_header.GetRwAddress();
|
||||
const u8 *rx_binary = GetPointer<const u8>(src);
|
||||
const u8 *ro_binary = rx_binary + m_kip_header.GetRxCompressedSize();
|
||||
const u8 *rw_binary = ro_binary + m_kip_header.GetRoCompressedSize();
|
||||
|
||||
/* Copy text. */
|
||||
if (util::AlignUp(m_kip_header->GetRxSize(), PageSize)) {
|
||||
std::memcpy(GetVoidPointer(rx_address), rx_binary, m_kip_header->GetRxCompressedSize());
|
||||
if (m_kip_header->IsRxCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(rx_address + m_kip_header->GetRxCompressedSize()));
|
||||
if (util::AlignUp(m_kip_header.GetRxSize(), PageSize)) {
|
||||
std::memmove(GetVoidPointer(rx_address), rx_binary, m_kip_header.GetRxCompressedSize());
|
||||
if (m_kip_header.IsRxCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(rx_address + m_kip_header.GetRxCompressedSize()));
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy rodata. */
|
||||
if (util::AlignUp(m_kip_header->GetRoSize(), PageSize)) {
|
||||
std::memcpy(GetVoidPointer(ro_address), ro_binary, m_kip_header->GetRoCompressedSize());
|
||||
if (m_kip_header->IsRoCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(ro_address + m_kip_header->GetRoCompressedSize()));
|
||||
if (util::AlignUp(m_kip_header.GetRoSize(), PageSize)) {
|
||||
std::memmove(GetVoidPointer(ro_address), ro_binary, m_kip_header.GetRoCompressedSize());
|
||||
if (m_kip_header.IsRoCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(ro_address + m_kip_header.GetRoCompressedSize()));
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy rwdata. */
|
||||
if (util::AlignUp(m_kip_header->GetRwSize(), PageSize)) {
|
||||
std::memcpy(GetVoidPointer(rw_address), rw_binary, m_kip_header->GetRwCompressedSize());
|
||||
if (m_kip_header->IsRwCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(rw_address + m_kip_header->GetRwCompressedSize()));
|
||||
if (util::AlignUp(m_kip_header.GetRwSize(), PageSize)) {
|
||||
std::memmove(GetVoidPointer(rw_address), rw_binary, m_kip_header.GetRwCompressedSize());
|
||||
if (m_kip_header.IsRwCompressed()) {
|
||||
BlzUncompress(GetVoidPointer(rw_address + m_kip_header.GetRwCompressedSize()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,27 +189,27 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
Result KInitialProcessReader::SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter ¶ms) const {
|
||||
const size_t rx_size = m_kip_header->GetRxSize();
|
||||
const size_t ro_size = m_kip_header->GetRoSize();
|
||||
const size_t rw_size = m_kip_header->GetRwSize();
|
||||
const size_t bss_size = m_kip_header->GetBssSize();
|
||||
const size_t rx_size = m_kip_header.GetRxSize();
|
||||
const size_t ro_size = m_kip_header.GetRoSize();
|
||||
const size_t rw_size = m_kip_header.GetRwSize();
|
||||
const size_t bss_size = m_kip_header.GetBssSize();
|
||||
|
||||
/* Set R-X pages. */
|
||||
if (rx_size) {
|
||||
const uintptr_t start = m_kip_header->GetRxAddress() + params.code_address;
|
||||
const uintptr_t start = m_kip_header.GetRxAddress() + params.code_address;
|
||||
R_TRY(page_table.SetProcessMemoryPermission(start, util::AlignUp(rx_size, PageSize), ams::svc::MemoryPermission_ReadExecute));
|
||||
}
|
||||
|
||||
/* Set R-- pages. */
|
||||
if (ro_size) {
|
||||
const uintptr_t start = m_kip_header->GetRoAddress() + params.code_address;
|
||||
const uintptr_t start = m_kip_header.GetRoAddress() + params.code_address;
|
||||
R_TRY(page_table.SetProcessMemoryPermission(start, util::AlignUp(ro_size, PageSize), ams::svc::MemoryPermission_Read));
|
||||
}
|
||||
|
||||
/* Set RW- pages. */
|
||||
if (rw_size || bss_size) {
|
||||
const uintptr_t start = (rw_size ? m_kip_header->GetRwAddress() : m_kip_header->GetBssAddress()) + params.code_address;
|
||||
const uintptr_t end = (bss_size ? m_kip_header->GetBssAddress() + bss_size : m_kip_header->GetRwAddress() + rw_size) + params.code_address;
|
||||
const uintptr_t start = (rw_size ? m_kip_header.GetRwAddress() : m_kip_header.GetBssAddress()) + params.code_address;
|
||||
const uintptr_t end = (bss_size ? m_kip_header.GetBssAddress() + bss_size : m_kip_header.GetRwAddress() + rw_size) + params.code_address;
|
||||
R_TRY(page_table.SetProcessMemoryPermission(start, util::AlignUp(end - start, PageSize), ams::svc::MemoryPermission_ReadWrite));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue