ams: revamp assertion system

This commit is contained in:
Michael Scire
2020-02-22 23:05:14 -08:00
parent 9572fb2ce3
commit 40400aee1f
168 changed files with 1014 additions and 696 deletions

View File

@@ -165,8 +165,8 @@ namespace ams::pm::impl {
std::scoped_lock lk(this->lock);
const size_t index = this->GetProcessInfoIndex(process_info);
AMS_ASSERT(index < MaxProcessInfos);
AMS_ASSERT(this->process_info_allocated[index]);
AMS_ABORT_UNLESS(index < MaxProcessInfos);
AMS_ABORT_UNLESS(this->process_info_allocated[index]);
process_info->~ProcessInfo();
this->process_info_allocated[index] = false;
@@ -308,7 +308,7 @@ namespace ams::pm::impl {
/* Make new process info. */
void *process_info_storage = g_process_info_allocator.AllocateProcessInfoStorage();
AMS_ASSERT(process_info_storage != nullptr);
AMS_ABORT_UNLESS(process_info_storage != nullptr);
ProcessInfo *process_info = new (process_info_storage) ProcessInfo(process_handle, process_id, pin_id, location, override_status);
/* Link new process info. */
@@ -374,7 +374,7 @@ namespace ams::pm::impl {
const ProcessState old_state = process_info->GetState();
{
u64 tmp = 0;
R_ASSERT(svcGetProcessInfo(&tmp, process_info->GetHandle(), ProcessInfoType_ProcessState));
R_ABORT_UNLESS(svcGetProcessInfo(&tmp, process_info->GetHandle(), ProcessInfoType_ProcessState));
process_info->SetState(static_cast<ProcessState>(tmp));
}
const ProcessState new_state = process_info->GetState();
@@ -452,16 +452,16 @@ namespace ams::pm::impl {
/* Initialization. */
Result InitializeProcessManager() {
/* Create events. */
R_ASSERT(g_process_event.InitializeAsInterProcessEvent());
R_ASSERT(g_hook_to_create_process_event.InitializeAsInterProcessEvent());
R_ASSERT(g_hook_to_create_application_process_event.InitializeAsInterProcessEvent());
R_ASSERT(g_boot_finished_event.InitializeAsInterProcessEvent());
R_ABORT_UNLESS(g_process_event.InitializeAsInterProcessEvent());
R_ABORT_UNLESS(g_hook_to_create_process_event.InitializeAsInterProcessEvent());
R_ABORT_UNLESS(g_hook_to_create_application_process_event.InitializeAsInterProcessEvent());
R_ABORT_UNLESS(g_boot_finished_event.InitializeAsInterProcessEvent());
/* Initialize resource limits. */
R_TRY(resource::InitializeResourceManager());
/* Start thread. */
R_ASSERT(g_process_track_thread.Start());
R_ABORT_UNLESS(g_process_track_thread.Start());
return ResultSuccess();
}
@@ -711,7 +711,7 @@ namespace ams::pm::impl {
/* In 8.0.0, Nintendo added this command, which signals that the boot sysmodule has finished. */
/* Nintendo only signals it in safe mode FIRM, and this function aborts on normal FIRM. */
/* We will signal it always, but only allow this function to succeed on safe mode. */
AMS_ASSERT(spl::IsRecoveryBoot());
AMS_ABORT_UNLESS(spl::IsRecoveryBoot());
*out = g_boot_finished_event.GetReadableHandle();
return ResultSuccess();
}

View File

@@ -147,7 +147,7 @@ namespace ams::pm::resource {
u64 value = 0;
while (true) {
R_ASSERT(svcGetResourceLimitCurrentValue(&value, reslimit_hnd, resource));
R_ABORT_UNLESS(svcGetResourceLimitCurrentValue(&value, reslimit_hnd, resource));
if (value == 0) {
break;
}
@@ -159,7 +159,7 @@ namespace ams::pm::resource {
void WaitApplicationMemoryAvailable() {
u64 value = 0;
while (true) {
R_ASSERT(svcGetSystemInfo(&value, SystemInfoType_UsedPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Application));
R_ABORT_UNLESS(svcGetSystemInfo(&value, SystemInfoType_UsedPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Application));
if (value == 0) {
break;
}
@@ -175,10 +175,10 @@ namespace ams::pm::resource {
for (size_t i = 0; i < ResourceLimitGroup_Count; i++) {
if (i == ResourceLimitGroup_System) {
u64 value = 0;
R_ASSERT(svcGetInfo(&value, InfoType_ResourceLimit, INVALID_HANDLE, 0));
R_ABORT_UNLESS(svcGetInfo(&value, InfoType_ResourceLimit, INVALID_HANDLE, 0));
g_resource_limit_handles[i] = static_cast<Handle>(value);
} else {
R_ASSERT(svcCreateResourceLimit(&g_resource_limit_handles[i]));
R_ABORT_UNLESS(svcCreateResourceLimit(&g_resource_limit_handles[i]));
}
}
@@ -210,7 +210,7 @@ namespace ams::pm::resource {
if (hos::GetVersion() >= hos::Version_700) {
/* See how many threads we have available. */
u64 total_threads_available = 0;
R_ASSERT(svcGetResourceLimitLimitValue(&total_threads_available, GetResourceLimitHandle(ResourceLimitGroup_System), LimitableResource_Threads));
R_ABORT_UNLESS(svcGetResourceLimitLimitValue(&total_threads_available, GetResourceLimitHandle(ResourceLimitGroup_System), LimitableResource_Threads));
/* See how many threads we're expecting. */
const size_t total_threads_allocated = g_resource_limits[ResourceLimitGroup_System][LimitableResource_Threads] -
@@ -218,7 +218,7 @@ namespace ams::pm::resource {
g_resource_limits[ResourceLimitGroup_Applet][LimitableResource_Threads];
/* Ensure we don't over-commit threads. */
AMS_ASSERT(total_threads_allocated <= total_threads_available);
AMS_ABORT_UNLESS(total_threads_allocated <= total_threads_available);
/* Set number of extra threads. */
g_extra_application_threads_available = total_threads_available - total_threads_allocated;
@@ -231,18 +231,18 @@ namespace ams::pm::resource {
/* Get total memory available. */
u64 total_memory = 0;
R_ASSERT(svcGetResourceLimitLimitValue(&total_memory, GetResourceLimitHandle(ResourceLimitGroup_System), LimitableResource_Memory));
R_ABORT_UNLESS(svcGetResourceLimitLimitValue(&total_memory, GetResourceLimitHandle(ResourceLimitGroup_System), LimitableResource_Memory));
/* Get and save application + applet memory. */
R_ASSERT(svcGetSystemInfo(&g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Application], SystemInfoType_TotalPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Application));
R_ASSERT(svcGetSystemInfo(&g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Applet], SystemInfoType_TotalPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Applet));
R_ABORT_UNLESS(svcGetSystemInfo(&g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Application], SystemInfoType_TotalPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Application));
R_ABORT_UNLESS(svcGetSystemInfo(&g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Applet], SystemInfoType_TotalPhysicalMemorySize, INVALID_HANDLE, PhysicalMemoryInfo_Applet));
const u64 application_size = g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Application];
const u64 applet_size = g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_Applet];
const u64 reserved_non_system_size = (application_size + applet_size + ReservedMemorySize600);
/* Ensure there's enough memory for the system region. */
AMS_ASSERT(reserved_non_system_size < total_memory);
AMS_ABORT_UNLESS(reserved_non_system_size < total_memory);
g_memory_resource_limits[spl::MemoryArrangement_Dynamic][ResourceLimitGroup_System] = total_memory - reserved_non_system_size;
} else {
@@ -267,7 +267,7 @@ namespace ams::pm::resource {
std::scoped_lock lk(g_resource_limit_lock);
for (size_t group = 0; group < ResourceLimitGroup_Count; group++) {
R_ASSERT(SetResourceLimitLimitValues(static_cast<ResourceLimitGroup>(group), g_memory_resource_limits[g_memory_arrangement][group]));
R_ABORT_UNLESS(SetResourceLimitLimitValues(static_cast<ResourceLimitGroup>(group), g_memory_resource_limits[g_memory_arrangement][group]));
}
}
@@ -286,10 +286,10 @@ namespace ams::pm::resource {
/* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */
if (boost_size < g_system_memory_boost_size) {
R_TRY(svcSetUnsafeLimit(boost_size));
R_ASSERT(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
R_ABORT_UNLESS(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
} else {
R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size));
R_ASSERT(svcSetUnsafeLimit(boost_size));
R_ABORT_UNLESS(svcSetUnsafeLimit(boost_size));
}
} else {
const u64 new_sys_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_System] + boost_size;
@@ -340,8 +340,8 @@ namespace ams::pm::resource {
Result GetResourceLimitValues(u64 *out_cur, u64 *out_lim, ResourceLimitGroup group, LimitableResource resource) {
/* Do not allow out of bounds access. */
AMS_ASSERT(group < ResourceLimitGroup_Count);
AMS_ASSERT(resource < LimitableResource_Count);
AMS_ABORT_UNLESS(group < ResourceLimitGroup_Count);
AMS_ABORT_UNLESS(resource < LimitableResource_Count);
const Handle reslimit_hnd = GetResourceLimitHandle(group);
R_TRY(svcGetResourceLimitCurrentValue(out_cur, reslimit_hnd, resource));

View File

@@ -87,12 +87,12 @@ namespace {
/* Get a debug handle. */
os::ManagedHandle debug_handle;
R_ASSERT(svcDebugActiveProcess(debug_handle.GetPointer(), static_cast<u64>(process_id)));
R_ABORT_UNLESS(svcDebugActiveProcess(debug_handle.GetPointer(), static_cast<u64>(process_id)));
/* Loop until we get the event that tells us about the process. */
svc::DebugEventInfo d;
while (true) {
R_ASSERT(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
R_ABORT_UNLESS(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
if (d.type == svc::DebugEvent_AttachProcess) {
return ncm::ProgramId{d.info.attach_process.program_id};
}
@@ -117,7 +117,7 @@ namespace {
/* Get list of processes, register all privileged ones. */
u32 num_pids;
os::ProcessId pids[ProcessCountMax];
R_ASSERT(svcGetProcessList(&num_pids, reinterpret_cast<u64 *>(pids), ProcessCountMax));
R_ABORT_UNLESS(svcGetProcessList(&num_pids, reinterpret_cast<u64 *>(pids), ProcessCountMax));
for (size_t i = 0; i < num_pids; i++) {
if (min_priv_process_id <= pids[i] && pids[i] <= max_priv_process_id) {
RegisterPrivilegedProcess(pids[i]);
@@ -131,19 +131,19 @@ void __appInit(void) {
hos::SetVersionForLibnx();
sm::DoWithSession([&]() {
R_ASSERT(fsprInitialize());
R_ASSERT(smManagerInitialize());
R_ABORT_UNLESS(fsprInitialize());
R_ABORT_UNLESS(smManagerInitialize());
/* This works around a bug with process permissions on < 4.0.0. */
/* It also informs SM of privileged process information. */
RegisterPrivilegedProcesses();
/* Use AMS manager extension to tell SM that FS has been worked around. */
R_ASSERT(sm::manager::EndInitialDefers());
R_ABORT_UNLESS(sm::manager::EndInitialDefers());
R_ASSERT(lrInitialize());
R_ASSERT(ldrPmInitialize());
R_ASSERT(splInitialize());
R_ABORT_UNLESS(lrInitialize());
R_ABORT_UNLESS(ldrPmInitialize());
R_ABORT_UNLESS(splInitialize());
});
ams::CheckApiVersion();
@@ -187,20 +187,20 @@ namespace {
int main(int argc, char **argv)
{
/* Initialize process manager implementation. */
R_ASSERT(pm::impl::InitializeProcessManager());
R_ABORT_UNLESS(pm::impl::InitializeProcessManager());
/* Create Services. */
/* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */
/* Also Note: PM was rewritten in 5.0.0, so the shell and dmnt services are different before/after. */
if (hos::GetVersion() >= hos::Version_500) {
R_ASSERT((g_server_manager.RegisterServer<pm::shell::ShellService>(ShellServiceName, ShellMaxSessions)));
R_ASSERT((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellService>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
} else {
R_ASSERT((g_server_manager.RegisterServer<pm::shell::ShellServiceDeprecated>(ShellServiceName, ShellMaxSessions)));
R_ASSERT((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorServiceDeprecated>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellServiceDeprecated>(ShellServiceName, ShellMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorServiceDeprecated>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
}
R_ASSERT((g_server_manager.RegisterServer<pm::bm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
R_ASSERT((g_server_manager.RegisterServer<pm::info::InformationService>(InformationServiceName, InformationMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::bm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::info::InformationService>(InformationServiceName, InformationMaxSessions)));
/* Loop forever, servicing our services. */
g_server_manager.LoopProcess();

View File

@@ -37,11 +37,11 @@ namespace ams::pm::shell {
}
void ShellServiceBase::GetProcessEventHandle(sf::OutCopyHandle out) {
R_ASSERT(impl::GetProcessEventHandle(out.GetHandlePointer()));
R_ABORT_UNLESS(impl::GetProcessEventHandle(out.GetHandlePointer()));
}
void ShellServiceBase::GetProcessEventInfo(sf::Out<ProcessEventInfo> out) {
R_ASSERT(impl::GetProcessEventInfo(out.GetPointer()));
R_ABORT_UNLESS(impl::GetProcessEventInfo(out.GetPointer()));
}
Result ShellServiceBase::CleanupProcess(os::ProcessId process_id) {
@@ -53,7 +53,7 @@ namespace ams::pm::shell {
}
void ShellServiceBase::NotifyBootFinished() {
R_ASSERT(impl::NotifyBootFinished());
R_ABORT_UNLESS(impl::NotifyBootFinished());
}
Result ShellServiceBase::GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out) {
@@ -69,7 +69,7 @@ namespace ams::pm::shell {
}
void ShellServiceBase::GetBootFinishedEventHandle(sf::OutCopyHandle out) {
R_ASSERT(impl::GetBootFinishedEventHandle(out.GetHandlePointer()));
R_ABORT_UNLESS(impl::GetBootFinishedEventHandle(out.GetHandlePointer()));
}
}