2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

kernel: offset code entry point for 39-bit address space type (#11326)

This commit is contained in:
liamwhite 2023-08-25 17:59:32 -04:00 committed by GitHub
parent 92e6ff30a1
commit 18ad55be0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 11 deletions

View file

@ -38,7 +38,7 @@ namespace {
*/ */
void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority,
KProcessAddress stack_top) { 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)); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1));
KThread* thread = KThread::Create(system.Kernel()); KThread* thread = KThread::Create(system.Kernel());
@ -358,6 +358,21 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
m_system_resource_size = metadata.GetSystemResourceSize(); m_system_resource_size = metadata.GetSystemResourceSize();
m_image_size = code_size; m_image_size = code_size;
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( KScopedResourceReservation memory_reservation(
m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size); m_resource_limit, LimitableResource::PhysicalMemoryMax, code_size + m_system_resource_size);
if (!memory_reservation.Succeeded()) { if (!memory_reservation.Succeeded()) {
@ -368,15 +383,15 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize process address space // Initialize process address space
if (const Result result{m_page_table.InitializeForProcess( if (const Result result{m_page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application, metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
0x8000000, code_size, std::addressof(m_kernel.GetAppSystemResource()), m_resource_limit, this->GetEntryPoint(), code_size, std::addressof(m_kernel.GetAppSystemResource()),
m_kernel.System().ApplicationMemory())}; m_resource_limit, m_kernel.System().ApplicationMemory())};
result.IsError()) { result.IsError()) {
R_RETURN(result); R_RETURN(result);
} }
// Map process code region // Map process code region
if (const Result result{m_page_table.MapProcessCode(m_page_table.GetCodeRegionStart(), if (const Result result{m_page_table.MapProcessCode(this->GetEntryPoint(), code_size / PageSize,
code_size / PageSize, KMemoryState::Code, KMemoryState::Code,
KMemoryPermission::None)}; KMemoryPermission::None)};
result.IsError()) { result.IsError()) {
R_RETURN(result); R_RETURN(result);

View file

@ -177,6 +177,10 @@ public:
return m_program_id; return m_program_id;
} }
KProcessAddress GetEntryPoint() const {
return m_code_address;
}
/// Gets the resource limit descriptor for this process /// Gets the resource limit descriptor for this process
KResourceLimit* GetResourceLimit() const; KResourceLimit* GetResourceLimit() const;
@ -485,6 +489,9 @@ private:
/// Address indicating the location of the process' dedicated TLS region. /// Address indicating the location of the process' dedicated TLS region.
KProcessAddress m_plr_address = 0; KProcessAddress m_plr_address = 0;
/// Address indicating the location of the process's entry point.
KProcessAddress m_code_address = 0;
/// Random values for svcGetInfo RandomEntropy /// Random values for svcGetInfo RandomEntropy
std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{}; std::array<u64, RANDOM_ENTROPY_SIZE> m_random_entropy{};

View file

@ -153,7 +153,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
// Load NSO modules // Load NSO modules
modules.clear(); modules.clear();
const VAddr base_address{GetInteger(process.GetPageTable().GetCodeRegionStart())}; const VAddr base_address{GetInteger(process.GetEntryPoint())};
VAddr next_load_addr{base_address}; VAddr next_load_addr{base_address};
const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(), const FileSys::PatchManager pm{metadata.GetTitleID(), system.GetFileSystemController(),
system.GetContentProvider()}; system.GetContentProvider()};

View file

@ -96,7 +96,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process,
} }
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.GetEntryPoint());
process.LoadModule(std::move(codeset), base_address); process.LoadModule(std::move(codeset), base_address);
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address); LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", kip->GetName(), base_address);

View file

@ -203,7 +203,7 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector<u8>& data)
// Load codeset for current process // Load codeset for current process
codeset.memory = std::move(program_image); codeset.memory = std::move(program_image);
process.LoadModule(std::move(codeset), process.GetPageTable().GetCodeRegionStart()); process.LoadModule(std::move(codeset), process.GetEntryPoint());
return true; return true;
} }

View file

@ -167,7 +167,7 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::S
modules.clear(); modules.clear();
// Load module // Load module
const VAddr base_address = GetInteger(process.GetPageTable().GetCodeRegionStart()); const VAddr base_address = GetInteger(process.GetEntryPoint());
if (!LoadModule(process, system, *file, base_address, true, true)) { if (!LoadModule(process, system, *file, base_address, true, true)) {
return {ResultStatus::ErrorLoadingNSO, {}}; return {ResultStatus::ErrorLoadingNSO, {}};
} }

View file

@ -117,8 +117,8 @@ json GetProcessorStateDataAuto(Core::System& system) {
arm.SaveContext(context); arm.SaveContext(context);
return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32", return GetProcessorStateData(process->Is64BitProcess() ? "AArch64" : "AArch32",
GetInteger(process->GetPageTable().GetCodeRegionStart()), GetInteger(process->GetEntryPoint()), context.sp, context.pc,
context.sp, context.pc, context.pstate, context.cpu_registers); context.pstate, context.cpu_registers);
} }
json GetBacktraceData(Core::System& system) { json GetBacktraceData(Core::System& system) {