mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-09 21:51:45 +00:00
ProcessManager: Fix svcCreateEvent handle inversion bug, and others.
NOTE: Debugging logs have been left in, and will be cleaned up once PM is working.
This commit is contained in:
parent
6e5d4b8fc9
commit
6d6ecb503a
8 changed files with 81 additions and 35 deletions
|
@ -1,10 +1,14 @@
|
|||
#include <switch.h>
|
||||
#include "pm_boot_mode.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
static bool g_is_maintenance_boot = false;
|
||||
|
||||
Result BootModeService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
LogForService("BOOTMODE\x00", 8);
|
||||
LogForService(&cmd_id, 8);
|
||||
LogForService(armGetTls(), 0x100);
|
||||
switch ((BootModeCmd)cmd_id) {
|
||||
case BootMode_Cmd_GetBootMode:
|
||||
rc = WrapIpcCommandImpl<&BootModeService::get_boot_mode>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
|
@ -15,6 +19,10 @@ Result BootModeService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LogForService(armGetTls(), 0x100);
|
||||
if (R_FAILED(rc)) {
|
||||
Reboot();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#include <switch.h>
|
||||
#include "pm_registration.hpp"
|
||||
#include "pm_info.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
Result InformationService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
LogForService("INFOSRV\x00", 8);
|
||||
LogForService(&cmd_id, 8);
|
||||
LogForService(armGetTls(), 0x100);
|
||||
switch ((InformationCmd)cmd_id) {
|
||||
case Information_Cmd_GetTitleId:
|
||||
rc = WrapIpcCommandImpl<&InformationService::get_title_id>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
|
@ -11,6 +15,10 @@ Result InformationService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64
|
|||
default:
|
||||
break;
|
||||
}
|
||||
LogForService(armGetTls(), 0x100);
|
||||
if (R_FAILED(rc)) {
|
||||
Reboot();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "pm_shell.hpp"
|
||||
#include "pm_process_track.hpp"
|
||||
#include "pm_registration.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
|
|
|
@ -2,15 +2,26 @@
|
|||
#include <stratosphere.hpp>
|
||||
#include "pm_process_track.hpp"
|
||||
#include "pm_registration.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
void ProcessTracking::MainLoop(void *arg) {
|
||||
/* Make a new waitable manager. */
|
||||
WaitableManager *process_waiter = new WaitableManager(U64_MAX);
|
||||
process_waiter->add_waitable(Registration::GetProcessLaunchStartEvent());
|
||||
WaitableManager *process_waiter = new WaitableManager(1000);
|
||||
process_waiter->add_waitable(Registration::GetProcessList());
|
||||
|
||||
|
||||
static unsigned int i = 0;
|
||||
/* Service processes. */
|
||||
process_waiter->process();
|
||||
while (true) {
|
||||
process_waiter->process_until_timeout();
|
||||
|
||||
i++;
|
||||
if (Registration::TryWaitProcessLaunchStartEvent()) {
|
||||
Registration::HandleProcessLaunch();
|
||||
}
|
||||
if (i > 1000000) {
|
||||
Reboot();
|
||||
}
|
||||
}
|
||||
|
||||
delete process_waiter;
|
||||
svcExitThread();
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "pm_registration.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
class ProcessWaiter : public IWaitable {
|
||||
public:
|
||||
Registration::Process process;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
static ProcessList g_process_list;
|
||||
static ProcessList g_dead_process_list;
|
||||
|
||||
static HosSemaphore g_sema_start_launch;
|
||||
static HosSemaphore g_sema_finish_launch;
|
||||
|
||||
static HosMutex g_process_launch_mutex;
|
||||
|
@ -19,7 +20,6 @@ static std::atomic<u64> g_debug_on_launch_tid(0);
|
|||
static SystemEvent *g_process_event = NULL;
|
||||
static SystemEvent *g_debug_title_event = NULL;
|
||||
static SystemEvent *g_debug_application_event = NULL;
|
||||
static SystemEvent *g_process_launch_start_event = NULL;
|
||||
|
||||
static const u64 g_memory_resource_limits[5][3] = {
|
||||
{0x010D00000ULL, 0x0CD500000ULL, 0x021700000ULL},
|
||||
|
@ -61,7 +61,6 @@ void Registration::InitializeSystemResources() {
|
|||
g_process_event = new SystemEvent(&IEvent::PanicCallback);
|
||||
g_debug_title_event = new SystemEvent(&IEvent::PanicCallback);
|
||||
g_debug_application_event = new SystemEvent(&IEvent::PanicCallback);
|
||||
g_process_launch_start_event = new SystemEvent(&Registration::ProcessLaunchStartCallback);
|
||||
|
||||
/* Get memory limits. */
|
||||
u64 memory_arrangement;
|
||||
|
@ -112,13 +111,8 @@ void Registration::InitializeSystemResources() {
|
|||
}
|
||||
}
|
||||
|
||||
Result Registration::ProcessLaunchStartCallback(Handle *handles, size_t num_handles, u64 timeout) {
|
||||
Registration::HandleProcessLaunch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWaitable *Registration::GetProcessLaunchStartEvent() {
|
||||
return g_process_launch_start_event;
|
||||
bool Registration::TryWaitProcessLaunchStartEvent() {
|
||||
return g_sema_start_launch.TryWait();
|
||||
}
|
||||
|
||||
IWaitable *Registration::GetProcessList() {
|
||||
|
@ -129,17 +123,19 @@ void Registration::HandleProcessLaunch() {
|
|||
LoaderProgramInfo program_info = {0};
|
||||
Result rc;
|
||||
u64 launch_flags = g_process_launch_state.launch_flags;
|
||||
const u8 *acid_fac, *aci0_fah, *acid_sac, *aci0_sac;
|
||||
u64 *out_pid = g_process_launch_state.out_pid;
|
||||
u32 reslimit_idx;
|
||||
Process new_process = {0};
|
||||
new_process.tid_sid = g_process_launch_state.tid_sid;
|
||||
|
||||
u8 *ac_buf = new u8[4 * sizeof(LoaderProgramInfo)];
|
||||
std::fill(ac_buf, ac_buf + 4 * sizeof(LoaderProgramInfo), 0xCC);
|
||||
u8 *acid_sac = ac_buf, *aci0_sac = acid_sac + sizeof(LoaderProgramInfo), *fac = aci0_sac + sizeof(LoaderProgramInfo), *fah = fac + sizeof(LoaderProgramInfo);
|
||||
|
||||
/* Check that this is a real program. */
|
||||
if (R_FAILED((rc = ldrPmGetProgramInfo(new_process.tid_sid.title_id, new_process.tid_sid.storage_id, &program_info)))) {
|
||||
goto HANDLE_PROCESS_LAUNCH_END;
|
||||
}
|
||||
|
||||
|
||||
/* Get the resource limit handle, ensure that we can launch the program. */
|
||||
if ((program_info.application_type & 3) == 1) {
|
||||
if (HasApplicationProcess(NULL)) {
|
||||
|
@ -155,7 +151,7 @@ void Registration::HandleProcessLaunch() {
|
|||
if (R_FAILED((rc = ldrPmRegisterTitle(new_process.tid_sid.title_id, new_process.tid_sid.storage_id, &new_process.ldr_queue_index)))) {
|
||||
goto HANDLE_PROCESS_LAUNCH_END;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure the previous application is cleaned up. */
|
||||
if ((program_info.application_type & 3) == 1) {
|
||||
EnsureApplicationResourcesAvailable();
|
||||
|
@ -165,24 +161,24 @@ void Registration::HandleProcessLaunch() {
|
|||
if (R_FAILED((rc = ldrPmCreateProcess(LAUNCHFLAGS_ARGLOW(launch_flags) | LAUNCHFLAGS_ARGHIGH(launch_flags), new_process.ldr_queue_index, g_resource_limit_handles[reslimit_idx], &new_process.handle)))) {
|
||||
goto PROCESS_CREATION_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Get the new process's id. */
|
||||
svcGetProcessId(&new_process.pid, new_process.handle);
|
||||
|
||||
|
||||
/* Register with FS. */
|
||||
acid_fac = program_info.ac_buffer + program_info.acid_sac_size + program_info.aci0_sac_size;
|
||||
aci0_fah = acid_fac + program_info.acid_fac_size;
|
||||
if (R_FAILED((rc = fsprRegisterProgram(new_process.pid, new_process.tid_sid.title_id, new_process.tid_sid.storage_id, aci0_fah, program_info.aci0_fah_size, acid_fac, program_info.acid_fac_size)))) {
|
||||
memcpy(fac, program_info.ac_buffer + program_info.acid_sac_size + program_info.aci0_sac_size, program_info.acid_fac_size);
|
||||
memcpy(fah, program_info.ac_buffer + program_info.acid_sac_size + program_info.aci0_sac_size + program_info.acid_fac_size, program_info.aci0_fah_size);
|
||||
if (R_FAILED((rc = fsprRegisterProgram(new_process.pid, new_process.tid_sid.title_id, new_process.tid_sid.storage_id, fah, program_info.aci0_fah_size, fac, program_info.acid_fac_size)))) {
|
||||
goto FS_REGISTRATION_FAILED;
|
||||
}
|
||||
|
||||
/* Register with PM. */
|
||||
acid_sac = program_info.ac_buffer;
|
||||
aci0_sac = program_info.ac_buffer + program_info.acid_sac_size;
|
||||
|
||||
/* Register with SM. */
|
||||
memcpy(acid_sac, program_info.ac_buffer, program_info.acid_sac_size);
|
||||
memcpy(aci0_sac, program_info.ac_buffer + program_info.acid_sac_size, program_info.aci0_sac_size);
|
||||
if (R_FAILED((rc = smManagerRegisterProcess(new_process.pid, acid_sac, program_info.acid_sac_size, aci0_sac, program_info.aci0_sac_size)))) {
|
||||
goto SM_REGISTRATION_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* Setup process flags. */
|
||||
if (program_info.application_type & 1) {
|
||||
new_process.flags |= 0x40;
|
||||
|
@ -213,8 +209,11 @@ void Registration::HandleProcessLaunch() {
|
|||
rc = 0;
|
||||
} else {
|
||||
rc = svcStartProcess(new_process.handle, program_info.main_thread_priority, program_info.default_cpu_id, program_info.main_thread_stack_size);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
SetProcessState(new_process.pid, ProcessState_DebugDetached);
|
||||
Log("MADENEWPROCESS", 16);
|
||||
Log(GetProcess(new_process.pid), sizeof(Process));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,6 +242,7 @@ HANDLE_PROCESS_LAUNCH_END:
|
|||
if (R_SUCCEEDED(rc)) {
|
||||
*out_pid = new_process.pid;
|
||||
}
|
||||
delete ac_buf;
|
||||
g_sema_finish_launch.Signal();
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ Result Registration::LaunchProcess(u64 title_id, FsStorageId storage_id, u64 lau
|
|||
g_process_launch_state.out_pid = out_pid;
|
||||
|
||||
/* Start a launch, and wait for it to exit. */
|
||||
g_process_launch_start_event->signal_event();
|
||||
g_sema_start_launch.Signal();
|
||||
g_sema_finish_launch.Wait();
|
||||
|
||||
rc = g_process_launch_state.result;
|
||||
|
@ -272,7 +272,10 @@ Result Registration::LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64
|
|||
|
||||
void Registration::HandleSignaledProcess(Process *process) {
|
||||
u64 tmp;
|
||||
|
||||
|
||||
Log("PROCESSIGNALED\x00", 16);
|
||||
Log(process, sizeof(*process));
|
||||
|
||||
/* Reset the signal. */
|
||||
svcResetSignal(process->handle);
|
||||
|
||||
|
@ -280,6 +283,7 @@ void Registration::HandleSignaledProcess(Process *process) {
|
|||
old_state = process->state;
|
||||
svcGetProcessInfo(&tmp, process->handle, ProcessInfoType_ProcessState);
|
||||
process->state = (ProcessState)tmp;
|
||||
Log(process, sizeof(*process));
|
||||
|
||||
if (old_state == ProcessState_Crashed && process->state != ProcessState_Crashed) {
|
||||
process->flags &= ~0x4;
|
||||
|
@ -317,6 +321,7 @@ void Registration::HandleSignaledProcess(Process *process) {
|
|||
} else {
|
||||
FinalizeExitedProcess(process);
|
||||
}
|
||||
//Reboot();
|
||||
break;
|
||||
case ProcessState_DebugSuspended:
|
||||
if (process->flags & 8) {
|
||||
|
@ -454,9 +459,10 @@ void Registration::GetProcessEventType(u64 *out_pid, u64 *out_type) {
|
|||
return;
|
||||
}
|
||||
if (p->flags & 0x10) {
|
||||
u64 old_flags = p->flags;
|
||||
p->flags &= ~0x10;
|
||||
*out_pid = p->pid;
|
||||
*out_type = kernelAbove500() ? (((p->flags >> 5) & 1) | 4) : (((p->flags >> 5) & 1) + 3);
|
||||
*out_type = kernelAbove500() ? (((old_flags >> 5) & 1) | 4) : (((old_flags >> 5) & 1) + 3);
|
||||
return;
|
||||
}
|
||||
if (p->flags & 2) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#define LAUNCHFLAGS_NOTIFYWHENEXITED(flags) (flags & 1)
|
||||
#define LAUNCHFLAGS_STARTSUSPENDED(flags) (flags & (kernelAbove500() ? 0x10 : 0x2))
|
||||
#define LAUNCHFLAGS_ARGLOW(flags) (kernelAbove500() ? ((flags & 0x14) != 0x10) : (kernelAbove200() ? ((flags & 0x6) != 0x2) : ((flags >> 2) & 1)))
|
||||
#define LAUNCHFLAGS_ARGHIGH(flags) (flags & (kernelAbove500() ? 0x20 : 0x8))
|
||||
#define LAUNCHFLAGS_ARGHIGH(flags) ((flags & (kernelAbove500() ? 0x20 : 0x8)) ? 2 : 0)
|
||||
#define LAUNCHFLAGS_NOTIFYDEBUGEVENTS(flags) (flags & (kernelAbove500() ? 0x8 : 0x10))
|
||||
#define LAUNCHFLAGS_NOTIYDEBUGSPECIAL(flags) (flags & (kernelAbove500() ? 0x2 : (kernelAbove200() ? 0x20 : 0x0)))
|
||||
|
||||
|
@ -41,8 +41,7 @@ class Registration {
|
|||
};
|
||||
|
||||
static void InitializeSystemResources();
|
||||
static IWaitable *GetProcessLaunchStartEvent();
|
||||
static Result ProcessLaunchStartCallback(Handle *handles, size_t num_handles, u64 timeout);
|
||||
static bool TryWaitProcessLaunchStartEvent();
|
||||
|
||||
static IWaitable *GetProcessList();
|
||||
static void HandleSignaledProcess(Process *process);
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#include <switch.h>
|
||||
#include "pm_registration.hpp"
|
||||
#include "pm_shell.hpp"
|
||||
#include "pm_debug.hpp"
|
||||
|
||||
static bool g_has_boot_finished = false;
|
||||
|
||||
Result ShellService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
LogForService("SHELLSRV", 8);
|
||||
LogForService(&cmd_id, 8);
|
||||
LogForService(armGetTls(), 0x100);
|
||||
if (kernelAbove500()) {
|
||||
switch ((ShellCmd_5X)cmd_id) {
|
||||
case Shell_Cmd_5X_LaunchProcess:
|
||||
|
@ -69,6 +73,12 @@ Result ShellService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id
|
|||
break;
|
||||
}
|
||||
}
|
||||
//Log(armGetTls(), 0x100);
|
||||
LogForService(armGetTls(), 0x100);
|
||||
if (R_FAILED(rc)) {
|
||||
|
||||
Reboot();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -88,7 +98,7 @@ std::tuple<Result> ShellService::terminate_process_id(u64 pid) {
|
|||
|
||||
Registration::Process *proc = Registration::GetProcess(pid);
|
||||
if (proc != NULL) {
|
||||
return {svcCloseHandle(proc->handle)};
|
||||
return {svcTerminateProcess(proc->handle)};
|
||||
} else {
|
||||
return {0x20F};
|
||||
}
|
||||
|
@ -99,7 +109,7 @@ std::tuple<Result> ShellService::terminate_title_id(u64 tid) {
|
|||
|
||||
Registration::Process *proc = Registration::GetProcessByTitleId(tid);
|
||||
if (proc != NULL) {
|
||||
return {svcCloseHandle(proc->handle)};
|
||||
return {svcTerminateProcess(proc->handle)};
|
||||
} else {
|
||||
return {0x20F};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue