early-access version 3827
This commit is contained in:
parent
1d8654a60d
commit
af2061a2c2
@ -1,7 +1,7 @@
|
|||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3826.
|
This is the source code for early-access 3827.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
@ -297,11 +297,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||||||
emulationActivity?.let {
|
emulationActivity?.let {
|
||||||
it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.int) {
|
it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.int) {
|
||||||
Settings.LayoutOption_MobileLandscape ->
|
Settings.LayoutOption_MobileLandscape ->
|
||||||
ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||||
Settings.LayoutOption_MobilePortrait ->
|
Settings.LayoutOption_MobilePortrait ->
|
||||||
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
||||||
Settings.LayoutOption_Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
Settings.LayoutOption_Unspecified -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||||
else -> ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
else -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,8 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
|
|||||||
const Service::FileSystem::FileSystemController& fs_controller) {
|
const Service::FileSystem::FileSystemController& fs_controller) {
|
||||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
||||||
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
if ((type != ContentRecordType::Program && type != ContentRecordType::Data &&
|
||||||
|
type != ContentRecordType::HtmlDocument) ||
|
||||||
(load_dir == nullptr && sdmc_load_dir == nullptr)) {
|
(load_dir == nullptr && sdmc_load_dir == nullptr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -381,6 +382,12 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
|
|||||||
auto ext_dir = FindSubdirectoryCaseless(subdir, "romfs_ext");
|
auto ext_dir = FindSubdirectoryCaseless(subdir, "romfs_ext");
|
||||||
if (ext_dir != nullptr)
|
if (ext_dir != nullptr)
|
||||||
layers_ext.push_back(std::make_shared<CachedVfsDirectory>(ext_dir));
|
layers_ext.push_back(std::make_shared<CachedVfsDirectory>(ext_dir));
|
||||||
|
|
||||||
|
if (type == ContentRecordType::HtmlDocument) {
|
||||||
|
auto manual_dir = FindSubdirectoryCaseless(subdir, "manual_html");
|
||||||
|
if (manual_dir != nullptr)
|
||||||
|
layers.push_back(std::make_shared<CachedVfsDirectory>(manual_dir));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When there are no layers to apply, return early as there is no need to rebuild the RomFS
|
// When there are no layers to apply, return early as there is no need to rebuild the RomFS
|
||||||
|
@ -606,9 +606,9 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
|
|||||||
const auto result = RemoveExistingEntry(title_id);
|
const auto result = RemoveExistingEntry(title_id);
|
||||||
|
|
||||||
// Install Metadata File
|
// Install Metadata File
|
||||||
const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
|
const auto meta_result = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id_data);
|
||||||
if (res != InstallResult::Success) {
|
if (meta_result != InstallResult::Success) {
|
||||||
return res;
|
return meta_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install all the other NCAs
|
// Install all the other NCAs
|
||||||
@ -621,9 +621,19 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
|
|||||||
if (nca == nullptr) {
|
if (nca == nullptr) {
|
||||||
return InstallResult::ErrorCopyFailed;
|
return InstallResult::ErrorCopyFailed;
|
||||||
}
|
}
|
||||||
const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
|
if (nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
|
||||||
if (res2 != InstallResult::Success) {
|
nca->GetTitleId() != title_id) {
|
||||||
return res2;
|
// Create fake cnmt for patch to multiprogram application
|
||||||
|
const auto sub_nca_result =
|
||||||
|
InstallEntry(*nca, TitleType::Update, overwrite_if_exists, copy);
|
||||||
|
if (sub_nca_result != InstallResult::Success) {
|
||||||
|
return sub_nca_result;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto nca_result = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
|
||||||
|
if (nca_result != InstallResult::Success) {
|
||||||
|
return nca_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,6 +673,8 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
|
bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
|
||||||
|
bool removed_data = false;
|
||||||
|
|
||||||
const auto delete_nca = [this](const NcaID& id) {
|
const auto delete_nca = [this](const NcaID& id) {
|
||||||
const auto path = GetRelativePathFromNcaID(id, false, true, false);
|
const auto path = GetRelativePathFromNcaID(id, false, true, false);
|
||||||
|
|
||||||
@ -706,11 +718,18 @@ bool RegisteredCache::RemoveExistingEntry(u64 title_id) const {
|
|||||||
const auto deleted_html = delete_nca(html_id);
|
const auto deleted_html = delete_nca(html_id);
|
||||||
const auto deleted_legal = delete_nca(legal_id);
|
const auto deleted_legal = delete_nca(legal_id);
|
||||||
|
|
||||||
return deleted_meta && (deleted_meta || deleted_program || deleted_data ||
|
removed_data |= (deleted_meta || deleted_program || deleted_data || deleted_control ||
|
||||||
deleted_control || deleted_html || deleted_legal);
|
deleted_html || deleted_legal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// If patch entries for any program exist in yuzu meta, remove them
|
||||||
|
for (u8 i = 0; i < 0x10; i++) {
|
||||||
|
const auto meta_dir = dir->CreateDirectoryRelative("yuzu_meta");
|
||||||
|
const auto filename = GetCNMTName(TitleType::Update, title_id + i);
|
||||||
|
removed_data |= meta_dir->DeleteFile(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
|
InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFunction& copy,
|
||||||
|
@ -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);
|
||||||
|
@ -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{};
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ protected:
|
|||||||
using HandlerFnP = void (Self::*)(HLERequestContext&);
|
using HandlerFnP = void (Self::*)(HLERequestContext&);
|
||||||
|
|
||||||
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
/// Used to gain exclusive access to the service members, e.g. from CoreTiming thread.
|
||||||
[[nodiscard]] std::scoped_lock<std::mutex> LockService() {
|
[[nodiscard]] virtual std::unique_lock<std::mutex> LockService() {
|
||||||
return std::scoped_lock{lock_service};
|
return std::unique_lock{lock_service};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// System context that the service operates under.
|
/// System context that the service operates under.
|
||||||
|
@ -1029,6 +1029,11 @@ BSD::~BSD() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> BSD::LockService() {
|
||||||
|
// Do not lock socket IClient instances.
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
|
BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
|
@ -186,6 +186,9 @@ private:
|
|||||||
|
|
||||||
// Callback identifier for the OnProxyPacketReceived event.
|
// Callback identifier for the OnProxyPacketReceived event.
|
||||||
Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
|
Network::RoomMember::CallbackHandle<Network::ProxyPacket> proxy_packet_received;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual std::unique_lock<std::mutex> LockService() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BSDCFG final : public ServiceFramework<BSDCFG> {
|
class BSDCFG final : public ServiceFramework<BSDCFG> {
|
||||||
|
@ -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()};
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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, {}};
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user