strat: use m_ for member variables

This commit is contained in:
Michael Scire
2021-10-10 00:14:06 -07:00
parent ce28591ab2
commit a595c232b9
425 changed files with 8531 additions and 8484 deletions

View File

@@ -91,14 +91,14 @@ namespace ams::mitm::socket::resolver {
const char *hostname = reinterpret_cast<const char *>(name.GetPointer());
LogDebug("[%016lx]: GetHostByNameRequest(%s)\n", this->client_info.program_id.value, hostname);
LogDebug("[%016lx]: GetHostByNameRequest(%s)\n", m_client_info.program_id.value, hostname);
R_UNLESS(hostname != nullptr, sm::mitm::ResultShouldForwardToSession());
ams::socket::InAddrT redirect_addr = {};
R_UNLESS(GetRedirectedHostByName(std::addressof(redirect_addr), hostname), sm::mitm::ResultShouldForwardToSession());
LogDebug("[%016lx]: Redirecting %s to %u.%u.%u.%u\n", this->client_info.program_id.value, hostname, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
LogDebug("[%016lx]: Redirecting %s to %u.%u.%u.%u\n", m_client_info.program_id.value, hostname, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
const auto size = SerializeRedirectedHostEnt(out_hostent.GetPointer(), out_hostent.GetSize(), hostname, redirect_addr);
*out_host_error = 0;
@@ -113,7 +113,7 @@ namespace ams::mitm::socket::resolver {
const char *hostname = reinterpret_cast<const char *>(node.GetPointer());
LogDebug("[%016lx]: GetAddrInfoRequest(%s, %s)\n", this->client_info.program_id.value, reinterpret_cast<const char *>(node.GetPointer()), reinterpret_cast<const char *>(srv.GetPointer()));
LogDebug("[%016lx]: GetAddrInfoRequest(%s, %s)\n", m_client_info.program_id.value, reinterpret_cast<const char *>(node.GetPointer()), reinterpret_cast<const char *>(srv.GetPointer()));
R_UNLESS(hostname != nullptr, sm::mitm::ResultShouldForwardToSession());
@@ -129,7 +129,7 @@ namespace ams::mitm::socket::resolver {
}
}
LogDebug("[%016lx]: Redirecting %s:%u to %u.%u.%u.%u\n", this->client_info.program_id.value, hostname, port, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
LogDebug("[%016lx]: Redirecting %s:%u to %u.%u.%u.%u\n", m_client_info.program_id.value, hostname, port, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
const bool use_hint = serialized_hint.GetPointer() != nullptr;
struct addrinfo hint = {};
@@ -152,14 +152,14 @@ namespace ams::mitm::socket::resolver {
const char *hostname = reinterpret_cast<const char *>(name.GetPointer());
LogDebug("[%016lx]: GetHostByNameRequestWithOptions(%s)\n", this->client_info.program_id.value, hostname);
LogDebug("[%016lx]: GetHostByNameRequestWithOptions(%s)\n", m_client_info.program_id.value, hostname);
R_UNLESS(hostname != nullptr, sm::mitm::ResultShouldForwardToSession());
ams::socket::InAddrT redirect_addr = {};
R_UNLESS(GetRedirectedHostByName(std::addressof(redirect_addr), hostname), sm::mitm::ResultShouldForwardToSession());
LogDebug("[%016lx]: Redirecting %s to %u.%u.%u.%u\n", this->client_info.program_id.value, hostname, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
LogDebug("[%016lx]: Redirecting %s to %u.%u.%u.%u\n", m_client_info.program_id.value, hostname, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
const auto size = SerializeRedirectedHostEnt(out_hostent.GetPointer(), out_hostent.GetSize(), hostname, redirect_addr);
*out_host_error = 0;
@@ -174,7 +174,7 @@ namespace ams::mitm::socket::resolver {
const char *hostname = reinterpret_cast<const char *>(node.GetPointer());
LogDebug("[%016lx]: GetAddrInfoRequestWithOptions(%s, %s)\n", this->client_info.program_id.value, hostname, reinterpret_cast<const char *>(srv.GetPointer()));
LogDebug("[%016lx]: GetAddrInfoRequestWithOptions(%s, %s)\n", m_client_info.program_id.value, hostname, reinterpret_cast<const char *>(srv.GetPointer()));
R_UNLESS(hostname != nullptr, sm::mitm::ResultShouldForwardToSession());
@@ -190,7 +190,7 @@ namespace ams::mitm::socket::resolver {
}
}
LogDebug("[%016lx]: Redirecting %s:%u to %u.%u.%u.%u\n", this->client_info.program_id.value, hostname, port, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
LogDebug("[%016lx]: Redirecting %s:%u to %u.%u.%u.%u\n", m_client_info.program_id.value, hostname, port, (redirect_addr >> 0) & 0xFF, (redirect_addr >> 8) & 0xFF, (redirect_addr >> 16) & 0xFF, (redirect_addr >> 24) & 0xFF);
const bool use_hint = serialized_hint.GetPointer() != nullptr;
struct addrinfo hint = {};

View File

@@ -217,21 +217,21 @@ namespace ams::mitm::fs {
}
Result FsMitmService::OpenFileSystemWithPatch(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type) {
return OpenWebContentFileSystem(out, this->client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), this->forward_service.get(), nullptr, false, this->client_info.override_status.IsProgramSpecific());
return OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), m_forward_service.get(), nullptr, false, m_client_info.override_status.IsProgramSpecific());
}
Result FsMitmService::OpenFileSystemWithId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type) {
return OpenWebContentFileSystem(out, this->client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), this->forward_service.get(), std::addressof(path), true, this->client_info.override_status.IsProgramSpecific());
return OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), m_forward_service.get(), std::addressof(path), true, m_client_info.override_status.IsProgramSpecific());
}
Result FsMitmService::OpenSdCardFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out) {
/* We only care about redirecting this for NS/emummc. */
R_UNLESS(this->client_info.program_id == ncm::SystemProgramId::Ns, sm::mitm::ResultShouldForwardToSession());
R_UNLESS(m_client_info.program_id == ncm::SystemProgramId::Ns, sm::mitm::ResultShouldForwardToSession());
R_UNLESS(emummc::IsActive(), sm::mitm::ResultShouldForwardToSession());
/* Create a new SD card filesystem. */
FsFileSystem sd_fs;
R_TRY(fsOpenSdCardFileSystemFwd(this->forward_service.get(), std::addressof(sd_fs)));
R_TRY(fsOpenSdCardFileSystemFwd(m_forward_service.get(), std::addressof(sd_fs)));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(sd_fs.s))};
/* Return output filesystem. */
@@ -242,14 +242,14 @@ namespace ams::mitm::fs {
Result FsMitmService::OpenSaveDataFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 _space_id, const fs::SaveDataAttribute &attribute) {
/* We only want to intercept saves for games, right now. */
const bool is_game_or_hbl = this->client_info.override_status.IsHbl() || ncm::IsApplicationId(this->client_info.program_id);
const bool is_game_or_hbl = m_client_info.override_status.IsHbl() || ncm::IsApplicationId(m_client_info.program_id);
R_UNLESS(is_game_or_hbl, sm::mitm::ResultShouldForwardToSession());
/* Only redirect if the appropriate system setting is set. */
R_UNLESS(GetSettingsItemBooleanValue("atmosphere", "fsmitm_redirect_saves_to_sd"), sm::mitm::ResultShouldForwardToSession());
/* Only redirect if the specific title being accessed has a redirect save flag. */
R_UNLESS(cfg::HasContentSpecificFlag(this->client_info.program_id, "redirect_save"), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(cfg::HasContentSpecificFlag(m_client_info.program_id, "redirect_save"), sm::mitm::ResultShouldForwardToSession());
/* Only redirect account savedata. */
R_UNLESS(attribute.type == fs::SaveDataType::Account, sm::mitm::ResultShouldForwardToSession());
@@ -260,7 +260,7 @@ namespace ams::mitm::fs {
/* Verify we can open the save. */
static_assert(sizeof(fs::SaveDataAttribute) == sizeof(::FsSaveDataAttribute));
FsFileSystem save_fs;
R_UNLESS(R_SUCCEEDED(fsOpenSaveDataFileSystemFwd(this->forward_service.get(), std::addressof(save_fs), space_id, reinterpret_cast<const FsSaveDataAttribute *>(std::addressof(attribute)))), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(R_SUCCEEDED(fsOpenSaveDataFileSystemFwd(m_forward_service.get(), std::addressof(save_fs), space_id, reinterpret_cast<const FsSaveDataAttribute *>(std::addressof(attribute)))), sm::mitm::ResultShouldForwardToSession());
std::unique_ptr<fs::fsa::IFileSystem> save_ifs = std::make_unique<fs::RemoteFileSystem>(save_fs);
/* Mount the SD card using fs.mitm's session. */
@@ -270,7 +270,7 @@ namespace ams::mitm::fs {
std::shared_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_shared<fs::RemoteFileSystem>(sd_fs);
/* Verify that we can open the save directory, and that it exists. */
const ncm::ProgramId application_id = attribute.program_id == ncm::InvalidProgramId ? this->client_info.program_id : attribute.program_id;
const ncm::ProgramId application_id = attribute.program_id == ncm::InvalidProgramId ? m_client_info.program_id : attribute.program_id;
char save_dir_path[fs::EntryNameLengthMax + 1];
R_TRY(mitm::fs::SaveUtil::GetDirectorySaveDataPath(save_dir_path, sizeof(save_dir_path), application_id, space_id, attribute));
@@ -310,11 +310,11 @@ namespace ams::mitm::fs {
/* Try to open a storage for the partition. */
FsStorage bis_storage;
R_TRY(fsOpenBisStorageFwd(this->forward_service.get(), std::addressof(bis_storage), bis_partition_id));
R_TRY(fsOpenBisStorageFwd(m_forward_service.get(), std::addressof(bis_storage), bis_partition_id));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(bis_storage.s))};
const bool is_sysmodule = ncm::IsSystemProgramId(this->client_info.program_id);
const bool is_hbl = this->client_info.override_status.IsHbl();
const bool is_sysmodule = ncm::IsSystemProgramId(m_client_info.program_id);
const bool is_hbl = m_client_info.override_status.IsHbl();
const bool can_write_bis = is_sysmodule || (is_hbl && GetSettingsItemBooleanValue("atmosphere", "enable_hbl_bis_write"));
/* Allow HBL to write to boot1 (safe firm) + package2. */
@@ -327,12 +327,12 @@ namespace ams::mitm::fs {
/* Set output storage. */
if (bis_partition_id == FsBisPartitionId_BootPartition1Root) {
if (IsBoot0CustomPublicKey(bis_storage)) {
out.SetValue(MakeSharedStorage(new CustomPublicKeyBoot0Storage(bis_storage, this->client_info, spl::GetSocType())), target_object_id);
out.SetValue(MakeSharedStorage(new CustomPublicKeyBoot0Storage(bis_storage, m_client_info, spl::GetSocType())), target_object_id);
} else {
out.SetValue(MakeSharedStorage(new Boot0Storage(bis_storage, this->client_info)), target_object_id);
out.SetValue(MakeSharedStorage(new Boot0Storage(bis_storage, m_client_info)), target_object_id);
}
} else if (bis_partition_id == FsBisPartitionId_CalibrationBinary) {
out.SetValue(MakeSharedStorage(new CalibrationBinaryStorage(bis_storage, this->client_info)), target_object_id);
out.SetValue(MakeSharedStorage(new CalibrationBinaryStorage(bis_storage, m_client_info)), target_object_id);
} else {
if (can_write_bis || can_write_bis_for_choi_support) {
/* We can write, so create a writable storage. */
@@ -348,14 +348,14 @@ namespace ams::mitm::fs {
Result FsMitmService::OpenDataStorageByCurrentProcess(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out) {
/* Only mitm if we should override contents for the current process. */
R_UNLESS(this->client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
/* Only mitm if there is actually an override romfs. */
R_UNLESS(mitm::fs::HasSdRomfsContent(this->client_info.program_id), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(mitm::fs::HasSdRomfsContent(m_client_info.program_id), sm::mitm::ResultShouldForwardToSession());
/* Try to open the process romfs. */
FsStorage data_storage;
R_TRY(fsOpenDataStorageByCurrentProcessFwd(this->forward_service.get(), std::addressof(data_storage)));
R_TRY(fsOpenDataStorageByCurrentProcessFwd(m_forward_service.get(), std::addressof(data_storage)));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
/* Get a scoped lock. */
@@ -363,7 +363,7 @@ namespace ams::mitm::fs {
/* Try to get a storage from the cache. */
{
std::shared_ptr<fs::IStorage> cached_storage = GetStorageCacheEntry(this->client_info.program_id);
std::shared_ptr<fs::IStorage> cached_storage = GetStorageCacheEntry(m_client_info.program_id);
if (cached_storage != nullptr) {
out.SetValue(MakeSharedStorage(cached_storage), target_object_id);
return ResultSuccess();
@@ -376,17 +376,17 @@ namespace ams::mitm::fs {
/* Create the layered storage. */
FsFile data_file;
if (R_SUCCEEDED(OpenAtmosphereSdFile(std::addressof(data_file), this->client_info.program_id, "romfs.bin", OpenMode_Read))) {
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), std::make_unique<ReadOnlyStorageAdapter>(new FileStorage(new RemoteFile(data_file))), this->client_info.program_id);
if (R_SUCCEEDED(OpenAtmosphereSdFile(std::addressof(data_file), m_client_info.program_id, "romfs.bin", OpenMode_Read))) {
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), std::make_unique<ReadOnlyStorageAdapter>(new FileStorage(new RemoteFile(data_file))), m_client_info.program_id);
layered_storage->BeginInitialize();
new_storage = std::move(layered_storage);
} else {
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), nullptr, this->client_info.program_id);
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), nullptr, m_client_info.program_id);
layered_storage->BeginInitialize();
new_storage = std::move(layered_storage);
}
SetStorageCacheEntry(this->client_info.program_id, std::addressof(new_storage));
SetStorageCacheEntry(m_client_info.program_id, std::addressof(new_storage));
out.SetValue(MakeSharedStorage(new_storage), target_object_id);
}
@@ -395,7 +395,7 @@ namespace ams::mitm::fs {
Result FsMitmService::OpenDataStorageByDataId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId _data_id, u8 storage_id) {
/* Only mitm if we should override contents for the current process. */
R_UNLESS(this->client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
/* TODO: Decide how to handle DataId vs ProgramId for this API. */
const ncm::ProgramId data_id = {_data_id.value};
@@ -405,7 +405,7 @@ namespace ams::mitm::fs {
/* Try to open the process romfs. */
FsStorage data_storage;
R_TRY(fsOpenDataStorageByDataIdFwd(this->forward_service.get(), std::addressof(data_storage), static_cast<u64>(data_id), static_cast<NcmStorageId>(storage_id)));
R_TRY(fsOpenDataStorageByDataIdFwd(m_forward_service.get(), std::addressof(data_storage), static_cast<u64>(data_id), static_cast<NcmStorageId>(storage_id)));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
/* Get a scoped lock. */
@@ -445,10 +445,10 @@ namespace ams::mitm::fs {
Result FsMitmService::OpenDataStorageWithProgramIndex(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u8 program_index) {
/* Only mitm if we should override contents for the current process. */
R_UNLESS(this->client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
/* Get the relevant program id. */
const ncm::ProgramId program_id = g_program_index_map_info_manager.GetProgramId(this->client_info.program_id, program_index);
const ncm::ProgramId program_id = g_program_index_map_info_manager.GetProgramId(m_client_info.program_id, program_index);
/* If we don't know about the program or don't have content, forward. */
R_UNLESS(program_id != ncm::InvalidProgramId, sm::mitm::ResultShouldForwardToSession());
@@ -456,7 +456,7 @@ namespace ams::mitm::fs {
/* Try to open the process romfs. */
FsStorage data_storage;
R_TRY(fsOpenDataStorageWithProgramIndexFwd(this->forward_service.get(), std::addressof(data_storage), program_index));
R_TRY(fsOpenDataStorageWithProgramIndexFwd(m_forward_service.get(), std::addressof(data_storage), program_index));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
/* Get a scoped lock. */
@@ -496,7 +496,7 @@ namespace ams::mitm::fs {
Result FsMitmService::RegisterProgramIndexMapInfo(const sf::InBuffer &info_buffer, s32 info_count) {
/* Try to register with FS. */
R_TRY(fsRegisterProgramIndexMapInfoFwd(this->forward_service.get(), info_buffer.GetPointer(), info_buffer.GetSize(), info_count));
R_TRY(fsRegisterProgramIndexMapInfoFwd(m_forward_service.get(), info_buffer.GetPointer(), info_buffer.GetSize(), info_count));
/* Register with ourselves. */
R_ABORT_UNLESS(g_program_index_map_info_manager.Reset(reinterpret_cast<const fs::ProgramIndexMapInfo *>(info_buffer.GetPointer()), info_count));

View File

@@ -22,9 +22,9 @@ namespace ams::mitm::fs {
namespace {
os::SdkMutex g_boot0_access_mutex;
constinit os::SdkMutex g_boot0_access_mutex;
constinit bool g_custom_public_key = false;
u8 g_boot0_bct_buffer[Boot0Storage::BctEndOffset];
constinit u8 g_boot0_bct_buffer[Boot0Storage::BctEndOffset];
/* Recognize special public key (https://gist.github.com/SciresM/16b63ac1d80494522bdba2c57995257c). */
/* P = 19 */
@@ -59,11 +59,11 @@ namespace ams::mitm::fs {
/* RCM bug patched. */
/* Only allow NS to update the BCT pubks. */
/* AutoRCM on a patched unit will cause a brick, so homebrew should NOT be allowed to write. */
return this->client_info.program_id == ncm::SystemProgramId::Ns;
return m_client_info.program_id == ncm::SystemProgramId::Ns;
} else {
/* RCM bug unpatched. */
/* Allow homebrew but not NS to update the BCT pubks. */
return this->client_info.override_status.IsHbl();
return m_client_info.override_status.IsHbl();
}
}
@@ -139,7 +139,7 @@ namespace ams::mitm::fs {
return Base::Write(0, g_boot0_bct_buffer, BctEndOffset);
}
CustomPublicKeyBoot0Storage::CustomPublicKeyBoot0Storage(FsStorage &s, const sm::MitmProcessInfo &c, spl::SocType soc) : Base(s), client_info(c), soc_type(soc) {
CustomPublicKeyBoot0Storage::CustomPublicKeyBoot0Storage(FsStorage &s, const sm::MitmProcessInfo &c, spl::SocType soc) : Base(s), m_client_info(c), m_soc_type(soc) {
std::scoped_lock lk{g_boot0_access_mutex};
/* We're custom public key. */
@@ -157,7 +157,7 @@ namespace ams::mitm::fs {
/* Check if we're reading the first BCTs for NS. */
/* If we are, we want to lie about the contents of BCT0/1 so that they validate. */
if (offset < 0x8000 && this->client_info.program_id == ncm::SystemProgramId::Ns) {
if (offset < 0x8000 && m_client_info.program_id == ncm::SystemProgramId::Ns) {
R_TRY(Base::Read(0, g_boot0_bct_buffer, Boot0Storage::BctEndOffset));
/* Determine the readable size. */
@@ -207,7 +207,7 @@ namespace ams::mitm::fs {
}
/* On erista, we want to protect the EKS region. */
if (this->soc_type == spl::SocType_Erista) {
if (m_soc_type == spl::SocType_Erista) {
if (offset <= Boot0Storage::EksStart) {
if (offset + size < Boot0Storage::EksStart) {
/* Fall through, no need to do anything here. */

View File

@@ -23,7 +23,7 @@ namespace ams::mitm::fs {
class SectoredStorageAdapter : public Base {
static_assert(std::is_base_of<ams::fs::IStorage, Base>::value);
private:
u8 sector_buf[SectorSize];
u8 m_sector_buf[SectorSize];
public:
/* Inherit constructors. */
using Base::Base;
@@ -44,15 +44,15 @@ namespace ams::mitm::fs {
return Base::Read(offset, buffer, size);
}
R_TRY(Base::Read(seek, this->sector_buf, SectorSize));
R_TRY(Base::Read(seek, m_sector_buf, SectorSize));
if (size + sector_ofs <= SectorSize) {
/* Staying within the sector. */
std::memcpy(buffer, this->sector_buf + sector_ofs, size);
std::memcpy(buffer, m_sector_buf + sector_ofs, size);
} else {
/* Leaving the sector. */
const size_t size_in_sector = SectorSize - sector_ofs;
std::memcpy(buffer, this->sector_buf + sector_ofs, size_in_sector);
std::memcpy(buffer, m_sector_buf + sector_ofs, size_in_sector);
size -= size_in_sector;
/* Read as many guaranteed aligned sectors as we can. */
@@ -64,8 +64,8 @@ namespace ams::mitm::fs {
/* Read any leftover data. */
if (size) {
R_TRY(Base::Read(offset + size_in_sector + aligned_remaining_size, this->sector_buf, SectorSize));
std::memcpy(buffer + size_in_sector + aligned_remaining_size, this->sector_buf, size);
R_TRY(Base::Read(offset + size_in_sector + aligned_remaining_size, m_sector_buf, SectorSize));
std::memcpy(buffer + size_in_sector + aligned_remaining_size, m_sector_buf, size);
}
}
@@ -89,17 +89,17 @@ namespace ams::mitm::fs {
}
/* Load existing sector data. */
R_TRY(Base::Read(seek, this->sector_buf, SectorSize));
R_TRY(Base::Read(seek, m_sector_buf, SectorSize));
if (size + sector_ofs <= SectorSize) {
/* Staying within the sector. */
std::memcpy(this->sector_buf + sector_ofs, buffer, size);
R_TRY(Base::Write(seek, this->sector_buf, SectorSize));
std::memcpy(m_sector_buf + sector_ofs, buffer, size);
R_TRY(Base::Write(seek, m_sector_buf, SectorSize));
} else {
/* Leaving the sector. */
const size_t size_in_sector = SectorSize - sector_ofs;
std::memcpy(this->sector_buf + sector_ofs, buffer, size_in_sector);
R_TRY(Base::Write(seek, this->sector_buf, SectorSize));
std::memcpy(m_sector_buf + sector_ofs, buffer, size_in_sector);
R_TRY(Base::Write(seek, m_sector_buf, SectorSize));
size -= size_in_sector;
/* Write as many guaranteed aligned sectors as we can. */
@@ -111,9 +111,9 @@ namespace ams::mitm::fs {
/* Write any leftover data. */
if (size) {
R_TRY(Base::Read(offset + size_in_sector + aligned_remaining_size, this->sector_buf, SectorSize));
std::memcpy(this->sector_buf, buffer + size_in_sector + aligned_remaining_size, size);
R_TRY(Base::Write(offset + size_in_sector + aligned_remaining_size, this->sector_buf, SectorSize));
R_TRY(Base::Read(offset + size_in_sector + aligned_remaining_size, m_sector_buf, SectorSize));
std::memcpy(m_sector_buf, buffer + size_in_sector + aligned_remaining_size, size);
R_TRY(Base::Write(offset + size_in_sector + aligned_remaining_size, m_sector_buf, SectorSize));
}
}
@@ -136,11 +136,11 @@ namespace ams::mitm::fs {
static constexpr s64 EksSize = static_cast<s64>(ams::updater::EksSize);
static constexpr s64 EksEnd = EksStart + EksSize;
private:
sm::MitmProcessInfo client_info;
sm::MitmProcessInfo m_client_info;
private:
bool CanModifyBctPublicKey();
public:
Boot0Storage(FsStorage &s, const sm::MitmProcessInfo &c) : Base(s), client_info(c) { /* ... */ }
Boot0Storage(FsStorage &s, const sm::MitmProcessInfo &c) : Base(s), m_client_info(c) { /* ... */ }
public:
virtual Result Read(s64 offset, void *_buffer, size_t size) override;
virtual Result Write(s64 offset, const void *_buffer, size_t size) override;
@@ -150,8 +150,8 @@ namespace ams::mitm::fs {
public:
using Base = SectoredStorageAdapter<ams::fs::RemoteStorage, 0x200>;
private:
sm::MitmProcessInfo client_info;
spl::SocType soc_type;
sm::MitmProcessInfo m_client_info;
spl::SocType m_soc_type;
public:
CustomPublicKeyBoot0Storage(FsStorage &s, const sm::MitmProcessInfo &c, spl::SocType soc);
public:

View File

@@ -36,7 +36,7 @@ namespace ams::mitm::fs {
R_SUCCEED_IF(size == 0);
/* Handle the blank region. */
if (this->read_blank) {
if (m_read_blank) {
if (BlankStartOffset <= offset && offset < BlankEndOffset) {
const size_t blank_size = std::min(size, static_cast<size_t>(BlankEndOffset - offset));
mitm::ReadFromBlankCalibrationBinary(offset, buffer, blank_size);
@@ -88,10 +88,10 @@ namespace ams::mitm::fs {
R_SUCCEED_IF(size == 0);
/* Only allow writes if we should. */
R_UNLESS(this->allow_writes, fs::ResultUnsupportedOperation());
R_UNLESS(m_allow_writes, fs::ResultUnsupportedOperation());
/* Handle the blank region. */
if (this->read_blank) {
if (m_read_blank) {
if (BlankStartOffset <= offset && offset < BlankEndOffset) {
const size_t blank_size = std::min(size, static_cast<size_t>(BlankEndOffset - offset));
mitm::WriteToBlankCalibrationBinary(offset, buffer, blank_size);

View File

@@ -34,14 +34,14 @@ namespace ams::mitm::fs {
static constexpr s64 FakeSecureSize = static_cast<s64>(SecureCalibrationBinaryBackupSize);
static constexpr s64 FakeSecureEndOffset = FakeSecureStartOffset + FakeSecureSize;
private:
sm::MitmProcessInfo client_info;
bool read_blank;
bool allow_writes;
sm::MitmProcessInfo m_client_info;
bool m_read_blank;
bool m_allow_writes;
public:
CalibrationBinaryStorage(FsStorage &s, const sm::MitmProcessInfo &c)
: Base(s), client_info(c),
read_blank(mitm::ShouldReadBlankCalibrationBinary()),
allow_writes(mitm::IsWriteToCalibrationBinaryAllowed())
: Base(s), m_client_info(c),
m_read_blank(mitm::ShouldReadBlankCalibrationBinary()),
m_allow_writes(mitm::IsWriteToCalibrationBinaryAllowed())
{
/* ... */
}

View File

@@ -62,40 +62,40 @@ namespace ams::mitm::fs {
using namespace ams::fs;
LayeredRomfsStorage::LayeredRomfsStorage(std::unique_ptr<IStorage> s_r, std::unique_ptr<IStorage> f_r, ncm::ProgramId pr_id) : storage_romfs(std::move(s_r)), file_romfs(std::move(f_r)), initialize_event(os::EventClearMode_ManualClear), program_id(std::move(pr_id)), is_initialized(false), started_initialize(false) {
LayeredRomfsStorage::LayeredRomfsStorage(std::unique_ptr<IStorage> s_r, std::unique_ptr<IStorage> f_r, ncm::ProgramId pr_id) : m_storage_romfs(std::move(s_r)), m_file_romfs(std::move(f_r)), m_initialize_event(os::EventClearMode_ManualClear), m_program_id(std::move(pr_id)), m_is_initialized(false), m_started_initialize(false) {
/* ... */
}
LayeredRomfsStorage::~LayeredRomfsStorage() {
for (size_t i = 0; i < this->source_infos.size(); i++) {
this->source_infos[i].Cleanup();
for (size_t i = 0; i < m_source_infos.size(); i++) {
m_source_infos[i].Cleanup();
}
}
void LayeredRomfsStorage::BeginInitialize() {
AMS_ABORT_UNLESS(!this->started_initialize);
AMS_ABORT_UNLESS(!m_started_initialize);
RequestInitializeStorage(reinterpret_cast<uintptr_t>(this));
this->started_initialize = true;
m_started_initialize = true;
}
void LayeredRomfsStorage::InitializeImpl() {
/* Build new virtual romfs. */
romfs::Builder builder(this->program_id);
romfs::Builder builder(m_program_id);
if (mitm::IsInitialized()) {
builder.AddSdFiles();
}
if (this->file_romfs) {
builder.AddStorageFiles(this->file_romfs.get(), romfs::DataSourceType::File);
if (m_file_romfs) {
builder.AddStorageFiles(m_file_romfs.get(), romfs::DataSourceType::File);
}
if (this->storage_romfs) {
builder.AddStorageFiles(this->storage_romfs.get(), romfs::DataSourceType::Storage);
if (m_storage_romfs) {
builder.AddStorageFiles(m_storage_romfs.get(), romfs::DataSourceType::Storage);
}
builder.Build(std::addressof(this->source_infos));
builder.Build(std::addressof(m_source_infos));
this->is_initialized = true;
this->initialize_event.Signal();
m_is_initialized = true;
m_initialize_event.Signal();
}
Result LayeredRomfsStorage::Read(s64 offset, void *buffer, size_t size) {
@@ -103,8 +103,8 @@ namespace ams::mitm::fs {
R_SUCCEED_IF(size == 0);
/* Ensure we're initialized. */
if (!this->is_initialized) {
this->initialize_event.Wait();
if (!m_is_initialized) {
m_initialize_event.Wait();
}
/* Validate offset/size. */
@@ -116,7 +116,7 @@ namespace ams::mitm::fs {
}
/* Find first source info via binary search. */
auto it = std::lower_bound(this->source_infos.begin(), this->source_infos.end(), offset);
auto it = std::lower_bound(m_source_infos.begin(), m_source_infos.end(), offset);
u8 *cur_dst = static_cast<u8 *>(buffer);
/* Our operator < compares against start of info instead of end, so we need to subtract one from lower bound. */
@@ -132,15 +132,15 @@ namespace ams::mitm::fs {
const size_t cur_read_size = std::min(size - read_so_far, static_cast<size_t>(cur_source.size - offset_within_source));
switch (cur_source.source_type) {
case romfs::DataSourceType::Storage:
R_ABORT_UNLESS(this->storage_romfs->Read(cur_source.storage_source_info.offset + offset_within_source, cur_dst, cur_read_size));
R_ABORT_UNLESS(m_storage_romfs->Read(cur_source.storage_source_info.offset + offset_within_source, cur_dst, cur_read_size));
break;
case romfs::DataSourceType::File:
R_ABORT_UNLESS(this->file_romfs->Read(cur_source.file_source_info.offset + offset_within_source, cur_dst, cur_read_size));
R_ABORT_UNLESS(m_file_romfs->Read(cur_source.file_source_info.offset + offset_within_source, cur_dst, cur_read_size));
break;
case romfs::DataSourceType::LooseSdFile:
{
FsFile file;
R_ABORT_UNLESS(mitm::fs::OpenAtmosphereSdRomfsFile(std::addressof(file), this->program_id, cur_source.loose_source_info.path, OpenMode_Read));
R_ABORT_UNLESS(mitm::fs::OpenAtmosphereSdRomfsFile(std::addressof(file), m_program_id, cur_source.loose_source_info.path, OpenMode_Read));
ON_SCOPE_EXIT { fsFileClose(std::addressof(file)); };
u64 out_read = 0;
@@ -180,8 +180,8 @@ namespace ams::mitm::fs {
Result LayeredRomfsStorage::GetSize(s64 *out_size) {
/* Ensure we're initialized. */
if (!this->is_initialized) {
this->initialize_event.Wait();
if (!m_is_initialized) {
m_initialize_event.Wait();
}
*out_size = this->GetSize();

View File

@@ -22,16 +22,16 @@ namespace ams::mitm::fs {
class LayeredRomfsStorage : public std::enable_shared_from_this<LayeredRomfsStorage>, public ams::fs::IStorage {
private:
std::vector<romfs::SourceInfo> source_infos;
std::unique_ptr<ams::fs::IStorage> storage_romfs;
std::unique_ptr<ams::fs::IStorage> file_romfs;
os::Event initialize_event;
ncm::ProgramId program_id;
bool is_initialized;
bool started_initialize;
std::vector<romfs::SourceInfo> m_source_infos;
std::unique_ptr<ams::fs::IStorage> m_storage_romfs;
std::unique_ptr<ams::fs::IStorage> m_file_romfs;
os::Event m_initialize_event;
ncm::ProgramId m_program_id;
bool m_is_initialized;
bool m_started_initialize;
protected:
inline s64 GetSize() const {
const auto &back = this->source_infos.back();
const auto &back = m_source_infos.back();
return back.virtual_offset + back.size;
}
public:

View File

@@ -20,10 +20,10 @@ namespace ams::mitm::fs {
class ReadOnlyLayeredFileSystem : public ams::fs::fsa::IFileSystem {
private:
ams::fs::ReadOnlyFileSystem fs_1;
ams::fs::ReadOnlyFileSystem fs_2;
ams::fs::ReadOnlyFileSystem m_fs_1;
ams::fs::ReadOnlyFileSystem m_fs_2;
public:
explicit ReadOnlyLayeredFileSystem(std::unique_ptr<ams::fs::fsa::IFileSystem> a, std::unique_ptr<ams::fs::fsa::IFileSystem> b) : fs_1(std::move(a)), fs_2(std::move(b)) { /* ... */ }
explicit ReadOnlyLayeredFileSystem(std::unique_ptr<ams::fs::fsa::IFileSystem> a, std::unique_ptr<ams::fs::fsa::IFileSystem> b) : m_fs_1(std::move(a)), m_fs_2(std::move(b)) { /* ... */ }
virtual ~ReadOnlyLayeredFileSystem() { /* ... */ }
private:
@@ -63,18 +63,18 @@ namespace ams::mitm::fs {
}
virtual Result DoGetEntryType(ams::fs::DirectoryEntryType *out, const char *path) override final {
R_SUCCEED_IF(R_SUCCEEDED(this->fs_1.GetEntryType(out, path)));
return this->fs_2.GetEntryType(out, path);
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.GetEntryType(out, path)));
return m_fs_2.GetEntryType(out, path);
}
virtual Result DoOpenFile(std::unique_ptr<ams::fs::fsa::IFile> *out_file, const char *path, ams::fs::OpenMode mode) override final {
R_SUCCEED_IF(R_SUCCEEDED(this->fs_1.OpenFile(out_file, path, mode)));
return this->fs_2.OpenFile(out_file, path, mode);
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.OpenFile(out_file, path, mode)));
return m_fs_2.OpenFile(out_file, path, mode);
}
virtual Result DoOpenDirectory(std::unique_ptr<ams::fs::fsa::IDirectory> *out_dir, const char *path, ams::fs::OpenDirectoryMode mode) override final {
R_SUCCEED_IF(R_SUCCEEDED(this->fs_1.OpenDirectory(out_dir, path, mode)));
return this->fs_2.OpenDirectory(out_dir, path, mode);
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.OpenDirectory(out_dir, path, mode)));
return m_fs_2.OpenDirectory(out_dir, path, mode);
}
virtual Result DoCommit() override final {
@@ -97,8 +97,8 @@ namespace ams::mitm::fs {
}
virtual Result DoGetFileTimeStampRaw(ams::fs::FileTimeStampRaw *out, const char *path) {
R_SUCCEED_IF(R_SUCCEEDED(this->fs_1.GetFileTimeStampRaw(out, path)));
return this->fs_2.GetFileTimeStampRaw(out, path);
R_SUCCEED_IF(R_SUCCEEDED(m_fs_1.GetFileTimeStampRaw(out, path)));
return m_fs_2.GetFileTimeStampRaw(out, path);
}
};

View File

@@ -72,26 +72,26 @@ namespace ams::mitm::fs {
static constexpr size_t MaxCachedSize = (1_MB / 4);
static constexpr size_t FallbackCacheSize = 1_KB;
private:
ams::fs::IStorage *storage;
size_t offset;
size_t size;
size_t cache_idx;
void *cache;
u8 fallback_cache[FallbackCacheSize];
ams::fs::IStorage *m_storage;
size_t m_offset;
size_t m_size;
size_t m_cache_idx;
void *m_cache;
u8 m_fallback_cache[FallbackCacheSize];
private:
ALWAYS_INLINE void Read(size_t ofs, void *dst, size_t size) {
R_ABORT_UNLESS(this->storage->Read(this->offset + ofs, dst, size));
R_ABORT_UNLESS(m_storage->Read(m_offset + ofs, dst, size));
}
ALWAYS_INLINE void ReloadCacheImpl(size_t idx) {
const size_t rel_ofs = idx * MaxCachedSize;
AMS_ABORT_UNLESS(rel_ofs < this->size);
const size_t new_cache_size = std::min(this->size - rel_ofs, MaxCachedSize);
this->Read(rel_ofs, this->cache, new_cache_size);
this->cache_idx = idx;
AMS_ABORT_UNLESS(rel_ofs < m_size);
const size_t new_cache_size = std::min(m_size - rel_ofs, MaxCachedSize);
this->Read(rel_ofs, m_cache, new_cache_size);
m_cache_idx = idx;
}
ALWAYS_INLINE void ReloadCache(size_t idx) {
if (this->cache_idx != idx) {
if (m_cache_idx != idx) {
this->ReloadCacheImpl(idx);
}
}
@@ -100,14 +100,14 @@ namespace ams::mitm::fs {
return ofs / MaxCachedSize;
}
public:
TableReader(ams::fs::IStorage *s, size_t ofs, size_t sz) : storage(s), offset(ofs), size(sz), cache_idx(0) {
this->cache = std::malloc(std::min(sz, MaxCachedSize));
AMS_ABORT_UNLESS(this->cache != nullptr);
TableReader(ams::fs::IStorage *s, size_t ofs, size_t sz) : m_storage(s), m_offset(ofs), m_size(sz), m_cache_idx(0) {
m_cache = std::malloc(std::min(sz, MaxCachedSize));
AMS_ABORT_UNLESS(m_cache != nullptr);
this->ReloadCacheImpl(0);
}
~TableReader() {
std::free(this->cache);
std::free(m_cache);
}
const Entry *GetEntry(u32 entry_offset) {
@@ -115,10 +115,10 @@ namespace ams::mitm::fs {
const size_t ofs = entry_offset % MaxCachedSize;
const Entry *entry = reinterpret_cast<const Entry *>(reinterpret_cast<uintptr_t>(this->cache) + ofs);
const Entry *entry = reinterpret_cast<const Entry *>(reinterpret_cast<uintptr_t>(m_cache) + ofs);
if (AMS_UNLIKELY(this->GetCacheIndex(entry_offset) != this->GetCacheIndex(entry_offset + sizeof(Entry) + entry->name_size + sizeof(u32)))) {
this->Read(entry_offset, this->fallback_cache, std::min(this->size - entry_offset, FallbackCacheSize));
entry = reinterpret_cast<const Entry *>(this->fallback_cache);
this->Read(entry_offset, m_fallback_cache, std::min(m_size - entry_offset, FallbackCacheSize));
entry = reinterpret_cast<const Entry *>(m_fallback_cache);
}
return entry;
}
@@ -132,38 +132,38 @@ namespace ams::mitm::fs {
static constexpr size_t MaxCachedSize = (1_MB / 4);
static constexpr size_t FallbackCacheSize = 1_KB;
private:
::FsFile *file;
size_t offset;
size_t size;
size_t cache_idx;
void *cache;
u8 fallback_cache[FallbackCacheSize];
size_t fallback_cache_entry_offset;
size_t fallback_cache_entry_size;
bool cache_dirty;
bool fallback_cache_dirty;
::FsFile *m_file;
size_t m_offset;
size_t m_size;
size_t m_cache_idx;
void *m_cache;
u8 m_fallback_cache[FallbackCacheSize];
size_t m_fallback_cache_entry_offset;
size_t m_fallback_cache_entry_size;
bool m_cache_dirty;
bool m_fallback_cache_dirty;
private:
ALWAYS_INLINE void Read(size_t ofs, void *dst, size_t sz) {
u64 read_size;
R_ABORT_UNLESS(fsFileRead(this->file, this->offset + ofs, dst, sz, 0, std::addressof(read_size)));
R_ABORT_UNLESS(fsFileRead(m_file, m_offset + ofs, dst, sz, 0, std::addressof(read_size)));
AMS_ABORT_UNLESS(read_size == sz);
}
ALWAYS_INLINE void Write(size_t ofs, const void *src, size_t sz) {
R_ABORT_UNLESS(fsFileWrite(this->file, this->offset + ofs, src, sz, FsWriteOption_None));
R_ABORT_UNLESS(fsFileWrite(m_file, m_offset + ofs, src, sz, FsWriteOption_None));
}
ALWAYS_INLINE void Flush() {
AMS_ABORT_UNLESS(!(this->cache_dirty && this->fallback_cache_dirty));
AMS_ABORT_UNLESS(!(m_cache_dirty && m_fallback_cache_dirty));
if (this->cache_dirty) {
const size_t ofs = this->cache_idx * MaxCachedSize;
this->Write(ofs, this->cache, std::min(this->size - ofs, MaxCachedSize));
this->cache_dirty = false;
if (m_cache_dirty) {
const size_t ofs = m_cache_idx * MaxCachedSize;
this->Write(ofs, m_cache, std::min(m_size - ofs, MaxCachedSize));
m_cache_dirty = false;
}
if (this->fallback_cache_dirty) {
this->Write(this->fallback_cache_entry_offset, this->fallback_cache, this->fallback_cache_entry_size);
this->fallback_cache_dirty = false;
if (m_fallback_cache_dirty) {
this->Write(m_fallback_cache_entry_offset, m_fallback_cache, m_fallback_cache_entry_size);
m_fallback_cache_dirty = false;
}
}
@@ -172,32 +172,32 @@ namespace ams::mitm::fs {
}
ALWAYS_INLINE void RefreshCacheImpl() {
const size_t cur_cache = this->cache_idx * MaxCachedSize;
this->Read(cur_cache, this->cache, std::min(this->size - cur_cache, MaxCachedSize));
const size_t cur_cache = m_cache_idx * MaxCachedSize;
this->Read(cur_cache, m_cache, std::min(m_size - cur_cache, MaxCachedSize));
}
ALWAYS_INLINE void RefreshCache(u32 entry_offset) {
if (size_t idx = this->GetCacheIndex(entry_offset); idx != this->cache_idx || this->fallback_cache_dirty) {
if (size_t idx = this->GetCacheIndex(entry_offset); idx != m_cache_idx || m_fallback_cache_dirty) {
this->Flush();
this->cache_idx = idx;
m_cache_idx = idx;
this->RefreshCacheImpl();
}
}
public:
TableWriter(::FsFile *f, size_t ofs, size_t sz) : file(f), offset(ofs), size(sz), cache_idx(0), fallback_cache_entry_offset(), fallback_cache_entry_size(), cache_dirty(), fallback_cache_dirty() {
TableWriter(::FsFile *f, size_t ofs, size_t sz) : m_file(f), m_offset(ofs), m_size(sz), m_cache_idx(0), m_fallback_cache_entry_offset(), m_fallback_cache_entry_size(), m_cache_dirty(), m_fallback_cache_dirty() {
const size_t cache_size = std::min(sz, MaxCachedSize);
this->cache = std::malloc(cache_size);
AMS_ABORT_UNLESS(this->cache != nullptr);
std::memset(this->cache, 0, cache_size);
std::memset(this->fallback_cache, 0, sizeof(this->fallback_cache));
for (size_t cur = 0; cur < this->size; cur += MaxCachedSize) {
this->Write(cur, this->cache, std::min(this->size - cur, MaxCachedSize));
m_cache = std::malloc(cache_size);
AMS_ABORT_UNLESS(m_cache != nullptr);
std::memset(m_cache, 0, cache_size);
std::memset(m_fallback_cache, 0, sizeof(m_fallback_cache));
for (size_t cur = 0; cur < m_size; cur += MaxCachedSize) {
this->Write(cur, m_cache, std::min(m_size - cur, MaxCachedSize));
}
}
~TableWriter() {
this->Flush();
std::free(this->cache);
std::free(m_cache);
}
Entry *GetEntry(u32 entry_offset, u32 name_len) {
@@ -205,18 +205,18 @@ namespace ams::mitm::fs {
const size_t ofs = entry_offset % MaxCachedSize;
Entry *entry = reinterpret_cast<Entry *>(reinterpret_cast<uintptr_t>(this->cache) + ofs);
Entry *entry = reinterpret_cast<Entry *>(reinterpret_cast<uintptr_t>(m_cache) + ofs);
if (ofs + sizeof(Entry) + util::AlignUp(name_len, sizeof(u32)) > MaxCachedSize) {
this->Flush();
this->fallback_cache_entry_offset = entry_offset;
this->fallback_cache_entry_size = sizeof(Entry) + util::AlignUp(name_len, sizeof(u32));
this->Read(this->fallback_cache_entry_offset, this->fallback_cache, this->fallback_cache_entry_size);
m_fallback_cache_entry_offset = entry_offset;
m_fallback_cache_entry_size = sizeof(Entry) + util::AlignUp(name_len, sizeof(u32));
this->Read(m_fallback_cache_entry_offset, m_fallback_cache, m_fallback_cache_entry_size);
entry = reinterpret_cast<Entry *>(this->fallback_cache);
this->fallback_cache_dirty = true;
entry = reinterpret_cast<Entry *>(m_fallback_cache);
m_fallback_cache_dirty = true;
} else {
this->cache_dirty = true;
m_cache_dirty = true;
}
return entry;
@@ -269,12 +269,12 @@ namespace ams::mitm::fs {
}
Builder::Builder(ncm::ProgramId pr_id) : program_id(pr_id), num_dirs(0), num_files(0), dir_table_size(0), file_table_size(0), dir_hash_table_size(0), file_hash_table_size(0), file_partition_size(0) {
auto res = this->directories.emplace(std::make_unique<BuildDirectoryContext>(BuildDirectoryContext::RootTag{}));
Builder::Builder(ncm::ProgramId pr_id) : m_program_id(pr_id), m_num_dirs(0), m_num_files(0), m_dir_table_size(0), m_file_table_size(0), m_dir_hash_table_size(0), m_file_hash_table_size(0), m_file_partition_size(0) {
auto res = m_directories.emplace(std::make_unique<BuildDirectoryContext>(BuildDirectoryContext::RootTag{}));
AMS_ABORT_UNLESS(res.second);
this->root = res.first->get();
this->num_dirs = 1;
this->dir_table_size = 0x18;
m_root = res.first->get();
m_num_dirs = 1;
m_dir_table_size = 0x18;
}
void Builder::AddDirectory(BuildDirectoryContext **out, BuildDirectoryContext *parent_ctx, std::unique_ptr<BuildDirectoryContext> child_ctx) {
@@ -282,18 +282,18 @@ namespace ams::mitm::fs {
child_ctx->parent = parent_ctx;
/* Check if the directory already exists. */
auto existing = this->directories.find(child_ctx);
if (existing != this->directories.end()) {
auto existing = m_directories.find(child_ctx);
if (existing != m_directories.end()) {
*out = existing->get();
return;
}
/* Add a new directory. */
this->num_dirs++;
this->dir_table_size += sizeof(DirectoryEntry) + util::AlignUp(child_ctx->path_len, 4);
m_num_dirs++;
m_dir_table_size += sizeof(DirectoryEntry) + util::AlignUp(child_ctx->path_len, 4);
*out = child_ctx.get();
this->directories.emplace(std::move(child_ctx));
m_directories.emplace(std::move(child_ctx));
}
void Builder::AddFile(BuildDirectoryContext *parent_ctx, std::unique_ptr<BuildFileContext> file_ctx) {
@@ -301,14 +301,14 @@ namespace ams::mitm::fs {
file_ctx->parent = parent_ctx;
/* Check if the file already exists. */
if (this->files.find(file_ctx) != this->files.end()) {
if (m_files.find(file_ctx) != m_files.end()) {
return;
}
/* Add a new file. */
this->num_files++;
this->file_table_size += sizeof(FileEntry) + util::AlignUp(file_ctx->path_len, 4);
this->files.emplace(std::move(file_ctx));
m_num_files++;
m_file_table_size += sizeof(FileEntry) + util::AlignUp(file_ctx->path_len, 4);
m_files.emplace(std::move(file_ctx));
}
void Builder::VisitDirectory(FsFileSystem *fs, BuildDirectoryContext *parent) {
@@ -317,7 +317,7 @@ namespace ams::mitm::fs {
/* Get number of child directories. */
s64 num_child_dirs = 0;
{
OpenFileSystemRomfsDirectory(std::addressof(dir), this->program_id, parent, OpenDirectoryMode_Directory, fs);
OpenFileSystemRomfsDirectory(std::addressof(dir), m_program_id, parent, OpenDirectoryMode_Directory, fs);
ON_SCOPE_EXIT { fsDirClose(std::addressof(dir)); };
R_ABORT_UNLESS(fsDirGetEntryCount(std::addressof(dir), std::addressof(num_child_dirs)));
}
@@ -330,27 +330,27 @@ namespace ams::mitm::fs {
s64 cur_child_dir_ind = 0;
{
OpenFileSystemRomfsDirectory(std::addressof(dir), this->program_id, parent, OpenDirectoryMode_All, fs);
OpenFileSystemRomfsDirectory(std::addressof(dir), m_program_id, parent, OpenDirectoryMode_All, fs);
ON_SCOPE_EXIT { fsDirClose(std::addressof(dir)); };
s64 read_entries = 0;
while (true) {
R_ABORT_UNLESS(fsDirRead(std::addressof(dir), std::addressof(read_entries), 1, std::addressof(this->dir_entry)));
R_ABORT_UNLESS(fsDirRead(std::addressof(dir), std::addressof(read_entries), 1, std::addressof(m_dir_entry)));
if (read_entries != 1) {
break;
}
AMS_ABORT_UNLESS(this->dir_entry.type == FsDirEntryType_Dir || this->dir_entry.type == FsDirEntryType_File);
if (this->dir_entry.type == FsDirEntryType_Dir) {
AMS_ABORT_UNLESS(m_dir_entry.type == FsDirEntryType_Dir || m_dir_entry.type == FsDirEntryType_File);
if (m_dir_entry.type == FsDirEntryType_Dir) {
AMS_ABORT_UNLESS(child_dirs != nullptr);
BuildDirectoryContext *real_child = nullptr;
this->AddDirectory(std::addressof(real_child), parent, std::make_unique<BuildDirectoryContext>(this->dir_entry.name, strlen(this->dir_entry.name)));
this->AddDirectory(std::addressof(real_child), parent, std::make_unique<BuildDirectoryContext>(m_dir_entry.name, strlen(m_dir_entry.name)));
AMS_ABORT_UNLESS(real_child != nullptr);
child_dirs[cur_child_dir_ind++] = real_child;
AMS_ABORT_UNLESS(cur_child_dir_ind <= num_child_dirs);
} else /* if (this->dir_entry.type == FsDirEntryType_File) */ {
this->AddFile(parent, std::make_unique<BuildFileContext>(this->dir_entry.name, strlen(this->dir_entry.name), this->dir_entry.file_size, 0, this->cur_source_type));
} else /* if (m_dir_entry.type == FsDirEntryType_File) */ {
this->AddFile(parent, std::make_unique<BuildFileContext>(m_dir_entry.name, strlen(m_dir_entry.name), m_dir_entry.file_size, 0, m_cur_source_type));
}
}
}
@@ -380,7 +380,7 @@ namespace ams::mitm::fs {
while (cur_file_offset != EmptyEntry) {
const FileEntry *cur_file = file_table.GetEntry(cur_file_offset);
this->AddFile(parent, std::make_unique<BuildFileContext>(cur_file->name, cur_file->name_size, cur_file->size, cur_file->offset, this->cur_source_type));
this->AddFile(parent, std::make_unique<BuildFileContext>(cur_file->name, cur_file->name_size, cur_file->size, cur_file->offset, m_cur_source_type));
cur_file_offset = cur_file->sibling;
}
@@ -415,14 +415,14 @@ namespace ams::mitm::fs {
/* If there is no romfs folder on the SD, don't bother continuing. */
{
FsDir dir;
if (R_FAILED(mitm::fs::OpenAtmosphereRomfsDirectory(std::addressof(dir), this->program_id, this->root->path.get(), OpenDirectoryMode_Directory, std::addressof(sd_filesystem)))) {
if (R_FAILED(mitm::fs::OpenAtmosphereRomfsDirectory(std::addressof(dir), m_program_id, m_root->path.get(), OpenDirectoryMode_Directory, std::addressof(sd_filesystem)))) {
return;
}
fsDirClose(std::addressof(dir));
}
this->cur_source_type = DataSourceType::LooseSdFile;
this->VisitDirectory(std::addressof(sd_filesystem), this->root);
m_cur_source_type = DataSourceType::LooseSdFile;
this->VisitDirectory(std::addressof(sd_filesystem), m_root);
}
void Builder::AddStorageFiles(ams::fs::IStorage *storage, DataSourceType source_type) {
@@ -434,8 +434,8 @@ namespace ams::mitm::fs {
DirectoryTableReader dir_table(storage, header.dir_table_ofs, header.dir_table_size);
FileTableReader file_table(storage, header.file_table_ofs, header.file_table_size);
this->cur_source_type = source_type;
this->VisitDirectory(this->root, 0x0, dir_table, file_table);
m_cur_source_type = source_type;
this->VisitDirectory(m_root, 0x0, dir_table, file_table);
}
void Builder::Build(std::vector<SourceInfo> *out_infos) {
@@ -448,19 +448,19 @@ namespace ams::mitm::fs {
ON_SCOPE_EXIT { fsFsClose(std::addressof(sd_filesystem)); };
/* Calculate hash table sizes. */
const size_t num_dir_hash_table_entries = GetHashTableSize(this->num_dirs);
const size_t num_file_hash_table_entries = GetHashTableSize(this->num_files);
this->dir_hash_table_size = sizeof(u32) * num_dir_hash_table_entries;
this->file_hash_table_size = sizeof(u32) * num_file_hash_table_entries;
const size_t num_dir_hash_table_entries = GetHashTableSize(m_num_dirs);
const size_t num_file_hash_table_entries = GetHashTableSize(m_num_files);
m_dir_hash_table_size = sizeof(u32) * num_dir_hash_table_entries;
m_file_hash_table_size = sizeof(u32) * num_file_hash_table_entries;
/* Allocate metadata, make pointers. */
Header *header = reinterpret_cast<Header *>(std::malloc(sizeof(Header)));
std::memset(header, 0x00, sizeof(*header));
/* Open metadata file. */
const size_t metadata_size = this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size + this->file_table_size;
const size_t metadata_size = m_dir_hash_table_size + m_dir_table_size + m_file_hash_table_size + m_file_table_size;
FsFile metadata_file;
R_ABORT_UNLESS(mitm::fs::CreateAndOpenAtmosphereSdFile(std::addressof(metadata_file), this->program_id, "romfs_metadata.bin", metadata_size));
R_ABORT_UNLESS(mitm::fs::CreateAndOpenAtmosphereSdFile(std::addressof(metadata_file), m_program_id, "romfs_metadata.bin", metadata_size));
/* Ensure later hash tables will have correct defaults. */
static_assert(EmptyEntry == 0xFFFFFFFF);
@@ -473,25 +473,25 @@ namespace ams::mitm::fs {
u32 entry_offset = 0;
BuildFileContext *cur_file = nullptr;
BuildFileContext *prev_file = nullptr;
for (const auto &it : this->files) {
for (const auto &it : m_files) {
cur_file = it.get();
/* By default, pad to 0x10 alignment. */
this->file_partition_size = util::AlignUp(this->file_partition_size, 0x10);
m_file_partition_size = util::AlignUp(m_file_partition_size, 0x10);
/* Check if extra padding is present in original source, preserve it to make our life easier. */
const bool is_storage_or_file = cur_file->source_type == DataSourceType::Storage || cur_file->source_type == DataSourceType::File;
if (prev_file != nullptr && prev_file->source_type == cur_file->source_type && is_storage_or_file) {
const s64 expected = this->file_partition_size - prev_file->offset + prev_file->orig_offset;
const s64 expected = m_file_partition_size - prev_file->offset + prev_file->orig_offset;
if (expected != cur_file->orig_offset) {
AMS_ABORT_UNLESS(expected <= cur_file->orig_offset);
this->file_partition_size += cur_file->orig_offset - expected;
m_file_partition_size += cur_file->orig_offset - expected;
}
}
/* Calculate offsets. */
cur_file->offset = this->file_partition_size;
this->file_partition_size += cur_file->size;
cur_file->offset = m_file_partition_size;
m_file_partition_size += cur_file->size;
cur_file->entry_offset = entry_offset;
entry_offset += sizeof(FileEntry) + util::AlignUp(cur_file->path_len, 4);
@@ -499,7 +499,7 @@ namespace ams::mitm::fs {
prev_file = cur_file;
}
/* Assign deferred parent/sibling ownership. */
for (auto it = this->files.rbegin(); it != this->files.rend(); it++) {
for (auto it = m_files.rbegin(); it != m_files.rend(); it++) {
cur_file = it->get();
cur_file->sibling = cur_file->parent->file;
cur_file->parent->file = cur_file;
@@ -510,15 +510,15 @@ namespace ams::mitm::fs {
{
u32 entry_offset = 0;
BuildDirectoryContext *cur_dir = nullptr;
for (const auto &it : this->directories) {
for (const auto &it : m_directories) {
cur_dir = it.get();
cur_dir->entry_offset = entry_offset;
entry_offset += sizeof(DirectoryEntry) + util::AlignUp(cur_dir->path_len, 4);
}
/* Assign deferred parent/sibling ownership. */
for (auto it = this->directories.rbegin(); it != this->directories.rend(); it++) {
for (auto it = m_directories.rbegin(); it != m_directories.rend(); it++) {
cur_dir = it->get();
if (cur_dir == this->root) {
if (cur_dir == m_root) {
continue;
}
cur_dir->sibling = cur_dir->parent->child;
@@ -529,20 +529,20 @@ namespace ams::mitm::fs {
/* Populate file tables. */
{
/* Allocate the hash table. */
void *fht_buf = std::malloc(this->file_hash_table_size);
void *fht_buf = std::malloc(m_file_hash_table_size);
AMS_ABORT_UNLESS(fht_buf != nullptr);
u32 *file_hash_table = reinterpret_cast<u32 *>(fht_buf);
std::memset(file_hash_table, 0xFF, this->file_hash_table_size);
std::memset(file_hash_table, 0xFF, m_file_hash_table_size);
ON_SCOPE_EXIT {
R_ABORT_UNLESS(fsFileWrite(std::addressof(metadata_file), this->dir_hash_table_size + this->dir_table_size, file_hash_table, this->file_hash_table_size, FsWriteOption_None));
R_ABORT_UNLESS(fsFileWrite(std::addressof(metadata_file), m_dir_hash_table_size + m_dir_table_size, file_hash_table, m_file_hash_table_size, FsWriteOption_None));
std::free(fht_buf);
};
/* Write the file table. */
{
FileTableWriter file_table(std::addressof(metadata_file), this->dir_hash_table_size + this->dir_table_size + this->file_hash_table_size, this->file_table_size);
FileTableWriter file_table(std::addressof(metadata_file), m_dir_hash_table_size + m_dir_table_size + m_file_hash_table_size, m_file_table_size);
for (const auto &it : this->files) {
for (const auto &it : m_files) {
BuildFileContext *cur_file = it.get();
FileEntry *cur_entry = file_table.GetEntry(cur_file->entry_offset, cur_file->path_len);
@@ -597,25 +597,25 @@ namespace ams::mitm::fs {
/* Populate directory tables. */
{
/* Allocate the hash table. */
void *dht_buf = std::malloc(this->dir_hash_table_size);
void *dht_buf = std::malloc(m_dir_hash_table_size);
AMS_ABORT_UNLESS(dht_buf != nullptr);
u32 *dir_hash_table = reinterpret_cast<u32 *>(dht_buf);
std::memset(dir_hash_table, 0xFF, this->dir_hash_table_size);
std::memset(dir_hash_table, 0xFF, m_dir_hash_table_size);
ON_SCOPE_EXIT {
R_ABORT_UNLESS(fsFileWrite(std::addressof(metadata_file), 0, dir_hash_table, this->dir_hash_table_size, FsWriteOption_None));
R_ABORT_UNLESS(fsFileWrite(std::addressof(metadata_file), 0, dir_hash_table, m_dir_hash_table_size, FsWriteOption_None));
std::free(dht_buf);
};
/* Write the file table. */
{
DirectoryTableWriter dir_table(std::addressof(metadata_file), this->dir_hash_table_size, this->dir_table_size);
DirectoryTableWriter dir_table(std::addressof(metadata_file), m_dir_hash_table_size, m_dir_table_size);
for (const auto &it : this->directories) {
for (const auto &it : m_directories) {
BuildDirectoryContext *cur_dir = it.get();
DirectoryEntry *cur_entry = dir_table.GetEntry(cur_dir->entry_offset, cur_dir->path_len);
/* Set entry fields. */
cur_entry->parent = cur_dir == this->root ? 0 : cur_dir->parent->entry_offset;
cur_entry->parent = cur_dir == m_root ? 0 : cur_dir->parent->entry_offset;
cur_entry->sibling = (cur_dir->sibling == nullptr) ? EmptyEntry : cur_dir->sibling->entry_offset;
cur_entry->child = (cur_dir->child == nullptr) ? EmptyEntry : cur_dir->child->entry_offset;
cur_entry->file = (cur_dir->file == nullptr) ? EmptyEntry : cur_dir->file->entry_offset;
@@ -639,21 +639,21 @@ namespace ams::mitm::fs {
}
/* Delete maps. */
this->root = nullptr;
this->directories.clear();
this->files.clear();
m_root = nullptr;
m_directories.clear();
m_files.clear();
/* Set header fields. */
header->header_size = sizeof(*header);
header->file_hash_table_size = this->file_hash_table_size;
header->file_table_size = this->file_table_size;
header->dir_hash_table_size = this->dir_hash_table_size;
header->dir_table_size = this->dir_table_size;
header->file_partition_ofs = FilePartitionOffset;
header->dir_hash_table_ofs = util::AlignUp(FilePartitionOffset + this->file_partition_size, 4);
header->dir_table_ofs = header->dir_hash_table_ofs + header->dir_hash_table_size;
header->file_hash_table_ofs = header->dir_table_ofs + header->dir_table_size;
header->file_table_ofs = header->file_hash_table_ofs + header->file_hash_table_size;
header->header_size = sizeof(*header);
header->file_hash_table_size = m_file_hash_table_size;
header->file_table_size = m_file_table_size;
header->dir_hash_table_size = m_dir_hash_table_size;
header->dir_table_size = m_dir_table_size;
header->file_partition_ofs = FilePartitionOffset;
header->dir_hash_table_ofs = util::AlignUp(FilePartitionOffset + m_file_partition_size, 4);
header->dir_table_ofs = header->dir_hash_table_ofs + header->dir_hash_table_size;
header->file_hash_table_ofs = header->dir_table_ofs + header->dir_table_size;
header->file_table_ofs = header->file_hash_table_ofs + header->file_hash_table_size;
/* Save metadata to the SD card, to save on memory space. */
{

View File

@@ -202,7 +202,7 @@ namespace ams::mitm::fs::romfs {
class DirectoryTableReader;
class FileTableReader;
struct Builder {
class Builder {
NON_COPYABLE(Builder);
NON_MOVEABLE(Builder);
private:
@@ -230,20 +230,20 @@ namespace ams::mitm::fs::romfs {
template<typename T>
using ContextSet = std::set<std::unique_ptr<T>, Comparator<T>>;
private:
ncm::ProgramId program_id;
BuildDirectoryContext *root;
ContextSet<BuildDirectoryContext> directories;
ContextSet<BuildFileContext> files;
size_t num_dirs;
size_t num_files;
size_t dir_table_size;
size_t file_table_size;
size_t dir_hash_table_size;
size_t file_hash_table_size;
size_t file_partition_size;
ncm::ProgramId m_program_id;
BuildDirectoryContext *m_root;
ContextSet<BuildDirectoryContext> m_directories;
ContextSet<BuildFileContext> m_files;
size_t m_num_dirs;
size_t m_num_files;
size_t m_dir_table_size;
size_t m_file_table_size;
size_t m_dir_hash_table_size;
size_t m_file_hash_table_size;
size_t m_file_partition_size;
ams::fs::DirectoryEntry dir_entry;
DataSourceType cur_source_type;
ams::fs::DirectoryEntry m_dir_entry;
DataSourceType m_cur_source_type;
private:
void VisitDirectory(FsFileSystem *fs, BuildDirectoryContext *parent);
void VisitDirectory(BuildDirectoryContext *parent, u32 parent_offset, DirectoryTableReader &dir_table, FileTableReader &file_table);

View File

@@ -20,7 +20,7 @@
namespace ams::mitm::ns {
Result NsAmMitmService::GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type) {
return nsamGetApplicationContentPathFwd(this->forward_service.get(), out_path.GetPointer(), out_path.GetSize(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return nsamGetApplicationContentPathFwd(m_forward_service.get(), out_path.GetPointer(), out_path.GetSize(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
}
Result NsAmMitmService::ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type) {
@@ -28,14 +28,14 @@ namespace ams::mitm::ns {
/* This enables hbl html. */
bool is_hbl;
if (R_SUCCEEDED(pm::info::IsHblProgramId(&is_hbl, application_id)) && is_hbl) {
nsamResolveApplicationContentPathFwd(this->forward_service.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
nsamResolveApplicationContentPathFwd(m_forward_service.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return ResultSuccess();
}
return nsamResolveApplicationContentPathFwd(this->forward_service.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return nsamResolveApplicationContentPathFwd(m_forward_service.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
}
Result NsAmMitmService::GetRunningApplicationProgramId(sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id) {
return nsamGetRunningApplicationProgramIdFwd(this->forward_service.get(), reinterpret_cast<u64 *>(out.GetPointer()), static_cast<u64>(application_id));
return nsamGetRunningApplicationProgramIdFwd(m_forward_service.get(), reinterpret_cast<u64 *>(out.GetPointer()), static_cast<u64>(application_id));
}
}

View File

@@ -19,7 +19,7 @@
namespace ams::mitm::ns {
Result NsDocumentService::GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type) {
return nswebGetApplicationContentPath(this->srv.get(), out_path.GetPointer(), out_path.GetSize(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return nswebGetApplicationContentPath(m_srv.get(), out_path.GetPointer(), out_path.GetSize(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
}
Result NsDocumentService::ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type) {
@@ -27,23 +27,23 @@ namespace ams::mitm::ns {
/* This enables hbl html. */
bool is_hbl;
if (R_SUCCEEDED(pm::info::IsHblProgramId(std::addressof(is_hbl), application_id)) && is_hbl) {
nswebResolveApplicationContentPath(this->srv.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
nswebResolveApplicationContentPath(m_srv.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return ResultSuccess();
}
return nswebResolveApplicationContentPath(this->srv.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
return nswebResolveApplicationContentPath(m_srv.get(), static_cast<u64>(application_id), static_cast<NcmContentType>(content_type));
}
Result NsDocumentService::GetRunningApplicationProgramId(sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id) {
return nswebGetRunningApplicationProgramId(this->srv.get(), reinterpret_cast<u64 *>(out.GetPointer()), static_cast<u64>(application_id));
return nswebGetRunningApplicationProgramId(m_srv.get(), reinterpret_cast<u64 *>(out.GetPointer()), static_cast<u64>(application_id));
}
Result NsWebMitmService::GetDocumentInterface(sf::Out<sf::SharedPointer<impl::IDocumentInterface>> out) {
/* Open a document interface. */
NsDocumentInterface doc;
R_TRY(nsGetDocumentInterfaceFwd(this->forward_service.get(), std::addressof(doc)));
R_TRY(nsGetDocumentInterfaceFwd(m_forward_service.get(), std::addressof(doc)));
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(doc.s))};
out.SetValue(sf::CreateSharedObjectEmplaced<impl::IDocumentInterface, NsDocumentService>(this->client_info, std::make_unique<NsDocumentInterface>(doc)), target_object_id);
out.SetValue(sf::CreateSharedObjectEmplaced<impl::IDocumentInterface, NsDocumentService>(m_client_info, std::make_unique<NsDocumentInterface>(doc)), target_object_id);
return ResultSuccess();
}

View File

@@ -34,13 +34,13 @@ namespace ams::mitm::ns {
class NsDocumentService {
private:
sm::MitmProcessInfo client_info;
std::unique_ptr<::NsDocumentInterface> srv;
sm::MitmProcessInfo m_client_info;
std::unique_ptr<::NsDocumentInterface> m_srv;
public:
NsDocumentService(const sm::MitmProcessInfo &cl, std::unique_ptr<::NsDocumentInterface> s) : client_info(cl), srv(std::move(s)) { /* .. */ }
NsDocumentService(const sm::MitmProcessInfo &cl, std::unique_ptr<::NsDocumentInterface> s) : m_client_info(cl), m_srv(std::move(s)) { /* .. */ }
virtual ~NsDocumentService() {
nsDocumentInterfaceClose(this->srv.get());
nsDocumentInterfaceClose(m_srv.get());
}
public:
/* Actual command API. */

View File

@@ -30,13 +30,13 @@ namespace ams::mitm::settings {
}
SetMitmService::SetMitmService(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &c) : sf::MitmServiceImplBase(std::forward<std::shared_ptr<::Service>>(s), c) {
if (this->client_info.program_id == ncm::SystemProgramId::Ns) {
if (m_client_info.program_id == ncm::SystemProgramId::Ns) {
os::ProcessId application_process_id;
if (R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(std::addressof(application_process_id))) && g_application_process_id == application_process_id) {
this->locale = g_application_locale;
this->is_valid_language = g_valid_language;
this->is_valid_region = g_valid_region;
this->got_locale = true;
m_locale = g_application_locale;
m_is_valid_language = g_valid_language;
m_is_valid_region = g_valid_region;
m_got_locale = true;
} else {
this->InvalidateLocale();
}
@@ -47,16 +47,16 @@ namespace ams::mitm::settings {
Result SetMitmService::EnsureLocale() {
/* Optimization: if locale has already been gotten, we can stop. */
if (AMS_LIKELY(this->got_locale)) {
if (AMS_LIKELY(m_got_locale)) {
return ResultSuccess();
}
std::scoped_lock lk(this->lock);
std::scoped_lock lk(m_lock);
const bool is_ns = this->client_info.program_id == ncm::SystemProgramId::Ns;
const bool is_ns = m_client_info.program_id == ncm::SystemProgramId::Ns;
if (!this->got_locale) {
ncm::ProgramId program_id = this->client_info.program_id;
if (!m_got_locale) {
ncm::ProgramId program_id = m_client_info.program_id;
os::ProcessId application_process_id = os::InvalidProcessId;
if (is_ns) {
@@ -64,15 +64,15 @@ namespace ams::mitm::settings {
R_TRY(pm::dmnt::GetApplicationProcessId(std::addressof(application_process_id)));
R_TRY(pm::info::GetProgramId(std::addressof(program_id), application_process_id));
}
this->locale = cfg::GetOverrideLocale(program_id);
this->is_valid_language = settings::IsValidLanguageCode(this->locale.language_code);
this->is_valid_region = settings::IsValidRegionCode(this->locale.region_code);
this->got_locale = true;
m_locale = cfg::GetOverrideLocale(program_id);
m_is_valid_language = settings::IsValidLanguageCode(m_locale.language_code);
m_is_valid_region = settings::IsValidRegionCode(m_locale.region_code);
m_got_locale = true;
if (is_ns) {
g_application_locale = this->locale;
g_valid_language = this->is_valid_language;
g_valid_region = this->is_valid_region;
g_application_locale = m_locale;
g_valid_language = m_is_valid_language;
g_valid_region = m_is_valid_region;
g_application_process_id = application_process_id;
}
}
@@ -81,30 +81,30 @@ namespace ams::mitm::settings {
}
void SetMitmService::InvalidateLocale() {
std::scoped_lock lk(this->lock);
std::scoped_lock lk(m_lock);
std::memset(std::addressof(this->locale), 0xCC, sizeof(this->locale));
this->is_valid_language = false;
this->is_valid_region = false;
this->got_locale = false;
std::memset(std::addressof(m_locale), 0xCC, sizeof(m_locale));
m_is_valid_language = false;
m_is_valid_region = false;
m_got_locale = false;
}
Result SetMitmService::GetLanguageCode(sf::Out<settings::LanguageCode> out) {
this->EnsureLocale();
/* If there's no override locale, just use the actual one. */
if (AMS_UNLIKELY(!this->is_valid_language)) {
if (AMS_UNLIKELY(!m_is_valid_language)) {
static_assert(sizeof(u64) == sizeof(settings::LanguageCode));
R_TRY(setGetLanguageCodeFwd(this->forward_service.get(), reinterpret_cast<u64 *>(std::addressof(this->locale.language_code))));
R_TRY(setGetLanguageCodeFwd(m_forward_service.get(), reinterpret_cast<u64 *>(std::addressof(m_locale.language_code))));
this->is_valid_language = true;
if (this->client_info.program_id == ncm::SystemProgramId::Ns) {
g_application_locale.language_code = this->locale.language_code;
m_is_valid_language = true;
if (m_client_info.program_id == ncm::SystemProgramId::Ns) {
g_application_locale.language_code = m_locale.language_code;
g_valid_language = true;
}
}
out.SetValue(this->locale.language_code);
out.SetValue(m_locale.language_code);
return ResultSuccess();
}
@@ -112,18 +112,18 @@ namespace ams::mitm::settings {
this->EnsureLocale();
/* If there's no override locale, just use the actual one. */
if (AMS_UNLIKELY(!this->is_valid_region)) {
if (AMS_UNLIKELY(!m_is_valid_region)) {
static_assert(sizeof(::SetRegion) == sizeof(settings::RegionCode));
R_TRY(setGetRegionCodeFwd(this->forward_service.get(), reinterpret_cast<::SetRegion *>(std::addressof(this->locale.region_code))));
R_TRY(setGetRegionCodeFwd(m_forward_service.get(), reinterpret_cast<::SetRegion *>(std::addressof(m_locale.region_code))));
this->is_valid_region = true;
if (this->client_info.program_id == ncm::SystemProgramId::Ns) {
g_application_locale.region_code = this->locale.region_code;
m_is_valid_region = true;
if (m_client_info.program_id == ncm::SystemProgramId::Ns) {
g_application_locale.region_code = m_locale.region_code;
g_valid_region = true;
}
}
out.SetValue(this->locale.region_code);
out.SetValue(m_locale.region_code);
return ResultSuccess();
}

View File

@@ -26,11 +26,11 @@ namespace ams::mitm::settings {
class SetMitmService : public sf::MitmServiceImplBase {
private:
os::SdkMutex lock{};
cfg::OverrideLocale locale;
bool got_locale = false;
bool is_valid_language = false;
bool is_valid_region = false;
os::SdkMutex m_lock{};
cfg::OverrideLocale m_locale;
bool m_got_locale = false;
bool m_is_valid_language = false;
bool m_is_valid_region = false;
public:
SetMitmService(std::shared_ptr<::Service> &&s, const sm::MitmProcessInfo &c);
public:

View File

@@ -90,7 +90,7 @@ namespace ams::mitm::settings {
}
Result SetSysMitmService::GetFirmwareVersion(sf::Out<settings::FirmwareVersion> out) {
R_TRY(GetFirmwareVersionImpl(out.GetPointer(), this->client_info));
R_TRY(GetFirmwareVersionImpl(out.GetPointer(), m_client_info));
/* GetFirmwareVersion sanitizes the revision fields. */
out.GetPointer()->revision_major = 0;
@@ -99,7 +99,7 @@ namespace ams::mitm::settings {
}
Result SetSysMitmService::GetFirmwareVersion2(sf::Out<settings::FirmwareVersion> out) {
return GetFirmwareVersionImpl(out.GetPointer(), this->client_info);
return GetFirmwareVersionImpl(out.GetPointer(), m_client_info);
}
Result SetSysMitmService::GetSettingsItemValueSize(sf::Out<u64> out_size, const settings::SettingsName &name, const settings::SettingsItemKey &key) {
@@ -122,7 +122,7 @@ namespace ams::mitm::settings {
Result SetSysMitmService::GetDebugModeFlag(sf::Out<bool> out) {
/* If we're not processing for am, just return the real flag value. */
R_UNLESS(this->client_info.program_id == ncm::SystemProgramId::Am, sm::mitm::ResultShouldForwardToSession());
R_UNLESS(m_client_info.program_id == ncm::SystemProgramId::Am, sm::mitm::ResultShouldForwardToSession());
/* Retrieve the user configuration. */
u8 en = 0;

View File

@@ -79,7 +79,7 @@ namespace ams::mitm::sysupdater {
Result SystemUpdateApplyManager::ApplyPackageTask(ncm::PackageSystemDowngradeTask *task) {
/* Lock the apply mutex. */
std::scoped_lock lk(this->apply_mutex);
std::scoped_lock lk(m_apply_mutex);
/* NOTE: Here, Nintendo creates a system report for the update. */

View File

@@ -20,9 +20,9 @@ namespace ams::mitm::sysupdater {
class SystemUpdateApplyManager {
private:
os::SdkMutex apply_mutex;
os::SdkMutex m_apply_mutex;
public:
constexpr SystemUpdateApplyManager() : apply_mutex() { /* ... */ }
constexpr SystemUpdateApplyManager() : m_apply_mutex() { /* ... */ }
Result ApplyPackageTask(ncm::PackageSystemDowngradeTask *task);
};

View File

@@ -29,10 +29,10 @@ namespace ams::mitm::sysupdater {
}
AsyncPrepareSdCardUpdateImpl::~AsyncPrepareSdCardUpdateImpl() {
if (this->thread_info) {
os::WaitThread(this->thread_info->thread);
os::DestroyThread(this->thread_info->thread);
GetAsyncThreadAllocator()->Free(*this->thread_info);
if (m_thread_info) {
os::WaitThread(m_thread_info->thread);
os::DestroyThread(m_thread_info->thread);
GetAsyncThreadAllocator()->Free(*m_thread_info);
}
}
@@ -46,16 +46,16 @@ namespace ams::mitm::sysupdater {
/* Ensure that we clean up appropriately. */
ON_SCOPE_EXIT {
if (!this->thread_info) {
if (!m_thread_info) {
GetAsyncThreadAllocator()->Free(info);
}
};
/* Create a thread for the task. */
R_TRY(os::CreateThread(info.thread, [](void *arg) {
auto *_this = reinterpret_cast<AsyncPrepareSdCardUpdateImpl *>(arg);
_this->result = _this->Execute();
_this->event.Signal();
auto *async = reinterpret_cast<AsyncPrepareSdCardUpdateImpl *>(arg);
async->m_result = async->Execute();
async->m_event.Signal();
}, this, info.stack, info.stack_size, info.priority));
/* Set the thread name. */
@@ -65,16 +65,16 @@ namespace ams::mitm::sysupdater {
os::StartThread(info.thread);
/* Set our thread info. */
this->thread_info = info;
m_thread_info = info;
return ResultSuccess();
}
Result AsyncPrepareSdCardUpdateImpl::Execute() {
return this->task->PrepareAndExecute();
return m_task->PrepareAndExecute();
}
void AsyncPrepareSdCardUpdateImpl::CancelImpl() {
this->task->Cancel();
m_task->Cancel();
}
}

View File

@@ -21,16 +21,16 @@ namespace ams::mitm::sysupdater {
class ErrorContextHolder {
private:
err::ErrorContext error_context;
err::ErrorContext m_error_context;
public:
constexpr ErrorContextHolder() : error_context{} { /* ... */ }
constexpr ErrorContextHolder() : m_error_context{} { /* ... */ }
virtual ~ErrorContextHolder() { /* ... */ }
template<typename T>
Result SaveErrorContextIfFailed(T &async, Result result) {
if (R_FAILED(result)) {
async.GetErrorContext(std::addressof(this->error_context));
async.GetErrorContext(std::addressof(m_error_context));
return result;
}
@@ -46,7 +46,7 @@ namespace ams::mitm::sysupdater {
template<typename T>
Result SaveInternalTaskErrorContextIfFailed(T &async, Result result) {
if (R_FAILED(result)) {
async.CreateErrorContext(std::addressof(this->error_context));
async.CreateErrorContext(std::addressof(m_error_context));
return result;
}
@@ -54,7 +54,7 @@ namespace ams::mitm::sysupdater {
}
const err::ErrorContext &GetErrorContextImpl() {
return this->error_context;
return m_error_context;
}
};
@@ -93,15 +93,15 @@ namespace ams::mitm::sysupdater {
/* We don't implement the RequestServer::ManagedStop details, as we don't implement stoppable request list. */
class AsyncPrepareSdCardUpdateImpl : public AsyncResultBase, private ErrorContextHolder {
private:
Result result;
os::SystemEvent event;
util::optional<ThreadInfo> thread_info;
ncm::InstallTaskBase *task;
Result m_result;
os::SystemEvent m_event;
util::optional<ThreadInfo> m_thread_info;
ncm::InstallTaskBase *m_task;
public:
AsyncPrepareSdCardUpdateImpl(ncm::InstallTaskBase *task) : result(ResultSuccess()), event(os::EventClearMode_ManualClear, true), thread_info(), task(task) { /* ... */ }
AsyncPrepareSdCardUpdateImpl(ncm::InstallTaskBase *task) : m_result(ResultSuccess()), m_event(os::EventClearMode_ManualClear, true), m_thread_info(), m_task(task) { /* ... */ }
virtual ~AsyncPrepareSdCardUpdateImpl();
os::SystemEvent &GetEvent() { return this->event; }
os::SystemEvent &GetEvent() { return m_event; }
virtual Result GetErrorContext(sf::Out<err::ErrorContext> out) override {
*out = ErrorContextHolder::GetErrorContextImpl();
@@ -113,7 +113,7 @@ namespace ams::mitm::sysupdater {
Result Execute();
virtual void CancelImpl() override;
virtual Result GetImpl() override { return this->result; }
virtual Result GetImpl() override { return m_result; }
};
}

View File

@@ -211,16 +211,16 @@ namespace ams::mitm::sysupdater {
}
bool PathView::HasPrefix(util::string_view prefix) const {
return this->path.compare(0, prefix.length(), prefix) == 0;
return m_path.compare(0, prefix.length(), prefix) == 0;
}
bool PathView::HasSuffix(util::string_view suffix) const {
return this->path.compare(this->path.length() - suffix.length(), suffix.length(), suffix) == 0;
return m_path.compare(m_path.length() - suffix.length(), suffix.length(), suffix) == 0;
}
util::string_view PathView::GetFileName() const {
auto pos = this->path.find_last_of("/");
return pos != util::string_view::npos ? this->path.substr(pos + 1) : this->path;
auto pos = m_path.find_last_of("/");
return pos != util::string_view::npos ? m_path.substr(pos + 1) : m_path;
}
Result MountSdCardContentMeta(const char *mount_name, const char *path) {

View File

@@ -20,9 +20,9 @@ namespace ams::mitm::sysupdater {
class PathView {
private:
util::string_view path;
util::string_view m_path;
public:
PathView(util::string_view p) : path(p) { /* ...*/ }
PathView(util::string_view p) : m_path(p) { /* ...*/ }
bool HasPrefix(util::string_view prefix) const;
bool HasSuffix(util::string_view suffix) const;
util::string_view GetFileName() const;

View File

@@ -420,18 +420,18 @@ namespace ams::mitm::sysupdater {
Result SystemUpdateService::RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<sf::SharedPointer<ns::impl::IAsyncResult>> out_async) {
/* Ensure the update is setup but not prepared. */
R_UNLESS(this->setup_update, ns::ResultCardUpdateNotSetup());
R_UNLESS(!this->requested_update, ns::ResultPrepareCardUpdateAlreadyRequested());
R_UNLESS(m_setup_update, ns::ResultCardUpdateNotSetup());
R_UNLESS(!m_requested_update, ns::ResultPrepareCardUpdateAlreadyRequested());
/* Create the async result. */
auto async_result = sf::CreateSharedObjectEmplaced<ns::impl::IAsyncResult, AsyncPrepareSdCardUpdateImpl>(std::addressof(*this->update_task));
auto async_result = sf::CreateSharedObjectEmplaced<ns::impl::IAsyncResult, AsyncPrepareSdCardUpdateImpl>(std::addressof(*m_update_task));
R_UNLESS(async_result != nullptr, ns::ResultOutOfMaxRunningTask());
/* Run the task. */
R_TRY(async_result.GetImpl().Run());
/* We prepared the task! */
this->requested_update = true;
m_requested_update = true;
out_event_handle.SetValue(async_result.GetImpl().GetEvent().GetReadableHandle(), false);
*out_async = std::move(async_result);
@@ -440,38 +440,38 @@ namespace ams::mitm::sysupdater {
Result SystemUpdateService::GetPrepareUpdateProgress(sf::Out<SystemUpdateProgress> out) {
/* Ensure the update is setup. */
R_UNLESS(this->setup_update, ns::ResultCardUpdateNotSetup());
R_UNLESS(m_setup_update, ns::ResultCardUpdateNotSetup());
/* Get the progress. */
auto install_progress = this->update_task->GetProgress();
auto install_progress = m_update_task->GetProgress();
out.SetValue({ .current_size = install_progress.installed_size, .total_size = install_progress.total_size });
return ResultSuccess();
}
Result SystemUpdateService::HasPreparedUpdate(sf::Out<bool> out) {
/* Ensure the update is setup. */
R_UNLESS(this->setup_update, ns::ResultCardUpdateNotSetup());
R_UNLESS(m_setup_update, ns::ResultCardUpdateNotSetup());
out.SetValue(this->update_task->GetProgress().state == ncm::InstallProgressState::Downloaded);
out.SetValue(m_update_task->GetProgress().state == ncm::InstallProgressState::Downloaded);
return ResultSuccess();
}
Result SystemUpdateService::ApplyPreparedUpdate() {
/* Ensure the update is setup. */
R_UNLESS(this->setup_update, ns::ResultCardUpdateNotSetup());
R_UNLESS(m_setup_update, ns::ResultCardUpdateNotSetup());
/* Ensure the update is prepared. */
R_UNLESS(this->update_task->GetProgress().state == ncm::InstallProgressState::Downloaded, ns::ResultCardUpdateNotPrepared());
R_UNLESS(m_update_task->GetProgress().state == ncm::InstallProgressState::Downloaded, ns::ResultCardUpdateNotPrepared());
/* Apply the task. */
R_TRY(this->apply_manager.ApplyPackageTask(std::addressof(*this->update_task)));
R_TRY(m_apply_manager.ApplyPackageTask(std::addressof(*m_update_task)));
return ResultSuccess();
}
Result SystemUpdateService::SetupUpdateImpl(sf::NativeHandle &&transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
/* Ensure we don't already have an update set up. */
R_UNLESS(!this->setup_update, ns::ResultCardUpdateAlreadySetup());
R_UNLESS(!m_setup_update, ns::ResultCardUpdateAlreadySetup());
/* Destroy any existing update tasks. */
nim::SystemUpdateTaskId id;
@@ -484,21 +484,21 @@ namespace ams::mitm::sysupdater {
R_TRY(InitializeUpdateTask(std::move(transfer_memory), transfer_memory_size, path, exfat, firmware_variation_id));
/* The update is now set up. */
this->setup_update = true;
m_setup_update = true;
return ResultSuccess();
}
Result SystemUpdateService::InitializeUpdateTask(sf::NativeHandle &&transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id) {
/* Map the transfer memory. */
const size_t tmem_buffer_size = static_cast<size_t>(transfer_memory_size);
this->update_transfer_memory.emplace(tmem_buffer_size, transfer_memory.GetOsHandle(), transfer_memory.IsManaged());
m_update_transfer_memory.emplace(tmem_buffer_size, transfer_memory.GetOsHandle(), transfer_memory.IsManaged());
transfer_memory.Detach();
void *tmem_buffer;
R_TRY(this->update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None));
R_TRY(m_update_transfer_memory->Map(std::addressof(tmem_buffer), os::MemoryPermission_None));
auto tmem_guard = SCOPE_GUARD {
this->update_transfer_memory->Unmap();
this->update_transfer_memory = util::nullopt;
m_update_transfer_memory->Unmap();
m_update_transfer_memory = util::nullopt;
};
/* Adjust the package root. */
@@ -510,8 +510,8 @@ namespace ams::mitm::sysupdater {
const char *context_path = "@Sdcard:/atmosphere/update/cup.ctx";
/* Create and initialize the update task. */
this->update_task.emplace();
R_TRY(this->update_task->Initialize(package_root.str, context_path, tmem_buffer, tmem_buffer_size, exfat, firmware_variation_id));
m_update_task.emplace();
R_TRY(m_update_task->Initialize(package_root.str, context_path, tmem_buffer, tmem_buffer_size, exfat, firmware_variation_id));
/* We successfully setup the update. */
tmem_guard.Cancel();

View File

@@ -56,13 +56,13 @@ namespace ams::mitm::sysupdater {
class SystemUpdateService {
private:
SystemUpdateApplyManager apply_manager;
util::optional<ncm::PackageSystemDowngradeTask> update_task;
util::optional<os::TransferMemory> update_transfer_memory;
bool setup_update;
bool requested_update;
SystemUpdateApplyManager m_apply_manager;
util::optional<ncm::PackageSystemDowngradeTask> m_update_task;
util::optional<os::TransferMemory> m_update_transfer_memory;
bool m_setup_update;
bool m_requested_update;
public:
constexpr SystemUpdateService() : apply_manager(), update_task(), update_transfer_memory(), setup_update(false), requested_update(false) { /* ... */ }
constexpr SystemUpdateService() : m_apply_manager(), m_update_task(), m_update_transfer_memory(), m_setup_update(false), m_requested_update(false) { /* ... */ }
private:
Result SetupUpdateImpl(sf::NativeHandle &&transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
Result InitializeUpdateTask(sf::NativeHandle &&transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);

View File

@@ -19,18 +19,18 @@
namespace ams::mitm::sysupdater {
Result ThreadAllocator::Allocate(ThreadInfo *out) {
std::scoped_lock lk(this->mutex);
std::scoped_lock lk(m_mutex);
for (int i = 0; i < this->thread_count; ++i) {
for (int i = 0; i < m_thread_count; ++i) {
const u64 mask = (static_cast<u64>(1) << i);
if ((this->bitmap & mask) == 0) {
if ((m_bitmap & mask) == 0) {
*out = {
.thread = this->thread_list + i,
.priority = this->thread_priority,
.stack = this->stack_heap + (this->stack_size * i),
.stack_size = this->stack_size,
.thread = m_thread_list + i,
.priority = m_thread_priority,
.stack = m_stack_heap + (m_stack_size * i),
.stack_size = m_stack_size,
};
this->bitmap |= mask;
m_bitmap |= mask;
return ResultSuccess();
}
}
@@ -39,12 +39,12 @@ namespace ams::mitm::sysupdater {
}
void ThreadAllocator::Free(const ThreadInfo &info) {
std::scoped_lock lk(this->mutex);
std::scoped_lock lk(m_mutex);
for (int i = 0; i < this->thread_count; ++i) {
if (info.thread == std::addressof(this->thread_list[i])) {
for (int i = 0; i < m_thread_count; ++i) {
if (info.thread == std::addressof(m_thread_list[i])) {
const u64 mask = (static_cast<u64>(1) << i);
this->bitmap &= ~mask;
m_bitmap &= ~mask;
return;
}
}

View File

@@ -28,20 +28,20 @@ namespace ams::mitm::sysupdater {
/* NOTE: Nintendo uses a util::BitArray, but this seems excessive. */
class ThreadAllocator {
private:
os::ThreadType *thread_list;
const int thread_priority;
const int thread_count;
u8 *stack_heap;
const size_t stack_heap_size;
const size_t stack_size;
u64 bitmap;
os::SdkMutex mutex;
os::ThreadType *m_thread_list;
const int m_thread_priority;
const int m_thread_count;
u8 *m_stack_heap;
const size_t m_stack_heap_size;
const size_t m_stack_size;
u64 m_bitmap;
os::SdkMutex m_mutex;
public:
constexpr ThreadAllocator(os::ThreadType *thread_list, int count, int priority, u8 *stack_heap, size_t stack_heap_size, size_t stack_size)
: thread_list(thread_list), thread_priority(priority), thread_count(count), stack_heap(stack_heap), stack_heap_size(stack_heap_size), stack_size(stack_size), bitmap()
: m_thread_list(thread_list), m_thread_priority(priority), m_thread_count(count), m_stack_heap(stack_heap), m_stack_heap_size(stack_heap_size), m_stack_size(stack_size), m_bitmap()
{
AMS_ASSERT(count <= static_cast<int>(stack_heap_size / stack_size));
AMS_ASSERT(count <= static_cast<int>(BITSIZEOF(this->bitmap)));
AMS_ASSERT(count <= static_cast<int>(BITSIZEOF(m_bitmap)));
}
Result Allocate(ThreadInfo *out);

View File

@@ -20,54 +20,54 @@ namespace ams::boot {
class BatteryDriver {
private:
powctl::Session battery_session;
powctl::Session m_battery_session;
public:
BatteryDriver() : battery_session() {
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(this->battery_session), powctl::DeviceCode_Max17050, ddsf::AccessMode_ReadWrite));
BatteryDriver() : m_battery_session() {
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(m_battery_session), powctl::DeviceCode_Max17050, ddsf::AccessMode_ReadWrite));
}
~BatteryDriver() {
powctl::CloseSession(this->battery_session);
powctl::CloseSession(m_battery_session);
}
public:
Result IsBatteryRemoved(bool *out) {
bool present;
R_TRY(powctl::IsBatteryPresent(std::addressof(present), this->battery_session));
R_TRY(powctl::IsBatteryPresent(std::addressof(present), m_battery_session));
*out = !present;
return ResultSuccess();
}
Result GetSocRep(float *out) {
return powctl::GetBatterySocRep(out, this->battery_session);
return powctl::GetBatterySocRep(out, m_battery_session);
}
Result GetAverageVCell(int *out) {
return powctl::GetBatteryAverageVCell(out, this->battery_session);
return powctl::GetBatteryAverageVCell(out, m_battery_session);
}
Result GetOpenCircuitVoltage(int *out) {
return powctl::GetBatteryOpenCircuitVoltage(out, this->battery_session);
return powctl::GetBatteryOpenCircuitVoltage(out, m_battery_session);
}
Result GetAverageCurrent(int *out) {
return powctl::GetBatteryAverageCurrent(out, this->battery_session);
return powctl::GetBatteryAverageCurrent(out, m_battery_session);
}
Result GetCurrent(int *out) {
return powctl::GetBatteryCurrent(out, this->battery_session);
return powctl::GetBatteryCurrent(out, m_battery_session);
}
Result GetTemperature(float *out) {
return powctl::GetBatteryTemperature(out, this->battery_session);
return powctl::GetBatteryTemperature(out, m_battery_session);
}
Result IsI2cShutdownEnabled(bool *out) {
return powctl::IsBatteryI2cShutdownEnabled(out, this->battery_session);
return powctl::IsBatteryI2cShutdownEnabled(out, m_battery_session);
}
Result SetI2cShutdownEnabled(bool en) {
return powctl::SetBatteryI2cShutdownEnabled(this->battery_session, en);
return powctl::SetBatteryI2cShutdownEnabled(m_battery_session, en);
}
};

View File

@@ -27,14 +27,14 @@ namespace ams::boot {
class ChargerDriver {
private:
powctl::Session charger_session;
powctl::Session m_charger_session;
public:
ChargerDriver() : charger_session() {
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(this->charger_session), powctl::DeviceCode_Bq24193, ddsf::AccessMode_ReadWrite));
ChargerDriver() : m_charger_session() {
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(m_charger_session), powctl::DeviceCode_Bq24193, ddsf::AccessMode_ReadWrite));
}
~ChargerDriver() {
powctl::CloseSession(this->charger_session);
powctl::CloseSession(m_charger_session);
}
Result Initialize(bool set_input_current_limit) {
@@ -46,51 +46,51 @@ namespace ams::boot {
/* Set input current limit to 500 ma. */
if (set_input_current_limit) {
R_TRY(powctl::SetChargerInputCurrentLimit(this->charger_session, 500));
R_TRY(powctl::SetChargerInputCurrentLimit(m_charger_session, 500));
}
/* Set input voltage limit to 500 mv. */
R_TRY(powctl::SetChargerInputVoltageLimit(this->charger_session, 500));
R_TRY(powctl::SetChargerInputVoltageLimit(m_charger_session, 500));
/* Disable hi-z mode. */
R_TRY(powctl::SetChargerHiZEnabled(this->charger_session, false));
R_TRY(powctl::SetChargerHiZEnabled(m_charger_session, false));
/* Set configuration to charge battery. */
R_TRY(powctl::SetChargerChargerConfiguration(this->charger_session, powctl::ChargerConfiguration_ChargeBattery));
R_TRY(powctl::SetChargerChargerConfiguration(m_charger_session, powctl::ChargerConfiguration_ChargeBattery));
return ResultSuccess();
}
Result GetChargeCurrentState(powctl::ChargeCurrentState *out) {
return powctl::GetChargerChargeCurrentState(out, this->charger_session);
return powctl::GetChargerChargeCurrentState(out, m_charger_session);
}
Result SetChargeCurrentState(powctl::ChargeCurrentState state) {
return powctl::SetChargerChargeCurrentState(this->charger_session, state);
return powctl::SetChargerChargeCurrentState(m_charger_session, state);
}
Result GetInputCurrentLimit(int *out) {
return powctl::GetChargerInputCurrentLimit(out, this->charger_session);
return powctl::GetChargerInputCurrentLimit(out, m_charger_session);
}
Result SetChargerConfiguration(powctl::ChargerConfiguration cfg) {
return powctl::SetChargerChargerConfiguration(this->charger_session, cfg);
return powctl::SetChargerChargerConfiguration(m_charger_session, cfg);
}
Result GetFastChargeCurrentLimit(int *out) {
return powctl::GetChargerFastChargeCurrentLimit(out, this->charger_session);
return powctl::GetChargerFastChargeCurrentLimit(out, m_charger_session);
}
Result SetFastChargeCurrentLimit(int limit) {
return powctl::SetChargerFastChargeCurrentLimit(this->charger_session, limit);
return powctl::SetChargerFastChargeCurrentLimit(m_charger_session, limit);
}
Result GetChargeVoltageLimit(int *out) {
return powctl::GetChargerChargeVoltageLimit(out, this->charger_session);
return powctl::GetChargerChargeVoltageLimit(out, m_charger_session);
}
Result SetChargeVoltageLimit(int limit) {
return powctl::SetChargerChargeVoltageLimit(this->charger_session, limit);
return powctl::SetChargerChargeVoltageLimit(m_charger_session, limit);
}
Result GetChargerStatus(boot::ChargerStatus *out) {
@@ -99,7 +99,7 @@ namespace ams::boot {
/* Get the powctl status. */
powctl::ChargerStatus powctl_status;
R_TRY(powctl::GetChargerChargerStatus(std::addressof(powctl_status), this->charger_session));
R_TRY(powctl::GetChargerChargerStatus(std::addressof(powctl_status), m_charger_session));
switch (powctl_status) {
case powctl::ChargerStatus_Charging: *out = boot::ChargerStatus_Charging; break;
@@ -111,19 +111,19 @@ namespace ams::boot {
}
Result GetBatteryCompensation(int *out) {
return powctl::GetChargerBatteryCompensation(out, this->charger_session);
return powctl::GetChargerBatteryCompensation(out, m_charger_session);
}
Result SetBatteryCompensation(int v) {
return powctl::SetChargerBatteryCompensation(this->charger_session, v);
return powctl::SetChargerBatteryCompensation(m_charger_session, v);
}
Result GetVoltageClamp(int *out) {
return powctl::GetChargerVoltageClamp(out, this->charger_session);
return powctl::GetChargerVoltageClamp(out, m_charger_session);
}
Result SetVoltageClamp(int v) {
return powctl::SetChargerVoltageClamp(this->charger_session, v);
return powctl::SetChargerVoltageClamp(m_charger_session, v);
}
};

View File

@@ -42,18 +42,18 @@ namespace ams::boot {
class BatteryChecker {
private:
boot::ChargerDriver &charger_driver;
boot::BatteryDriver &battery_driver;
const powctl::driver::impl::ChargeParameters &charge_parameters;
powctl::driver::impl::ChargeArbiter charge_arbiter;
powctl::ChargeCurrentState charge_current_state;
int fast_charge_current_limit;
int charge_voltage_limit;
int battery_compensation;
int voltage_clamp;
TimeSpan charging_done_interval;
bool has_start_time;
TimeSpan start_time;
boot::ChargerDriver &m_charger_driver;
boot::BatteryDriver &m_battery_driver;
const powctl::driver::impl::ChargeParameters &m_charge_parameters;
powctl::driver::impl::ChargeArbiter m_charge_arbiter;
powctl::ChargeCurrentState m_charge_current_state;
int m_fast_charge_current_limit;
int m_charge_voltage_limit;
int m_battery_compensation;
int m_voltage_clamp;
TimeSpan m_charging_done_interval;
bool m_has_start_time;
TimeSpan m_start_time;
private:
bool IsChargeDone();
void UpdateChargeDoneCurrent();
@@ -63,25 +63,25 @@ namespace ams::boot {
void UpdateStartTime() {
/* Update start time. */
this->start_time = os::ConvertToTimeSpan(os::GetSystemTick());
this->has_start_time = true;
m_start_time = os::ConvertToTimeSpan(os::GetSystemTick());
m_has_start_time = true;
}
public:
BatteryChecker(boot::ChargerDriver &cd, boot::BatteryDriver &bd, const powctl::driver::impl::ChargeParameters &cp, int cvl) : charger_driver(cd), battery_driver(bd), charge_parameters(cp), charge_arbiter(cp.rules, cp.num_rules, cvl), charging_done_interval(TimeSpan::FromSeconds(2)), has_start_time(false) {
BatteryChecker(boot::ChargerDriver &cd, boot::BatteryDriver &bd, const powctl::driver::impl::ChargeParameters &cp, int cvl) : m_charger_driver(cd), m_battery_driver(bd), m_charge_parameters(cp), m_charge_arbiter(cp.rules, cp.num_rules, cvl), m_charging_done_interval(TimeSpan::FromSeconds(2)), m_has_start_time(false) {
/* Get parameters from charger. */
if (R_FAILED(this->charger_driver.GetChargeCurrentState(std::addressof(this->charge_current_state)))) {
if (R_FAILED(m_charger_driver.GetChargeCurrentState(std::addressof(m_charge_current_state)))) {
boot::ShutdownSystem();
}
if (R_FAILED(this->charger_driver.GetFastChargeCurrentLimit(std::addressof(this->fast_charge_current_limit)))) {
if (R_FAILED(m_charger_driver.GetFastChargeCurrentLimit(std::addressof(m_fast_charge_current_limit)))) {
boot::ShutdownSystem();
}
if (R_FAILED(this->charger_driver.GetChargeVoltageLimit(std::addressof(this->charge_voltage_limit)))) {
if (R_FAILED(m_charger_driver.GetChargeVoltageLimit(std::addressof(m_charge_voltage_limit)))) {
boot::ShutdownSystem();
}
if (R_FAILED(this->charger_driver.GetBatteryCompensation(std::addressof(this->battery_compensation)))) {
if (R_FAILED(m_charger_driver.GetBatteryCompensation(std::addressof(m_battery_compensation)))) {
boot::ShutdownSystem();
}
if (R_FAILED(this->charger_driver.GetVoltageClamp(std::addressof(this->voltage_clamp)))) {
if (R_FAILED(m_charger_driver.GetVoltageClamp(std::addressof(m_voltage_clamp)))) {
boot::ShutdownSystem();
}
@@ -112,16 +112,16 @@ namespace ams::boot {
/* Get various battery metrics. */
int avg_current, current, open_circuit_voltage;
float temp;
if (R_FAILED(this->battery_driver.GetAverageCurrent(std::addressof(avg_current)))) {
if (R_FAILED(m_battery_driver.GetAverageCurrent(std::addressof(avg_current)))) {
return;
}
if (R_FAILED(this->battery_driver.GetCurrent(std::addressof(current)))) {
if (R_FAILED(m_battery_driver.GetCurrent(std::addressof(current)))) {
return;
}
if (R_FAILED(this->battery_driver.GetTemperature(std::addressof(temp)))) {
if (R_FAILED(m_battery_driver.GetTemperature(std::addressof(temp)))) {
return;
}
if (R_FAILED(this->battery_driver.GetOpenCircuitVoltage(std::addressof(open_circuit_voltage)))) {
if (R_FAILED(m_battery_driver.GetOpenCircuitVoltage(std::addressof(open_circuit_voltage)))) {
return;
}
@@ -132,7 +132,7 @@ namespace ams::boot {
bool BatteryChecker::IsChargeDone() {
/* Get the charger status. */
boot::ChargerStatus charger_status;
if (R_FAILED(this->charger_driver.GetChargerStatus(std::addressof(charger_status)))) {
if (R_FAILED(m_charger_driver.GetChargerStatus(std::addressof(charger_status)))) {
boot::ShutdownSystem();
}
@@ -142,20 +142,20 @@ namespace ams::boot {
}
/* Return whether a done current of zero is acceptable. */
return this->charge_arbiter.IsBatteryDoneCurrentAcceptable(0);
return m_charge_arbiter.IsBatteryDoneCurrentAcceptable(0);
}
void BatteryChecker::UpdateChargeDoneCurrent() {
int done_current = 0;
if (this->has_start_time && (os::ConvertToTimeSpan(os::GetSystemTick()) - this->start_time) >= this->charging_done_interval) {
if (m_has_start_time && (os::ConvertToTimeSpan(os::GetSystemTick()) - m_start_time) >= m_charging_done_interval) {
/* Get the current. */
if (R_FAILED(this->battery_driver.GetCurrent(std::addressof(done_current)))) {
if (R_FAILED(m_battery_driver.GetCurrent(std::addressof(done_current)))) {
boot::ShutdownSystem();
}
} else {
/* Get the charger status. */
boot::ChargerStatus charger_status;
if (R_FAILED(this->charger_driver.GetChargerStatus(std::addressof(charger_status)))) {
if (R_FAILED(m_charger_driver.GetChargerStatus(std::addressof(charger_status)))) {
boot::ShutdownSystem();
}
@@ -166,50 +166,50 @@ namespace ams::boot {
}
/* Update done current. */
this->charge_arbiter.SetBatteryDoneCurrent(done_current);
m_charge_arbiter.SetBatteryDoneCurrent(done_current);
}
void BatteryChecker::UpdateCharger() {
/* Get the battery temperature. */
float temp;
if (R_FAILED(this->battery_driver.GetTemperature(std::addressof(temp)))) {
if (R_FAILED(m_battery_driver.GetTemperature(std::addressof(temp)))) {
boot::ShutdownSystem();
}
/* Update the temperature level. */
powctl::BatteryTemperatureLevel temp_level;
if (temp < static_cast<float>(this->charge_parameters.temp_min)) {
if (temp < static_cast<float>(m_charge_parameters.temp_min)) {
temp_level = powctl::BatteryTemperatureLevel::TooLow;
} else if (temp < static_cast<float>(this->charge_parameters.temp_low)) {
} else if (temp < static_cast<float>(m_charge_parameters.temp_low)) {
temp_level = powctl::BatteryTemperatureLevel::Low;
} else if (temp < static_cast<float>(this->charge_parameters.temp_high)) {
} else if (temp < static_cast<float>(m_charge_parameters.temp_high)) {
temp_level = powctl::BatteryTemperatureLevel::Medium;
} else if (temp < static_cast<float>(this->charge_parameters.temp_max)) {
} else if (temp < static_cast<float>(m_charge_parameters.temp_max)) {
temp_level = powctl::BatteryTemperatureLevel::High;
} else {
temp_level = powctl::BatteryTemperatureLevel::TooHigh;
}
this->charge_arbiter.SetBatteryTemperatureLevel(temp_level);
m_charge_arbiter.SetBatteryTemperatureLevel(temp_level);
/* Update average voltage. */
int avg_v_cell;
if (R_FAILED(this->battery_driver.GetAverageVCell(std::addressof(avg_v_cell)))) {
if (R_FAILED(m_battery_driver.GetAverageVCell(std::addressof(avg_v_cell)))) {
boot::ShutdownSystem();
}
this->charge_arbiter.SetBatteryAverageVCell(avg_v_cell);
m_charge_arbiter.SetBatteryAverageVCell(avg_v_cell);
/* Update open circuit voltage. */
int ocv;
if (R_FAILED(this->battery_driver.GetOpenCircuitVoltage(std::addressof(ocv)))) {
if (R_FAILED(m_battery_driver.GetOpenCircuitVoltage(std::addressof(ocv)))) {
boot::ShutdownSystem();
}
this->charge_arbiter.SetBatteryOpenCircuitVoltage(ocv);
m_charge_arbiter.SetBatteryOpenCircuitVoltage(ocv);
/* Update charge done current. */
this->UpdateChargeDoneCurrent();
/* Update arbiter power state. */
this->charge_arbiter.SetPowerState(powctl::PowerState::ShutdownChargeMain);
m_charge_arbiter.SetPowerState(powctl::PowerState::ShutdownChargeMain);
/* Apply the newly selected rule. */
this->ApplyArbiterRule();
@@ -217,19 +217,19 @@ namespace ams::boot {
void BatteryChecker::ApplyArbiterRule() {
/* Get the selected rule. */
const auto *rule = this->charge_arbiter.GetSelectedRule();
const auto *rule = m_charge_arbiter.GetSelectedRule();
AMS_ASSERT(rule != nullptr);
/* Check if we need to perform charger initialization. */
const bool reinit_charger = rule->reinitialize_charger;
const auto cur_charge_current_state = this->charge_current_state;
const auto cur_charge_current_state = m_charge_current_state;
/* Set the charger to not charging while we make changes. */
if (!reinit_charger || cur_charge_current_state != powctl::ChargeCurrentState_NotCharging) {
if (R_FAILED(this->charger_driver.SetChargeCurrentState(powctl::ChargeCurrentState_NotCharging))) {
if (R_FAILED(m_charger_driver.SetChargeCurrentState(powctl::ChargeCurrentState_NotCharging))) {
boot::ShutdownSystem();
}
this->charge_current_state = powctl::ChargeCurrentState_NotCharging;
m_charge_current_state = powctl::ChargeCurrentState_NotCharging;
/* Update start time. */
this->UpdateStartTime();
@@ -237,25 +237,25 @@ namespace ams::boot {
/* Process fast charge current limit when rule is smaller. */
const auto rule_fast_charge_current_limit = rule->fast_charge_current_limit;
const auto cur_fast_charge_current_limit = this->fast_charge_current_limit;
const auto cur_fast_charge_current_limit = m_fast_charge_current_limit;
if (rule_fast_charge_current_limit < cur_fast_charge_current_limit) {
if (R_FAILED(this->charger_driver.SetFastChargeCurrentLimit(rule_fast_charge_current_limit))) {
if (R_FAILED(m_charger_driver.SetFastChargeCurrentLimit(rule_fast_charge_current_limit))) {
boot::ShutdownSystem();
}
this->fast_charge_current_limit = rule_fast_charge_current_limit;
m_fast_charge_current_limit = rule_fast_charge_current_limit;
/* Update start time. */
this->UpdateStartTime();
}
/* Process charge voltage limit when rule is smaller. */
const auto rule_charge_voltage_limit = std::min(rule->charge_voltage_limit, this->charge_arbiter.GetChargeVoltageLimit());
const auto cur_charge_voltage_limit = this->charge_voltage_limit;
const auto rule_charge_voltage_limit = std::min(rule->charge_voltage_limit, m_charge_arbiter.GetChargeVoltageLimit());
const auto cur_charge_voltage_limit = m_charge_voltage_limit;
if (rule_charge_voltage_limit < cur_charge_voltage_limit) {
if (R_FAILED(this->charger_driver.SetChargeVoltageLimit(rule_charge_voltage_limit))) {
if (R_FAILED(m_charger_driver.SetChargeVoltageLimit(rule_charge_voltage_limit))) {
boot::ShutdownSystem();
}
this->charge_voltage_limit = rule_charge_voltage_limit;
m_charge_voltage_limit = rule_charge_voltage_limit;
/* Update start time. */
this->UpdateStartTime();
@@ -263,12 +263,12 @@ namespace ams::boot {
/* Process battery compensation when rule is smaller. */
const auto rule_battery_compensation = rule->battery_compensation;
const auto cur_battery_compensation = this->battery_compensation;
const auto cur_battery_compensation = m_battery_compensation;
if (rule_battery_compensation < cur_battery_compensation) {
if (R_FAILED(this->charger_driver.SetBatteryCompensation(rule_battery_compensation))) {
if (R_FAILED(m_charger_driver.SetBatteryCompensation(rule_battery_compensation))) {
boot::ShutdownSystem();
}
this->battery_compensation = rule_battery_compensation;
m_battery_compensation = rule_battery_compensation;
/* Update start time. */
this->UpdateStartTime();
@@ -276,12 +276,12 @@ namespace ams::boot {
/* Process voltage clamp when rule is smaller. */
const auto rule_voltage_clamp = rule->voltage_clamp;
const auto cur_voltage_clamp = this->voltage_clamp;
const auto cur_voltage_clamp = m_voltage_clamp;
if (rule_voltage_clamp < cur_voltage_clamp) {
if (R_FAILED(this->charger_driver.SetVoltageClamp(rule_voltage_clamp))) {
if (R_FAILED(m_charger_driver.SetVoltageClamp(rule_voltage_clamp))) {
boot::ShutdownSystem();
}
this->voltage_clamp = rule_voltage_clamp;
m_voltage_clamp = rule_voltage_clamp;
/* Update start time. */
this->UpdateStartTime();
@@ -289,10 +289,10 @@ namespace ams::boot {
/* Process voltage clamp when rule is larger. */
if (rule_voltage_clamp > cur_voltage_clamp) {
if (R_FAILED(this->charger_driver.SetVoltageClamp(rule_voltage_clamp))) {
if (R_FAILED(m_charger_driver.SetVoltageClamp(rule_voltage_clamp))) {
boot::ShutdownSystem();
}
this->voltage_clamp = rule_voltage_clamp;
m_voltage_clamp = rule_voltage_clamp;
/* Update start time. */
this->UpdateStartTime();
@@ -300,10 +300,10 @@ namespace ams::boot {
/* Process battery compensation when rule is larger. */
if (rule_battery_compensation > cur_battery_compensation) {
if (R_FAILED(this->charger_driver.SetBatteryCompensation(rule_battery_compensation))) {
if (R_FAILED(m_charger_driver.SetBatteryCompensation(rule_battery_compensation))) {
boot::ShutdownSystem();
}
this->battery_compensation = rule_battery_compensation;
m_battery_compensation = rule_battery_compensation;
/* Update start time. */
this->UpdateStartTime();
@@ -311,10 +311,10 @@ namespace ams::boot {
/* Process fast charge current limit when rule is larger. */
if (rule_fast_charge_current_limit > cur_fast_charge_current_limit) {
if (R_FAILED(this->charger_driver.SetFastChargeCurrentLimit(rule_fast_charge_current_limit))) {
if (R_FAILED(m_charger_driver.SetFastChargeCurrentLimit(rule_fast_charge_current_limit))) {
boot::ShutdownSystem();
}
this->fast_charge_current_limit = rule_fast_charge_current_limit;
m_fast_charge_current_limit = rule_fast_charge_current_limit;
/* Update start time. */
this->UpdateStartTime();
@@ -322,10 +322,10 @@ namespace ams::boot {
/* Process charge voltage limit when rule is larger. */
if (rule_charge_voltage_limit > cur_charge_voltage_limit) {
if (R_FAILED(this->charger_driver.SetChargeVoltageLimit(rule_charge_voltage_limit))) {
if (R_FAILED(m_charger_driver.SetChargeVoltageLimit(rule_charge_voltage_limit))) {
boot::ShutdownSystem();
}
this->charge_voltage_limit = rule_charge_voltage_limit;
m_charge_voltage_limit = rule_charge_voltage_limit;
/* Update start time. */
this->UpdateStartTime();
@@ -333,10 +333,10 @@ namespace ams::boot {
/* If we're not charging and we expect to reinitialize the charger, do so. */
if (cur_charge_current_state != powctl::ChargeCurrentState_Charging && reinit_charger) {
if (R_FAILED(this->charger_driver.SetChargeCurrentState(powctl::ChargeCurrentState_Charging))) {
if (R_FAILED(m_charger_driver.SetChargeCurrentState(powctl::ChargeCurrentState_Charging))) {
boot::ShutdownSystem();
}
this->charge_current_state = powctl::ChargeCurrentState_Charging;
m_charge_current_state = powctl::ChargeCurrentState_Charging;
/* Update start time. */
this->UpdateStartTime();
@@ -357,7 +357,7 @@ namespace ams::boot {
if (show_charging_display) {
/* Get the raw battery charge. */
float raw_battery_charge;
if (R_FAILED(this->battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
if (R_FAILED(m_battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
return CheckBatteryResult::Shutdown;
}
@@ -372,13 +372,13 @@ namespace ams::boot {
while (true) {
/* Get the raw battery charge. */
float raw_battery_charge;
if (R_FAILED(this->battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
if (R_FAILED(m_battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
return CheckBatteryResult::Shutdown;
}
/* Get the average vcell. */
int battery_voltage;
if (R_FAILED(this->battery_driver.GetAverageVCell(std::addressof(battery_voltage)))) {
if (R_FAILED(m_battery_driver.GetAverageVCell(std::addressof(battery_voltage)))) {
return CheckBatteryResult::Shutdown;
}

View File

@@ -36,17 +36,17 @@ namespace ams::boot {
Result PmicDriver::GetOnOffIrq(u8 *out) {
const u8 addr = 0x0B;
return ReadI2cRegister(this->i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
return ReadI2cRegister(m_i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
}
Result PmicDriver::GetPowerStatus(u8 *out) {
const u8 addr = 0x15;
return ReadI2cRegister(this->i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
return ReadI2cRegister(m_i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
}
Result PmicDriver::GetNvErc(u8 *out) {
const u8 addr = 0x0C;
return ReadI2cRegister(this->i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
return ReadI2cRegister(m_i2c_session, out, sizeof(*out), std::addressof(addr), sizeof(addr));
}
Result PmicDriver::GetPowerButtonPressed(bool *out) {
@@ -62,17 +62,17 @@ namespace ams::boot {
/* Get value, set or clear software reset mask. */
u8 on_off_2_val = 0;
R_ABORT_UNLESS(ReadI2cRegister(this->i2c_session, std::addressof(on_off_2_val), sizeof(on_off_2_val), std::addressof(on_off_2_addr), sizeof(on_off_2_addr)));
R_ABORT_UNLESS(ReadI2cRegister(m_i2c_session, std::addressof(on_off_2_val), sizeof(on_off_2_val), std::addressof(on_off_2_addr), sizeof(on_off_2_addr)));
if (reboot) {
on_off_2_val |= 0x80;
} else {
on_off_2_val &= ~0x80;
}
R_ABORT_UNLESS(WriteI2cRegister(this->i2c_session, std::addressof(on_off_2_val), sizeof(on_off_2_val), std::addressof(on_off_2_addr), sizeof(on_off_2_addr)));
R_ABORT_UNLESS(WriteI2cRegister(m_i2c_session, std::addressof(on_off_2_val), sizeof(on_off_2_val), std::addressof(on_off_2_addr), sizeof(on_off_2_addr)));
/* Get value, set software reset mask. */
u8 on_off_1_val = 0;
R_ABORT_UNLESS(ReadI2cRegister(this->i2c_session, std::addressof(on_off_1_val), sizeof(on_off_1_val), std::addressof(on_off_1_addr), sizeof(on_off_1_addr)));
R_ABORT_UNLESS(ReadI2cRegister(m_i2c_session, std::addressof(on_off_1_val), sizeof(on_off_1_val), std::addressof(on_off_1_addr), sizeof(on_off_1_addr)));
on_off_1_val |= 0x80;
/* Finalize the battery on non-Calcio. */
@@ -82,7 +82,7 @@ namespace ams::boot {
}
/* Actually write the value to trigger shutdown/reset. */
R_ABORT_UNLESS(WriteI2cRegister(this->i2c_session, std::addressof(on_off_1_val), sizeof(on_off_1_val), std::addressof(on_off_1_addr), sizeof(on_off_1_addr)));
R_ABORT_UNLESS(WriteI2cRegister(m_i2c_session, std::addressof(on_off_1_val), sizeof(on_off_1_val), std::addressof(on_off_1_addr), sizeof(on_off_1_addr)));
/* Allow up to 5 seconds for shutdown/reboot to take place. */
os::SleepThread(TimeSpan::FromSeconds(5));

View File

@@ -21,14 +21,14 @@ namespace ams::boot {
/* Driver object. */
class PmicDriver {
private:
i2c::driver::I2cSession i2c_session;
i2c::driver::I2cSession m_i2c_session;
public:
PmicDriver() {
R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Max77620Pmic));
R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(m_i2c_session), i2c::DeviceCode_Max77620Pmic));
}
~PmicDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::CloseSession(m_i2c_session);
}
private:
Result GetPowerStatus(u8 *out);

View File

@@ -21,14 +21,14 @@ namespace ams::boot {
Result RtcDriver::ReadRtcRegister(u8 *out, u8 address) {
const u8 update_addr = 0x04;
const u8 update_val = 0x10;
R_TRY(WriteI2cRegister(this->i2c_session, &update_val, sizeof(update_val), &update_addr, sizeof(update_addr)));
R_TRY(WriteI2cRegister(m_i2c_session, &update_val, sizeof(update_val), &update_addr, sizeof(update_addr)));
os::SleepThread(TimeSpan::FromMilliSeconds(16));
return ReadI2cRegister(this->i2c_session, out, sizeof(*out), &address, sizeof(address));
return ReadI2cRegister(m_i2c_session, out, sizeof(*out), &address, sizeof(address));
}
Result RtcDriver::GetRtcIntr(u8 *out) {
const u8 addr = 0x00;
return ReadI2cRegister(this->i2c_session, out, sizeof(*out), &addr, sizeof(addr));
return ReadI2cRegister(m_i2c_session, out, sizeof(*out), &addr, sizeof(addr));
}
Result RtcDriver::GetRtcIntrM(u8 *out) {

View File

@@ -20,14 +20,14 @@ namespace ams::boot {
class RtcDriver {
private:
i2c::driver::I2cSession i2c_session;
i2c::driver::I2cSession m_i2c_session;
public:
RtcDriver() {
R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(this->i2c_session), i2c::DeviceCode_Max77620Rtc));
R_ABORT_UNLESS(i2c::driver::OpenSession(std::addressof(m_i2c_session), i2c::DeviceCode_Max77620Rtc));
}
~RtcDriver() {
i2c::driver::CloseSession(this->i2c_session);
i2c::driver::CloseSession(m_i2c_session);
}
private:
Result ReadRtcRegister(u8 *out, u8 address);

View File

@@ -86,31 +86,31 @@ namespace ams::creport {
void CrashReport::Initialize() {
/* Initialize the heap. */
this->heap_handle = lmem::CreateExpHeap(this->heap_storage, sizeof(this->heap_storage), lmem::CreateOption_None);
m_heap_handle = lmem::CreateExpHeap(m_heap_storage, sizeof(m_heap_storage), lmem::CreateOption_None);
/* Allocate members. */
this->module_list = std::construct_at(static_cast<ModuleList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ModuleList))));
this->thread_list = std::construct_at(static_cast<ThreadList *>(lmem::AllocateFromExpHeap(this->heap_handle, sizeof(ThreadList))));
this->dying_message = static_cast<u8 *>(lmem::AllocateFromExpHeap(this->heap_handle, DyingMessageSizeMax));
if (this->dying_message != nullptr) {
std::memset(this->dying_message, 0, DyingMessageSizeMax);
m_module_list = std::construct_at(static_cast<ModuleList *>(lmem::AllocateFromExpHeap(m_heap_handle, sizeof(ModuleList))));
m_thread_list = std::construct_at(static_cast<ThreadList *>(lmem::AllocateFromExpHeap(m_heap_handle, sizeof(ThreadList))));
m_dying_message = static_cast<u8 *>(lmem::AllocateFromExpHeap(m_heap_handle, DyingMessageSizeMax));
if (m_dying_message != nullptr) {
std::memset(m_dying_message, 0, DyingMessageSizeMax);
}
}
void CrashReport::BuildReport(os::ProcessId process_id, bool has_extra_info) {
this->has_extra_info = has_extra_info;
m_has_extra_info = has_extra_info;
if (this->OpenProcess(process_id)) {
ON_SCOPE_EXIT { this->Close(); };
/* Parse info from the crashed process. */
this->ProcessExceptions();
this->module_list->FindModulesFromThreadInfo(this->debug_handle, this->crashed_thread);
this->thread_list->ReadFromProcess(this->debug_handle, this->thread_tls_map, this->Is64Bit());
m_module_list->FindModulesFromThreadInfo(m_debug_handle, m_crashed_thread);
m_thread_list->ReadFromProcess(m_debug_handle, m_thread_tls_map, this->Is64Bit());
/* Associate module list to threads. */
this->crashed_thread.SetModuleList(this->module_list);
this->thread_list->SetModuleList(this->module_list);
m_crashed_thread.SetModuleList(m_module_list);
m_thread_list->SetModuleList(m_module_list);
/* Process dying message for applications. */
if (this->IsApplication()) {
@@ -119,13 +119,13 @@ namespace ams::creport {
/* Nintendo's creport finds extra modules by looking at all threads if application, */
/* but there's no reason for us not to always go looking. */
for (size_t i = 0; i < this->thread_list->GetThreadCount(); i++) {
this->module_list->FindModulesFromThreadInfo(this->debug_handle, this->thread_list->GetThreadInfo(i));
for (size_t i = 0; i < m_thread_list->GetThreadCount(); i++) {
m_module_list->FindModulesFromThreadInfo(m_debug_handle, m_thread_list->GetThreadInfo(i));
}
/* Cache the module base address to send to fatal. */
if (this->module_list->GetModuleCount()) {
this->module_base_address = this->module_list->GetModuleStartAddress(0);
if (m_module_list->GetModuleCount()) {
m_module_base_address = m_module_list->GetModuleStartAddress(0);
}
/* Nintendo's creport saves the report to erpt here, but we'll save to SD card later. */
@@ -139,33 +139,33 @@ namespace ams::creport {
/* TODO: Support generating 32-bit fatal contexts? */
out->architecture = fatal::CpuContext::Architecture_Aarch64;
out->type = static_cast<u32>(this->exception_info.type);
out->type = static_cast<u32>(m_exception_info.type);
for (size_t i = 0; i < fatal::aarch64::RegisterName_FP; i++) {
out->aarch64_ctx.SetRegisterValue(static_cast<fatal::aarch64::RegisterName>(i), this->crashed_thread.GetGeneralPurposeRegister(i));
out->aarch64_ctx.SetRegisterValue(static_cast<fatal::aarch64::RegisterName>(i), m_crashed_thread.GetGeneralPurposeRegister(i));
}
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_FP, this->crashed_thread.GetFP());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_LR, this->crashed_thread.GetLR());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_SP, this->crashed_thread.GetSP());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_PC, this->crashed_thread.GetPC());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_FP, m_crashed_thread.GetFP());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_LR, m_crashed_thread.GetLR());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_SP, m_crashed_thread.GetSP());
out->aarch64_ctx.SetRegisterValue(fatal::aarch64::RegisterName_PC, m_crashed_thread.GetPC());
out->aarch64_ctx.stack_trace_size = this->crashed_thread.GetStackTraceSize();
out->aarch64_ctx.stack_trace_size = m_crashed_thread.GetStackTraceSize();
for (size_t i = 0; i < out->aarch64_ctx.stack_trace_size; i++) {
out->aarch64_ctx.stack_trace[i] = this->crashed_thread.GetStackTrace(i);
out->aarch64_ctx.stack_trace[i] = m_crashed_thread.GetStackTrace(i);
}
if (this->module_base_address != 0) {
out->aarch64_ctx.SetBaseAddress(this->module_base_address);
if (m_module_base_address != 0) {
out->aarch64_ctx.SetBaseAddress(m_module_base_address);
}
/* For ams fatal, which doesn't use afsr0, pass program_id instead. */
out->aarch64_ctx.SetProgramIdForAtmosphere(ncm::ProgramId{this->process_info.program_id});
out->aarch64_ctx.SetProgramIdForAtmosphere(ncm::ProgramId{m_process_info.program_id});
}
void CrashReport::ProcessExceptions() {
/* Loop all debug events. */
svc::DebugEventInfo d;
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), this->debug_handle))) {
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), m_debug_handle))) {
switch (d.type) {
case svc::DebugEvent_CreateProcess:
this->HandleDebugEventInfoCreateProcess(d);
@@ -183,11 +183,11 @@ namespace ams::creport {
}
/* Parse crashed thread info. */
this->crashed_thread.ReadFromProcess(this->debug_handle, this->thread_tls_map, this->crashed_thread_id, this->Is64Bit());
m_crashed_thread.ReadFromProcess(m_debug_handle, m_thread_tls_map, m_crashed_thread_id, this->Is64Bit());
}
void CrashReport::HandleDebugEventInfoCreateProcess(const svc::DebugEventInfo &d) {
this->process_info = d.info.create_process;
m_process_info = d.info.create_process;
/* On 5.0.0+, we want to parse out a dying message from application crashes. */
if (hos::GetVersion() < hos::Version_5_0_0 || !IsApplication()) {
@@ -195,12 +195,12 @@ namespace ams::creport {
}
/* Parse out user data. */
const u64 address = this->process_info.user_exception_context_address + DyingMessageAddressOffset;
const u64 address = m_process_info.user_exception_context_address + DyingMessageAddressOffset;
u64 userdata_address = 0;
u64 userdata_size = 0;
/* Read userdata address. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_address)), this->debug_handle, address, sizeof(userdata_address)))) {
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_address)), m_debug_handle, address, sizeof(userdata_address)))) {
return;
}
@@ -210,48 +210,48 @@ namespace ams::creport {
}
/* Read userdata size. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_size)), this->debug_handle, address + sizeof(userdata_address), sizeof(userdata_size)))) {
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(userdata_size)), m_debug_handle, address + sizeof(userdata_address), sizeof(userdata_size)))) {
return;
}
/* Cap userdata size. */
userdata_size = std::min(size_t(userdata_size), DyingMessageSizeMax);
this->dying_message_address = userdata_address;
this->dying_message_size = userdata_size;
m_dying_message_address = userdata_address;
m_dying_message_size = userdata_size;
}
void CrashReport::HandleDebugEventInfoCreateThread(const svc::DebugEventInfo &d) {
/* Save info on the thread's TLS address for later. */
this->thread_tls_map.SetThreadTls(d.info.create_thread.thread_id, d.info.create_thread.tls_address);
m_thread_tls_map.SetThreadTls(d.info.create_thread.thread_id, d.info.create_thread.tls_address);
}
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
switch (d.info.exception.type) {
case svc::DebugException_UndefinedInstruction:
this->result = creport::ResultUndefinedInstruction();
m_result = creport::ResultUndefinedInstruction();
break;
case svc::DebugException_InstructionAbort:
this->result = creport::ResultInstructionAbort();
m_result = creport::ResultInstructionAbort();
break;
case svc::DebugException_DataAbort:
this->result = creport::ResultDataAbort();
m_result = creport::ResultDataAbort();
break;
case svc::DebugException_AlignmentFault:
this->result = creport::ResultAlignmentFault();
m_result = creport::ResultAlignmentFault();
break;
case svc::DebugException_UserBreak:
this->result = creport::ResultUserBreak();
m_result = creport::ResultUserBreak();
/* Try to parse out the user break result. */
if (hos::GetVersion() >= hos::Version_5_0_0) {
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(this->result)), this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result));
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(m_result)), m_debug_handle, d.info.exception.specific.user_break.address, sizeof(m_result));
}
break;
case svc::DebugException_UndefinedSystemCall:
this->result = creport::ResultUndefinedSystemCall();
m_result = creport::ResultUndefinedSystemCall();
break;
case svc::DebugException_MemorySystemError:
this->result = creport::ResultMemorySystemError();
m_result = creport::ResultMemorySystemError();
break;
case svc::DebugException_DebuggerAttached:
case svc::DebugException_BreakPoint:
@@ -260,8 +260,8 @@ namespace ams::creport {
}
/* Save exception info. */
this->exception_info = d.info.exception;
this->crashed_thread_id = d.thread_id;
m_exception_info = d.info.exception;
m_crashed_thread_id = d.thread_id;
}
void CrashReport::ProcessDyingMessage() {
@@ -271,10 +271,10 @@ namespace ams::creport {
}
/* Validate address/size. */
if (this->dying_message_address == 0 || this->dying_message_address & 0xFFF) {
if (m_dying_message_address == 0 || m_dying_message_address & 0xFFF) {
return;
}
if (this->dying_message_size > DyingMessageSizeMax) {
if (m_dying_message_size > DyingMessageSizeMax) {
return;
}
@@ -284,12 +284,12 @@ namespace ams::creport {
}
/* Verify that we have a dying message buffer. */
if (this->dying_message == nullptr) {
if (m_dying_message == nullptr) {
return;
}
/* Read the dying message. */
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(this->dying_message), this->debug_handle, this->dying_message_address, this->dying_message_size);
svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(m_dying_message), m_debug_handle, m_dying_message_address, m_dying_message_size);
}
void CrashReport::SaveReport(bool enable_screenshot) {
@@ -307,7 +307,7 @@ namespace ams::creport {
char file_path[fs::EntryNameLengthMax + 1];
/* Save crash report. */
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, this->process_info.program_id);
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, m_process_info.program_id);
{
ScopedFile file(file_path);
if (file.IsOpen()) {
@@ -316,25 +316,25 @@ namespace ams::creport {
}
/* Dump threads. */
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, this->process_info.program_id);
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/dumps/%011lu_%016lx_thread_info.bin", timestamp, m_process_info.program_id);
{
ScopedFile file(file_path);
if (file.IsOpen()) {
this->thread_list->DumpBinary(file, this->crashed_thread.GetThreadId());
m_thread_list->DumpBinary(file, m_crashed_thread.GetThreadId());
}
}
/* Finalize our heap. */
std::destroy_at(this->module_list);
std::destroy_at(this->thread_list);
lmem::FreeToExpHeap(this->heap_handle, this->module_list);
lmem::FreeToExpHeap(this->heap_handle, this->thread_list);
if (this->dying_message != nullptr) {
lmem::FreeToExpHeap(this->heap_handle, this->dying_message);
std::destroy_at(m_module_list);
std::destroy_at(m_thread_list);
lmem::FreeToExpHeap(m_heap_handle, m_module_list);
lmem::FreeToExpHeap(m_heap_handle, m_thread_list);
if (m_dying_message != nullptr) {
lmem::FreeToExpHeap(m_heap_handle, m_dying_message);
}
this->module_list = nullptr;
this->thread_list = nullptr;
this->dying_message = nullptr;
m_module_list = nullptr;
m_thread_list = nullptr;
m_dying_message = nullptr;
/* Try to take a screenshot. */
/* NOTE: Nintendo validates that enable_screenshot is true here, and validates that the application id is not in a blacklist. */
@@ -345,11 +345,11 @@ namespace ams::creport {
ON_SCOPE_EXIT { capsrv::FinalizeScreenShotControl(); };
u64 jpeg_size;
if (R_SUCCEEDED(capsrv::CaptureJpegScreenshot(std::addressof(jpeg_size), this->heap_storage, sizeof(this->heap_storage), vi::LayerStack_ApplicationForDebug, TimeSpan::FromSeconds(10)))) {
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, this->process_info.program_id);
if (R_SUCCEEDED(capsrv::CaptureJpegScreenshot(std::addressof(jpeg_size), m_heap_storage, sizeof(m_heap_storage), vi::LayerStack_ApplicationForDebug, TimeSpan::FromSeconds(10)))) {
util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.jpg", timestamp, m_process_info.program_id);
ScopedFile file(file_path);
if (file.IsOpen()) {
file.Write(this->heap_storage, jpeg_size);
file.Write(m_heap_storage, jpeg_size);
}
}
}
@@ -360,42 +360,42 @@ namespace ams::creport {
void CrashReport::SaveToFile(ScopedFile &file) {
file.WriteFormat("Atmosphère Crash Report (v1.6):\n");
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->result.GetValue(), this->result.GetModule(), this->result.GetDescription());
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", m_result.GetValue(), m_result.GetModule(), m_result.GetDescription());
/* Process Info. */
char name_buf[0x10] = {};
static_assert(sizeof(name_buf) >= sizeof(this->process_info.name), "buffer overflow!");
std::memcpy(name_buf, this->process_info.name, sizeof(this->process_info.name));
static_assert(sizeof(name_buf) >= sizeof(m_process_info.name), "buffer overflow!");
std::memcpy(name_buf, m_process_info.name, sizeof(m_process_info.name));
file.WriteFormat("Process Info:\n");
file.WriteFormat(" Process Name: %s\n", name_buf);
file.WriteFormat(" Program ID: %016lx\n", this->process_info.program_id);
file.WriteFormat(" Process ID: %016lx\n", this->process_info.process_id);
file.WriteFormat(" Process Flags: %08x\n", this->process_info.flags);
file.WriteFormat(" Program ID: %016lx\n", m_process_info.program_id);
file.WriteFormat(" Process ID: %016lx\n", m_process_info.process_id);
file.WriteFormat(" Process Flags: %08x\n", m_process_info.flags);
if (hos::GetVersion() >= hos::Version_5_0_0) {
file.WriteFormat(" User Exception Address: %s\n", this->module_list->GetFormattedAddressString(this->process_info.user_exception_context_address));
file.WriteFormat(" User Exception Address: %s\n", m_module_list->GetFormattedAddressString(m_process_info.user_exception_context_address));
}
/* Exception Info. */
file.WriteFormat("Exception Info:\n");
file.WriteFormat(" Type: %s\n", GetDebugExceptionString(this->exception_info.type));
file.WriteFormat(" Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.address));
switch (this->exception_info.type) {
file.WriteFormat(" Type: %s\n", GetDebugExceptionString(m_exception_info.type));
file.WriteFormat(" Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.address));
switch (m_exception_info.type) {
case svc::DebugException_UndefinedInstruction:
file.WriteFormat(" Opcode: %08x\n", this->exception_info.specific.undefined_instruction.insn);
file.WriteFormat(" Opcode: %08x\n", m_exception_info.specific.undefined_instruction.insn);
break;
case svc::DebugException_DataAbort:
case svc::DebugException_AlignmentFault:
if (this->exception_info.specific.raw != this->exception_info.address) {
file.WriteFormat(" Fault Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.specific.raw));
if (m_exception_info.specific.raw != m_exception_info.address) {
file.WriteFormat(" Fault Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.specific.raw));
}
break;
case svc::DebugException_UndefinedSystemCall:
file.WriteFormat(" Svc Id: 0x%02x\n", this->exception_info.specific.undefined_system_call.id);
file.WriteFormat(" Svc Id: 0x%02x\n", m_exception_info.specific.undefined_system_call.id);
break;
case svc::DebugException_UserBreak:
file.WriteFormat(" Break Reason: 0x%x\n", this->exception_info.specific.user_break.break_reason);
file.WriteFormat(" Break Address: %s\n", this->module_list->GetFormattedAddressString(this->exception_info.specific.user_break.address));
file.WriteFormat(" Break Size: 0x%lx\n", this->exception_info.specific.user_break.size);
file.WriteFormat(" Break Reason: 0x%x\n", m_exception_info.specific.user_break.break_reason);
file.WriteFormat(" Break Address: %s\n", m_module_list->GetFormattedAddressString(m_exception_info.specific.user_break.address));
file.WriteFormat(" Break Size: 0x%lx\n", m_exception_info.specific.user_break.size);
break;
default:
break;
@@ -403,23 +403,23 @@ namespace ams::creport {
/* Crashed Thread Info. */
file.WriteFormat("Crashed Thread Info:\n");
this->crashed_thread.SaveToFile(file);
m_crashed_thread.SaveToFile(file);
/* Dying Message. */
if (hos::GetVersion() >= hos::Version_5_0_0 && this->dying_message_size != 0) {
if (hos::GetVersion() >= hos::Version_5_0_0 && m_dying_message_size != 0) {
file.WriteFormat("Dying Message Info:\n");
file.WriteFormat(" Address: 0x%s\n", this->module_list->GetFormattedAddressString(this->dying_message_address));
file.WriteFormat(" Size: 0x%016lx\n", this->dying_message_size);
file.DumpMemory( " Dying Message: ", this->dying_message, this->dying_message_size);
file.WriteFormat(" Address: 0x%s\n", m_module_list->GetFormattedAddressString(m_dying_message_address));
file.WriteFormat(" Size: 0x%016lx\n", m_dying_message_size);
file.DumpMemory( " Dying Message: ", m_dying_message, m_dying_message_size);
}
/* Module Info. */
file.WriteFormat("Module Info:\n");
this->module_list->SaveToFile(file);
m_module_list->SaveToFile(file);
/* Thread Info. */
file.WriteFormat("Thread Report:\n");
this->thread_list->SaveToFile(file);
m_thread_list->SaveToFile(file);
}
}

View File

@@ -25,66 +25,66 @@ namespace ams::creport {
static constexpr size_t MemoryHeapSize = 512_KB;
static_assert(MemoryHeapSize >= DyingMessageSizeMax + sizeof(ModuleList) + sizeof(ThreadList) + os::MemoryPageSize);
private:
os::NativeHandle debug_handle = os::InvalidNativeHandle;
bool has_extra_info = true;
Result result = creport::ResultIncompleteReport();
os::NativeHandle m_debug_handle = os::InvalidNativeHandle;
bool m_has_extra_info = true;
Result m_result = creport::ResultIncompleteReport();
/* Meta, used for building module/thread list. */
ThreadTlsMap thread_tls_map = {};
ThreadTlsMap m_thread_tls_map = {};
/* Attach process info. */
svc::DebugInfoCreateProcess process_info = {};
u64 dying_message_address = 0;
u64 dying_message_size = 0;
u8 *dying_message = nullptr;
svc::DebugInfoCreateProcess m_process_info = {};
u64 m_dying_message_address = 0;
u64 m_dying_message_size = 0;
u8 *m_dying_message = nullptr;
/* Exception info. */
svc::DebugInfoException exception_info = {};
u64 module_base_address = 0;
u64 crashed_thread_id = 0;
ThreadInfo crashed_thread;
svc::DebugInfoException m_exception_info = {};
u64 m_module_base_address = 0;
u64 m_crashed_thread_id = 0;
ThreadInfo m_crashed_thread;
/* Lists. */
ModuleList *module_list = nullptr;
ThreadList *thread_list = nullptr;
ModuleList *m_module_list = nullptr;
ThreadList *m_thread_list = nullptr;
/* Memory heap. */
lmem::HeapHandle heap_handle = nullptr;
u8 heap_storage[MemoryHeapSize] = {};
lmem::HeapHandle m_heap_handle = nullptr;
u8 m_heap_storage[MemoryHeapSize] = {};
public:
constexpr CrashReport() = default;
Result GetResult() const {
return this->result;
return m_result;
}
bool IsComplete() const {
return !ResultIncompleteReport::Includes(this->result);
return !ResultIncompleteReport::Includes(m_result);
}
bool IsOpen() const {
return this->debug_handle != os::InvalidNativeHandle;
return m_debug_handle != os::InvalidNativeHandle;
}
bool IsApplication() const {
return (this->process_info.flags & svc::CreateProcessFlag_IsApplication) != 0;
return (m_process_info.flags & svc::CreateProcessFlag_IsApplication) != 0;
}
bool Is64Bit() const {
return (this->process_info.flags & svc::CreateProcessFlag_Is64Bit) != 0;
return (m_process_info.flags & svc::CreateProcessFlag_Is64Bit) != 0;
}
bool IsUserBreak() const {
return this->exception_info.type == svc::DebugException_UserBreak;
return m_exception_info.type == svc::DebugException_UserBreak;
}
bool OpenProcess(os::ProcessId process_id) {
return R_SUCCEEDED(svc::DebugActiveProcess(std::addressof(this->debug_handle), process_id.value));
return R_SUCCEEDED(svc::DebugActiveProcess(std::addressof(m_debug_handle), process_id.value));
}
void Close() {
os::CloseNativeHandle(this->debug_handle);
this->debug_handle = os::InvalidNativeHandle;
os::CloseNativeHandle(m_debug_handle);
m_debug_handle = os::InvalidNativeHandle;
}
void Initialize();

View File

@@ -46,12 +46,12 @@ namespace ams::creport {
}
void ModuleList::SaveToFile(ScopedFile &file) {
file.WriteFormat(" Number of Modules: %zu\n", this->num_modules);
for (size_t i = 0; i < this->num_modules; i++) {
const auto& module = this->modules[i];
file.WriteFormat(" Number of Modules: %zu\n", m_num_modules);
for (size_t i = 0; i < m_num_modules; i++) {
const auto& module = m_modules[i];
file.WriteFormat(" Module %02zu:\n", i);
file.WriteFormat(" Address: %016lx-%016lx\n", module.start_address, module.end_address);
if (std::strcmp(this->modules[i].name, "") != 0) {
if (std::strcmp(m_modules[i].name, "") != 0) {
file.WriteFormat(" Name: %s\n", module.name);
}
file.DumpMemory(" Build Id: ", module.build_id, sizeof(module.build_id));
@@ -60,7 +60,7 @@ namespace ams::creport {
void ModuleList::FindModulesFromThreadInfo(os::NativeHandle debug_handle, const ThreadInfo &thread) {
/* Set the debug handle, for access in other member functions. */
this->debug_handle = debug_handle;
m_debug_handle = debug_handle;
/* Try to add the thread's PC. */
this->TryAddModule(thread.GetPC());
@@ -82,25 +82,25 @@ namespace ams::creport {
}
/* Check whether we already have this module. */
for (size_t i = 0; i < this->num_modules; i++) {
if (this->modules[i].start_address <= base_address && base_address < this->modules[i].end_address) {
for (size_t i = 0; i < m_num_modules; i++) {
if (m_modules[i].start_address <= base_address && base_address < m_modules[i].end_address) {
return;
}
}
/* Add all contiguous modules. */
uintptr_t cur_address = base_address;
while (this->num_modules < ModuleCountMax) {
while (m_num_modules < ModuleCountMax) {
/* Get the region extents. */
svc::MemoryInfo mi;
svc::PageInfo pi;
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), this->debug_handle, cur_address))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, cur_address))) {
break;
}
/* Parse module. */
if (mi.permission == svc::MemoryPermission_ReadExecute) {
auto& module = this->modules[this->num_modules++];
auto& module = m_modules[m_num_modules++];
module.start_address = mi.base_address;
module.end_address = mi.base_address + mi.size;
GetModuleName(module.name, module.start_address, module.end_address);
@@ -129,20 +129,20 @@ namespace ams::creport {
/* Query the memory region our guess falls in. */
svc::MemoryInfo mi;
svc::PageInfo pi;
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), this->debug_handle, guess))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, guess))) {
return false;
}
/* If we fall into a RW region, it may be rwdata. Query the region before it, which may be rodata or text. */
if (mi.permission == svc::MemoryPermission_ReadWrite) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), debug_handle, mi.base_address - 4))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, mi.base_address - 4))) {
return false;
}
}
/* If we fall into an RO region, it may be rodata. Query the region before it, which should be text. */
if (mi.permission == svc::MemoryPermission_Read) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), debug_handle, mi.base_address - 4))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, mi.base_address - 4))) {
return false;
}
}
@@ -155,7 +155,7 @@ namespace ams::creport {
/* Modules are a series of contiguous (text/rodata/rwdata) regions. */
/* Iterate backwards until we find unmapped memory, to find the start of the set of modules loaded here. */
while (mi.base_address > 0) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), debug_handle, mi.base_address - 4))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, mi.base_address - 4))) {
return false;
}
@@ -181,7 +181,7 @@ namespace ams::creport {
svc::PageInfo pi;
/* Verify .rodata is read-only. */
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), this->debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
return;
}
@@ -189,7 +189,7 @@ namespace ams::creport {
const u64 rw_start_address = mi.base_address + mi.size;
/* Read start of .rodata. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(rodata_start)), this->debug_handle, ro_start_address, sizeof(rodata_start)))) {
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(rodata_start)), m_debug_handle, ro_start_address, sizeof(rodata_start)))) {
return;
}
@@ -228,13 +228,13 @@ namespace ams::creport {
/* Verify .rodata is read-only. */
svc::MemoryInfo mi;
svc::PageInfo pi;
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), this->debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), m_debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
return;
}
/* We want to read the last two pages of .rodata. */
const size_t read_size = mi.size >= sizeof(g_last_rodata_pages) ? sizeof(g_last_rodata_pages) : (sizeof(g_last_rodata_pages) / 2);
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(g_last_rodata_pages), this->debug_handle, mi.base_address + mi.size - read_size, read_size))) {
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(g_last_rodata_pages), m_debug_handle, mi.base_address + mi.size - read_size, read_size))) {
return;
}
@@ -249,18 +249,18 @@ namespace ams::creport {
const char *ModuleList::GetFormattedAddressString(uintptr_t address) {
/* Print default formatted string. */
util::SNPrintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx", address);
util::SNPrintf(m_address_str_buf, sizeof(m_address_str_buf), "%016lx", address);
/* See if the address is inside a module, for pretty-printing. */
for (size_t i = 0; i < this->num_modules; i++) {
const auto& module = this->modules[i];
for (size_t i = 0; i < m_num_modules; i++) {
const auto& module = m_modules[i];
if (module.start_address <= address && address < module.end_address) {
util::SNPrintf(this->address_str_buf, sizeof(this->address_str_buf), "%016lx (%s + 0x%lx)", address, module.name, address - module.start_address);
util::SNPrintf(m_address_str_buf, sizeof(m_address_str_buf), "%016lx (%s + 0x%lx)", address, module.name, address - module.start_address);
break;
}
}
return this->address_str_buf;
return m_address_str_buf;
}
}

View File

@@ -32,23 +32,23 @@ namespace ams::creport {
u64 end_address;
};
private:
os::NativeHandle debug_handle;
size_t num_modules;
ModuleInfo modules[ModuleCountMax];
os::NativeHandle m_debug_handle;
size_t m_num_modules;
ModuleInfo m_modules[ModuleCountMax];
/* For pretty-printing. */
char address_str_buf[0x280];
char m_address_str_buf[0x280];
public:
ModuleList() : debug_handle(os::InvalidNativeHandle), num_modules(0) {
std::memset(this->modules, 0, sizeof(this->modules));
ModuleList() : m_debug_handle(os::InvalidNativeHandle), m_num_modules(0) {
std::memset(m_modules, 0, sizeof(m_modules));
}
size_t GetModuleCount() const {
return this->num_modules;
return m_num_modules;
}
u64 GetModuleStartAddress(size_t i) const {
return this->modules[i].start_address;
return m_modules[i].start_address;
}
void FindModulesFromThreadInfo(os::NativeHandle debug_handle, const ThreadInfo &thread);

View File

@@ -90,8 +90,8 @@ namespace ams::creport {
}
/* Advance, if we write successfully. */
if (R_SUCCEEDED(fs::WriteFile(this->file, this->offset, data, size, fs::WriteOption::Flush))) {
this->offset += size;
if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::Flush))) {
m_offset += size;
}
}

View File

@@ -22,24 +22,24 @@ namespace ams::creport {
NON_COPYABLE(ScopedFile);
NON_MOVEABLE(ScopedFile);
private:
fs::FileHandle file;
s64 offset;
bool opened;
fs::FileHandle m_file;
s64 m_offset;
bool m_opened;
public:
ScopedFile(const char *path) : file(), offset(), opened(false) {
ScopedFile(const char *path) : m_file(), m_offset(), m_opened(false) {
if (R_SUCCEEDED(fs::CreateFile(path, 0))) {
this->opened = R_SUCCEEDED(fs::OpenFile(std::addressof(this->file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
m_opened = R_SUCCEEDED(fs::OpenFile(std::addressof(m_file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
}
}
~ScopedFile() {
if (this->opened) {
fs::CloseFile(file);
if (m_opened) {
fs::CloseFile(m_file);
}
}
bool IsOpen() const {
return this->opened;
return m_opened;
}
void WriteString(const char *str);

View File

@@ -61,67 +61,67 @@ namespace ams::creport {
}
void ThreadList::SaveToFile(ScopedFile &file) {
file.WriteFormat("Number of Threads: %02zu\n", this->thread_count);
for (size_t i = 0; i < this->thread_count; i++) {
file.WriteFormat("Number of Threads: %02zu\n", m_thread_count);
for (size_t i = 0; i < m_thread_count; i++) {
file.WriteFormat("Threads[%02zu]:\n", i);
this->threads[i].SaveToFile(file);
m_threads[i].SaveToFile(file);
}
}
void ThreadInfo::SaveToFile(ScopedFile &file) {
file.WriteFormat(" Thread ID: %016lx\n", this->thread_id);
if (std::strcmp(this->name, "") != 0) {
file.WriteFormat(" Thread Name: %s\n", this->name);
file.WriteFormat(" Thread ID: %016lx\n", m_thread_id);
if (std::strcmp(m_name, "") != 0) {
file.WriteFormat(" Thread Name: %s\n", m_name);
}
if (this->stack_top != 0) {
file.WriteFormat(" Stack Region: %016lx-%016lx\n", this->stack_bottom, this->stack_top);
if (m_stack_top != 0) {
file.WriteFormat(" Stack Region: %016lx-%016lx\n", m_stack_bottom, m_stack_top);
}
file.WriteFormat(" Registers:\n");
{
for (unsigned int i = 0; i <= 28; i++) {
file.WriteFormat(" X[%02u]: %s\n", i, this->module_list->GetFormattedAddressString(this->context.r[i]));
file.WriteFormat(" X[%02u]: %s\n", i, m_module_list->GetFormattedAddressString(m_context.r[i]));
}
file.WriteFormat(" FP: %s\n", this->module_list->GetFormattedAddressString(this->context.fp));
file.WriteFormat(" LR: %s\n", this->module_list->GetFormattedAddressString(this->context.lr));
file.WriteFormat(" SP: %s\n", this->module_list->GetFormattedAddressString(this->context.sp));
file.WriteFormat(" PC: %s\n", this->module_list->GetFormattedAddressString(this->context.pc));
file.WriteFormat(" FP: %s\n", m_module_list->GetFormattedAddressString(m_context.fp));
file.WriteFormat(" LR: %s\n", m_module_list->GetFormattedAddressString(m_context.lr));
file.WriteFormat(" SP: %s\n", m_module_list->GetFormattedAddressString(m_context.sp));
file.WriteFormat(" PC: %s\n", m_module_list->GetFormattedAddressString(m_context.pc));
}
if (this->stack_trace_size != 0) {
if (m_stack_trace_size != 0) {
file.WriteFormat(" Stack Trace:\n");
for (size_t i = 0; i < this->stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02zu]: %s\n", i, this->module_list->GetFormattedAddressString(this->stack_trace[i]));
for (size_t i = 0; i < m_stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02zu]: %s\n", i, m_module_list->GetFormattedAddressString(m_stack_trace[i]));
}
}
if (this->stack_dump_base != 0) {
if (m_stack_dump_base != 0) {
file.WriteFormat(" Stack Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
for (size_t i = 0; i < 0x10; i++) {
const size_t ofs = i * 0x10;
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
this->stack_dump_base + ofs, this->stack_dump[ofs + 0], this->stack_dump[ofs + 1], this->stack_dump[ofs + 2], this->stack_dump[ofs + 3], this->stack_dump[ofs + 4], this->stack_dump[ofs + 5], this->stack_dump[ofs + 6], this->stack_dump[ofs + 7],
this->stack_dump[ofs + 8], this->stack_dump[ofs + 9], this->stack_dump[ofs + 10], this->stack_dump[ofs + 11], this->stack_dump[ofs + 12], this->stack_dump[ofs + 13], this->stack_dump[ofs + 14], this->stack_dump[ofs + 15]);
m_stack_dump_base + ofs, m_stack_dump[ofs + 0], m_stack_dump[ofs + 1], m_stack_dump[ofs + 2], m_stack_dump[ofs + 3], m_stack_dump[ofs + 4], m_stack_dump[ofs + 5], m_stack_dump[ofs + 6], m_stack_dump[ofs + 7],
m_stack_dump[ofs + 8], m_stack_dump[ofs + 9], m_stack_dump[ofs + 10], m_stack_dump[ofs + 11], m_stack_dump[ofs + 12], m_stack_dump[ofs + 13], m_stack_dump[ofs + 14], m_stack_dump[ofs + 15]);
}
}
if (this->tls_address != 0) {
file.WriteFormat(" TLS Address: %016lx\n", this->tls_address);
if (m_tls_address != 0) {
file.WriteFormat(" TLS Address: %016lx\n", m_tls_address);
file.WriteFormat(" TLS Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
for (size_t i = 0; i < 0x10; i++) {
const size_t ofs = i * 0x10;
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
this->tls_address + ofs, this->tls[ofs + 0], this->tls[ofs + 1], this->tls[ofs + 2], this->tls[ofs + 3], this->tls[ofs + 4], this->tls[ofs + 5], this->tls[ofs + 6], this->tls[ofs + 7],
this->tls[ofs + 8], this->tls[ofs + 9], this->tls[ofs + 10], this->tls[ofs + 11], this->tls[ofs + 12], this->tls[ofs + 13], this->tls[ofs + 14], this->tls[ofs + 15]);
m_tls_address + ofs, m_tls[ofs + 0], m_tls[ofs + 1], m_tls[ofs + 2], m_tls[ofs + 3], m_tls[ofs + 4], m_tls[ofs + 5], m_tls[ofs + 6], m_tls[ofs + 7],
m_tls[ofs + 8], m_tls[ofs + 9], m_tls[ofs + 10], m_tls[ofs + 11], m_tls[ofs + 12], m_tls[ofs + 13], m_tls[ofs + 14], m_tls[ofs + 15]);
}
}
}
bool ThreadInfo::ReadFromProcess(os::NativeHandle debug_handle, ThreadTlsMap &tls_map, u64 thread_id, bool is_64_bit) {
/* Set thread id. */
this->thread_id = thread_id;
m_thread_id = thread_id;
/* Verify that the thread is running or waiting. */
{
u64 _;
u32 _thread_state;
if (R_FAILED(svc::GetDebugThreadParam(&_, &_thread_state, debug_handle, this->thread_id, svc::DebugThreadParam_State))) {
if (R_FAILED(svc::GetDebugThreadParam(&_, &_thread_state, debug_handle, m_thread_id, svc::DebugThreadParam_State))) {
return false;
}
@@ -132,24 +132,24 @@ namespace ams::creport {
}
/* Get the thread context. */
if (R_FAILED(svc::GetDebugThreadContext(std::addressof(this->context), debug_handle, this->thread_id, svc::ThreadContextFlag_All))) {
if (R_FAILED(svc::GetDebugThreadContext(std::addressof(m_context), debug_handle, m_thread_id, svc::ThreadContextFlag_All))) {
return false;
}
/* In aarch32 mode svc::GetDebugThreadContext does not set the LR, FP, and SP registers correctly. */
if (!is_64_bit) {
this->context.fp = this->context.r[11];
this->context.sp = this->context.r[13];
this->context.lr = this->context.r[14];
m_context.fp = m_context.r[11];
m_context.sp = m_context.r[13];
m_context.lr = m_context.r[14];
}
/* Read TLS, if present. */
/* TODO: struct definitions for nnSdk's ThreadType/TLS Layout? */
this->tls_address = 0;
if (tls_map.GetThreadTls(std::addressof(this->tls_address), thread_id)) {
m_tls_address = 0;
if (tls_map.GetThreadTls(std::addressof(m_tls_address), thread_id)) {
u8 thread_tls[sizeof(svc::ThreadLocalRegion)];
if (R_SUCCEEDED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(thread_tls), debug_handle, this->tls_address, sizeof(thread_tls)))) {
std::memcpy(this->tls, thread_tls, sizeof(this->tls));
if (R_SUCCEEDED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(thread_tls), debug_handle, m_tls_address, sizeof(thread_tls)))) {
std::memcpy(m_tls, thread_tls, sizeof(m_tls));
/* Try to detect libnx threads, and skip name parsing then. */
if (*(reinterpret_cast<u32 *>(std::addressof(thread_tls[0x1E0]))) != LibnxThreadVarMagic) {
u8 thread_type[0x1C0];
@@ -161,12 +161,12 @@ namespace ams::creport {
/* Check thread name is actually at thread name. */
static_assert(0x1A8 - 0x188 == NameLengthMax, "NameLengthMax definition!");
if (*(reinterpret_cast<u64 *>(std::addressof(thread_type[0x1A8]))) == thread_type_addr + 0x188) {
std::memcpy(this->name, thread_type + 0x188, NameLengthMax);
std::memcpy(m_name, thread_type + 0x188, NameLengthMax);
}
} else if (thread_version == 1) {
static_assert(0x1A0 - 0x180 == NameLengthMax, "NameLengthMax definition!");
if (*(reinterpret_cast<u64 *>(std::addressof(thread_type[0x1A0]))) == thread_type_addr + 0x180) {
std::memcpy(this->name, thread_type + 0x180, NameLengthMax);
std::memcpy(m_name, thread_type + 0x180, NameLengthMax);
}
}
}
@@ -179,9 +179,9 @@ namespace ams::creport {
/* Dump stack trace. */
if (is_64_bit) {
ReadStackTrace<u64>(std::addressof(this->stack_trace_size), this->stack_trace, StackTraceSizeMax, debug_handle, this->context.fp);
ReadStackTrace<u64>(std::addressof(m_stack_trace_size), m_stack_trace, StackTraceSizeMax, debug_handle, m_context.fp);
} else {
ReadStackTrace<u32>(std::addressof(this->stack_trace_size), this->stack_trace, StackTraceSizeMax, debug_handle, this->context.fp);
ReadStackTrace<u32>(std::addressof(m_stack_trace_size), m_stack_trace, StackTraceSizeMax, debug_handle, m_context.fp);
}
return true;
@@ -191,7 +191,7 @@ namespace ams::creport {
/* Query stack region. */
svc::MemoryInfo mi;
svc::PageInfo pi;
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), debug_handle, this->context.sp))) {
if (R_FAILED(svc::QueryDebugProcessMemory(std::addressof(mi), std::addressof(pi), debug_handle, m_context.sp))) {
return;
}
@@ -204,56 +204,56 @@ namespace ams::creport {
}
/* Save stack extents. */
this->stack_bottom = mi.base_address;
this->stack_top = mi.base_address + mi.size;
m_stack_bottom = mi.base_address;
m_stack_top = mi.base_address + mi.size;
/* We always want to dump 0x100 of stack, starting from the lowest 0x10-byte aligned address below the stack pointer. */
/* Note: if the stack pointer is below the stack bottom, we will start dumping from the stack bottom. */
this->stack_dump_base = std::min(std::max(this->context.sp & ~0xFul, this->stack_bottom), this->stack_top - sizeof(this->stack_dump));
m_stack_dump_base = std::min(std::max(m_context.sp & ~0xFul, m_stack_bottom), m_stack_top - sizeof(m_stack_dump));
/* Try to read stack. */
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(this->stack_dump), debug_handle, this->stack_dump_base, sizeof(this->stack_dump)))) {
this->stack_dump_base = 0;
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(m_stack_dump), debug_handle, m_stack_dump_base, sizeof(m_stack_dump)))) {
m_stack_dump_base = 0;
}
}
void ThreadInfo::DumpBinary(ScopedFile &file) {
/* Dump id and context. */
file.Write(std::addressof(this->thread_id), sizeof(this->thread_id));
file.Write(std::addressof(this->context), sizeof(this->context));
file.Write(std::addressof(m_thread_id), sizeof(m_thread_id));
file.Write(std::addressof(m_context), sizeof(m_context));
/* Dump TLS info and name. */
file.Write(std::addressof(this->tls_address), sizeof(this->tls_address));
file.Write(std::addressof(this->tls), sizeof(this->tls));
file.Write(std::addressof(this->name), sizeof(this->name));
file.Write(std::addressof(m_tls_address), sizeof(m_tls_address));
file.Write(std::addressof(m_tls), sizeof(m_tls));
file.Write(std::addressof(m_name), sizeof(m_name));
/* Dump stack extents and stack dump. */
file.Write(std::addressof(this->stack_bottom), sizeof(this->stack_bottom));
file.Write(std::addressof(this->stack_top), sizeof(this->stack_top));
file.Write(std::addressof(this->stack_dump_base), sizeof(this->stack_dump_base));
file.Write(std::addressof(this->stack_dump), sizeof(this->stack_dump));
file.Write(std::addressof(m_stack_bottom), sizeof(m_stack_bottom));
file.Write(std::addressof(m_stack_top), sizeof(m_stack_top));
file.Write(std::addressof(m_stack_dump_base), sizeof(m_stack_dump_base));
file.Write(std::addressof(m_stack_dump), sizeof(m_stack_dump));
/* Dump stack trace. */
{
const u64 sts = this->stack_trace_size;
const u64 sts = m_stack_trace_size;
file.Write(std::addressof(sts), sizeof(sts));
}
file.Write(this->stack_trace, this->stack_trace_size);
file.Write(m_stack_trace, m_stack_trace_size);
}
void ThreadList::DumpBinary(ScopedFile &file, u64 crashed_thread_id) {
const u32 magic = DumpedThreadInfoMagic;
const u32 count = this->thread_count;
const u32 count = m_thread_count;
file.Write(std::addressof(magic), sizeof(magic));
file.Write(std::addressof(count), sizeof(count));
file.Write(std::addressof(crashed_thread_id), sizeof(crashed_thread_id));
for (size_t i = 0; i < this->thread_count; i++) {
this->threads[i].DumpBinary(file);
for (size_t i = 0; i < m_thread_count; i++) {
m_threads[i].DumpBinary(file);
}
}
void ThreadList::ReadFromProcess(os::NativeHandle debug_handle, ThreadTlsMap &tls_map, bool is_64_bit) {
this->thread_count = 0;
m_thread_count = 0;
/* Get thread list. */
s32 num_threads;
@@ -267,8 +267,8 @@ namespace ams::creport {
/* Parse thread infos. */
for (s32 i = 0; i < num_threads; i++) {
if (this->threads[this->thread_count].ReadFromProcess(debug_handle, tls_map, thread_ids[i], is_64_bit)) {
this->thread_count++;
if (m_threads[m_thread_count].ReadFromProcess(debug_handle, tls_map, thread_ids[i], is_64_bit)) {
m_thread_count++;
}
}
}

View File

@@ -60,53 +60,53 @@ namespace ams::creport {
static constexpr size_t StackTraceSizeMax = 0x20;
static constexpr size_t NameLengthMax = 0x20;
private:
svc::ThreadContext context = {};
u64 thread_id = 0;
u64 stack_top = 0;
u64 stack_bottom = 0;
u64 stack_trace[StackTraceSizeMax] = {};
size_t stack_trace_size = 0;
u64 tls_address = 0;
u8 tls[0x100] = {};
u64 stack_dump_base = 0;
u8 stack_dump[0x100] = {};
char name[NameLengthMax + 1] = {};
ModuleList *module_list = nullptr;
svc::ThreadContext m_context = {};
u64 m_thread_id = 0;
u64 m_stack_top = 0;
u64 m_stack_bottom = 0;
u64 m_stack_trace[StackTraceSizeMax] = {};
size_t m_stack_trace_size = 0;
u64 m_tls_address = 0;
u8 m_tls[0x100] = {};
u64 m_stack_dump_base = 0;
u8 m_stack_dump[0x100] = {};
char m_name[NameLengthMax + 1] = {};
ModuleList *m_module_list = nullptr;
public:
u64 GetGeneralPurposeRegister(size_t i) const {
return this->context.r[i];
return m_context.r[i];
}
u64 GetPC() const {
return this->context.pc;
return m_context.pc;
}
u64 GetLR() const {
return this->context.lr;
return m_context.lr;
}
u64 GetFP() const {
return this->context.fp;
return m_context.fp;
}
u64 GetSP() const {
return this->context.sp;
return m_context.sp;
}
u64 GetThreadId() const {
return this->thread_id;
return m_thread_id;
}
size_t GetStackTraceSize() const {
return this->stack_trace_size;
return m_stack_trace_size;
}
u64 GetStackTrace(size_t i) const {
return this->stack_trace[i];
return m_stack_trace[i];
}
void SetModuleList(ModuleList *ml) {
this->module_list = ml;
m_module_list = ml;
}
bool ReadFromProcess(os::NativeHandle debug_handle, ThreadTlsMap &tls_map, u64 thread_id, bool is_64_bit);
@@ -118,20 +118,20 @@ namespace ams::creport {
class ThreadList {
private:
size_t thread_count = 0;
ThreadInfo threads[ThreadCountMax];
size_t m_thread_count = 0;
ThreadInfo m_threads[ThreadCountMax];
public:
size_t GetThreadCount() const {
return this->thread_count;
return m_thread_count;
}
const ThreadInfo &GetThreadInfo(size_t i) const {
return this->threads[i];
return m_threads[i];
}
void SetModuleList(ModuleList *ml) {
for (size_t i = 0; i < this->thread_count; i++) {
this->threads[i].SetModuleList(ml);
for (size_t i = 0; i < m_thread_count; i++) {
m_threads[i].SetModuleList(ml);
}
}

View File

@@ -83,28 +83,28 @@ namespace ams::dmnt::cheat::impl {
private:
static constexpr size_t ThreadStackSize = 0x4000;
private:
os::SdkMutex cheat_lock;
os::Event unsafe_break_event;
os::Event debug_events_event; /* Autoclear. */
os::ThreadType detect_thread, debug_events_thread;
os::SystemEvent cheat_process_event;
os::NativeHandle cheat_process_debug_handle = os::InvalidNativeHandle;
CheatProcessMetadata cheat_process_metadata = {};
os::SdkMutex m_cheat_lock;
os::Event m_unsafe_break_event;
os::Event m_debug_events_event; /* Autoclear. */
os::ThreadType m_detect_thread, m_debug_events_thread;
os::SystemEvent m_cheat_process_event;
os::NativeHandle m_cheat_process_debug_handle = os::InvalidNativeHandle;
CheatProcessMetadata m_cheat_process_metadata = {};
os::ThreadType vm_thread;
bool broken_unsafe = false;
bool needs_reload_vm = false;
CheatVirtualMachine cheat_vm;
os::ThreadType m_vm_thread;
bool m_broken_unsafe = false;
bool m_needs_reload_vm = false;
CheatVirtualMachine m_cheat_vm;
bool enable_cheats_by_default = true;
bool always_save_cheat_toggles = false;
bool should_save_cheat_toggles = false;
CheatEntry cheat_entries[MaxCheatCount] = {};
FrozenAddressMap frozen_addresses_map = {};
bool m_enable_cheats_by_default = true;
bool m_always_save_cheat_toggles = false;
bool m_should_save_cheat_toggles = false;
CheatEntry m_cheat_entries[MaxCheatCount] = {};
FrozenAddressMap m_frozen_addresses_map = {};
alignas(os::MemoryPageSize) u8 detect_thread_stack[ThreadStackSize] = {};
alignas(os::MemoryPageSize) u8 debug_events_thread_stack[ThreadStackSize] = {};
alignas(os::MemoryPageSize) u8 vm_thread_stack[ThreadStackSize] = {};
alignas(os::MemoryPageSize) u8 m_detect_thread_stack[ThreadStackSize] = {};
alignas(os::MemoryPageSize) u8 m_debug_events_thread_stack[ThreadStackSize] = {};
alignas(os::MemoryPageSize) u8 m_vm_thread_stack[ThreadStackSize] = {};
private:
static void DetectLaunchThread(void *_this);
static void VirtualMachineThread(void *_this);
@@ -119,18 +119,18 @@ namespace ams::dmnt::cheat::impl {
void SaveCheatToggles(const ncm::ProgramId program_id);
bool GetNeedsReloadVm() const {
return this->needs_reload_vm;
return m_needs_reload_vm;
}
void SetNeedsReloadVm(bool reload) {
this->needs_reload_vm = reload;
m_needs_reload_vm = reload;
}
void ResetCheatEntry(size_t i) {
if (i < MaxCheatCount) {
std::memset(this->cheat_entries + i, 0, sizeof(this->cheat_entries[i]));
this->cheat_entries[i].cheat_id = i;
std::memset(m_cheat_entries + i, 0, sizeof(m_cheat_entries[i]));
m_cheat_entries[i].cheat_id = i;
this->SetNeedsReloadVm(true);
}
@@ -141,12 +141,12 @@ namespace ams::dmnt::cheat::impl {
this->ResetCheatEntry(i);
}
this->cheat_vm.ResetStaticRegisters();
m_cheat_vm.ResetStaticRegisters();
}
CheatEntry *GetCheatEntryById(size_t i) {
if (i < MaxCheatCount) {
return this->cheat_entries + i;
return m_cheat_entries + i;
}
return nullptr;
@@ -155,8 +155,8 @@ namespace ams::dmnt::cheat::impl {
CheatEntry *GetCheatEntryByReadableName(const char *readable_name) {
/* Check all non-master cheats for match. */
for (size_t i = 1; i < MaxCheatCount; i++) {
if (std::strncmp(this->cheat_entries[i].definition.readable_name, readable_name, sizeof(this->cheat_entries[i].definition.readable_name)) == 0) {
return this->cheat_entries + i;
if (std::strncmp(m_cheat_entries[i].definition.readable_name, readable_name, sizeof(m_cheat_entries[i].definition.readable_name)) == 0) {
return m_cheat_entries + i;
}
}
@@ -166,8 +166,8 @@ namespace ams::dmnt::cheat::impl {
CheatEntry *GetFreeCheatEntry() {
/* Check all non-master cheats for availability. */
for (size_t i = 1; i < MaxCheatCount; i++) {
if (this->cheat_entries[i].definition.num_opcodes == 0) {
return this->cheat_entries + i;
if (m_cheat_entries[i].definition.num_opcodes == 0) {
return m_cheat_entries + i;
}
}
@@ -175,53 +175,53 @@ namespace ams::dmnt::cheat::impl {
}
void CloseActiveCheatProcess() {
if (this->cheat_process_debug_handle != os::InvalidNativeHandle) {
if (m_cheat_process_debug_handle != os::InvalidNativeHandle) {
/* We don't need to do any unsafe brekaing. */
this->broken_unsafe = false;
this->unsafe_break_event.Signal();
m_broken_unsafe = false;
m_unsafe_break_event.Signal();
/* Knock out the debug events thread. */
os::CancelThreadSynchronization(std::addressof(this->debug_events_thread));
os::CancelThreadSynchronization(std::addressof(m_debug_events_thread));
/* Close resources. */
R_ABORT_UNLESS(svc::CloseHandle(this->cheat_process_debug_handle));
this->cheat_process_debug_handle = os::InvalidNativeHandle;
R_ABORT_UNLESS(svc::CloseHandle(m_cheat_process_debug_handle));
m_cheat_process_debug_handle = os::InvalidNativeHandle;
/* Save cheat toggles. */
if (this->always_save_cheat_toggles || this->should_save_cheat_toggles) {
this->SaveCheatToggles(this->cheat_process_metadata.program_id);
this->should_save_cheat_toggles = false;
if (m_always_save_cheat_toggles || m_should_save_cheat_toggles) {
this->SaveCheatToggles(m_cheat_process_metadata.program_id);
m_should_save_cheat_toggles = false;
}
/* Clear metadata. */
static_assert(util::is_pod<decltype(this->cheat_process_metadata)>::value, "CheatProcessMetadata definition!");
std::memset(std::addressof(this->cheat_process_metadata), 0, sizeof(this->cheat_process_metadata));
static_assert(util::is_pod<decltype(m_cheat_process_metadata)>::value, "CheatProcessMetadata definition!");
std::memset(std::addressof(m_cheat_process_metadata), 0, sizeof(m_cheat_process_metadata));
/* Clear cheat list. */
this->ResetAllCheatEntries();
/* Clear frozen addresses. */
{
auto it = this->frozen_addresses_map.begin();
while (it != this->frozen_addresses_map.end()) {
auto it = m_frozen_addresses_map.begin();
while (it != m_frozen_addresses_map.end()) {
FrozenAddressMapEntry *entry = std::addressof(*it);
it = this->frozen_addresses_map.erase(it);
it = m_frozen_addresses_map.erase(it);
DeallocateFrozenAddress(entry);
}
}
/* Signal to our fans. */
this->cheat_process_event.Signal();
m_cheat_process_event.Signal();
}
}
bool HasActiveCheatProcess() {
/* Note: This function *MUST* be called only with the cheat lock held. */
os::ProcessId pid;
bool has_cheat_process = this->cheat_process_debug_handle != os::InvalidNativeHandle;
has_cheat_process &= R_SUCCEEDED(os::GetProcessId(std::addressof(pid), this->cheat_process_debug_handle));
bool has_cheat_process = m_cheat_process_debug_handle != os::InvalidNativeHandle;
has_cheat_process &= R_SUCCEEDED(os::GetProcessId(std::addressof(pid), m_cheat_process_debug_handle));
has_cheat_process &= R_SUCCEEDED(pm::dmnt::GetApplicationProcessId(std::addressof(pid)));
has_cheat_process &= (pid == this->cheat_process_metadata.process_id);
has_cheat_process &= (pid == m_cheat_process_metadata.process_id);
if (!has_cheat_process) {
this->CloseActiveCheatProcess();
@@ -236,7 +236,7 @@ namespace ams::dmnt::cheat::impl {
}
os::NativeHandle GetCheatProcessHandle() const {
return this->cheat_process_debug_handle;
return m_cheat_process_debug_handle;
}
os::NativeHandle HookToCreateApplicationProcess() const {
@@ -250,50 +250,50 @@ namespace ams::dmnt::cheat::impl {
}
public:
CheatProcessManager() : cheat_lock(), unsafe_break_event(os::EventClearMode_ManualClear), debug_events_event(os::EventClearMode_AutoClear), cheat_process_event(os::EventClearMode_AutoClear, true) {
CheatProcessManager() : m_cheat_lock(), m_unsafe_break_event(os::EventClearMode_ManualClear), m_debug_events_event(os::EventClearMode_AutoClear), m_cheat_process_event(os::EventClearMode_AutoClear, true) {
/* Learn whether we should enable cheats by default. */
{
u8 en = 0;
if (settings::fwdbg::GetSettingsItemValue(std::addressof(en), sizeof(en), "atmosphere", "dmnt_cheats_enabled_by_default") == sizeof(en)) {
this->enable_cheats_by_default = (en != 0);
m_enable_cheats_by_default = (en != 0);
}
en = 0;
if (settings::fwdbg::GetSettingsItemValue( std::addressof(en), sizeof(en), "atmosphere", "dmnt_always_save_cheat_toggles") == sizeof(en)) {
this->always_save_cheat_toggles = (en != 0);
m_always_save_cheat_toggles = (en != 0);
}
}
/* Spawn application detection thread, spawn cheat vm thread. */
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->detect_thread), DetectLaunchThread, this, this->detect_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatDetect)));
os::SetThreadNamePointer(std::addressof(this->detect_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatDetect));
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->vm_thread), VirtualMachineThread, this, this->vm_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatVirtualMachine)));
os::SetThreadNamePointer(std::addressof(this->vm_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatVirtualMachine));
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->debug_events_thread), DebugEventsThread, this, this->debug_events_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatDebugEvents)));
os::SetThreadNamePointer(std::addressof(this->debug_events_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatDebugEvents));
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_detect_thread), DetectLaunchThread, this, m_detect_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatDetect)));
os::SetThreadNamePointer(std::addressof(m_detect_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatDetect));
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_vm_thread), VirtualMachineThread, this, m_vm_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatVirtualMachine)));
os::SetThreadNamePointer(std::addressof(m_vm_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatVirtualMachine));
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_debug_events_thread), DebugEventsThread, this, m_debug_events_thread_stack, ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, CheatDebugEvents)));
os::SetThreadNamePointer(std::addressof(m_debug_events_thread), AMS_GET_SYSTEM_THREAD_NAME(dmnt, CheatDebugEvents));
/* Start threads. */
os::StartThread(std::addressof(this->detect_thread));
os::StartThread(std::addressof(this->vm_thread));
os::StartThread(std::addressof(this->debug_events_thread));
os::StartThread(std::addressof(m_detect_thread));
os::StartThread(std::addressof(m_vm_thread));
os::StartThread(std::addressof(m_debug_events_thread));
}
bool GetHasActiveCheatProcess() {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
return this->HasActiveCheatProcess();
}
os::NativeHandle GetCheatProcessEventHandle() const {
return this->cheat_process_event.GetReadableHandle();
return m_cheat_process_event.GetReadableHandle();
}
Result GetCheatProcessMetadata(CheatProcessMetadata *out) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
std::memcpy(out, std::addressof(this->cheat_process_metadata), sizeof(*out));
std::memcpy(out, std::addressof(m_cheat_process_metadata), sizeof(*out));
return ResultSuccess();
}
@@ -313,7 +313,7 @@ namespace ams::dmnt::cheat::impl {
Result WriteCheatProcessMemoryUnsafe(u64 proc_addr, const void *data, size_t size) {
R_TRY(svc::WriteDebugProcessMemory(this->GetCheatProcessHandle(), reinterpret_cast<uintptr_t>(data), proc_addr, size));
for (auto &entry : this->frozen_addresses_map) {
for (auto &entry : m_frozen_addresses_map) {
/* Get address/value. */
const u64 address = entry.GetAddress();
auto &value = entry.GetValue();
@@ -335,20 +335,20 @@ namespace ams::dmnt::cheat::impl {
}
Result PauseCheatProcessUnsafe() {
this->broken_unsafe = true;
this->unsafe_break_event.Clear();
m_broken_unsafe = true;
m_unsafe_break_event.Clear();
return svc::BreakDebugProcess(this->GetCheatProcessHandle());
}
Result ResumeCheatProcessUnsafe() {
this->broken_unsafe = false;
this->unsafe_break_event.Signal();
m_broken_unsafe = false;
m_unsafe_break_event.Signal();
dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle());
return ResultSuccess();
}
Result GetCheatProcessMappingCount(u64 *out_count) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -372,7 +372,7 @@ namespace ams::dmnt::cheat::impl {
}
Result GetCheatProcessMappings(svc::MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -399,7 +399,7 @@ namespace ams::dmnt::cheat::impl {
}
Result ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -407,7 +407,7 @@ namespace ams::dmnt::cheat::impl {
}
Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -415,7 +415,7 @@ namespace ams::dmnt::cheat::impl {
}
Result QueryCheatProcessMemory(svc::MemoryInfo *mapping, u64 address) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -424,7 +424,7 @@ namespace ams::dmnt::cheat::impl {
}
Result PauseCheatProcess() {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -432,7 +432,7 @@ namespace ams::dmnt::cheat::impl {
}
Result ResumeCheatProcess() {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -440,13 +440,13 @@ namespace ams::dmnt::cheat::impl {
}
Result GetCheatCount(u64 *out_count) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
size_t count = 0;
for (size_t i = 0; i < MaxCheatCount; i++) {
if (this->cheat_entries[i].definition.num_opcodes) {
if (m_cheat_entries[i].definition.num_opcodes) {
count++;
}
}
@@ -456,16 +456,16 @@ namespace ams::dmnt::cheat::impl {
}
Result GetCheats(CheatEntry *out_cheats, size_t max_count, u64 *out_count, u64 offset) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
size_t count = 0, total_count = 0;
for (size_t i = 0; i < MaxCheatCount && count < max_count; i++) {
if (this->cheat_entries[i].definition.num_opcodes) {
if (m_cheat_entries[i].definition.num_opcodes) {
total_count++;
if (total_count > offset) {
out_cheats[count++] = this->cheat_entries[i];
out_cheats[count++] = m_cheat_entries[i];
}
}
}
@@ -475,7 +475,7 @@ namespace ams::dmnt::cheat::impl {
}
Result GetCheatById(CheatEntry *out_cheat, u32 cheat_id) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -488,7 +488,7 @@ namespace ams::dmnt::cheat::impl {
}
Result ToggleCheat(u32 cheat_id) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -507,7 +507,7 @@ namespace ams::dmnt::cheat::impl {
}
Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
@@ -530,7 +530,7 @@ namespace ams::dmnt::cheat::impl {
}
Result RemoveCheat(u32 cheat_id) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
R_UNLESS(cheat_id < MaxCheatCount, dmnt::cheat::ResultCheatUnknownId());
@@ -544,14 +544,14 @@ namespace ams::dmnt::cheat::impl {
}
Result SetMasterCheat(const CheatDefinition &def) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
R_UNLESS(def.num_opcodes != 0, dmnt::cheat::ResultCheatInvalid());
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), dmnt::cheat::ResultCheatInvalid());
CheatEntry *master_entry = this->cheat_entries + 0;
CheatEntry *master_entry = m_cheat_entries + 0;
master_entry->enabled = true;
master_entry->definition = def;
@@ -563,50 +563,50 @@ namespace ams::dmnt::cheat::impl {
}
Result ReadStaticRegister(u64 *out, size_t which) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, dmnt::cheat::ResultCheatInvalid());
*out = this->cheat_vm.GetStaticRegister(which);
*out = m_cheat_vm.GetStaticRegister(which);
return ResultSuccess();
}
Result WriteStaticRegister(size_t which, u64 value) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
R_UNLESS(which < CheatVirtualMachine::NumStaticRegisters, dmnt::cheat::ResultCheatInvalid());
this->cheat_vm.SetStaticRegister(which, value);
m_cheat_vm.SetStaticRegister(which, value);
return ResultSuccess();
}
Result ResetStaticRegisters() {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
this->cheat_vm.ResetStaticRegisters();
m_cheat_vm.ResetStaticRegisters();
return ResultSuccess();
}
Result GetFrozenAddressCount(u64 *out_count) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
*out_count = std::distance(this->frozen_addresses_map.begin(), this->frozen_addresses_map.end());
*out_count = std::distance(m_frozen_addresses_map.begin(), m_frozen_addresses_map.end());
return ResultSuccess();
}
Result GetFrozenAddresses(FrozenAddressEntry *frz_addrs, size_t max_count, u64 *out_count, u64 offset) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
u64 total_count = 0, written_count = 0;
for (const auto &entry : this->frozen_addresses_map) {
for (const auto &entry : m_frozen_addresses_map) {
if (written_count >= max_count) {
break;
}
@@ -624,12 +624,12 @@ namespace ams::dmnt::cheat::impl {
}
Result GetFrozenAddress(FrozenAddressEntry *frz_addr, u64 address) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
const auto it = this->frozen_addresses_map.find_key(address);
R_UNLESS(it != this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
const auto it = m_frozen_addresses_map.find_key(address);
R_UNLESS(it != m_frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
frz_addr->address = it->GetAddress();
frz_addr->value = it->GetValue();
@@ -637,12 +637,12 @@ namespace ams::dmnt::cheat::impl {
}
Result EnableFrozenAddress(u64 *out_value, u64 address, u64 width) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
const auto it = this->frozen_addresses_map.find_key(address);
R_UNLESS(it == this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressAlreadyExists());
const auto it = m_frozen_addresses_map.find_key(address);
R_UNLESS(it == m_frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressAlreadyExists());
FrozenAddressValue value = {};
value.width = width;
@@ -651,21 +651,21 @@ namespace ams::dmnt::cheat::impl {
FrozenAddressMapEntry *entry = AllocateFrozenAddress(address, value);
R_UNLESS(entry != nullptr, dmnt::cheat::ResultFrozenAddressOutOfResource());
this->frozen_addresses_map.insert(*entry);
m_frozen_addresses_map.insert(*entry);
*out_value = value.value;
return ResultSuccess();
}
Result DisableFrozenAddress(u64 address) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
R_TRY(this->EnsureCheatProcess());
const auto it = this->frozen_addresses_map.find_key(address);
R_UNLESS(it != this->frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
const auto it = m_frozen_addresses_map.find_key(address);
R_UNLESS(it != m_frozen_addresses_map.end(), dmnt::cheat::ResultFrozenAddressNotFound());
FrozenAddressMapEntry *entry = std::addressof(*it);
this->frozen_addresses_map.erase(it);
m_frozen_addresses_map.erase(it);
DeallocateFrozenAddress(entry);
return ResultSuccess();
@@ -674,37 +674,37 @@ namespace ams::dmnt::cheat::impl {
};
void CheatProcessManager::DetectLaunchThread(void *_this) {
CheatProcessManager *this_ptr = reinterpret_cast<CheatProcessManager *>(_this);
CheatProcessManager *manager = reinterpret_cast<CheatProcessManager *>(_this);
Event hook;
while (true) {
eventLoadRemote(std::addressof(hook), this_ptr->HookToCreateApplicationProcess(), true);
eventLoadRemote(std::addressof(hook), manager->HookToCreateApplicationProcess(), true);
if (R_SUCCEEDED(eventWait(std::addressof(hook), std::numeric_limits<u64>::max()))) {
this_ptr->AttachToApplicationProcess(true);
manager->AttachToApplicationProcess(true);
}
eventClose(std::addressof(hook));
}
}
void CheatProcessManager::DebugEventsThread(void *_this) {
CheatProcessManager *this_ptr = reinterpret_cast<CheatProcessManager *>(_this);
CheatProcessManager *manager = reinterpret_cast<CheatProcessManager *>(_this);
while (true) {
/* Atomically wait (and clear) signal for new process. */
this_ptr->debug_events_event.Wait();
manager->m_debug_events_event.Wait();
while (true) {
os::NativeHandle cheat_process_handle = this_ptr->GetCheatProcessHandle();
os::NativeHandle cheat_process_handle = manager->GetCheatProcessHandle();
s32 dummy;
while (cheat_process_handle != os::InvalidNativeHandle && R_SUCCEEDED(svc::WaitSynchronization(std::addressof(dummy), std::addressof(cheat_process_handle), 1, std::numeric_limits<u64>::max()))) {
this_ptr->cheat_lock.Lock();
ON_SCOPE_EXIT { this_ptr->cheat_lock.Unlock(); };
manager->m_cheat_lock.Lock();
ON_SCOPE_EXIT { manager->m_cheat_lock.Unlock(); };
{
ON_SCOPE_EXIT { cheat_process_handle = this_ptr->GetCheatProcessHandle(); };
ON_SCOPE_EXIT { cheat_process_handle = manager->GetCheatProcessHandle(); };
/* If we did an unsafe break, wait until we're not broken. */
if (this_ptr->broken_unsafe) {
this_ptr->cheat_lock.Unlock();
this_ptr->unsafe_break_event.Wait();
this_ptr->cheat_lock.Lock();
if (this_ptr->GetCheatProcessHandle() != os::InvalidNativeHandle) {
if (manager->m_broken_unsafe) {
manager->m_cheat_lock.Unlock();
manager->m_unsafe_break_event.Wait();
manager->m_cheat_lock.Lock();
if (manager->GetCheatProcessHandle() != os::InvalidNativeHandle) {
continue;
} else {
break;
@@ -712,10 +712,10 @@ namespace ams::dmnt::cheat::impl {
}
/* Handle any pending debug events. */
if (this_ptr->HasActiveCheatProcess()) {
R_TRY_CATCH(dmnt::cheat::impl::ContinueCheatProcess(this_ptr->GetCheatProcessHandle())) {
if (manager->HasActiveCheatProcess()) {
R_TRY_CATCH(dmnt::cheat::impl::ContinueCheatProcess(manager->GetCheatProcessHandle())) {
R_CATCH(svc::ResultProcessTerminated) {
this_ptr->CloseActiveCheatProcess();
manager->CloseActiveCheatProcess();
break;
}
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
@@ -725,8 +725,8 @@ namespace ams::dmnt::cheat::impl {
/* WaitSynchronization failed. This means someone canceled our synchronization, possibly us. */
/* Let's check if we should quit! */
std::scoped_lock lk(this_ptr->cheat_lock);
if (!this_ptr->HasActiveCheatProcess()) {
std::scoped_lock lk(manager->m_cheat_lock);
if (!manager->HasActiveCheatProcess()) {
break;
}
}
@@ -734,30 +734,30 @@ namespace ams::dmnt::cheat::impl {
}
void CheatProcessManager::VirtualMachineThread(void *_this) {
CheatProcessManager *this_ptr = reinterpret_cast<CheatProcessManager *>(_this);
CheatProcessManager *manager = reinterpret_cast<CheatProcessManager *>(_this);
while (true) {
/* Apply cheats. */
{
std::scoped_lock lk(this_ptr->cheat_lock);
std::scoped_lock lk(manager->m_cheat_lock);
if (this_ptr->HasActiveCheatProcess()) {
if (manager->HasActiveCheatProcess()) {
/* Execute VM. */
if (!this_ptr->GetNeedsReloadVm() || this_ptr->cheat_vm.LoadProgram(this_ptr->cheat_entries, util::size(this_ptr->cheat_entries))) {
this_ptr->SetNeedsReloadVm(false);
if (!manager->GetNeedsReloadVm() || manager->m_cheat_vm.LoadProgram(manager->m_cheat_entries, util::size(manager->m_cheat_entries))) {
manager->SetNeedsReloadVm(false);
/* Execute program only if it has opcodes. */
if (this_ptr->cheat_vm.GetProgramSize()) {
this_ptr->cheat_vm.Execute(std::addressof(this_ptr->cheat_process_metadata));
if (manager->m_cheat_vm.GetProgramSize()) {
manager->m_cheat_vm.Execute(std::addressof(manager->m_cheat_process_metadata));
}
}
/* Apply frozen addresses. */
for (const auto &entry : this_ptr->frozen_addresses_map) {
for (const auto &entry : manager->m_frozen_addresses_map) {
const auto address = entry.GetAddress();
const auto &value = entry.GetValue();
/* Use Write SVC directly, to avoid the usual frozen address update logic. */
svc::WriteDebugProcessMemory(this_ptr->GetCheatProcessHandle(), reinterpret_cast<uintptr_t>(std::addressof(value.value)), address, value.width);
svc::WriteDebugProcessMemory(manager->GetCheatProcessHandle(), reinterpret_cast<uintptr_t>(std::addressof(value.value)), address, value.width);
}
}
}
@@ -778,7 +778,7 @@ namespace ams::dmnt::cheat::impl {
}
Result CheatProcessManager::AttachToApplicationProcess(bool on_process_launch) {
std::scoped_lock lk(this->cheat_lock);
std::scoped_lock lk(m_cheat_lock);
/* Close the active process, if needed. */
{
@@ -792,12 +792,12 @@ namespace ams::dmnt::cheat::impl {
}
/* Get the application process's ID. */
R_ABORT_UNLESS_IF_NEW_PROCESS(pm::dmnt::GetApplicationProcessId(std::addressof(this->cheat_process_metadata.process_id)));
R_ABORT_UNLESS_IF_NEW_PROCESS(pm::dmnt::GetApplicationProcessId(std::addressof(m_cheat_process_metadata.process_id)));
auto proc_guard = SCOPE_GUARD {
if (on_process_launch) {
this->StartProcess(this->cheat_process_metadata.process_id);
this->StartProcess(m_cheat_process_metadata.process_id);
}
this->cheat_process_metadata.process_id = os::ProcessId{};
m_cheat_process_metadata.process_id = os::ProcessId{};
};
/* Get process handle, use it to learn memory extents. */
@@ -806,17 +806,17 @@ namespace ams::dmnt::cheat::impl {
ncm::ProgramLocation loc = {};
cfg::OverrideStatus status = {};
R_ABORT_UNLESS_IF_NEW_PROCESS(pm::dmnt::AtmosphereGetProcessInfo(std::addressof(proc_h), std::addressof(loc), std::addressof(status), this->cheat_process_metadata.process_id));
R_ABORT_UNLESS_IF_NEW_PROCESS(pm::dmnt::AtmosphereGetProcessInfo(std::addressof(proc_h), std::addressof(loc), std::addressof(status), m_cheat_process_metadata.process_id));
ON_SCOPE_EXIT { os::CloseNativeHandle(proc_h); };
this->cheat_process_metadata.program_id = loc.program_id;
m_cheat_process_metadata.program_id = loc.program_id;
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.heap_extents.base), svc::InfoType_HeapRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.heap_extents.size), svc::InfoType_HeapRegionSize, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.alias_extents.base), svc::InfoType_AliasRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.alias_extents.size), svc::InfoType_AliasRegionSize, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.aslr_extents.base), svc::InfoType_AslrRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(this->cheat_process_metadata.aslr_extents.size), svc::InfoType_AslrRegionSize, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.heap_extents.base), svc::InfoType_HeapRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.heap_extents.size), svc::InfoType_HeapRegionSize, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.alias_extents.base), svc::InfoType_AliasRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.alias_extents.size), svc::InfoType_AliasRegionSize, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.aslr_extents.base), svc::InfoType_AslrRegionAddress, proc_h, 0));
R_ABORT_UNLESS(svc::GetInfo(std::addressof(m_cheat_process_metadata.aslr_extents.size), svc::InfoType_AslrRegionSize, proc_h, 0));
/* If new process launch, we may not want to actually attach. */
if (on_process_launch) {
@@ -830,7 +830,7 @@ namespace ams::dmnt::cheat::impl {
s32 num_modules;
/* TODO: ldr::dmnt:: */
R_ABORT_UNLESS_IF_NEW_PROCESS(ldrDmntGetProcessModuleInfo(static_cast<u64>(this->cheat_process_metadata.process_id), proc_modules, util::size(proc_modules), std::addressof(num_modules)));
R_ABORT_UNLESS_IF_NEW_PROCESS(ldrDmntGetProcessModuleInfo(static_cast<u64>(m_cheat_process_metadata.process_id), proc_modules, util::size(proc_modules), std::addressof(num_modules)));
/* All applications must have two modules. */
/* Only accept one (which means we're attaching to HBL) */
@@ -844,42 +844,42 @@ namespace ams::dmnt::cheat::impl {
return dmnt::cheat::ResultCheatNotAttached();
}
this->cheat_process_metadata.main_nso_extents.base = proc_module->base_address;
this->cheat_process_metadata.main_nso_extents.size = proc_module->size;
std::memcpy(this->cheat_process_metadata.main_nso_build_id, proc_module->build_id, sizeof(this->cheat_process_metadata.main_nso_build_id));
m_cheat_process_metadata.main_nso_extents.base = proc_module->base_address;
m_cheat_process_metadata.main_nso_extents.size = proc_module->size;
std::memcpy(m_cheat_process_metadata.main_nso_build_id, proc_module->build_id, sizeof(m_cheat_process_metadata.main_nso_build_id));
}
/* Read cheats off the SD. */
if (!this->LoadCheats(this->cheat_process_metadata.program_id, this->cheat_process_metadata.main_nso_build_id) ||
!this->LoadCheatToggles(this->cheat_process_metadata.program_id)) {
if (!this->LoadCheats(m_cheat_process_metadata.program_id, m_cheat_process_metadata.main_nso_build_id) ||
!this->LoadCheatToggles(m_cheat_process_metadata.program_id)) {
/* If new process launch, require success. */
R_UNLESS(!on_process_launch, dmnt::cheat::ResultCheatNotAttached());
}
/* Open a debug handle. */
svc::Handle debug_handle = svc::InvalidHandle;
R_ABORT_UNLESS_IF_NEW_PROCESS(svc::DebugActiveProcess(std::addressof(debug_handle), this->cheat_process_metadata.process_id.value));
R_ABORT_UNLESS_IF_NEW_PROCESS(svc::DebugActiveProcess(std::addressof(debug_handle), m_cheat_process_metadata.process_id.value));
/* Set our debug handle. */
this->cheat_process_debug_handle = debug_handle;
m_cheat_process_debug_handle = debug_handle;
/* Cancel process guard. */
proc_guard.Cancel();
/* Reset broken state. */
this->broken_unsafe = false;
this->unsafe_break_event.Signal();
m_broken_unsafe = false;
m_unsafe_break_event.Signal();
/* If new process, start the process. */
if (on_process_launch) {
this->StartProcess(this->cheat_process_metadata.process_id);
this->StartProcess(m_cheat_process_metadata.process_id);
}
/* Signal to the debug events thread. */
this->debug_events_event.Signal();
m_debug_events_event.Signal();
/* Signal to our fans. */
this->cheat_process_event.Signal();
m_cheat_process_event.Signal();
return ResultSuccess();
}
@@ -922,7 +922,7 @@ namespace ams::dmnt::cheat::impl {
i = j + 1;
} else if (s[i] == '{') {
/* We're parsing a master cheat. */
cur_entry = std::addressof(this->cheat_entries[0]);
cur_entry = std::addressof(m_cheat_entries[0]);
/* There can only be one master cheat. */
if (cur_entry->definition.num_opcodes > 0) {
@@ -978,14 +978,14 @@ namespace ams::dmnt::cheat::impl {
}
/* Master cheat can't be disabled. */
if (this->cheat_entries[0].definition.num_opcodes > 0) {
this->cheat_entries[0].enabled = true;
if (m_cheat_entries[0].definition.num_opcodes > 0) {
m_cheat_entries[0].enabled = true;
}
/* Enable all entries we parsed. */
for (size_t i = 1; i < MaxCheatCount; i++) {
if (this->cheat_entries[i].definition.num_opcodes > 0) {
this->cheat_entries[i].enabled = this->enable_cheats_by_default;
if (m_cheat_entries[i].definition.num_opcodes > 0) {
m_cheat_entries[i].enabled = m_enable_cheats_by_default;
}
}
@@ -1098,7 +1098,7 @@ namespace ams::dmnt::cheat::impl {
bool CheatProcessManager::LoadCheatToggles(const ncm::ProgramId program_id) {
/* Unless we successfully parse, don't save toggles on close. */
this->should_save_cheat_toggles = false;
m_should_save_cheat_toggles = false;
/* Open the file for program_id. */
fs::FileHandle file;
@@ -1130,8 +1130,8 @@ namespace ams::dmnt::cheat::impl {
g_text_file_buffer[file_size] = '\x00';
/* Parse toggle buffer. */
this->should_save_cheat_toggles = this->ParseCheatToggles(g_text_file_buffer, std::strlen(g_text_file_buffer));
return this->should_save_cheat_toggles;
m_should_save_cheat_toggles = this->ParseCheatToggles(g_text_file_buffer, std::strlen(g_text_file_buffer));
return m_should_save_cheat_toggles;
}
void CheatProcessManager::SaveCheatToggles(const ncm::ProgramId program_id) {
@@ -1153,14 +1153,14 @@ namespace ams::dmnt::cheat::impl {
/* Save all non-master cheats. */
for (size_t i = 1; i < MaxCheatCount; i++) {
if (this->cheat_entries[i].definition.num_opcodes != 0) {
util::SNPrintf(buf, sizeof(buf), "[%s]\n", this->cheat_entries[i].definition.readable_name);
if (m_cheat_entries[i].definition.num_opcodes != 0) {
util::SNPrintf(buf, sizeof(buf), "[%s]\n", m_cheat_entries[i].definition.readable_name);
const size_t name_len = std::strlen(buf);
if (R_SUCCEEDED(fs::WriteFile(file, offset, buf, name_len, fs::WriteOption::Flush))) {
offset += name_len;
}
const char *entry = this->cheat_entries[i].enabled ? "true\n" : "false\n";
const char *entry = m_cheat_entries[i].enabled ? "true\n" : "false\n";
const size_t entry_len = std::strlen(entry);
if (R_SUCCEEDED(fs::WriteFile(file, offset, entry, entry_len, fs::WriteOption::Flush))) {
offset += entry_len;

View File

@@ -27,13 +27,13 @@ namespace ams::dmnt::cheat::impl {
static constexpr size_t NumCores = 4;
static constexpr size_t ThreadStackSize = os::MemoryPageSize;
private:
std::array<uintptr_t, NumCores> handle_message_queue_buffers;
std::array<uintptr_t, NumCores> result_message_queue_buffers;
std::array<os::MessageQueue, NumCores> handle_message_queues;
std::array<os::MessageQueue, NumCores> result_message_queues;
std::array<os::ThreadType, NumCores> threads;
std::array<uintptr_t, NumCores> m_handle_message_queue_buffers;
std::array<uintptr_t, NumCores> m_result_message_queue_buffers;
std::array<os::MessageQueue, NumCores> m_handle_message_queues;
std::array<os::MessageQueue, NumCores> m_result_message_queues;
std::array<os::ThreadType, NumCores> m_threads;
alignas(os::MemoryPageSize) u8 thread_stacks[NumCores][ThreadStackSize];
alignas(os::MemoryPageSize) u8 m_thread_stacks[NumCores][ThreadStackSize];
private:
static void PerCoreThreadFunction(void *_this) {
/* This thread will wait on the appropriate message queue. */
@@ -73,12 +73,12 @@ namespace ams::dmnt::cheat::impl {
}
void SendHandle(size_t target_core, os::NativeHandle debug_handle) {
this->handle_message_queues[target_core].Send(static_cast<uintptr_t>(debug_handle));
m_handle_message_queues[target_core].Send(static_cast<uintptr_t>(debug_handle));
}
os::NativeHandle WaitReceiveHandle(size_t core_id) {
uintptr_t x = 0;
this->handle_message_queues[core_id].Receive(&x);
m_handle_message_queues[core_id].Receive(&x);
return static_cast<os::NativeHandle>(x);
}
@@ -91,38 +91,38 @@ namespace ams::dmnt::cheat::impl {
}
void SendContinueResult(size_t target_core, Result result) {
this->result_message_queues[target_core].Send(static_cast<uintptr_t>(result.GetValue()));
m_result_message_queues[target_core].Send(static_cast<uintptr_t>(result.GetValue()));
}
Result GetContinueResult(size_t core_id) {
uintptr_t x = 0;
this->result_message_queues[core_id].Receive(&x);
m_result_message_queues[core_id].Receive(&x);
return static_cast<Result>(x);
}
public:
DebugEventsManager()
: handle_message_queues{
os::MessageQueue(std::addressof(handle_message_queue_buffers[0]), 1),
os::MessageQueue(std::addressof(handle_message_queue_buffers[1]), 1),
os::MessageQueue(std::addressof(handle_message_queue_buffers[2]), 1),
os::MessageQueue(std::addressof(handle_message_queue_buffers[3]), 1)},
result_message_queues{
os::MessageQueue(std::addressof(result_message_queue_buffers[0]), 1),
os::MessageQueue(std::addressof(result_message_queue_buffers[1]), 1),
os::MessageQueue(std::addressof(result_message_queue_buffers[2]), 1),
os::MessageQueue(std::addressof(result_message_queue_buffers[3]), 1)},
thread_stacks{}
: m_handle_message_queues{
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[0]), 1),
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[1]), 1),
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[2]), 1),
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[3]), 1)},
m_result_message_queues{
os::MessageQueue(std::addressof(m_result_message_queue_buffers[0]), 1),
os::MessageQueue(std::addressof(m_result_message_queue_buffers[1]), 1),
os::MessageQueue(std::addressof(m_result_message_queue_buffers[2]), 1),
os::MessageQueue(std::addressof(m_result_message_queue_buffers[3]), 1)},
m_thread_stacks{}
{
for (size_t i = 0; i < NumCores; i++) {
/* Create thread. */
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->threads[i]), PerCoreThreadFunction, this, this->thread_stacks[i], ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, MultiCoreEventManager), i));
os::SetThreadNamePointer(std::addressof(this->threads[i]), AMS_GET_SYSTEM_THREAD_NAME(dmnt, MultiCoreEventManager));
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_threads[i]), PerCoreThreadFunction, this, m_thread_stacks[i], ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, MultiCoreEventManager), i));
os::SetThreadNamePointer(std::addressof(m_threads[i]), AMS_GET_SYSTEM_THREAD_NAME(dmnt, MultiCoreEventManager));
/* Set core mask. */
os::SetThreadCoreMask(std::addressof(this->threads[i]), i, (1u << i));
os::SetThreadCoreMask(std::addressof(m_threads[i]), i, (1u << i));
/* Start thread. */
os::StartThread(std::addressof(this->threads[i]));
os::StartThread(std::addressof(m_threads[i]));
}
}

View File

@@ -46,41 +46,41 @@ namespace ams::dmnt::cheat::impl {
void CheatVirtualMachine::OpenDebugLogFile() {
#ifdef DMNT_CHEAT_VM_DEBUG_LOG
CloseDebugLogFile();
R_ABORT_UNLESS(fs::OpenFile(std::addressof(this->debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt"));
this->debug_log_file_offset = 0;
R_ABORT_UNLESS(fs::OpenFile(std::addressof(m_debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt"));
m_debug_log_file_offset = 0;
#endif
}
void CheatVirtualMachine::CloseDebugLogFile() {
#ifdef DMNT_CHEAT_VM_DEBUG_LOG
if (this->has_debug_log_file) {
fs::CloseFile(this->debug_log_file);
if (m_has_debug_log_file) {
fs::CloseFile(m_debug_log_file);
}
this->has_debug_log_file = false;
m_has_debug_log_file = false;
#endif
}
void CheatVirtualMachine::LogToDebugFile(const char *format, ...) {
#ifdef DMNT_CHEAT_VM_DEBUG_LOG
if (!this->has_debug_log_file) {
if (!m_has_debug_log_file) {
return;
}
{
std::va_list vl;
va_start(vl, format);
util::VSNPrintf(this->debug_log_format_buf, sizeof(this->debug_log_format_buf) - 1, format, vl);
util::VSNPrintf(m_debug_log_format_buf, sizeof(m_debug_log_format_buf) - 1, format, vl);
va_end(vl);
}
size_t fmt_len = std::strlen(this->debug_log_format_buf);
if (this->debug_log_format_buf[fmt_len - 1] != '\n') {
this->debug_log_format_buf[fmt_len + 0] = '\n';
this->debug_log_format_buf[fmt_len + 1] = '\x00';
size_t fmt_len = std::strlen(m_debug_log_format_buf);
if (m_debug_log_format_buf[fmt_len - 1] != '\n') {
m_debug_log_format_buf[fmt_len + 0] = '\n';
m_debug_log_format_buf[fmt_len + 1] = '\x00';
fmt_len += 1;
}
fs::WriteFile(this->debug_log_file, this->debug_log_offset, this->debug_log_format_buf, fmt_len, fs::WriteOption::Flush);
fs::WriteFile(m_debug_log_file, m_debug_log_offset, m_debug_log_format_buf, fmt_len, fs::WriteOption::Flush);
#else
AMS_UNUSED(format);
#endif
@@ -295,10 +295,10 @@ namespace ams::dmnt::cheat::impl {
bool CheatVirtualMachine::DecodeNextOpcode(CheatVmOpcode *out) {
/* If we've ever seen a decode failure, return false. */
bool valid = this->decode_success;
bool valid = m_decode_success;
CheatVmOpcode opcode = {};
ON_SCOPE_EXIT {
this->decode_success &= valid;
m_decode_success &= valid;
if (valid) {
*out = opcode;
}
@@ -306,11 +306,11 @@ namespace ams::dmnt::cheat::impl {
/* Helper function for getting instruction dwords. */
auto GetNextDword = [&]() {
if (this->instruction_ptr >= this->num_opcodes) {
if (m_instruction_ptr >= m_num_opcodes) {
valid = false;
return static_cast<u32>(0);
}
return this->program[this->instruction_ptr++];
return m_program[m_instruction_ptr++];
};
/* Helper function for parsing a VmInt. */
@@ -671,12 +671,12 @@ namespace ams::dmnt::cheat::impl {
}
void CheatVirtualMachine::SkipConditionalBlock(bool is_if) {
if (this->condition_depth > 0) {
if (m_condition_depth > 0) {
/* We want to continue until we're out of the current block. */
const size_t desired_depth = this->condition_depth - 1;
const size_t desired_depth = m_condition_depth - 1;
CheatVmOpcode skip_opcode;
while (this->condition_depth > desired_depth && this->DecodeNextOpcode(std::addressof(skip_opcode))) {
while (m_condition_depth > desired_depth && this->DecodeNextOpcode(std::addressof(skip_opcode))) {
/* Decode instructions until we see end of the current conditional block. */
/* NOTE: This is broken in gateway's implementation. */
/* Gateway currently checks for "0x2" instead of "0x20000000" */
@@ -685,18 +685,18 @@ namespace ams::dmnt::cheat::impl {
/* We also support nesting of conditional blocks, and Gateway does not. */
if (skip_opcode.begin_conditional_block) {
this->condition_depth++;
m_condition_depth++;
} else if (skip_opcode.opcode == CheatVmOpcodeType_EndConditionalBlock) {
if (!skip_opcode.end_cond.is_else) {
this->condition_depth--;
} else if (is_if && this->condition_depth - 1 == desired_depth) {
m_condition_depth--;
} else if (is_if && m_condition_depth - 1 == desired_depth) {
/* An if will continue to an else at the same depth. */
break;
}
}
}
} else {
/* Skipping, but this->condition_depth = 0. */
/* Skipping, but m_condition_depth = 0. */
/* This is an error condition. */
/* This could occur with a mismatched "else" opcode, for example. */
R_ABORT_UNLESS(ResultVirtualMachineInvalidConditionDepth());
@@ -735,29 +735,29 @@ namespace ams::dmnt::cheat::impl {
void CheatVirtualMachine::ResetState() {
for (size_t i = 0; i < CheatVirtualMachine::NumRegisters; i++) {
this->registers[i] = 0;
this->saved_values[i] = 0;
this->loop_tops[i] = 0;
m_registers[i] = 0;
m_saved_values[i] = 0;
m_loop_tops[i] = 0;
}
this->instruction_ptr = 0;
this->condition_depth = 0;
this->decode_success = true;
m_instruction_ptr = 0;
m_condition_depth = 0;
m_decode_success = true;
}
bool CheatVirtualMachine::LoadProgram(const CheatEntry *cheats, size_t num_cheats) {
/* Reset opcode count. */
this->num_opcodes = 0;
m_num_opcodes = 0;
for (size_t i = 0; i < num_cheats; i++) {
if (cheats[i].enabled) {
/* Bounds check. */
if (cheats[i].definition.num_opcodes + this->num_opcodes > MaximumProgramOpcodeCount) {
this->num_opcodes = 0;
if (cheats[i].definition.num_opcodes + m_num_opcodes > MaximumProgramOpcodeCount) {
m_num_opcodes = 0;
return false;
}
for (size_t n = 0; n < cheats[i].definition.num_opcodes; n++) {
this->program[this->num_opcodes++] = cheats[i].definition.opcodes[n];
m_program[m_num_opcodes++] = cheats[i].definition.opcodes[n];
}
}
}
@@ -785,27 +785,27 @@ namespace ams::dmnt::cheat::impl {
/* Loop until program finishes. */
while (this->DecodeNextOpcode(std::addressof(cur_opcode))) {
this->LogToDebugFile("Instruction Ptr: %04x\n", (u32)this->instruction_ptr);
this->LogToDebugFile("Instruction Ptr: %04x\n", (u32)m_instruction_ptr);
for (size_t i = 0; i < NumRegisters; i++) {
this->LogToDebugFile("Registers[%02x]: %016lx\n", i, this->registers[i]);
this->LogToDebugFile("Registers[%02x]: %016lx\n", i, m_registers[i]);
}
for (size_t i = 0; i < NumRegisters; i++) {
this->LogToDebugFile("SavedRegs[%02x]: %016lx\n", i, this->saved_values[i]);
this->LogToDebugFile("SavedRegs[%02x]: %016lx\n", i, m_saved_values[i]);
}
this->LogOpcode(std::addressof(cur_opcode));
/* Increment conditional depth, if relevant. */
if (cur_opcode.begin_conditional_block) {
this->condition_depth++;
m_condition_depth++;
}
switch (cur_opcode.opcode) {
case CheatVmOpcodeType_StoreStatic:
{
/* Calculate address, write value to memory. */
u64 dst_address = GetCheatProcessAddress(metadata, cur_opcode.store_static.mem_type, cur_opcode.store_static.rel_address + this->registers[cur_opcode.store_static.offset_register]);
u64 dst_address = GetCheatProcessAddress(metadata, cur_opcode.store_static.mem_type, cur_opcode.store_static.rel_address + m_registers[cur_opcode.store_static.offset_register]);
u64 dst_value = GetVmInt(cur_opcode.store_static.value, cur_opcode.store_static.bit_width);
switch (cur_opcode.store_static.bit_width) {
case 1:
@@ -866,34 +866,34 @@ namespace ams::dmnt::cheat::impl {
} else {
/* Decrement the condition depth. */
/* We will assume, graciously, that mismatched conditional block ends are a nop. */
if (this->condition_depth > 0) {
this->condition_depth--;
if (m_condition_depth > 0) {
m_condition_depth--;
}
}
break;
case CheatVmOpcodeType_ControlLoop:
if (cur_opcode.ctrl_loop.start_loop) {
/* Start a loop. */
this->registers[cur_opcode.ctrl_loop.reg_index] = cur_opcode.ctrl_loop.num_iters;
this->loop_tops[cur_opcode.ctrl_loop.reg_index] = this->instruction_ptr;
m_registers[cur_opcode.ctrl_loop.reg_index] = cur_opcode.ctrl_loop.num_iters;
m_loop_tops[cur_opcode.ctrl_loop.reg_index] = m_instruction_ptr;
} else {
/* End a loop. */
this->registers[cur_opcode.ctrl_loop.reg_index]--;
if (this->registers[cur_opcode.ctrl_loop.reg_index] != 0) {
this->instruction_ptr = this->loop_tops[cur_opcode.ctrl_loop.reg_index];
m_registers[cur_opcode.ctrl_loop.reg_index]--;
if (m_registers[cur_opcode.ctrl_loop.reg_index] != 0) {
m_instruction_ptr = m_loop_tops[cur_opcode.ctrl_loop.reg_index];
}
}
break;
case CheatVmOpcodeType_LoadRegisterStatic:
/* Set a register to a static value. */
this->registers[cur_opcode.ldr_static.reg_index] = cur_opcode.ldr_static.value;
m_registers[cur_opcode.ldr_static.reg_index] = cur_opcode.ldr_static.value;
break;
case CheatVmOpcodeType_LoadRegisterMemory:
{
/* Choose source address. */
u64 src_address;
if (cur_opcode.ldr_memory.load_from_reg) {
src_address = this->registers[cur_opcode.ldr_memory.reg_index] + cur_opcode.ldr_memory.rel_address;
src_address = m_registers[cur_opcode.ldr_memory.reg_index] + cur_opcode.ldr_memory.rel_address;
} else {
src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, cur_opcode.ldr_memory.rel_address);
}
@@ -903,7 +903,7 @@ namespace ams::dmnt::cheat::impl {
case 2:
case 4:
case 8:
dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(this->registers[cur_opcode.ldr_memory.reg_index]), cur_opcode.ldr_memory.bit_width);
dmnt::cheat::impl::ReadCheatProcessMemoryUnsafe(src_address, std::addressof(m_registers[cur_opcode.ldr_memory.reg_index]), cur_opcode.ldr_memory.bit_width);
break;
}
}
@@ -911,10 +911,10 @@ namespace ams::dmnt::cheat::impl {
case CheatVmOpcodeType_StoreStaticToAddress:
{
/* Calculate address. */
u64 dst_address = this->registers[cur_opcode.str_static.reg_index];
u64 dst_address = m_registers[cur_opcode.str_static.reg_index];
u64 dst_value = cur_opcode.str_static.value;
if (cur_opcode.str_static.add_offset_reg) {
dst_address += this->registers[cur_opcode.str_static.offset_reg_index];
dst_address += m_registers[cur_opcode.str_static.offset_reg_index];
}
/* Write value to memory. Gateway only writes on valid bitwidth. */
switch (cur_opcode.str_static.bit_width) {
@@ -927,7 +927,7 @@ namespace ams::dmnt::cheat::impl {
}
/* Increment register if relevant. */
if (cur_opcode.str_static.increment_reg) {
this->registers[cur_opcode.str_static.reg_index] += cur_opcode.str_static.bit_width;
m_registers[cur_opcode.str_static.reg_index] += cur_opcode.str_static.bit_width;
}
}
break;
@@ -936,19 +936,19 @@ namespace ams::dmnt::cheat::impl {
/* Do requested math. */
switch (cur_opcode.perform_math_static.math_type) {
case RegisterArithmeticType_Addition:
this->registers[cur_opcode.perform_math_static.reg_index] += (u64)cur_opcode.perform_math_static.value;
m_registers[cur_opcode.perform_math_static.reg_index] += (u64)cur_opcode.perform_math_static.value;
break;
case RegisterArithmeticType_Subtraction:
this->registers[cur_opcode.perform_math_static.reg_index] -= (u64)cur_opcode.perform_math_static.value;
m_registers[cur_opcode.perform_math_static.reg_index] -= (u64)cur_opcode.perform_math_static.value;
break;
case RegisterArithmeticType_Multiplication:
this->registers[cur_opcode.perform_math_static.reg_index] *= (u64)cur_opcode.perform_math_static.value;
m_registers[cur_opcode.perform_math_static.reg_index] *= (u64)cur_opcode.perform_math_static.value;
break;
case RegisterArithmeticType_LeftShift:
this->registers[cur_opcode.perform_math_static.reg_index] <<= (u64)cur_opcode.perform_math_static.value;
m_registers[cur_opcode.perform_math_static.reg_index] <<= (u64)cur_opcode.perform_math_static.value;
break;
case RegisterArithmeticType_RightShift:
this->registers[cur_opcode.perform_math_static.reg_index] >>= (u64)cur_opcode.perform_math_static.value;
m_registers[cur_opcode.perform_math_static.reg_index] >>= (u64)cur_opcode.perform_math_static.value;
break;
default:
/* Do not handle extensions here. */
@@ -957,16 +957,16 @@ namespace ams::dmnt::cheat::impl {
/* Apply bit width. */
switch (cur_opcode.perform_math_static.bit_width) {
case 1:
this->registers[cur_opcode.perform_math_static.reg_index] = static_cast<u8>(this->registers[cur_opcode.perform_math_static.reg_index]);
m_registers[cur_opcode.perform_math_static.reg_index] = static_cast<u8>(m_registers[cur_opcode.perform_math_static.reg_index]);
break;
case 2:
this->registers[cur_opcode.perform_math_static.reg_index] = static_cast<u16>(this->registers[cur_opcode.perform_math_static.reg_index]);
m_registers[cur_opcode.perform_math_static.reg_index] = static_cast<u16>(m_registers[cur_opcode.perform_math_static.reg_index]);
break;
case 4:
this->registers[cur_opcode.perform_math_static.reg_index] = static_cast<u32>(this->registers[cur_opcode.perform_math_static.reg_index]);
m_registers[cur_opcode.perform_math_static.reg_index] = static_cast<u32>(m_registers[cur_opcode.perform_math_static.reg_index]);
break;
case 8:
this->registers[cur_opcode.perform_math_static.reg_index] = static_cast<u64>(this->registers[cur_opcode.perform_math_static.reg_index]);
m_registers[cur_opcode.perform_math_static.reg_index] = static_cast<u64>(m_registers[cur_opcode.perform_math_static.reg_index]);
break;
}
}
@@ -980,10 +980,10 @@ namespace ams::dmnt::cheat::impl {
break;
case CheatVmOpcodeType_PerformArithmeticRegister:
{
const u64 operand_1_value = this->registers[cur_opcode.perform_math_reg.src_reg_1_index];
const u64 operand_1_value = m_registers[cur_opcode.perform_math_reg.src_reg_1_index];
const u64 operand_2_value = cur_opcode.perform_math_reg.has_immediate ?
GetVmInt(cur_opcode.perform_math_reg.value, cur_opcode.perform_math_reg.bit_width) :
this->registers[cur_opcode.perform_math_reg.src_reg_2_index];
m_registers[cur_opcode.perform_math_reg.src_reg_2_index];
u64 res_val = 0;
/* Do requested math. */
@@ -1038,32 +1038,32 @@ namespace ams::dmnt::cheat::impl {
}
/* Save to register. */
this->registers[cur_opcode.perform_math_reg.dst_reg_index] = res_val;
m_registers[cur_opcode.perform_math_reg.dst_reg_index] = res_val;
}
break;
case CheatVmOpcodeType_StoreRegisterToAddress:
{
/* Calculate address. */
u64 dst_value = this->registers[cur_opcode.str_register.str_reg_index];
u64 dst_address = this->registers[cur_opcode.str_register.addr_reg_index];
u64 dst_value = m_registers[cur_opcode.str_register.str_reg_index];
u64 dst_address = m_registers[cur_opcode.str_register.addr_reg_index];
switch (cur_opcode.str_register.ofs_type) {
case StoreRegisterOffsetType_None:
/* Nothing more to do */
break;
case StoreRegisterOffsetType_Reg:
dst_address += this->registers[cur_opcode.str_register.ofs_reg_index];
dst_address += m_registers[cur_opcode.str_register.ofs_reg_index];
break;
case StoreRegisterOffsetType_Imm:
dst_address += cur_opcode.str_register.rel_address;
break;
case StoreRegisterOffsetType_MemReg:
dst_address = GetCheatProcessAddress(metadata, cur_opcode.str_register.mem_type, this->registers[cur_opcode.str_register.addr_reg_index]);
dst_address = GetCheatProcessAddress(metadata, cur_opcode.str_register.mem_type, m_registers[cur_opcode.str_register.addr_reg_index]);
break;
case StoreRegisterOffsetType_MemImm:
dst_address = GetCheatProcessAddress(metadata, cur_opcode.str_register.mem_type, cur_opcode.str_register.rel_address);
break;
case StoreRegisterOffsetType_MemImmReg:
dst_address = GetCheatProcessAddress(metadata, cur_opcode.str_register.mem_type, this->registers[cur_opcode.str_register.addr_reg_index] + cur_opcode.str_register.rel_address);
dst_address = GetCheatProcessAddress(metadata, cur_opcode.str_register.mem_type, m_registers[cur_opcode.str_register.addr_reg_index] + cur_opcode.str_register.rel_address);
break;
}
@@ -1079,7 +1079,7 @@ namespace ams::dmnt::cheat::impl {
/* Increment register if relevant. */
if (cur_opcode.str_register.increment_reg) {
this->registers[cur_opcode.str_register.addr_reg_index] += cur_opcode.str_register.bit_width;
m_registers[cur_opcode.str_register.addr_reg_index] += cur_opcode.str_register.bit_width;
}
}
break;
@@ -1089,16 +1089,16 @@ namespace ams::dmnt::cheat::impl {
u64 src_value = 0;
switch (cur_opcode.begin_reg_cond.bit_width) {
case 1:
src_value = static_cast<u8>(this->registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFul);
src_value = static_cast<u8>(m_registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFul);
break;
case 2:
src_value = static_cast<u16>(this->registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFul);
src_value = static_cast<u16>(m_registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFul);
break;
case 4:
src_value = static_cast<u32>(this->registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFFFFFul);
src_value = static_cast<u32>(m_registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFFFFFul);
break;
case 8:
src_value = static_cast<u64>(this->registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFFFFFFFFFFFFFul);
src_value = static_cast<u64>(m_registers[cur_opcode.begin_reg_cond.val_reg_index] & 0xFFFFFFFFFFFFFFFFul);
break;
}
@@ -1109,16 +1109,16 @@ namespace ams::dmnt::cheat::impl {
} else if (cur_opcode.begin_reg_cond.comp_type == CompareRegisterValueType_OtherRegister) {
switch (cur_opcode.begin_reg_cond.bit_width) {
case 1:
cond_value = static_cast<u8>(this->registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFul);
cond_value = static_cast<u8>(m_registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFul);
break;
case 2:
cond_value = static_cast<u16>(this->registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFul);
cond_value = static_cast<u16>(m_registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFul);
break;
case 4:
cond_value = static_cast<u32>(this->registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFFFFFul);
cond_value = static_cast<u32>(m_registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFFFFFul);
break;
case 8:
cond_value = static_cast<u64>(this->registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFFFFFFFFFFFFFul);
cond_value = static_cast<u64>(m_registers[cur_opcode.begin_reg_cond.other_reg_index] & 0xFFFFFFFFFFFFFFFFul);
break;
}
} else {
@@ -1128,13 +1128,13 @@ namespace ams::dmnt::cheat::impl {
cond_address = GetCheatProcessAddress(metadata, cur_opcode.begin_reg_cond.mem_type, cur_opcode.begin_reg_cond.rel_address);
break;
case CompareRegisterValueType_MemoryOfsReg:
cond_address = GetCheatProcessAddress(metadata, cur_opcode.begin_reg_cond.mem_type, this->registers[cur_opcode.begin_reg_cond.ofs_reg_index]);
cond_address = GetCheatProcessAddress(metadata, cur_opcode.begin_reg_cond.mem_type, m_registers[cur_opcode.begin_reg_cond.ofs_reg_index]);
break;
case CompareRegisterValueType_RegisterRelAddr:
cond_address = this->registers[cur_opcode.begin_reg_cond.addr_reg_index] + cur_opcode.begin_reg_cond.rel_address;
cond_address = m_registers[cur_opcode.begin_reg_cond.addr_reg_index] + cur_opcode.begin_reg_cond.rel_address;
break;
case CompareRegisterValueType_RegisterOfsReg:
cond_address = this->registers[cur_opcode.begin_reg_cond.addr_reg_index] + this->registers[cur_opcode.begin_reg_cond.ofs_reg_index];
cond_address = m_registers[cur_opcode.begin_reg_cond.addr_reg_index] + m_registers[cur_opcode.begin_reg_cond.ofs_reg_index];
break;
default:
break;
@@ -1182,17 +1182,17 @@ namespace ams::dmnt::cheat::impl {
/* Save or restore a register. */
switch (cur_opcode.save_restore_reg.op_type) {
case SaveRestoreRegisterOpType_ClearRegs:
this->registers[cur_opcode.save_restore_reg.dst_index] = 0ul;
m_registers[cur_opcode.save_restore_reg.dst_index] = 0ul;
break;
case SaveRestoreRegisterOpType_ClearSaved:
this->saved_values[cur_opcode.save_restore_reg.dst_index] = 0ul;
m_saved_values[cur_opcode.save_restore_reg.dst_index] = 0ul;
break;
case SaveRestoreRegisterOpType_Save:
this->saved_values[cur_opcode.save_restore_reg.dst_index] = this->registers[cur_opcode.save_restore_reg.src_index];
m_saved_values[cur_opcode.save_restore_reg.dst_index] = m_registers[cur_opcode.save_restore_reg.src_index];
break;
case SaveRestoreRegisterOpType_Restore:
default:
this->registers[cur_opcode.save_restore_reg.dst_index] = this->saved_values[cur_opcode.save_restore_reg.src_index];
m_registers[cur_opcode.save_restore_reg.dst_index] = m_saved_values[cur_opcode.save_restore_reg.src_index];
break;
}
break;
@@ -1203,14 +1203,14 @@ namespace ams::dmnt::cheat::impl {
switch (cur_opcode.save_restore_regmask.op_type) {
case SaveRestoreRegisterOpType_ClearSaved:
case SaveRestoreRegisterOpType_Save:
src = this->registers;
dst = this->saved_values;
src = m_registers;
dst = m_saved_values;
break;
case SaveRestoreRegisterOpType_ClearRegs:
case SaveRestoreRegisterOpType_Restore:
default:
src = this->saved_values;
dst = this->registers;
src = m_saved_values;
dst = m_registers;
break;
}
for (size_t i = 0; i < NumRegisters; i++) {
@@ -1232,10 +1232,10 @@ namespace ams::dmnt::cheat::impl {
case CheatVmOpcodeType_ReadWriteStaticRegister:
if (cur_opcode.rw_static_reg.static_idx < NumReadableStaticRegisters) {
/* Load a register with a static register. */
this->registers[cur_opcode.rw_static_reg.idx] = this->static_registers[cur_opcode.rw_static_reg.static_idx];
m_registers[cur_opcode.rw_static_reg.idx] = m_static_registers[cur_opcode.rw_static_reg.static_idx];
} else {
/* Store a register to a static register. */
this->static_registers[cur_opcode.rw_static_reg.static_idx] = this->registers[cur_opcode.rw_static_reg.idx];
m_static_registers[cur_opcode.rw_static_reg.static_idx] = m_registers[cur_opcode.rw_static_reg.idx];
}
break;
case CheatVmOpcodeType_PauseProcess:
@@ -1251,16 +1251,16 @@ namespace ams::dmnt::cheat::impl {
if (cur_opcode.debug_log.val_type == DebugLogValueType_RegisterValue) {
switch (cur_opcode.debug_log.bit_width) {
case 1:
log_value = static_cast<u8>(this->registers[cur_opcode.debug_log.val_reg_index] & 0xFFul);
log_value = static_cast<u8>(m_registers[cur_opcode.debug_log.val_reg_index] & 0xFFul);
break;
case 2:
log_value = static_cast<u16>(this->registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFul);
log_value = static_cast<u16>(m_registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFul);
break;
case 4:
log_value = static_cast<u32>(this->registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFFFFFul);
log_value = static_cast<u32>(m_registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFFFFFul);
break;
case 8:
log_value = static_cast<u64>(this->registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFFFFFFFFFFFFFul);
log_value = static_cast<u64>(m_registers[cur_opcode.debug_log.val_reg_index] & 0xFFFFFFFFFFFFFFFFul);
break;
}
} else {
@@ -1270,13 +1270,13 @@ namespace ams::dmnt::cheat::impl {
val_address = GetCheatProcessAddress(metadata, cur_opcode.debug_log.mem_type, cur_opcode.debug_log.rel_address);
break;
case DebugLogValueType_MemoryOfsReg:
val_address = GetCheatProcessAddress(metadata, cur_opcode.debug_log.mem_type, this->registers[cur_opcode.debug_log.ofs_reg_index]);
val_address = GetCheatProcessAddress(metadata, cur_opcode.debug_log.mem_type, m_registers[cur_opcode.debug_log.ofs_reg_index]);
break;
case DebugLogValueType_RegisterRelAddr:
val_address = this->registers[cur_opcode.debug_log.addr_reg_index] + cur_opcode.debug_log.rel_address;
val_address = m_registers[cur_opcode.debug_log.addr_reg_index] + cur_opcode.debug_log.rel_address;
break;
case DebugLogValueType_RegisterOfsReg:
val_address = this->registers[cur_opcode.debug_log.addr_reg_index] + this->registers[cur_opcode.debug_log.ofs_reg_index];
val_address = m_registers[cur_opcode.debug_log.addr_reg_index] + m_registers[cur_opcode.debug_log.ofs_reg_index];
break;
default:
break;

View File

@@ -277,15 +277,15 @@ namespace ams::dmnt::cheat::impl {
constexpr static size_t NumWritableStaticRegisters = 0x80;
constexpr static size_t NumStaticRegisters = NumReadableStaticRegisters + NumWritableStaticRegisters;
private:
size_t num_opcodes = 0;
size_t instruction_ptr = 0;
size_t condition_depth = 0;
bool decode_success = false;
u32 program[MaximumProgramOpcodeCount] = {0};
u64 registers[NumRegisters] = {0};
u64 saved_values[NumRegisters] = {0};
u64 static_registers[NumStaticRegisters] = {0};
size_t loop_tops[NumRegisters] = {0};
size_t m_num_opcodes = 0;
size_t m_instruction_ptr = 0;
size_t m_condition_depth = 0;
bool m_decode_success = false;
u32 m_program[MaximumProgramOpcodeCount] = {0};
u64 m_registers[NumRegisters] = {0};
u64 m_saved_values[NumRegisters] = {0};
u64 m_static_registers[NumStaticRegisters] = {0};
size_t m_loop_tops[NumRegisters] = {0};
private:
bool DecodeNextOpcode(CheatVmOpcode *out);
void SkipConditionalBlock(bool is_if);
@@ -303,32 +303,32 @@ namespace ams::dmnt::cheat::impl {
static u64 GetVmInt(VmInt value, u32 bit_width);
static u64 GetCheatProcessAddress(const CheatProcessMetadata* metadata, MemoryAccessType mem_type, u64 rel_address);
public:
CheatVirtualMachine() { }
constexpr CheatVirtualMachine() = default;
size_t GetProgramSize() {
return this->num_opcodes;
return m_num_opcodes;
}
bool LoadProgram(const CheatEntry *cheats, size_t num_cheats);
void Execute(const CheatProcessMetadata *metadata);
u64 GetStaticRegister(size_t which) const {
return this->static_registers[which];
return m_static_registers[which];
}
void SetStaticRegister(size_t which, u64 value) {
this->static_registers[which] = value;
m_static_registers[which] = value;
}
void ResetStaticRegisters() {
std::memset(this->static_registers, 0, sizeof(this->static_registers));
std::memset(m_static_registers, 0, sizeof(m_static_registers));
}
#ifdef DMNT_CHEAT_VM_DEBUG_LOG
private:
fs::FileHandle debug_log_file;
s64 debug_log_file_offset;
bool has_debug_log_file;
char debug_log_format_buf[0x100];
fs::FileHandle m_debug_log_file = {};
s64 m_debug_log_file_offset = 0;
bool m_has_debug_log_file = false;
char m_debug_log_format_buf[0x100] = {0};
#endif
};

View File

@@ -75,43 +75,43 @@ namespace ams::fatal::srv {
FatalConfig::FatalConfig() {
/* Get information from set. */
settings::system::GetSerialNumber(std::addressof(this->serial_number));
settings::system::GetFirmwareVersion(std::addressof(this->firmware_version));
setsysGetQuestFlag(std::addressof(this->quest_flag));
settings::system::GetSerialNumber(std::addressof(m_serial_number));
settings::system::GetFirmwareVersion(std::addressof(m_firmware_version));
setsysGetQuestFlag(std::addressof(m_quest_flag));
this->UpdateLanguageCode();
/* Read information from settings. */
settings::fwdbg::GetSettingsItemValue(std::addressof(this->transition_to_fatal), sizeof(this->transition_to_fatal), "fatal", "transition_to_fatal");
settings::fwdbg::GetSettingsItemValue(std::addressof(this->show_extra_info), sizeof(this->show_extra_info), "fatal", "show_extra_info");
settings::fwdbg::GetSettingsItemValue(std::addressof(m_transition_to_fatal), sizeof(m_transition_to_fatal), "fatal", "transition_to_fatal");
settings::fwdbg::GetSettingsItemValue(std::addressof(m_show_extra_info), sizeof(m_show_extra_info), "fatal", "show_extra_info");
u64 quest_interval_second;
settings::fwdbg::GetSettingsItemValue(std::addressof(quest_interval_second), sizeof(quest_interval_second), "fatal", "quest_reboot_interval_second");
this->quest_reboot_interval = TimeSpan::FromSeconds(quest_interval_second);
m_quest_reboot_interval = TimeSpan::FromSeconds(quest_interval_second);
/* Atmosphere extension for automatic reboot. */
u64 auto_reboot_ms;
if (settings::fwdbg::GetSettingsItemValue(std::addressof(auto_reboot_ms), sizeof(auto_reboot_ms), "atmosphere", "fatal_auto_reboot_interval") == sizeof(auto_reboot_ms)) {
this->fatal_auto_reboot_interval = TimeSpan::FromMilliSeconds(auto_reboot_ms);
this->fatal_auto_reboot_enabled = auto_reboot_ms != 0;
m_fatal_auto_reboot_interval = TimeSpan::FromMilliSeconds(auto_reboot_ms);
m_fatal_auto_reboot_enabled = auto_reboot_ms != 0;
}
/* Setup messages. */
{
this->error_msg = "Error Code: 2%03d-%04d (0x%x)\n";
m_error_msg = "Error Code: 2%03d-%04d (0x%x)\n";
this->error_desc = "An error has occurred.\n\n"
"Please press the POWER Button to restart the console normally, or a VOL button\n"
"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
"If the problem persists, refer to the Nintendo Support Website.\n"
"support.nintendo.com/switch/error\n";
m_error_desc = "An error has occurred.\n\n"
"Please press the POWER Button to restart the console normally, or a VOL button\n"
"to reboot to a payload (or RCM, if none is present). If you are unable to\n"
"restart the console, hold the POWER Button for 12 seconds to turn the console off.\n\n"
"If the problem persists, refer to the Nintendo Support Website.\n"
"support.nintendo.com/switch/error\n";
/* If you're running Atmosphere on a quest unit for some reason, talk to me on discord. */
this->quest_desc = "Please call 1-800-875-1852 for service.\n\n"
"Also, please be aware that running Atmosphere on a Quest device is not fully\n"
"supported. Perhaps try booting your device without Atmosphere before calling\n"
"an official Nintendo service hotline. If you encounter further issues, please\n"
"contact SciresM#0524 on Discord, or via some other means.\n";
m_quest_desc = "Please call 1-800-875-1852 for service.\n\n"
"Also, please be aware that running Atmosphere on a Quest device is not fully\n"
"supported. Perhaps try booting your device without Atmosphere before calling\n"
"an official Nintendo service hotline. If you encounter further issues, please\n"
"contact SciresM#0524 on Discord, or via some other means.\n";
/* TODO: Try to load dynamically? */
/* FsStorage message_storage; */

View File

@@ -20,70 +20,70 @@ namespace ams::fatal::srv {
class FatalConfig {
private:
settings::system::SerialNumber serial_number{};
settings::system::FirmwareVersion firmware_version{};
u64 language_code{};
TimeSpan quest_reboot_interval{};
bool transition_to_fatal{};
bool show_extra_info{};
bool quest_flag{};
const char *error_msg{};
const char *error_desc{};
const char *quest_desc{};
TimeSpan fatal_auto_reboot_interval{};
bool fatal_auto_reboot_enabled{};
settings::system::SerialNumber m_serial_number{};
settings::system::FirmwareVersion m_firmware_version{};
u64 m_language_code{};
TimeSpan m_quest_reboot_interval{};
bool m_transition_to_fatal{};
bool m_show_extra_info{};
bool m_quest_flag{};
const char *m_error_msg{};
const char *m_error_desc{};
const char *m_quest_desc{};
TimeSpan m_fatal_auto_reboot_interval{};
bool m_fatal_auto_reboot_enabled{};
public:
FatalConfig();
const settings::system::SerialNumber &GetSerialNumber() const {
return this->serial_number;
return m_serial_number;
}
const settings::system::FirmwareVersion &GetFirmwareVersion() const {
return this->firmware_version;
return m_firmware_version;
}
void UpdateLanguageCode() {
setGetLanguageCode(&this->language_code);
setGetLanguageCode(&m_language_code);
}
u64 GetLanguageCode() const {
return this->language_code;
return m_language_code;
}
bool ShouldTransitionToFatal() const {
return this->transition_to_fatal;
return m_transition_to_fatal;
}
bool ShouldShowExtraInfo() const {
return this->show_extra_info;
return m_show_extra_info;
}
bool IsQuest() const {
return this->quest_flag;
return m_quest_flag;
}
bool IsFatalRebootEnabled() const {
return this->fatal_auto_reboot_enabled;
return m_fatal_auto_reboot_enabled;
}
TimeSpan GetQuestRebootTimeoutInterval() const {
return this->quest_reboot_interval;
return m_quest_reboot_interval;
}
TimeSpan GetFatalRebootTimeoutInterval() const {
return this->fatal_auto_reboot_interval;
return m_fatal_auto_reboot_interval;
}
const char *GetErrorMessage() const {
return this->error_msg;
return m_error_msg;
}
const char *GetErrorDescription() const {
if (this->IsQuest()) {
return this->quest_desc;
return m_quest_desc;
} else {
return this->error_desc;
return m_error_desc;
}
}
};

View File

@@ -18,26 +18,26 @@
namespace ams::fatal::srv {
FatalEventManager::FatalEventManager() : lock() {
FatalEventManager::FatalEventManager() : m_lock() {
/* Just create all the events. */
for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) {
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(this->events[i]), os::EventClearMode_AutoClear, true));
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(m_events[i]), os::EventClearMode_AutoClear, true));
}
}
Result FatalEventManager::GetEvent(const os::SystemEventType **out) {
std::scoped_lock lk{this->lock};
std::scoped_lock lk{m_lock};
/* Only allow GetEvent to succeed NumFatalEvents times. */
R_UNLESS(this->num_events_gotten < FatalEventManager::NumFatalEvents, fatal::ResultTooManyEvents());
R_UNLESS(m_num_events_gotten < FatalEventManager::NumFatalEvents, fatal::ResultTooManyEvents());
*out = std::addressof(this->events[this->num_events_gotten++]);
*out = std::addressof(m_events[m_num_events_gotten++]);
return ResultSuccess();
}
void FatalEventManager::SignalEvents() {
for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) {
os::SignalSystemEvent(std::addressof(this->events[i]));
os::SignalSystemEvent(std::addressof(m_events[i]));
}
}

View File

@@ -24,9 +24,9 @@ namespace ams::fatal::srv {
public:
static constexpr size_t NumFatalEvents = 3;
private:
os::SdkMutex lock;
size_t num_events_gotten = 0;
os::SystemEventType events[NumFatalEvents];
os::SdkMutex m_lock;
size_t m_num_events_gotten = 0;
os::SystemEventType m_events[NumFatalEvents];
public:
FatalEventManager();
Result GetEvent(const os::SystemEventType **out);

View File

@@ -90,8 +90,8 @@ namespace ams::fatal::srv {
}
/* Advance, if we write successfully. */
if (R_SUCCEEDED(fs::WriteFile(this->file, this->offset, data, size, fs::WriteOption::Flush))) {
this->offset += size;
if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::Flush))) {
m_offset += size;
}
}

View File

@@ -22,24 +22,24 @@ namespace ams::fatal::srv {
NON_COPYABLE(ScopedFile);
NON_MOVEABLE(ScopedFile);
private:
fs::FileHandle file;
s64 offset;
bool opened;
fs::FileHandle m_file;
s64 m_offset;
bool m_opened;
public:
ScopedFile(const char *path) : file(), offset(), opened(false) {
ScopedFile(const char *path) : m_file(), m_offset(), m_opened(false) {
if (R_SUCCEEDED(fs::CreateFile(path, 0))) {
this->opened = R_SUCCEEDED(fs::OpenFile(std::addressof(this->file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
m_opened = R_SUCCEEDED(fs::OpenFile(std::addressof(m_file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend));
}
}
~ScopedFile() {
if (this->opened) {
fs::CloseFile(file);
if (m_opened) {
fs::CloseFile(m_file);
}
}
bool IsOpen() const {
return this->opened;
return m_opened;
}
void WriteString(const char *str);

View File

@@ -28,27 +28,27 @@ namespace ams::fatal::srv {
/* Service Context. */
class ServiceContext {
private:
os::Event erpt_event;
os::Event battery_event;
ThrowContext context;
FatalEventManager event_manager;
bool has_thrown;
os::Event m_erpt_event;
os::Event m_battery_event;
ThrowContext m_context;
FatalEventManager m_event_manager;
bool m_has_thrown;
private:
Result TrySetHasThrown() {
R_UNLESS(!this->has_thrown, fatal::ResultAlreadyThrown());
this->has_thrown = true;
R_UNLESS(!m_has_thrown, fatal::ResultAlreadyThrown());
m_has_thrown = true;
return ResultSuccess();
}
public:
ServiceContext()
: erpt_event(os::EventClearMode_ManualClear), battery_event(os::EventClearMode_ManualClear),
context(std::addressof(erpt_event), std::addressof(battery_event)), has_thrown(false)
: m_erpt_event(os::EventClearMode_ManualClear), m_battery_event(os::EventClearMode_ManualClear),
m_context(std::addressof(m_erpt_event), std::addressof(m_battery_event)), m_has_thrown(false)
{
/* ... */
}
Result GetEvent(const os::SystemEventType **out) {
return this->event_manager.GetEvent(out);
return m_event_manager.GetEvent(out);
}
Result ThrowFatal(Result result, os::ProcessId process_id) {
@@ -73,51 +73,51 @@ namespace ams::fatal::srv {
/* Note that we've thrown fatal. */
R_TRY(this->TrySetHasThrown());
/* At this point we have exclusive access to this->context. */
this->context.result = result;
this->context.cpu_ctx = cpu_ctx;
/* At this point we have exclusive access to m_context. */
m_context.result = result;
m_context.cpu_ctx = cpu_ctx;
/* Cap the stack trace to a sane limit. */
if (cpu_ctx.architecture == CpuContext::Architecture_Aarch64) {
this->context.cpu_ctx.aarch64_ctx.stack_trace_size = std::max(size_t(this->context.cpu_ctx.aarch64_ctx.stack_trace_size), aarch64::CpuContext::MaxStackTraceDepth);
m_context.cpu_ctx.aarch64_ctx.stack_trace_size = std::max(size_t(m_context.cpu_ctx.aarch64_ctx.stack_trace_size), aarch64::CpuContext::MaxStackTraceDepth);
} else {
this->context.cpu_ctx.aarch32_ctx.stack_trace_size = std::max(size_t(this->context.cpu_ctx.aarch32_ctx.stack_trace_size), aarch32::CpuContext::MaxStackTraceDepth);
m_context.cpu_ctx.aarch32_ctx.stack_trace_size = std::max(size_t(m_context.cpu_ctx.aarch32_ctx.stack_trace_size), aarch32::CpuContext::MaxStackTraceDepth);
}
/* Get program id. */
pm::info::GetProgramId(std::addressof(this->context.program_id), process_id);
this->context.is_creport = (this->context.program_id == ncm::SystemProgramId::Creport);
pm::info::GetProgramId(std::addressof(m_context.program_id), process_id);
m_context.is_creport = (m_context.program_id == ncm::SystemProgramId::Creport);
if (!this->context.is_creport) {
if (!m_context.is_creport) {
/* On firmware version 2.0.0, use debugging SVCs to collect information. */
if (hos::GetVersion() >= hos::Version_2_0_0) {
fatal::srv::TryCollectDebugInformation(std::addressof(this->context), process_id);
fatal::srv::TryCollectDebugInformation(std::addressof(m_context), process_id);
}
} else {
/* We received info from creport. Parse program id from afsr0. */
if (cpu_ctx.architecture == CpuContext::Architecture_Aarch64) {
this->context.program_id = cpu_ctx.aarch64_ctx.GetProgramIdForAtmosphere();
m_context.program_id = cpu_ctx.aarch64_ctx.GetProgramIdForAtmosphere();
} else {
this->context.program_id = cpu_ctx.aarch32_ctx.GetProgramIdForAtmosphere();
m_context.program_id = cpu_ctx.aarch32_ctx.GetProgramIdForAtmosphere();
}
}
/* Decide whether to generate a report. */
this->context.generate_error_report = (policy == FatalPolicy_ErrorReportAndErrorScreen);
m_context.generate_error_report = (policy == FatalPolicy_ErrorReportAndErrorScreen);
/* Adjust error code (ResultSuccess()/2000-0000 -> err::ResultSystemProgramAbort()/2162-0002). */
if (R_SUCCEEDED(this->context.result)) {
this->context.result = err::ResultSystemProgramAbort();
if (R_SUCCEEDED(m_context.result)) {
m_context.result = err::ResultSystemProgramAbort();
}
switch (policy) {
case FatalPolicy_ErrorReportAndErrorScreen:
case FatalPolicy_ErrorScreen:
/* Signal that we're throwing. */
this->event_manager.SignalEvents();
m_event_manager.SignalEvents();
if (GetFatalConfig().ShouldTransitionToFatal()) {
RunTasks(std::addressof(this->context));
RunTasks(std::addressof(m_context));
}
break;
/* N aborts here. Should we just return an error code? */

View File

@@ -29,7 +29,7 @@ namespace ams::fatal::srv {
class TaskThread {
NON_COPYABLE(TaskThread);
private:
os::ThreadType thread;
os::ThreadType m_thread;
private:
static void RunTaskImpl(void *arg) {
ITask *task = reinterpret_cast<ITask *>(arg);
@@ -41,9 +41,9 @@ namespace ams::fatal::srv {
public:
TaskThread() { /* ... */ }
void StartTask(ITask *task) {
R_ABORT_UNLESS(os::CreateThread(std::addressof(this->thread), RunTaskImpl, task, task->GetStack(), task->GetStackSize(), AMS_GET_SYSTEM_THREAD_PRIORITY(fatalsrv, FatalTaskThread), 3));
os::SetThreadNamePointer(std::addressof(this->thread), AMS_GET_SYSTEM_THREAD_NAME(fatalsrv, FatalTaskThread));
os::StartThread(std::addressof(this->thread));
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_thread), RunTaskImpl, task, task->GetStack(), task->GetStackSize(), AMS_GET_SYSTEM_THREAD_PRIORITY(fatalsrv, FatalTaskThread), 3));
os::SetThreadNamePointer(std::addressof(m_thread), AMS_GET_SYSTEM_THREAD_NAME(fatalsrv, FatalTaskThread));
os::StartThread(std::addressof(m_thread));
}
};
@@ -52,13 +52,13 @@ namespace ams::fatal::srv {
private:
static constexpr size_t MaxTasks = 8;
private:
TaskThread task_threads[MaxTasks];
size_t task_count = 0;
TaskThread m_task_threads[MaxTasks];
size_t m_task_count = 0;
public:
TaskManager() { /* ... */ }
void StartTask(ITask *task) {
AMS_ABORT_UNLESS(this->task_count < MaxTasks);
this->task_threads[this->task_count++].StartTask(task);
AMS_ABORT_UNLESS(m_task_count < MaxTasks);
m_task_threads[m_task_count++].StartTask(task);
}
};

View File

@@ -20,10 +20,10 @@ namespace ams::fatal::srv {
class ITask {
protected:
const ThrowContext *context = nullptr;
const ThrowContext *m_context = nullptr;
public:
void Initialize(const ThrowContext *context) {
this->context = context;
m_context = context;
}
virtual Result Run() = 0;
@@ -38,10 +38,10 @@ namespace ams::fatal::srv {
static constexpr size_t StackSize = _StackSize;
static_assert(util::IsAligned(StackSize, os::MemoryPageSize), "StackSize alignment");
protected:
alignas(os::MemoryPageSize) u8 stack_mem[StackSize] = {};
alignas(os::MemoryPageSize) u8 m_stack_mem[StackSize] = {};
public:
virtual u8 *GetStack() override final {
return this->stack_mem;
return m_stack_mem;
}
virtual size_t GetStackSize() const override final {

View File

@@ -79,61 +79,61 @@ namespace ams::fatal::srv {
/* Open report file. */
{
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(this->context->program_id));
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/%011lu_%016lx.log", timestamp, static_cast<u64>(m_context->program_id));
ScopedFile file(file_path);
if (file.IsOpen()) {
file.WriteFormat("Atmosphère Fatal Report (v1.1):\n");
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", this->context->result.GetValue(), this->context->result.GetModule(), this->context->result.GetDescription());
file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(this->context->program_id));
if (strlen(this->context->proc_name)) {
file.WriteFormat("Process Name: %s\n", this->context->proc_name);
file.WriteFormat("Result: 0x%X (2%03d-%04d)\n\n", m_context->result.GetValue(), m_context->result.GetModule(), m_context->result.GetDescription());
file.WriteFormat("Program ID: %016lx\n", static_cast<u64>(m_context->program_id));
if (strlen(m_context->proc_name)) {
file.WriteFormat("Process Name: %s\n", m_context->proc_name);
}
file.WriteFormat("Firmware: %s (Atmosphère %u.%u.%u-%s)\n", GetFatalConfig().GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision());
if (this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) {
if (m_context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32) {
file.WriteFormat("General Purpose Registers:\n");
for (size_t i = 0; i <= aarch32::RegisterName_PC; i++) {
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
file.WriteFormat( " %3s: %08x\n", aarch32::CpuContext::RegisterNameStrings[i], this->context->cpu_ctx.aarch32_ctx.r[i]);
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
file.WriteFormat( " %3s: %08x\n", aarch32::CpuContext::RegisterNameStrings[i], m_context->cpu_ctx.aarch32_ctx.r[i]);
}
}
file.WriteFormat("Start Address: %08x\n", this->context->cpu_ctx.aarch32_ctx.base_address);
file.WriteFormat("Start Address: %08x\n", m_context->cpu_ctx.aarch32_ctx.base_address);
file.WriteFormat("Stack Trace:\n");
for (unsigned int i = 0; i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02u]: %08x\n", i, this->context->cpu_ctx.aarch32_ctx.stack_trace[i]);
for (unsigned int i = 0; i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02u]: %08x\n", i, m_context->cpu_ctx.aarch32_ctx.stack_trace[i]);
}
} else {
file.WriteFormat("General Purpose Registers:\n");
for (size_t i = 0; i <= aarch64::RegisterName_PC; i++) {
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
file.WriteFormat( " %3s: %016lx\n", aarch64::CpuContext::RegisterNameStrings[i], this->context->cpu_ctx.aarch64_ctx.x[i]);
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
file.WriteFormat( " %3s: %016lx\n", aarch64::CpuContext::RegisterNameStrings[i], m_context->cpu_ctx.aarch64_ctx.x[i]);
}
}
file.WriteFormat("Start Address: %016lx\n", this->context->cpu_ctx.aarch64_ctx.base_address);
file.WriteFormat("Start Address: %016lx\n", m_context->cpu_ctx.aarch64_ctx.base_address);
file.WriteFormat("Stack Trace:\n");
for (unsigned int i = 0; i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02u]: %016lx\n", i, this->context->cpu_ctx.aarch64_ctx.stack_trace[i]);
for (unsigned int i = 0; i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size; i++) {
file.WriteFormat(" ReturnAddress[%02u]: %016lx\n", i, m_context->cpu_ctx.aarch64_ctx.stack_trace[i]);
}
}
if (this->context->stack_dump_size != 0) {
if (m_context->stack_dump_size != 0) {
file.WriteFormat("Stack Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
for (size_t i = 0; i < 0x10; i++) {
const size_t ofs = i * 0x10;
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
this->context->stack_dump_base + ofs, this->context->stack_dump[ofs + 0], this->context->stack_dump[ofs + 1], this->context->stack_dump[ofs + 2], this->context->stack_dump[ofs + 3], this->context->stack_dump[ofs + 4], this->context->stack_dump[ofs + 5], this->context->stack_dump[ofs + 6], this->context->stack_dump[ofs + 7],
this->context->stack_dump[ofs + 8], this->context->stack_dump[ofs + 9], this->context->stack_dump[ofs + 10], this->context->stack_dump[ofs + 11], this->context->stack_dump[ofs + 12], this->context->stack_dump[ofs + 13], this->context->stack_dump[ofs + 14], this->context->stack_dump[ofs + 15]);
m_context->stack_dump_base + ofs, m_context->stack_dump[ofs + 0], m_context->stack_dump[ofs + 1], m_context->stack_dump[ofs + 2], m_context->stack_dump[ofs + 3], m_context->stack_dump[ofs + 4], m_context->stack_dump[ofs + 5], m_context->stack_dump[ofs + 6], m_context->stack_dump[ofs + 7],
m_context->stack_dump[ofs + 8], m_context->stack_dump[ofs + 9], m_context->stack_dump[ofs + 10], m_context->stack_dump[ofs + 11], m_context->stack_dump[ofs + 12], m_context->stack_dump[ofs + 13], m_context->stack_dump[ofs + 14], m_context->stack_dump[ofs + 15]);
}
}
if (this->context->tls_address != 0) {
file.WriteFormat("TLS Address: %016lx\n", this->context->tls_address);
if (m_context->tls_address != 0) {
file.WriteFormat("TLS Address: %016lx\n", m_context->tls_address);
file.WriteFormat("TLS Dump: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
for (size_t i = 0; i < 0x10; i++) {
const size_t ofs = i * 0x10;
file.WriteFormat(" %012lx %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
this->context->tls_address + ofs, this->context->tls_dump[ofs + 0], this->context->tls_dump[ofs + 1], this->context->tls_dump[ofs + 2], this->context->tls_dump[ofs + 3], this->context->tls_dump[ofs + 4], this->context->tls_dump[ofs + 5], this->context->tls_dump[ofs + 6], this->context->tls_dump[ofs + 7],
this->context->tls_dump[ofs + 8], this->context->tls_dump[ofs + 9], this->context->tls_dump[ofs + 10], this->context->tls_dump[ofs + 11], this->context->tls_dump[ofs + 12], this->context->tls_dump[ofs + 13], this->context->tls_dump[ofs + 14], this->context->tls_dump[ofs + 15]);
m_context->tls_address + ofs, m_context->tls_dump[ofs + 0], m_context->tls_dump[ofs + 1], m_context->tls_dump[ofs + 2], m_context->tls_dump[ofs + 3], m_context->tls_dump[ofs + 4], m_context->tls_dump[ofs + 5], m_context->tls_dump[ofs + 6], m_context->tls_dump[ofs + 7],
m_context->tls_dump[ofs + 8], m_context->tls_dump[ofs + 9], m_context->tls_dump[ofs + 10], m_context->tls_dump[ofs + 11], m_context->tls_dump[ofs + 12], m_context->tls_dump[ofs + 13], m_context->tls_dump[ofs + 14], m_context->tls_dump[ofs + 15]);
}
}
}
@@ -141,29 +141,29 @@ namespace ams::fatal::srv {
/* Dump data to file. */
{
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(this->context->program_id));
util::SNPrintf(file_path, sizeof(file_path) - 1, "sdmc:/atmosphere/fatal_reports/dumps/%011lu_%016lx.bin", timestamp, static_cast<u64>(m_context->program_id));
ScopedFile file(file_path);
if (file.IsOpen()) {
file.Write(this->context->tls_dump, sizeof(this->context->tls_dump));
if (this->context->stack_dump_size) {
file.Write(this->context->stack_dump, this->context->stack_dump_size);
file.Write(m_context->tls_dump, sizeof(m_context->tls_dump));
if (m_context->stack_dump_size) {
file.Write(m_context->stack_dump, m_context->stack_dump_size);
}
}
}
}
Result ErrorReportTask::Run() {
if (this->context->generate_error_report) {
if (m_context->generate_error_report) {
/* Here, Nintendo creates an error report with erpt. AMS will not do that. */
}
/* Save report to SD card. */
if (!this->context->is_creport) {
if (!m_context->is_creport) {
this->SaveReportToSdCard();
}
/* Signal we're done with our job. */
this->context->erpt_event->Signal();
m_context->erpt_event->Signal();
return ResultSuccess();
}

View File

@@ -53,17 +53,17 @@ namespace ams::fatal::srv {
class RebootTimingObserver {
private:
os::Tick start_tick;
TimeSpan interval;
bool flag;
os::Tick m_start_tick;
TimeSpan m_interval;
bool m_flag;
public:
RebootTimingObserver(bool flag, TimeSpan iv) : start_tick(os::GetSystemTick()), interval(iv), flag(flag) {
RebootTimingObserver(bool flag, TimeSpan iv) : m_start_tick(os::GetSystemTick()), m_interval(iv), m_flag(flag) {
/* ... */
}
bool IsRebootTiming() const {
auto current_tick = os::GetSystemTick();
return this->flag && (current_tick - this->start_tick).ToTimeSpan() >= this->interval;
return m_flag && (current_tick - m_start_tick).ToTimeSpan() >= m_interval;
}
};
@@ -114,13 +114,13 @@ namespace ams::fatal::srv {
/* Check the battery state, and shutdown on low voltage. */
if (R_FAILED(psmGetBatteryVoltageState(std::addressof(bv_state))) || bv_state == PsmBatteryVoltageState_NeedsShutdown) {
/* Wait a second for the error report task to finish. */
this->context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
m_context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
this->TryShutdown();
return;
}
/* Signal we've checked the battery at least once. */
this->context->battery_event->Signal();
m_context->battery_event->Signal();
/* Loop querying voltage state every 5 seconds. */
while (true) {
@@ -148,7 +148,7 @@ namespace ams::fatal::srv {
void PowerButtonObserveTask::WaitForPowerButton() {
/* Wait up to a second for error report generation to finish. */
this->context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
m_context->erpt_event->TimedWait(TimeSpan::FromSeconds(1));
/* Force a reboot after some time if kiosk unit. */
const auto &config = GetFatalConfig();

View File

@@ -70,10 +70,10 @@ namespace ams::fatal::srv {
/* Task definitions. */
class ShowFatalTask : public ITaskWithStack<0x8000> {
private:
ViDisplay display;
ViLayer layer;
NWindow win;
NvMap map;
ViDisplay m_display;
ViLayer m_layer;
NWindow m_win;
NvMap m_map;
private:
Result SetupDisplayInternal();
Result SetupDisplayExternal();
@@ -156,19 +156,19 @@ namespace ams::fatal::srv {
R_TRY(SetupDisplayExternal());
/* Open the default display. */
R_TRY(viOpenDefaultDisplay(std::addressof(this->display)));
R_TRY(viOpenDefaultDisplay(std::addressof(m_display)));
/* Reset the display magnification to its default value. */
s32 display_width, display_height;
R_TRY(viGetDisplayLogicalResolution(std::addressof(this->display), std::addressof(display_width), std::addressof(display_height)));
R_TRY(viGetDisplayLogicalResolution(std::addressof(m_display), std::addressof(display_width), std::addressof(display_height)));
/* viSetDisplayMagnification was added in 3.0.0. */
if (hos::GetVersion() >= hos::Version_3_0_0) {
R_TRY(viSetDisplayMagnification(std::addressof(this->display), 0, 0, display_width, display_height));
R_TRY(viSetDisplayMagnification(std::addressof(m_display), 0, 0, display_width, display_height));
}
/* Create layer to draw to. */
R_TRY(viCreateLayer(std::addressof(this->display), std::addressof(this->layer)));
R_TRY(viCreateLayer(std::addressof(m_display), std::addressof(m_layer)));
/* Setup the layer. */
{
@@ -183,16 +183,16 @@ namespace ams::fatal::srv {
const float layer_x = static_cast<float>((display_width - LayerWidth) / 2);
const float layer_y = static_cast<float>((display_height - LayerHeight) / 2);
R_TRY(viSetLayerSize(std::addressof(this->layer), LayerWidth, LayerHeight));
R_TRY(viSetLayerSize(std::addressof(m_layer), LayerWidth, LayerHeight));
/* Set the layer's Z at display maximum, to be above everything else .*/
R_TRY(viSetLayerZ(std::addressof(this->layer), FatalLayerZ));
R_TRY(viSetLayerZ(std::addressof(m_layer), FatalLayerZ));
/* Center the layer in the screen. */
R_TRY(viSetLayerPosition(std::addressof(this->layer), layer_x, layer_y));
R_TRY(viSetLayerPosition(std::addressof(m_layer), layer_x, layer_y));
/* Create framebuffer. */
R_TRY(nwindowCreateFromLayer(std::addressof(this->win), std::addressof(this->layer)));
R_TRY(nwindowCreateFromLayer(std::addressof(m_win), std::addressof(m_layer)));
R_TRY(this->InitializeNativeWindow());
}
@@ -229,14 +229,14 @@ namespace ams::fatal::srv {
/* Draw error message and firmware. */
font::SetPosition(start_x, start_y);
font::SetFontSize(16.0f);
font::PrintFormat(config.GetErrorMessage(), this->context->result.GetModule(), this->context->result.GetDescription(), this->context->result.GetValue());
font::PrintFormat(config.GetErrorMessage(), m_context->result.GetModule(), m_context->result.GetDescription(), m_context->result.GetValue());
font::AddSpacingLines(0.5f);
font::PrintFormatLine( "Program: %016lX", static_cast<u64>(this->context->program_id));
font::PrintFormatLine( "Program: %016lX", static_cast<u64>(m_context->program_id));
font::AddSpacingLines(0.5f);
font::PrintFormatLine("Firmware: %s (Atmosphère %u.%u.%u-%s)", config.GetFirmwareVersion().display_version, ATMOSPHERE_RELEASE_VERSION, ams::GetGitRevision());
font::AddSpacingLines(1.5f);
if (!exosphere::ResultVersionMismatch::Includes(this->context->result)) {
if (!exosphere::ResultVersionMismatch::Includes(m_context->result)) {
font::Print(config.GetErrorDescription());
} else {
/* Print a special message for atmosphere version mismatch. */
@@ -260,7 +260,7 @@ namespace ams::fatal::srv {
u32 pc_x = 0;
/* Note architecutre. */
const bool is_aarch32 = this->context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32;
const bool is_aarch32 = m_context->cpu_ctx.architecture == CpuContext::Architecture_Aarch32;
/* Print GPRs. */
font::SetFontSize(14.0f);
@@ -273,8 +273,8 @@ namespace ams::fatal::srv {
u32 x = font::GetX();
font::PrintFormat("%s:", aarch32::CpuContext::RegisterNameStrings[i]);
font::SetPosition(x + 47, font::GetY());
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.r[i]);
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i))) {
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.r[i]);
font::PrintMonospaceBlank(8);
} else {
font::PrintMonospaceBlank(16);
@@ -283,8 +283,8 @@ namespace ams::fatal::srv {
pc_x = font::GetX();
font::PrintFormat("%s:", aarch32::CpuContext::RegisterNameStrings[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
font::SetPosition(pc_x + 47, font::GetY());
if (this->context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i + (aarch32::RegisterName_GeneralPurposeCount / 2)))) {
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.r[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
if (m_context->cpu_ctx.aarch32_ctx.HasRegisterValue(static_cast<aarch32::RegisterName>(i + (aarch32::RegisterName_GeneralPurposeCount / 2)))) {
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.r[i + (aarch32::RegisterName_GeneralPurposeCount / 2)]);
font::PrintMonospaceBlank(8);
} else {
font::PrintMonospaceBlank(16);
@@ -303,8 +303,8 @@ namespace ams::fatal::srv {
u32 x = font::GetX();
font::PrintFormat("%s:", aarch64::CpuContext::RegisterNameStrings[i]);
font::SetPosition(x + 47, font::GetY());
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.x[i]);
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i))) {
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.x[i]);
} else {
font::PrintMonospaceBlank(16);
}
@@ -312,8 +312,8 @@ namespace ams::fatal::srv {
pc_x = font::GetX();
font::PrintFormat("%s:", aarch64::CpuContext::RegisterNameStrings[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
font::SetPosition(pc_x + 47, font::GetY());
if (this->context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i + (aarch64::RegisterName_GeneralPurposeCount / 2)))) {
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.x[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
if (m_context->cpu_ctx.aarch64_ctx.HasRegisterValue(static_cast<aarch64::RegisterName>(i + (aarch64::RegisterName_GeneralPurposeCount / 2)))) {
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.x[i + (aarch64::RegisterName_GeneralPurposeCount / 2)]);
} else {
font::PrintMonospaceBlank(16);
}
@@ -336,17 +336,17 @@ namespace ams::fatal::srv {
font::SetPosition(x + 47, font::GetY());
}
if (is_aarch32) {
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.pc);
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.pc);
} else {
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.pc);
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.pc);
}
/* Print Backtrace. */
u32 bt_size;
if (is_aarch32) {
bt_size = this->context->cpu_ctx.aarch32_ctx.stack_trace_size;
bt_size = m_context->cpu_ctx.aarch32_ctx.stack_trace_size;
} else {
bt_size = this->context->cpu_ctx.aarch64_ctx.stack_trace_size;
bt_size = m_context->cpu_ctx.aarch64_ctx.stack_trace_size;
}
@@ -354,29 +354,29 @@ namespace ams::fatal::srv {
if (bt_size == 0) {
if (is_aarch32) {
font::Print("Start Address: ");
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.base_address);
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.base_address);
font::PrintLine("");
} else {
font::Print("Start Address: ");
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.base_address);
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.base_address);
font::PrintLine("");
}
} else {
if (is_aarch32) {
font::Print("Backtrace - Start Address: ");
font::PrintMonospaceU32(this->context->cpu_ctx.aarch32_ctx.base_address);
font::PrintMonospaceU32(m_context->cpu_ctx.aarch32_ctx.base_address);
font::PrintLine("");
font::AddSpacingLines(0.5f);
for (u32 i = 0; i < aarch32::CpuContext::MaxStackTraceDepth / 2; i++) {
u32 bt_cur = 0, bt_next = 0;
if (i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
bt_cur = this->context->cpu_ctx.aarch32_ctx.stack_trace[i];
if (i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
bt_cur = m_context->cpu_ctx.aarch32_ctx.stack_trace[i];
}
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
bt_next = this->context->cpu_ctx.aarch32_ctx.stack_trace[i + aarch32::CpuContext::MaxStackTraceDepth / 2];
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
bt_next = m_context->cpu_ctx.aarch32_ctx.stack_trace[i + aarch32::CpuContext::MaxStackTraceDepth / 2];
}
if (i < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
if (i < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
u32 x = font::GetX();
font::PrintFormat("BT[%02d]: ", i);
font::SetPosition(x + 72, font::GetY());
@@ -385,7 +385,7 @@ namespace ams::fatal::srv {
font::Print(" ");
}
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch32_ctx.stack_trace_size) {
if (i + aarch32::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch32_ctx.stack_trace_size) {
u32 x = font::GetX();
font::PrintFormat("BT[%02d]: ", i + aarch32::CpuContext::MaxStackTraceDepth / 2);
font::SetPosition(x + 72, font::GetY());
@@ -398,19 +398,19 @@ namespace ams::fatal::srv {
}
} else {
font::Print("Backtrace - Start Address: ");
font::PrintMonospaceU64(this->context->cpu_ctx.aarch64_ctx.base_address);
font::PrintMonospaceU64(m_context->cpu_ctx.aarch64_ctx.base_address);
font::PrintLine("");
font::AddSpacingLines(0.5f);
for (u32 i = 0; i < aarch64::CpuContext::MaxStackTraceDepth / 2; i++) {
u64 bt_cur = 0, bt_next = 0;
if (i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
bt_cur = this->context->cpu_ctx.aarch64_ctx.stack_trace[i];
if (i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
bt_cur = m_context->cpu_ctx.aarch64_ctx.stack_trace[i];
}
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
bt_next = this->context->cpu_ctx.aarch64_ctx.stack_trace[i + aarch64::CpuContext::MaxStackTraceDepth / 2];
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
bt_next = m_context->cpu_ctx.aarch64_ctx.stack_trace[i + aarch64::CpuContext::MaxStackTraceDepth / 2];
}
if (i < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
if (i < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
u32 x = font::GetX();
font::PrintFormat("BT[%02d]: ", i);
font::SetPosition(x + 72, font::GetY());
@@ -418,7 +418,7 @@ namespace ams::fatal::srv {
font::Print(" ");
}
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < this->context->cpu_ctx.aarch64_ctx.stack_trace_size) {
if (i + aarch64::CpuContext::MaxStackTraceDepth / 2 < m_context->cpu_ctx.aarch64_ctx.stack_trace_size) {
u32 x = font::GetX();
font::PrintFormat("BT[%02d]: ", i + aarch64::CpuContext::MaxStackTraceDepth / 2);
font::SetPosition(x + 72, font::GetY());
@@ -439,7 +439,7 @@ namespace ams::fatal::srv {
R_TRY(nvFenceInit());
/* Create nvmap. */
R_TRY(nvMapCreate(std::addressof(this->map), g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
R_TRY(nvMapCreate(std::addressof(m_map), g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
/* Setup graphics buffer. */
{
@@ -458,14 +458,14 @@ namespace ams::fatal::srv {
grbuf.planes[0].layout = NvLayout_BlockLinear;
grbuf.planes[0].kind = NvKind_Generic_16BX2;
grbuf.planes[0].block_height_log2 = 4;
grbuf.nvmap_id = nvMapGetId(std::addressof(this->map));
grbuf.nvmap_id = nvMapGetId(std::addressof(m_map));
grbuf.stride = FatalScreenWidthAligned;
grbuf.total_size = sizeof(g_framebuffer_memory);
grbuf.planes[0].pitch = FatalScreenWidthAlignedBytes;
grbuf.planes[0].size = sizeof(g_framebuffer_memory);
grbuf.planes[0].offset = 0;
R_TRY(nwindowConfigureBuffer(std::addressof(this->win), 0, std::addressof(grbuf)));
R_TRY(nwindowConfigureBuffer(std::addressof(m_win), 0, std::addressof(grbuf)));
}
return ResultSuccess();
@@ -473,9 +473,9 @@ namespace ams::fatal::srv {
void ShowFatalTask::DisplayPreRenderedFrame() {
s32 slot;
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(this->win), std::addressof(slot), nullptr));
R_ABORT_UNLESS(nwindowDequeueBuffer(std::addressof(m_win), std::addressof(slot), nullptr));
dd::FlushDataCache(g_framebuffer_memory, sizeof(g_framebuffer_memory));
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(this->win), this->win.cur_slot, NULL));
R_ABORT_UNLESS(nwindowQueueBuffer(std::addressof(m_win), m_win.cur_slot, NULL));
}
Result ShowFatalTask::ShowFatal() {
@@ -493,7 +493,7 @@ namespace ams::fatal::srv {
Result ShowFatalTask::Run() {
/* Don't show the fatal error screen until we've verified the battery is okay. */
this->context->battery_event->Wait();
m_context->battery_event->Wait();
return ShowFatal();
}

View File

@@ -59,15 +59,15 @@ namespace ams::ldr::caps {
using IdBits = CapabilityField<0, static_cast<size_t>(Id) + 1>; \
static constexpr u32 IdBitsValue = (static_cast<u32>(1) << static_cast<size_t>(Id)) - 1; \
private: \
util::BitPack32 value; \
util::BitPack32 m_value; \
private: \
template<typename FieldType> \
constexpr ALWAYS_INLINE typename FieldType::Type Get() const { return this->value.Get<FieldType>(); } \
constexpr ALWAYS_INLINE typename FieldType::Type Get() const { return m_value.Get<FieldType>(); } \
template<typename FieldType> \
constexpr ALWAYS_INLINE void Set(typename FieldType::Type fv) { this->value.Set<FieldType>(fv); } \
constexpr ALWAYS_INLINE u32 GetValue() const { return this->value.value; } \
constexpr ALWAYS_INLINE void Set(typename FieldType::Type fv) { m_value.Set<FieldType>(fv); } \
constexpr ALWAYS_INLINE u32 GetValue() const { return m_value.value; } \
public: \
constexpr ALWAYS_INLINE CAPABILITY_CLASS_NAME(id)(util::BitPack32 v) : value{v} { /* ... */ } \
constexpr ALWAYS_INLINE CAPABILITY_CLASS_NAME(id)(util::BitPack32 v) : m_value{v} { /* ... */ } \
\
static constexpr CAPABILITY_CLASS_NAME(id) Decode(util::BitPack32 v) { return CAPABILITY_CLASS_NAME(id)(v); } \
\

View File

@@ -25,23 +25,23 @@ namespace ams::ldr {
}
/* ScopedCodeMount functionality. */
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc) : lk(g_scoped_code_mount_lock), has_status(false), mounted_ams(false), mounted_sd_or_code(false), mounted_code(false) {
this->result = this->Initialize(loc);
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
m_result = this->Initialize(loc);
}
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o) : lk(g_scoped_code_mount_lock), override_status(o), has_status(true), mounted_ams(false), mounted_sd_or_code(false), mounted_code(false) {
this->result = this->Initialize(loc);
ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) {
m_result = this->Initialize(loc);
}
ScopedCodeMount::~ScopedCodeMount() {
/* Unmount filesystems. */
if (this->mounted_ams) {
if (m_mounted_ams) {
fs::Unmount(AtmosphereCodeMountName);
}
if (this->mounted_sd_or_code) {
if (m_mounted_sd_or_code) {
fs::Unmount(SdOrCodeMountName);
}
if (this->mounted_code) {
if (m_mounted_code) {
fs::Unmount(CodeMountName);
}
}
@@ -49,7 +49,7 @@ namespace ams::ldr {
Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc) {
/* Capture override status, if necessary. */
this->EnsureOverrideStatus(loc);
AMS_ABORT_UNLESS(this->has_status);
AMS_ABORT_UNLESS(m_has_status);
/* Get the content path. */
char content_path[fs::EntryNameLengthMax + 1] = "/";
@@ -58,27 +58,27 @@ namespace ams::ldr {
}
/* Mount the atmosphere code file system. */
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(this->ams_code_verification_data), AtmosphereCodeMountName, content_path, loc.program_id, this->override_status.IsHbl(), this->override_status.IsProgramSpecific()));
this->mounted_ams = true;
R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific()));
m_mounted_ams = true;
/* Mount the sd or base code file system. */
R_TRY(fs::MountCodeForAtmosphere(std::addressof(this->sd_or_base_code_verification_data), SdOrCodeMountName, content_path, loc.program_id));
this->mounted_sd_or_code = true;
R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, loc.program_id));
m_mounted_sd_or_code = true;
/* Mount the base code file system. */
if (R_SUCCEEDED(fs::MountCode(std::addressof(this->base_code_verification_data), CodeMountName, content_path, loc.program_id))) {
this->mounted_code = true;
if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, loc.program_id))) {
m_mounted_code = true;
}
return ResultSuccess();
}
void ScopedCodeMount::EnsureOverrideStatus(const ncm::ProgramLocation &loc) {
if (this->has_status) {
if (m_has_status) {
return;
}
this->override_status = cfg::CaptureOverrideStatus(loc.program_id);
this->has_status = true;
m_override_status = cfg::CaptureOverrideStatus(loc.program_id);
m_has_status = true;
}
/* Redirection API. */

View File

@@ -23,40 +23,40 @@ namespace ams::ldr {
NON_COPYABLE(ScopedCodeMount);
NON_MOVEABLE(ScopedCodeMount);
private:
std::scoped_lock<os::SdkMutex> lk;
cfg::OverrideStatus override_status;
fs::CodeVerificationData ams_code_verification_data;
fs::CodeVerificationData sd_or_base_code_verification_data;
fs::CodeVerificationData base_code_verification_data;
Result result;
bool has_status;
bool mounted_ams;
bool mounted_sd_or_code;
bool mounted_code;
std::scoped_lock<os::SdkMutex> m_lk;
cfg::OverrideStatus m_override_status;
fs::CodeVerificationData m_ams_code_verification_data;
fs::CodeVerificationData m_sd_or_base_code_verification_data;
fs::CodeVerificationData m_base_code_verification_data;
Result m_result;
bool m_has_status;
bool m_mounted_ams;
bool m_mounted_sd_or_code;
bool m_mounted_code;
public:
ScopedCodeMount(const ncm::ProgramLocation &loc);
ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
~ScopedCodeMount();
Result GetResult() const {
return this->result;
return m_result;
}
const cfg::OverrideStatus &GetOverrideStatus() const {
AMS_ABORT_UNLESS(this->has_status);
return this->override_status;
AMS_ABORT_UNLESS(m_has_status);
return m_override_status;
}
const fs::CodeVerificationData &GetAtmosphereCodeVerificationData() const {
return this->ams_code_verification_data;
return m_ams_code_verification_data;
}
const fs::CodeVerificationData &GetSdOrBaseCodeVerificationData() const {
return this->sd_or_base_code_verification_data;
return m_sd_or_base_code_verification_data;
}
const fs::CodeVerificationData &GetCodeVerificationData() const {
return this->base_code_verification_data;
return m_base_code_verification_data;
}
private:
Result Initialize(const ncm::ProgramLocation &loc);

View File

@@ -18,9 +18,9 @@
namespace ams::pm::impl {
ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : process_id(pid), pin_id(pin), loc(l), status(s), handle(h), state(svc::ProcessState_Created), flags(0) {
os::InitializeMultiWaitHolder(std::addressof(this->multi_wait_holder), this->handle);
os::SetMultiWaitHolderUserData(std::addressof(this->multi_wait_holder), reinterpret_cast<uintptr_t>(this));
ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0) {
os::InitializeMultiWaitHolder(std::addressof(m_multi_wait_holder), m_handle);
os::SetMultiWaitHolderUserData(std::addressof(m_multi_wait_holder), reinterpret_cast<uintptr_t>(this));
}
ProcessInfo::~ProcessInfo() {
@@ -28,18 +28,18 @@ namespace ams::pm::impl {
}
void ProcessInfo::Cleanup() {
if (this->handle != os::InvalidNativeHandle) {
if (m_handle != os::InvalidNativeHandle) {
/* Unregister the process. */
fsprUnregisterProgram(this->process_id.value);
sm::manager::UnregisterProcess(this->process_id);
ldr::pm::UnpinProgram(this->pin_id);
fsprUnregisterProgram(m_process_id.value);
sm::manager::UnregisterProcess(m_process_id);
ldr::pm::UnpinProgram(m_pin_id);
/* Close the process's handle. */
os::CloseNativeHandle(this->handle);
this->handle = os::InvalidNativeHandle;
os::CloseNativeHandle(m_handle);
m_handle = os::InvalidNativeHandle;
/* Unlink the process from its multi wait. */
os::UnlinkMultiWaitHolder(std::addressof(this->multi_wait_holder));
os::UnlinkMultiWaitHolder(std::addressof(m_multi_wait_holder));
}
}

View File

@@ -38,26 +38,26 @@ namespace ams::pm::impl {
Flag_UnhandledException = (1 << 9),
};
private:
util::IntrusiveListNode list_node;
const os::ProcessId process_id;
const ldr::PinId pin_id;
const ncm::ProgramLocation loc;
const cfg::OverrideStatus status;
os::NativeHandle handle;
svc::ProcessState state;
u32 flags;
os::MultiWaitHolderType multi_wait_holder;
util::IntrusiveListNode m_list_node;
const os::ProcessId m_process_id;
const ldr::PinId m_pin_id;
const ncm::ProgramLocation m_loc;
const cfg::OverrideStatus m_status;
os::NativeHandle m_handle;
svc::ProcessState m_state;
u32 m_flags;
os::MultiWaitHolderType m_multi_wait_holder;
private:
void SetFlag(Flag flag) {
this->flags |= flag;
m_flags |= flag;
}
void ClearFlag(Flag flag) {
this->flags &= ~flag;
m_flags &= ~flag;
}
bool HasFlag(Flag flag) const {
return (this->flags & flag);
return (m_flags & flag);
}
public:
ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s);
@@ -65,43 +65,43 @@ namespace ams::pm::impl {
void Cleanup();
void LinkToMultiWait(os::MultiWaitType &multi_wait) {
os::LinkMultiWaitHolder(std::addressof(multi_wait), std::addressof(this->multi_wait_holder));
os::LinkMultiWaitHolder(std::addressof(multi_wait), std::addressof(m_multi_wait_holder));
}
os::NativeHandle GetHandle() const {
return this->handle;
return m_handle;
}
os::ProcessId GetProcessId() const {
return this->process_id;
return m_process_id;
}
ldr::PinId GetPinId() const {
return this->pin_id;
return m_pin_id;
}
const ncm::ProgramLocation &GetProgramLocation() const {
return this->loc;
return m_loc;
}
const cfg::OverrideStatus &GetOverrideStatus() const {
return this->status;
return m_status;
}
svc::ProcessState GetState() const {
return this->state;
return m_state;
}
void SetState(svc::ProcessState state) {
this->state = state;
m_state = state;
}
bool HasStarted() const {
return this->state != svc::ProcessState_Created && this->state != svc::ProcessState_CreatedAttached;
return m_state != svc::ProcessState_Created && m_state != svc::ProcessState_CreatedAttached;
}
bool HasTerminated() const {
return this->state == svc::ProcessState_Terminated;
return m_state == svc::ProcessState_Terminated;
}
#define DEFINE_FLAG_SET(flag) \
@@ -165,18 +165,18 @@ namespace ams::pm::impl {
#undef DEFINE_FLAG_CLEAR
};
class ProcessList final : public util::IntrusiveListMemberTraits<&ProcessInfo::list_node>::ListType {
class ProcessList final : public util::IntrusiveListMemberTraits<&ProcessInfo::m_list_node>::ListType {
private:
os::SdkMutex lock;
os::SdkMutex m_lock;
public:
constexpr ProcessList() : lock() { /* ... */ }
constexpr ProcessList() : m_lock() { /* ... */ }
void Lock() {
this->lock.Lock();
m_lock.Lock();
}
void Unlock() {
this->lock.Unlock();
m_lock.Unlock();
}
void Remove(ProcessInfo *process_info) {
@@ -184,18 +184,18 @@ namespace ams::pm::impl {
}
ProcessInfo *Find(os::ProcessId process_id) {
for (auto it = this->begin(); it != this->end(); it++) {
if ((*it).GetProcessId() == process_id) {
return std::addressof(*it);
for (auto &info : *this) {
if (info.GetProcessId() == process_id) {
return std::addressof(info);
}
}
return nullptr;
}
ProcessInfo *Find(ncm::ProgramId program_id) {
for (auto it = this->begin(); it != this->end(); it++) {
if ((*it).GetProgramLocation().program_id == program_id) {
return std::addressof(*it);
for (auto &info : *this) {
if (info.GetProgramLocation().program_id == program_id) {
return std::addressof(info);
}
}
return nullptr;
@@ -205,30 +205,30 @@ namespace ams::pm::impl {
class ProcessListAccessor final {
private:
ProcessList &list;
ProcessList &m_list;
public:
explicit ProcessListAccessor(ProcessList &l) : list(l) {
this->list.Lock();
explicit ProcessListAccessor(ProcessList &l) : m_list(l) {
m_list.Lock();
}
~ProcessListAccessor() {
this->list.Unlock();
m_list.Unlock();
}
ProcessList *operator->() {
return std::addressof(this->list);
return std::addressof(m_list);
}
const ProcessList *operator->() const {
return std::addressof(this->list);
return std::addressof(m_list);
}
ProcessList &operator*() {
return this->list;
return m_list;
}
const ProcessList &operator*() const {
return this->list;
return m_list;
}
};

View File

@@ -78,27 +78,27 @@ namespace ams::pm::impl {
NON_MOVEABLE(ProcessInfoAllocator);
static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small.");
private:
util::TypedStorage<ProcessInfo> process_info_storages[MaxProcessInfos]{};
bool process_info_allocated[MaxProcessInfos]{};
os::SdkMutex lock{};
util::TypedStorage<ProcessInfo> m_process_info_storages[MaxProcessInfos]{};
bool m_process_info_allocated[MaxProcessInfos]{};
os::SdkMutex m_lock{};
private:
constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const {
return process_info - GetPointer(this->process_info_storages[0]);
return process_info - GetPointer(m_process_info_storages[0]);
}
public:
constexpr ProcessInfoAllocator() = default;
template<typename... Args>
ProcessInfo *AllocateProcessInfo(Args &&... args) {
std::scoped_lock lk(this->lock);
std::scoped_lock lk(m_lock);
for (size_t i = 0; i < MaxProcessInfos; i++) {
if (!this->process_info_allocated[i]) {
this->process_info_allocated[i] = true;
if (!m_process_info_allocated[i]) {
m_process_info_allocated[i] = true;
std::memset(this->process_info_storages + i, 0, sizeof(this->process_info_storages[i]));
std::memset(m_process_info_storages + i, 0, sizeof(m_process_info_storages[i]));
return util::ConstructAt(this->process_info_storages[i], std::forward<Args>(args)...);
return util::ConstructAt(m_process_info_storages[i], std::forward<Args>(args)...);
}
}
@@ -106,14 +106,14 @@ namespace ams::pm::impl {
}
void FreeProcessInfo(ProcessInfo *process_info) {
std::scoped_lock lk(this->lock);
std::scoped_lock lk(m_lock);
const size_t index = this->GetProcessInfoIndex(process_info);
AMS_ABORT_UNLESS(index < MaxProcessInfos);
AMS_ABORT_UNLESS(this->process_info_allocated[index]);
AMS_ABORT_UNLESS(m_process_info_allocated[index]);
util::DestroyAt(this->process_info_storages[index]);
this->process_info_allocated[index] = false;
util::DestroyAt(m_process_info_storages[index]);
m_process_info_allocated[index] = false;
}
};

View File

@@ -74,206 +74,277 @@ namespace ams::ro::impl {
};
struct ProcessContext {
bool nro_in_use[MaxNroInfos];
bool nrr_in_use[MaxNrrInfos];
NroInfo nro_infos[MaxNroInfos];
NrrInfo nrr_infos[MaxNrrInfos];
os::NativeHandle process_handle;
os::ProcessId process_id;
bool in_use;
private:
bool m_nro_in_use[MaxNroInfos]{};
bool m_nrr_in_use[MaxNrrInfos]{};
NroInfo m_nro_infos[MaxNroInfos]{};
NrrInfo m_nrr_infos[MaxNrrInfos]{};
os::NativeHandle m_process_handle = os::InvalidNativeHandle;
os::ProcessId m_process_id = os::InvalidProcessId;
bool m_in_use{};
public:
constexpr ProcessContext() = default;
ncm::ProgramId GetProgramId(os::NativeHandle other_process_h) const {
/* Automatically select a handle, allowing for override. */
if (other_process_h != os::InvalidNativeHandle) {
return os::GetProgramId(other_process_h);
} else {
return os::GetProgramId(this->process_handle);
void Initialize(os::NativeHandle process_handle, os::ProcessId process_id) {
AMS_ABORT_UNLESS(!m_in_use);
std::memset(m_nro_in_use, 0, sizeof(m_nro_in_use));
std::memset(m_nrr_in_use, 0, sizeof(m_nrr_in_use));
std::memset(m_nro_infos, 0, sizeof(m_nro_infos));
std::memset(m_nrr_infos, 0, sizeof(m_nrr_infos));
m_process_handle = process_handle;
m_process_id = process_id;
m_in_use = true;
}
}
Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (this->nrr_in_use[i] && this->nrr_infos[i].nrr_heap_address == nrr_heap_address) {
if (out != nullptr) {
*out = this->nrr_infos + i;
void Finalize() {
AMS_ABORT_UNLESS(m_in_use);
if (m_process_handle != os::InvalidNativeHandle) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (m_nrr_in_use[i]) {
UnmapNrr(m_process_handle, m_nrr_infos[i].mapped_header, m_nrr_infos[i].nrr_heap_address, m_nrr_infos[i].nrr_heap_size, m_nrr_infos[i].mapped_code_address);
}
}
os::CloseNativeHandle(m_process_handle);
}
std::memset(m_nro_in_use, 0, sizeof(m_nro_in_use));
std::memset(m_nrr_in_use, 0, sizeof(m_nrr_in_use));
std::memset(m_nro_infos, 0, sizeof(m_nro_infos));
std::memset(m_nrr_infos, 0, sizeof(m_nrr_infos));
m_process_handle = os::InvalidNativeHandle;
m_process_id = os::InvalidProcessId;
m_in_use = false;
}
os::NativeHandle GetProcessHandle() const {
return m_process_handle;
}
os::ProcessId GetProcessId() const {
return m_process_id;
}
bool IsFree() const {
return !m_in_use;
}
ncm::ProgramId GetProgramId(os::NativeHandle other_process_h) const {
/* Automatically select a handle, allowing for override. */
if (other_process_h != os::InvalidNativeHandle) {
return os::GetProgramId(other_process_h);
} else {
return os::GetProgramId(m_process_handle);
}
}
Result GetNrrInfoByAddress(NrrInfo **out, u64 nrr_heap_address) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (m_nrr_in_use[i] && m_nrr_infos[i].nrr_heap_address == nrr_heap_address) {
if (out != nullptr) {
*out = m_nrr_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultNotRegistered();
}
Result GetFreeNrrInfo(NrrInfo **out) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (!m_nrr_in_use[i]) {
if (out != nullptr) {
*out = m_nrr_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultTooManyNrr();
}
Result GetNroInfoByAddress(NroInfo **out, u64 nro_address) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (m_nro_in_use[i] && m_nro_infos[i].base_address == nro_address) {
if (out != nullptr) {
*out = m_nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultNotLoaded();
}
Result GetNroInfoByModuleId(NroInfo **out, const ModuleId *module_id) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (m_nro_in_use[i] && std::memcmp(std::addressof(m_nro_infos[i].module_id), module_id, sizeof(*module_id)) == 0) {
if (out != nullptr) {
*out = m_nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultNotLoaded();
}
Result GetFreeNroInfo(NroInfo **out) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (!m_nro_in_use[i]) {
if (out != nullptr) {
*out = m_nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultTooManyNro();
}
Result ValidateHasNroHash(const NroHeader *nro_header) const {
/* Calculate hash. */
Sha256Hash hash;
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), nro_header, nro_header->GetSize());
for (size_t i = 0; i < MaxNrrInfos; i++) {
/* Ensure we only check NRRs that are used. */
if (!m_nrr_in_use[i]) {
continue;
}
/* Get the mapped header, ensure that it has hashes. */
const NrrHeader *mapped_nrr_header = m_nrr_infos[i].mapped_header;
const size_t mapped_num_hashes = mapped_nrr_header->GetNumHashes();
if (mapped_num_hashes == 0) {
continue;
}
/* Locate the hash within the mapped array. */
const Sha256Hash *mapped_nro_hashes_start = reinterpret_cast<const Sha256Hash *>(mapped_nrr_header->GetHashes());
const Sha256Hash *mapped_nro_hashes_end = mapped_nro_hashes_start + mapped_nrr_header->GetNumHashes();
const Sha256Hash *mapped_lower_bound = std::lower_bound(mapped_nro_hashes_start, mapped_nro_hashes_end, hash);
if (mapped_lower_bound == mapped_nro_hashes_end || (*mapped_lower_bound != hash)) {
continue;
}
/* Check that the hash entry is valid, since our heuristic passed. */
const void *nrr_hash = std::addressof(m_nrr_infos[i].signed_area_hash);
const void *signed_area = m_nrr_infos[i].cached_signed_area;
const size_t signed_area_size = m_nrr_infos[i].cached_signed_area_size;
const size_t hashes_offset = m_nrr_infos[i].cached_hashes_offset;
const size_t num_hashes = m_nrr_infos[i].cached_num_hashes;
const u8 *hash_table = reinterpret_cast<const u8 *>(mapped_nro_hashes_start);
if (!ValidateNrrHashTableEntry(signed_area, signed_area_size, hashes_offset, num_hashes, nrr_hash, hash_table, std::addressof(hash))) {
continue;
}
/* The hash is valid! */
return ResultSuccess();
}
return ro::ResultNotAuthorized();
}
return ro::ResultNotRegistered();
}
Result GetFreeNrrInfo(NrrInfo **out) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (!this->nrr_in_use[i]) {
if (out != nullptr) {
*out = this->nrr_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultTooManyNrr();
}
Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) {
/* Find space to map the NRO. */
uintptr_t map_address;
R_UNLESS(R_SUCCEEDED(SearchFreeRegion(std::addressof(map_address), expected_nro_size)), ro::ResultOutOfAddressSpace());
Result GetNroInfoByAddress(NroInfo **out, u64 nro_address) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (this->nro_in_use[i] && this->nro_infos[i].base_address == nro_address) {
if (out != nullptr) {
*out = this->nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultNotLoaded();
}
/* Actually map the NRO. */
AutoCloseMap nro_map(map_address, m_process_handle, base_address, expected_nro_size);
R_TRY(nro_map.GetResult());
Result GetNroInfoByModuleId(NroInfo **out, const ModuleId *module_id) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (this->nro_in_use[i] && std::memcmp(std::addressof(this->nro_infos[i].module_id), module_id, sizeof(*module_id)) == 0) {
if (out != nullptr) {
*out = this->nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultNotLoaded();
}
/* Validate header. */
const NroHeader *header = reinterpret_cast<const NroHeader *>(map_address);
R_UNLESS(header->IsMagicValid(), ro::ResultInvalidNro());
Result GetFreeNroInfo(NroInfo **out) {
for (size_t i = 0; i < MaxNroInfos; i++) {
if (!this->nro_in_use[i]) {
if (out != nullptr) {
*out = this->nro_infos + i;
}
return ResultSuccess();
}
}
return ro::ResultTooManyNro();
}
/* Read sizes from header. */
const u64 nro_size = header->GetSize();
const u64 text_ofs = header->GetTextOffset();
const u64 text_size = header->GetTextSize();
const u64 ro_ofs = header->GetRoOffset();
const u64 ro_size = header->GetRoSize();
const u64 rw_ofs = header->GetRwOffset();
const u64 rw_size = header->GetRwSize();
const u64 bss_size = header->GetBssSize();
Result ValidateHasNroHash(const NroHeader *nro_header) const {
/* Calculate hash. */
Sha256Hash hash;
crypto::GenerateSha256Hash(std::addressof(hash), sizeof(hash), nro_header, nro_header->GetSize());
/* Validate sizes meet expected. */
R_UNLESS(nro_size == expected_nro_size, ro::ResultInvalidNro());
R_UNLESS(bss_size == expected_bss_size, ro::ResultInvalidNro());
for (size_t i = 0; i < MaxNrrInfos; i++) {
/* Ensure we only check NRRs that are used. */
if (!this->nrr_in_use[i]) {
continue;
}
/* Validate all sizes are aligned. */
R_UNLESS(util::IsAligned(text_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(ro_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(rw_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(bss_size, os::MemoryPageSize), ro::ResultInvalidNro());
/* Get the mapped header, ensure that it has hashes. */
const NrrHeader *mapped_nrr_header = this->nrr_infos[i].mapped_header;
const size_t mapped_num_hashes = mapped_nrr_header->GetNumHashes();
if (mapped_num_hashes == 0) {
continue;
}
/* Validate sections are in order. */
R_UNLESS(text_ofs <= ro_ofs, ro::ResultInvalidNro());
R_UNLESS(ro_ofs <= rw_ofs, ro::ResultInvalidNro());
/* Locate the hash within the mapped array. */
const Sha256Hash *mapped_nro_hashes_start = reinterpret_cast<const Sha256Hash *>(mapped_nrr_header->GetHashes());
const Sha256Hash *mapped_nro_hashes_end = mapped_nro_hashes_start + mapped_nrr_header->GetNumHashes();
/* Validate sections are sequential and contiguous. */
R_UNLESS(text_ofs == 0, ro::ResultInvalidNro());
R_UNLESS(text_ofs + text_size == ro_ofs, ro::ResultInvalidNro());
R_UNLESS(ro_ofs + ro_size == rw_ofs, ro::ResultInvalidNro());
R_UNLESS(rw_ofs + rw_size == nro_size, ro::ResultInvalidNro());
const Sha256Hash *mapped_lower_bound = std::lower_bound(mapped_nro_hashes_start, mapped_nro_hashes_end, hash);
if (mapped_lower_bound == mapped_nro_hashes_end || (*mapped_lower_bound != hash)) {
continue;
}
/* Verify NRO hash. */
R_TRY(this->ValidateHasNroHash(header));
/* Check that the hash entry is valid, since our heuristic passed. */
const void *nrr_hash = std::addressof(this->nrr_infos[i].signed_area_hash);
const void *signed_area = this->nrr_infos[i].cached_signed_area;
const size_t signed_area_size = this->nrr_infos[i].cached_signed_area_size;
const size_t hashes_offset = this->nrr_infos[i].cached_hashes_offset;
const size_t num_hashes = this->nrr_infos[i].cached_num_hashes;
const u8 *hash_table = reinterpret_cast<const u8 *>(mapped_nro_hashes_start);
if (!ValidateNrrHashTableEntry(signed_area, signed_area_size, hashes_offset, num_hashes, nrr_hash, hash_table, std::addressof(hash))) {
continue;
}
/* Check if NRO has already been loaded. */
const ModuleId *module_id = header->GetModuleId();
R_UNLESS(R_FAILED(this->GetNroInfoByModuleId(nullptr, module_id)), ro::ResultAlreadyLoaded());
/* The hash is valid! */
/* Apply patches to NRO. */
LocateAndApplyIpsPatchesToModule(module_id, reinterpret_cast<u8 *>(map_address), nro_size);
/* Copy to output. */
*out_module_id = *module_id;
*out_rx_size = text_size;
*out_ro_size = ro_size;
*out_rw_size = rw_size;
return ResultSuccess();
}
return ro::ResultNotAuthorized();
}
void SetNrrInfoInUse(const NrrInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(m_nrr_infos[0]) <= info && info <= std::addressof(m_nrr_infos[MaxNrrInfos - 1]));
const size_t index = info - std::addressof(m_nrr_infos[0]);
m_nrr_in_use[index] = in_use;
}
Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) {
/* Find space to map the NRO. */
uintptr_t map_address;
R_UNLESS(R_SUCCEEDED(SearchFreeRegion(std::addressof(map_address), expected_nro_size)), ro::ResultOutOfAddressSpace());
void SetNroInfoInUse(const NroInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(m_nro_infos[0]) <= info && info <= std::addressof(m_nro_infos[MaxNroInfos - 1]));
const size_t index = info - std::addressof(m_nro_infos[0]);
m_nro_in_use[index] = in_use;
}
/* Actually map the NRO. */
AutoCloseMap nro_map(map_address, this->process_handle, base_address, expected_nro_size);
R_TRY(nro_map.GetResult());
void GetProcessModuleInfo(u32 *out_count, LoaderModuleInfo *out_infos, size_t max_out_count) const {
size_t count = 0;
/* Validate header. */
const NroHeader *header = reinterpret_cast<const NroHeader *>(map_address);
R_UNLESS(header->IsMagicValid(), ro::ResultInvalidNro());
for (size_t i = 0; i < MaxNroInfos && count < max_out_count; i++) {
if (!m_nro_in_use[i]) {
continue;
}
/* Read sizes from header. */
const u64 nro_size = header->GetSize();
const u64 text_ofs = header->GetTextOffset();
const u64 text_size = header->GetTextSize();
const u64 ro_ofs = header->GetRoOffset();
const u64 ro_size = header->GetRoSize();
const u64 rw_ofs = header->GetRwOffset();
const u64 rw_size = header->GetRwSize();
const u64 bss_size = header->GetBssSize();
const NroInfo *nro_info = m_nro_infos + i;
/* Validate sizes meet expected. */
R_UNLESS(nro_size == expected_nro_size, ro::ResultInvalidNro());
R_UNLESS(bss_size == expected_bss_size, ro::ResultInvalidNro());
/* Just copy out the info. */
LoaderModuleInfo *out_info = std::addressof(out_infos[count++]);
memcpy(out_info->build_id, std::addressof(nro_info->module_id), sizeof(nro_info->module_id));
out_info->base_address = nro_info->base_address;
out_info->size = nro_info->nro_heap_size + nro_info->bss_heap_size;
}
/* Validate all sizes are aligned. */
R_UNLESS(util::IsAligned(text_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(ro_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(rw_size, os::MemoryPageSize), ro::ResultInvalidNro());
R_UNLESS(util::IsAligned(bss_size, os::MemoryPageSize), ro::ResultInvalidNro());
/* Validate sections are in order. */
R_UNLESS(text_ofs <= ro_ofs, ro::ResultInvalidNro());
R_UNLESS(ro_ofs <= rw_ofs, ro::ResultInvalidNro());
/* Validate sections are sequential and contiguous. */
R_UNLESS(text_ofs == 0, ro::ResultInvalidNro());
R_UNLESS(text_ofs + text_size == ro_ofs, ro::ResultInvalidNro());
R_UNLESS(ro_ofs + ro_size == rw_ofs, ro::ResultInvalidNro());
R_UNLESS(rw_ofs + rw_size == nro_size, ro::ResultInvalidNro());
/* Verify NRO hash. */
R_TRY(this->ValidateHasNroHash(header));
/* Check if NRO has already been loaded. */
const ModuleId *module_id = header->GetModuleId();
R_UNLESS(R_FAILED(this->GetNroInfoByModuleId(nullptr, module_id)), ro::ResultAlreadyLoaded());
/* Apply patches to NRO. */
LocateAndApplyIpsPatchesToModule(module_id, reinterpret_cast<u8 *>(map_address), nro_size);
/* Copy to output. */
*out_module_id = *module_id;
*out_rx_size = text_size;
*out_ro_size = ro_size;
*out_rw_size = rw_size;
return ResultSuccess();
}
void SetNrrInfoInUse(const NrrInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(this->nrr_infos[0]) <= info && info <= std::addressof(this->nrr_infos[MaxNrrInfos - 1]));
const size_t index = info - std::addressof(this->nrr_infos[0]);
this->nrr_in_use[index] = in_use;
}
void SetNroInfoInUse(const NroInfo *info, bool in_use) {
AMS_ASSERT(std::addressof(this->nro_infos[0]) <= info && info <= std::addressof(this->nro_infos[MaxNroInfos - 1]));
const size_t index = info - std::addressof(this->nro_infos[0]);
this->nro_in_use[index] = in_use;
}
*out_count = static_cast<u32>(count);
}
};
/* Globals. */
ProcessContext g_process_contexts[MaxSessions] = {};
bool g_is_development_hardware = false;
bool g_is_development_function_enabled = false;
constinit ProcessContext g_process_contexts[MaxSessions] = {};
constinit bool g_is_development_hardware = false;
constinit bool g_is_development_function_enabled = false;
/* Context Helpers. */
ProcessContext *GetContextById(size_t context_id) {
@@ -287,7 +358,7 @@ namespace ams::ro::impl {
ProcessContext *GetContextByProcessId(os::ProcessId process_id) {
for (size_t i = 0; i < MaxSessions; i++) {
if (g_process_contexts[i].process_id == process_id) {
if (g_process_contexts[i].GetProcessId() == process_id) {
return g_process_contexts + i;
}
}
@@ -299,11 +370,8 @@ namespace ams::ro::impl {
for (size_t i = 0; i < MaxSessions; i++) {
ProcessContext *context = g_process_contexts + i;
if (!context->in_use) {
std::memset(context, 0, sizeof(*context));
context->process_id = process_id;
context->process_handle = process_handle;
context->in_use = true;
if (context->IsFree()) {
context->Initialize(process_handle, process_id);
return i;
}
}
@@ -312,18 +380,8 @@ namespace ams::ro::impl {
}
void FreeContext(size_t context_id) {
ProcessContext *context = GetContextById(context_id);
if (context != nullptr) {
if (context->process_handle != os::InvalidNativeHandle) {
for (size_t i = 0; i < MaxNrrInfos; i++) {
if (context->nrr_in_use[i]) {
UnmapNrr(context->process_handle, context->nrr_infos[i].mapped_header, context->nrr_infos[i].nrr_heap_address, context->nrr_infos[i].nrr_heap_size, context->nrr_infos[i].mapped_code_address);
}
}
os::CloseNativeHandle(context->process_handle);
}
std::memset(context, 0, sizeof(*context));
context->in_use = false;
if (ProcessContext *context = GetContextById(context_id); context != nullptr) {
context->Finalize();
}
}
@@ -397,8 +455,8 @@ namespace ams::ro::impl {
Result ValidateProcess(size_t context_id, os::ProcessId process_id) {
const ProcessContext *ctx = GetContextById(context_id);
R_UNLESS(ctx != nullptr, ro::ResultInvalidProcess());
R_UNLESS(ctx->process_id == process_id, ro::ResultInvalidProcess());
R_UNLESS(ctx != nullptr, ro::ResultInvalidProcess());
R_UNLESS(ctx->GetProcessId() == process_id, ro::ResultInvalidProcess());
return ResultSuccess();
}
@@ -429,7 +487,7 @@ namespace ams::ro::impl {
/* Map. */
NrrHeader *header = nullptr;
u64 mapped_code_address = 0;
R_TRY(MapAndValidateNrr(std::addressof(header), std::addressof(mapped_code_address), std::addressof(signed_area_hash), sizeof(signed_area_hash), context->process_handle, program_id, nrr_address, nrr_size, nrr_kind, enforce_nrr_kind));
R_TRY(MapAndValidateNrr(std::addressof(header), std::addressof(mapped_code_address), std::addressof(signed_area_hash), sizeof(signed_area_hash), context->GetProcessHandle(), program_id, nrr_address, nrr_size, nrr_kind, enforce_nrr_kind));
/* Set NRR info. */
context->SetNrrInfoInUse(nrr_info, true);
@@ -467,7 +525,7 @@ namespace ams::ro::impl {
context->SetNrrInfoInUse(nrr_info, false);
std::memset(nrr_info, 0, sizeof(*nrr_info));
}
return UnmapNrr(context->process_handle, nrr_backup.mapped_header, nrr_backup.nrr_heap_address, nrr_backup.nrr_heap_size, nrr_backup.mapped_code_address);
return UnmapNrr(context->GetProcessHandle(), nrr_backup.mapped_header, nrr_backup.nrr_heap_address, nrr_backup.nrr_heap_size, nrr_backup.mapped_code_address);
}
Result MapManualLoadModuleMemory(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
@@ -492,20 +550,20 @@ namespace ams::ro::impl {
nro_info->bss_heap_size = bss_size;
/* Map the NRO. */
R_TRY(MapNro(std::addressof(nro_info->base_address), context->process_handle, nro_address, nro_size, bss_address, bss_size));
R_TRY(MapNro(std::addressof(nro_info->base_address), context->GetProcessHandle(), nro_address, nro_size, bss_address, bss_size));
/* Validate the NRO (parsing region extents). */
u64 rx_size = 0, ro_size = 0, rw_size = 0;
{
auto unmap_guard = SCOPE_GUARD { UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, nro_size, 0); };
auto unmap_guard = SCOPE_GUARD { UnmapNro(context->GetProcessHandle(), nro_info->base_address, nro_address, bss_address, bss_size, nro_size, 0); };
R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), nro_info->base_address, nro_size, bss_size));
unmap_guard.Cancel();
}
/* Set NRO perms. */
{
auto unmap_guard = SCOPE_GUARD { UnmapNro(context->process_handle, nro_info->base_address, nro_address, bss_address, bss_size, rx_size + ro_size, rw_size); };
R_TRY(SetNroPerms(context->process_handle, nro_info->base_address, rx_size, ro_size, rw_size + bss_size));
auto unmap_guard = SCOPE_GUARD { UnmapNro(context->GetProcessHandle(), nro_info->base_address, nro_address, bss_address, bss_size, rx_size + ro_size, rw_size); };
R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size));
unmap_guard.Cancel();
}
@@ -535,30 +593,15 @@ namespace ams::ro::impl {
context->SetNroInfoInUse(nro_info, false);
std::memset(nro_info, 0, sizeof(*nro_info));
}
return UnmapNro(context->process_handle, nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.bss_heap_address, nro_backup.bss_heap_size, nro_backup.code_size, nro_backup.rw_size);
return UnmapNro(context->GetProcessHandle(), nro_backup.base_address, nro_backup.nro_heap_address, nro_backup.bss_heap_address, nro_backup.bss_heap_size, nro_backup.code_size, nro_backup.rw_size);
}
/* Debug service implementations. */
Result GetProcessModuleInfo(u32 *out_count, LoaderModuleInfo *out_infos, size_t max_out_count, os::ProcessId process_id) {
size_t count = 0;
const ProcessContext *context = GetContextByProcessId(process_id);
if (context != nullptr) {
for (size_t i = 0; i < MaxNroInfos && count < max_out_count; i++) {
if (!context->nro_in_use[i]) {
continue;
}
const NroInfo *nro_info = context->nro_infos + i;
/* Just copy out the info. */
LoaderModuleInfo *out_info = std::addressof(out_infos[count++]);
memcpy(out_info->build_id, std::addressof(nro_info->module_id), sizeof(nro_info->module_id));
out_info->base_address = nro_info->base_address;
out_info->size = nro_info->nro_heap_size + nro_info->bss_heap_size;
}
if (const ProcessContext *context = GetContextByProcessId(process_id); context != nullptr) {
context->GetProcessModuleInfo(out_count, out_infos, max_out_count);
}
*out_count = static_cast<u32>(count);
return ResultSuccess();
}

View File

@@ -27,45 +27,45 @@ namespace ams::ro {
impl::SetDevelopmentFunctionEnabled(is_development_function_enabled);
}
RoService::RoService(NrrKind k) : context_id(impl::InvalidContextId), nrr_kind(k) {
RoService::RoService(NrrKind k) : m_context_id(impl::InvalidContextId), m_nrr_kind(k) {
/* ... */
}
RoService::~RoService() {
impl::UnregisterProcess(this->context_id);
impl::UnregisterProcess(m_context_id);
}
Result RoService::MapManualLoadModuleMemory(sf::Out<u64> load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
return impl::MapManualLoadModuleMemory(load_address.GetPointer(), this->context_id, nro_address, nro_size, bss_address, bss_size);
R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue()));
return impl::MapManualLoadModuleMemory(load_address.GetPointer(), m_context_id, nro_address, nro_size, bss_address, bss_size);
}
Result RoService::UnmapManualLoadModuleMemory(const sf::ClientProcessId &client_pid, u64 nro_address) {
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
return impl::UnmapManualLoadModuleMemory(this->context_id, nro_address);
R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue()));
return impl::UnmapManualLoadModuleMemory(m_context_id, nro_address);
}
Result RoService::RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size) {
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
return impl::RegisterModuleInfo(this->context_id, os::InvalidNativeHandle, nrr_address, nrr_size, NrrKind_User, true);
R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue()));
return impl::RegisterModuleInfo(m_context_id, os::InvalidNativeHandle, nrr_address, nrr_size, NrrKind_User, true);
}
Result RoService::UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address) {
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
return impl::UnregisterModuleInfo(this->context_id, nrr_address);
R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue()));
return impl::UnregisterModuleInfo(m_context_id, nrr_address);
}
Result RoService::RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle &&process_h) {
/* Register the process. */
return impl::RegisterProcess(std::addressof(this->context_id), std::move(process_h), client_pid.GetValue());
return impl::RegisterProcess(std::addressof(m_context_id), std::move(process_h), client_pid.GetValue());
}
Result RoService::RegisterProcessModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle &&process_h) {
/* Validate the process. */
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
R_TRY(impl::ValidateProcess(m_context_id, client_pid.GetValue()));
/* Register the module. */
return impl::RegisterModuleInfo(this->context_id, process_h.GetOsHandle(), nrr_address, nrr_size, this->nrr_kind, this->nrr_kind == NrrKind_JitPlugin);
return impl::RegisterModuleInfo(m_context_id, process_h.GetOsHandle(), nrr_address, nrr_size, m_nrr_kind, m_nrr_kind == NrrKind_JitPlugin);
}
}

View File

@@ -25,8 +25,8 @@ namespace ams::ro {
class RoService {
private:
size_t context_id;
NrrKind nrr_kind;
size_t m_context_id;
NrrKind m_nrr_kind;
protected:
explicit RoService(NrrKind k);
public:

View File

@@ -122,20 +122,20 @@ namespace ams::sm::impl {
class InitialProcessIdLimits {
private:
os::ProcessId min;
os::ProcessId max;
os::ProcessId m_min;
os::ProcessId m_max;
public:
InitialProcessIdLimits() {
/* Retrieve process limits. */
cfg::GetInitialProcessRange(std::addressof(this->min), std::addressof(this->max));
cfg::GetInitialProcessRange(std::addressof(m_min), std::addressof(m_max));
/* Ensure range is sane. */
AMS_ABORT_UNLESS(this->min <= this->max);
AMS_ABORT_UNLESS(m_min <= m_max);
}
bool IsInitialProcess(os::ProcessId process_id) const {
AMS_ABORT_UNLESS(process_id != os::InvalidProcessId);
return this->min <= process_id && process_id <= this->max;
return m_min <= process_id && process_id <= m_max;
}
};

View File

@@ -186,25 +186,25 @@ namespace ams::spl::impl {
/* Type definitions. */
class ScopedAesKeySlot {
private:
s32 slot;
bool has_slot;
s32 m_slot;
bool m_has_slot;
public:
ScopedAesKeySlot() : slot(-1), has_slot(false) {
ScopedAesKeySlot() : m_slot(-1), m_has_slot(false) {
/* ... */
}
~ScopedAesKeySlot() {
if (this->has_slot) {
DeallocateAesKeySlot(slot, this);
if (m_has_slot) {
DeallocateAesKeySlot(m_slot, this);
}
}
u32 GetKeySlot() const {
return this->slot;
return m_slot;
}
Result Allocate() {
R_TRY(AllocateAesKeySlot(std::addressof(this->slot), this));
this->has_slot = true;
R_TRY(AllocateAesKeySlot(std::addressof(m_slot), this));
m_has_slot = true;
return ResultSuccess();
}
};
@@ -222,17 +222,17 @@ namespace ams::spl::impl {
class DeviceAddressSpaceMapHelper {
private:
os::NativeHandle das_hnd;
u64 dst_addr;
u64 src_addr;
size_t size;
svc::MemoryPermission perm;
os::NativeHandle m_handle;
u64 m_dst_addr;
u64 m_src_addr;
size_t m_size;
svc::MemoryPermission m_perm;
public:
DeviceAddressSpaceMapHelper(os::NativeHandle h, u64 dst, u64 src, size_t sz, svc::MemoryPermission p) : das_hnd(h), dst_addr(dst), src_addr(src), size(sz), perm(p) {
R_ABORT_UNLESS(svc::MapDeviceAddressSpaceAligned(this->das_hnd, dd::GetCurrentProcessHandle(), this->src_addr, this->size, this->dst_addr, this->perm));
DeviceAddressSpaceMapHelper(os::NativeHandle h, u64 dst, u64 src, size_t sz, svc::MemoryPermission p) : m_handle(h), m_dst_addr(dst), m_src_addr(src), m_size(sz), m_perm(p) {
R_ABORT_UNLESS(svc::MapDeviceAddressSpaceAligned(m_handle, dd::GetCurrentProcessHandle(), m_src_addr, m_size, m_dst_addr, m_perm));
}
~DeviceAddressSpaceMapHelper() {
R_ABORT_UNLESS(svc::UnmapDeviceAddressSpace(this->das_hnd, dd::GetCurrentProcessHandle(), this->src_addr, this->size, this->dst_addr));
R_ABORT_UNLESS(svc::UnmapDeviceAddressSpace(m_handle, dd::GetCurrentProcessHandle(), m_src_addr, m_size, m_dst_addr));
}
};

View File

@@ -19,30 +19,30 @@
namespace ams::spl {
void CtrDrbg::Update(const void *data) {
aes128ContextCreate(std::addressof(this->aes_ctx), this->key, true);
for (size_t offset = 0; offset < sizeof(this->work[1]); offset += BlockSize) {
IncrementCounter(this->counter);
aes128EncryptBlock(std::addressof(this->aes_ctx), std::addressof(this->work[1][offset]), this->counter);
aes128ContextCreate(std::addressof(m_aes_ctx), m_key, true);
for (size_t offset = 0; offset < sizeof(m_work[1]); offset += BlockSize) {
IncrementCounter(m_counter);
aes128EncryptBlock(std::addressof(m_aes_ctx), std::addressof(m_work[1][offset]), m_counter);
}
Xor(this->work[1], data, sizeof(this->work[1]));
Xor(m_work[1], data, sizeof(m_work[1]));
std::memcpy(this->key, std::addressof(this->work[1][0]), sizeof(this->key));
std::memcpy(this->counter, std::addressof(this->work[1][BlockSize]), sizeof(this->key));
std::memcpy(m_key, std::addressof(m_work[1][0]), sizeof(m_key));
std::memcpy(m_counter, std::addressof(m_work[1][BlockSize]), sizeof(m_key));
}
void CtrDrbg::Initialize(const void *seed) {
std::memcpy(this->work[0], seed, sizeof(this->work[0]));
std::memset(this->key, 0, sizeof(this->key));
std::memset(this->counter, 0, sizeof(this->counter));
this->Update(this->work[0]);
this->reseed_counter = 1;
std::memcpy(m_work[0], seed, sizeof(m_work[0]));
std::memset(m_key, 0, sizeof(m_key));
std::memset(m_counter, 0, sizeof(m_counter));
this->Update(m_work[0]);
m_reseed_counter = 1;
}
void CtrDrbg::Reseed(const void *seed) {
std::memcpy(this->work[0], seed, sizeof(this->work[0]));
this->Update(this->work[0]);
this->reseed_counter = 1;
std::memcpy(m_work[0], seed, sizeof(m_work[0]));
this->Update(m_work[0]);
m_reseed_counter = 1;
}
bool CtrDrbg::GenerateRandomBytes(void *out, size_t size) {
@@ -50,30 +50,30 @@ namespace ams::spl {
return false;
}
if (this->reseed_counter > ReseedInterval) {
if (m_reseed_counter > ReseedInterval) {
return false;
}
aes128ContextCreate(std::addressof(this->aes_ctx), this->key, true);
aes128ContextCreate(std::addressof(m_aes_ctx), m_key, true);
u8 *cur_dst = reinterpret_cast<u8 *>(out);
size_t aligned_size = (size & ~(BlockSize - 1));
for (size_t offset = 0; offset < aligned_size; offset += BlockSize) {
IncrementCounter(this->counter);
aes128EncryptBlock(std::addressof(this->aes_ctx), cur_dst, this->counter);
IncrementCounter(m_counter);
aes128EncryptBlock(std::addressof(m_aes_ctx), cur_dst, m_counter);
cur_dst += BlockSize;
}
if (size > aligned_size) {
IncrementCounter(this->counter);
aes128EncryptBlock(std::addressof(this->aes_ctx), this->work[1], this->counter);
std::memcpy(cur_dst, this->work[1], size - aligned_size);
IncrementCounter(m_counter);
aes128EncryptBlock(std::addressof(m_aes_ctx), m_work[1], m_counter);
std::memcpy(cur_dst, m_work[1], size - aligned_size);
}
std::memset(this->work[0], 0, sizeof(this->work[0]));
this->Update(this->work[0]);
std::memset(m_work[0], 0, sizeof(m_work[0]));
this->Update(m_work[0]);
this->reseed_counter++;
m_reseed_counter++;
return true;
}

View File

@@ -26,11 +26,11 @@ namespace ams::spl {
static constexpr size_t BlockSize = AES_BLOCK_SIZE;
static constexpr size_t SeedSize = 2 * AES_BLOCK_SIZE;
private:
Aes128Context aes_ctx;
u8 counter[BlockSize];
u8 key[BlockSize];
u8 work[2][SeedSize];
u32 reseed_counter;
Aes128Context m_aes_ctx;
u8 m_counter[BlockSize];
u8 m_key[BlockSize];
u8 m_work[2][SeedSize];
u32 m_reseed_counter;
private:
static void Xor(void *dst, const void *src, size_t size) {
const u8 *src_u8 = reinterpret_cast<const u8 *>(src);

View File

@@ -26,25 +26,25 @@ namespace ams::spl {
public:
static constexpr size_t KeySize = crypto::AesDecryptor128::KeySize;
private:
const s32 slot_index;
s32 virtual_slot;
const s32 m_slot_index;
s32 m_virtual_slot;
public:
explicit KeySlotCacheEntry(s32 idx) : slot_index(idx), virtual_slot(-1) { /* ... */ }
explicit KeySlotCacheEntry(s32 idx) : m_slot_index(idx), m_virtual_slot(-1) { /* ... */ }
bool Contains(s32 virtual_slot) const {
return virtual_slot == this->virtual_slot;
return virtual_slot == m_virtual_slot;
}
s32 GetPhysicalKeySlotIndex() const { return this->slot_index; }
s32 GetPhysicalKeySlotIndex() const { return m_slot_index; }
s32 GetVirtualKeySlotIndex() const { return this->virtual_slot; }
s32 GetVirtualKeySlotIndex() const { return m_virtual_slot; }
void SetVirtualSlot(s32 virtual_slot) {
this->virtual_slot = virtual_slot;
m_virtual_slot = virtual_slot;
}
void ClearVirtualSlot() {
this->virtual_slot = -1;
m_virtual_slot = -1;
}
};
@@ -54,16 +54,16 @@ namespace ams::spl {
private:
using KeySlotCacheEntryList = util::IntrusiveListBaseTraits<KeySlotCacheEntry>::ListType;
private:
KeySlotCacheEntryList mru_list;
KeySlotCacheEntryList m_mru_list;
public:
constexpr KeySlotCache() : mru_list() { /* ... */ }
constexpr KeySlotCache() : m_mru_list() { /* ... */ }
s32 Allocate(s32 virtual_slot) {
return this->AllocateFromLru(virtual_slot);
}
bool Find(s32 *out, s32 virtual_slot) {
for (auto it = this->mru_list.begin(); it != this->mru_list.end(); ++it) {
for (auto it = m_mru_list.begin(); it != m_mru_list.end(); ++it) {
if (it->Contains(virtual_slot)) {
*out = it->GetPhysicalKeySlotIndex();
@@ -76,7 +76,7 @@ namespace ams::spl {
}
bool Release(s32 *out, s32 virtual_slot) {
for (auto it = this->mru_list.begin(); it != this->mru_list.end(); ++it) {
for (auto it = m_mru_list.begin(); it != m_mru_list.end(); ++it) {
if (it->Contains(virtual_slot)) {
*out = it->GetPhysicalKeySlotIndex();
it->ClearVirtualSlot();
@@ -90,7 +90,7 @@ namespace ams::spl {
}
bool FindPhysical(s32 physical_slot) {
for (auto it = this->mru_list.begin(); it != this->mru_list.end(); ++it) {
for (auto it = m_mru_list.begin(); it != m_mru_list.end(); ++it) {
if (it->GetPhysicalKeySlotIndex() == physical_slot) {
this->UpdateMru(it);
@@ -106,32 +106,32 @@ namespace ams::spl {
}
void AddEntry(KeySlotCacheEntry *entry) {
this->mru_list.push_front(*entry);
m_mru_list.push_front(*entry);
}
private:
s32 AllocateFromLru(s32 virtual_slot) {
AMS_ASSERT(!this->mru_list.empty());
AMS_ASSERT(!m_mru_list.empty());
auto it = this->mru_list.rbegin();
auto it = m_mru_list.rbegin();
it->SetVirtualSlot(virtual_slot);
auto *entry = std::addressof(*it);
this->mru_list.pop_back();
this->mru_list.push_front(*entry);
m_mru_list.pop_back();
m_mru_list.push_front(*entry);
return entry->GetPhysicalKeySlotIndex();
}
void UpdateMru(KeySlotCacheEntryList::iterator it) {
auto *entry = std::addressof(*it);
this->mru_list.erase(it);
this->mru_list.push_front(*entry);
m_mru_list.erase(it);
m_mru_list.push_front(*entry);
}
void UpdateLru(KeySlotCacheEntryList::iterator it) {
auto *entry = std::addressof(*it);
this->mru_list.erase(it);
this->mru_list.push_back(*entry);
m_mru_list.erase(it);
m_mru_list.push_back(*entry);
}
};