mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +12:00
[Kernel] Fix spontaneous r0 corruption
This commit is contained in:
parent
0add6b7d7a
commit
3529c9bf67
2 changed files with 12 additions and 7 deletions
|
@ -111,12 +111,15 @@ void Kernel::svcClearEvent() {
|
||||||
void Kernel::svcSignalEvent() {
|
void Kernel::svcSignalEvent() {
|
||||||
const Handle handle = regs[0];
|
const Handle handle = regs[0];
|
||||||
logSVC("SignalEvent(event handle = %X)\n", handle);
|
logSVC("SignalEvent(event handle = %X)\n", handle);
|
||||||
|
KernelObject* object = getObject(handle, KernelObjectType::Event);
|
||||||
if (!signalEvent(handle)) {
|
|
||||||
|
if (object == nullptr) {
|
||||||
Helpers::panic("Signalled non-existent event: %X\n", handle);
|
Helpers::panic("Signalled non-existent event: %X\n", handle);
|
||||||
regs[0] = SVCResult::BadHandle;
|
regs[0] = SVCResult::BadHandle;
|
||||||
} else {
|
} else {
|
||||||
|
// We must signalEvent after setting r0, otherwise the r0 of the new thread will ne corrupted
|
||||||
regs[0] = SVCResult::Success;
|
regs[0] = SVCResult::Success;
|
||||||
|
signalEvent(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,24 +78,26 @@ void Kernel::sendSyncRequest() {
|
||||||
|
|
||||||
// The sync request is being sent at a service rather than whatever port, so have the service manager intercept it
|
// The sync request is being sent at a service rather than whatever port, so have the service manager intercept it
|
||||||
if (KernelHandles::isServiceHandle(handle)) {
|
if (KernelHandles::isServiceHandle(handle)) {
|
||||||
serviceManager.sendCommandToService(messagePointer, handle);
|
// The service call might cause a reschedule and change threads. Hence, set r0 before executing the service call
|
||||||
|
// Because if the service call goes first, we might corrupt the new thread's r0!!
|
||||||
regs[0] = SVCResult::Success;
|
regs[0] = SVCResult::Success;
|
||||||
|
serviceManager.sendCommandToService(messagePointer, handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if our sync request is targetting a file instead of a service
|
// Check if our sync request is targetting a file instead of a service
|
||||||
bool isFileOperation = getObject(handle, KernelObjectType::File) != nullptr;
|
bool isFileOperation = getObject(handle, KernelObjectType::File) != nullptr;
|
||||||
if (isFileOperation) {
|
if (isFileOperation) {
|
||||||
|
regs[0] = SVCResult::Success; // r0 goes first here too
|
||||||
handleFileOperation(messagePointer, handle);
|
handleFileOperation(messagePointer, handle);
|
||||||
regs[0] = SVCResult::Success;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if our sync request is targetting a directory instead of a service
|
// Check if our sync request is targetting a directory instead of a service
|
||||||
bool isDirectoryOperation = getObject(handle, KernelObjectType::Directory) != nullptr;
|
bool isDirectoryOperation = getObject(handle, KernelObjectType::Directory) != nullptr;
|
||||||
if (isDirectoryOperation) {
|
if (isDirectoryOperation) {
|
||||||
|
regs[0] = SVCResult::Success; // r0 goes first here too
|
||||||
handleDirectoryOperation(messagePointer, handle);
|
handleDirectoryOperation(messagePointer, handle);
|
||||||
regs[0] = SVCResult::Success;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,13 +113,13 @@ void Kernel::sendSyncRequest() {
|
||||||
const Handle portHandle = sessionData->portHandle;
|
const Handle portHandle = sessionData->portHandle;
|
||||||
|
|
||||||
if (portHandle == srvHandle) { // Special-case SendSyncRequest targetting the "srv: port"
|
if (portHandle == srvHandle) { // Special-case SendSyncRequest targetting the "srv: port"
|
||||||
|
regs[0] = SVCResult::Success;
|
||||||
serviceManager.handleSyncRequest(messagePointer);
|
serviceManager.handleSyncRequest(messagePointer);
|
||||||
} else if (portHandle == errorPortHandle) { // Special-case "err:f" for juicy logs too
|
} else if (portHandle == errorPortHandle) { // Special-case "err:f" for juicy logs too
|
||||||
|
regs[0] = SVCResult::Success;
|
||||||
handleErrorSyncRequest(messagePointer);
|
handleErrorSyncRequest(messagePointer);
|
||||||
} else {
|
} else {
|
||||||
const auto portData = objects[portHandle].getData<Port>();
|
const auto portData = objects[portHandle].getData<Port>();
|
||||||
Helpers::panic("SendSyncRequest targetting port %s\n", portData->name);
|
Helpers::panic("SendSyncRequest targetting port %s\n", portData->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
regs[0] = SVCResult::Success;
|
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue