summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/k_process.cpp')
-rw-r--r--src/core/hle/kernel/k_process.cpp33
1 files changed, 26 insertions, 7 deletions
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 44c7cb22f..4a099286b 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -38,7 +38,7 @@ namespace {
*/
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
KProcessAddress stack_top) {
- const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart();
+ const KProcessAddress entry_point = owner_process.GetEntryPoint();
ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
KThread* thread = KThread::Create(system.Kernel());
@@ -81,7 +81,8 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
process->m_capabilities.InitializeForMetadatalessProcess();
process->m_is_initialized = true;
- std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr)));
+ std::mt19937 rng(Settings::values.rng_seed_enabled ? Settings::values.rng_seed.GetValue()
+ : static_cast<u32>(std::time(nullptr)));
std::uniform_int_distribution<u64> distribution;
std::generate(process->m_random_entropy.begin(), process->m_random_entropy.end(),
[&] { return distribution(rng); });
@@ -95,6 +96,7 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
process->m_is_suspended = false;
process->m_schedule_count = 0;
process->m_is_handle_table_initialized = false;
+ process->m_is_hbl = false;
// Open a reference to the resource limit.
process->m_resource_limit->Open();
@@ -350,12 +352,29 @@ Result KProcess::SetActivity(ProcessActivity activity) {
R_SUCCEED();
}
-Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size) {
+Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
+ bool is_hbl) {
m_program_id = metadata.GetTitleID();
m_ideal_core = metadata.GetMainThreadCore();
m_is_64bit_process = metadata.Is64BitProgram();
m_system_resource_size = metadata.GetSystemResourceSize();
m_image_size = code_size;
+ m_is_hbl = is_hbl;
+
+ if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) {
+ // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
+ // However, some (buggy) programs/libraries like skyline incorrectly depend on the
+ // existence of ASLR pages before the entry point, so we will adjust the load address
+ // to point to about 2GiB into the ASLR region.
+ m_code_address = 0x8000'0000;
+ } else {
+ // All other processes can be mapped at the beginning of the code region.
+ if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
+ m_code_address = 0x800'0000;
+ } else {
+ m_code_address = 0x20'0000;
+ }
+ }
KScopedResourceReservation memory_reservation(
m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
@@ -367,15 +386,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize process address space
if (const Result result{m_page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
- 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit,
- m_kernel.System().ApplicationMemory())};
+ this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
+ m_resource_limit, m_kernel.System().ApplicationMemory())};
result.IsError()) {
R_RETURN(result);
}
// Map process code region
- if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(),
- code_size / PageSize, KMemoryState::Code,
+ if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
+ KMemoryState::Code,
KMemoryPermission::None)};
result.IsError()) {
R_RETURN(result);