summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar liamwhite2023-08-25 17:59:32 -0400
committerGravatar GitHub2023-08-25 23:59:32 +0200
commit18ad55be0ba2c418c766c9857075b3b64d28104e (patch)
treef3ccc0f4554cba892c8b102adacf4774b70c862b /src/core/hle/kernel
parentMerge pull request #11357 from liamwhite/lime-vfs (diff)
downloadyuzu-18ad55be0ba2c418c766c9857075b3b64d28104e.tar.gz
yuzu-18ad55be0ba2c418c766c9857075b3b64d28104e.tar.xz
yuzu-18ad55be0ba2c418c766c9857075b3b64d28104e.zip
kernel: offset code entry point for 39-bit address space type (#11326)
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_process.cpp25
-rw-r--r--src/core/hle/kernel/k_process.h7
2 files changed, 27 insertions, 5 deletions
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index e573e2a57..703049ede 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -38,7 +38,7 @@ namespace {
38 */ 38 */
39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, 39void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
40 KProcessAddress stack_top) { 40 KProcessAddress stack_top) {
41 const KProcessAddress entry_point = owner_process.GetPageTable().GetCodeRegionStart(); 41 const KProcessAddress entry_point = owner_process.GetEntryPoint();
42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1)); 42 ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
43 43
44 KThread* thread = KThread::Create(system.Kernel()); 44 KThread* thread = KThread::Create(system.Kernel());
@@ -358,6 +358,21 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
358 m_system_resource_size = metadata.GetSystemResourceSize(); 358 m_system_resource_size = metadata.GetSystemResourceSize();
359 m_image_size = code_size; 359 m_image_size = code_size;
360 360
361 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is39Bit) {
362 // For 39-bit processes, the ASLR region starts at 0x800'0000 and is ~512GiB large.
363 // However, some (buggy) programs/libraries like skyline incorrectly depend on the
364 // existence of ASLR pages before the entry point, so we will adjust the load address
365 // to point to about 2GiB into the ASLR region.
366 m_code_address = 0x8000'0000;
367 } else {
368 // All other processes can be mapped at the beginning of the code region.
369 if (metadata.GetAddressSpaceType() == FileSys::ProgramAddressSpaceType::Is36Bit) {
370 m_code_address = 0x800'0000;
371 } else {
372 m_code_address = 0x20'0000;
373 }
374 }
375
361 KScopedResourceReservation memory_reservation( 376 KScopedResourceReservation memory_reservation(
362 m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size); 377 m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
363 if (!memory_reservation.Succeeded()) { 378 if (!memory_reservation.Succeeded()) {
@@ -368,15 +383,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
368 // Initialize process address space 383 // Initialize process address space
369 if (const Result result{m_page_table.InitializeForProcess( 384 if (const Result result{m_page_table.InitializeForProcess(
370 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, 385 metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
371 0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, 386 this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
372 m_kernel.System().ApplicationMemory())}; 387 m_resource_limit, m_kernel.System().ApplicationMemory())};
373 result.IsError()) { 388 result.IsError()) {
374 R_RETURN(result); 389 R_RETURN(result);
375 } 390 }
376 391
377 // Map process code region 392 // Map process code region
378 if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(), 393 if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
379 code_size / PageSize, KMemoryState::Code, 394 KMemoryState::Code,
380 KMemoryPermission::None)}; 395 KMemoryPermission::None)};
381 result.IsError()) { 396 result.IsError()) {
382 R_RETURN(result); 397 R_RETURN(result);
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index c9b37e138..4fdeaf11a 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -177,6 +177,10 @@ public:
177 return m_program_id; 177 return m_program_id;
178 } 178 }
179 179
180 KProcessAddress GetEntryPoint() const {
181 return m_code_address;
182 }
183
180 /// Gets the resource limit descriptor for this process 184 /// Gets the resource limit descriptor for this process
181 KResourceLimit* GetResourceLimit() const; 185 KResourceLimit* GetResourceLimit() const;
182 186
@@ -485,6 +489,9 @@ private:
485 /// Address indicating the location of the process' dedicated TLS region. 489 /// Address indicating the location of the process' dedicated TLS region.
486 KProcessAddress m_plr_address = 0; 490 KProcessAddress m_plr_address = 0;
487 491
492 /// Address indicating the location of the process's entry point.
493 KProcessAddress m_code_address = 0;
494
488 /// Random values for svcGetInfo RandomEntropy 495 /// Random values for svcGetInfo RandomEntropy
489 std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{}; 496 std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};
490 497