IPC bug fixes

This fixes two bugs in IPC that were discovered when running Puyo Puyo
Tetris.

The CloneCurrentObject control IPC will now correctly return the handle
of the newly created object through move handles, rather than pushing it
as a result.

The size array of u16s with the sizes of each C buffer is now taken into
account when reading them. Before this change C buffers were entirely
broken.
This commit is contained in:
◱ PixelyIon 2020-07-05 13:12:30 +01:00 committed by ◱ PixelyIon
parent 6e074d596c
commit 9ef25a6beb
2 changed files with 6 additions and 4 deletions

View File

@ -22,6 +22,8 @@ namespace skyline::kernel::ipc {
header = reinterpret_cast<CommandHeader *>(pointer); header = reinterpret_cast<CommandHeader *>(pointer);
pointer += sizeof(CommandHeader); pointer += sizeof(CommandHeader);
size_t cBufferLengthSize = util::AlignUp(((header->cFlag == BufferCFlag::None) ? 0 : ((header->cFlag > BufferCFlag::SingleDescriptor) ? (static_cast<u8>(header->cFlag) - 2) : 1)) * sizeof(u16), sizeof(u32));
if (header->handleDesc) { if (header->handleDesc) {
handleDesc = reinterpret_cast<HandleDescriptor *>(pointer); handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0); pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0);
@ -85,7 +87,7 @@ namespace skyline::kernel::ipc {
cmdArg = pointer; cmdArg = pointer;
cmdArgSz = domain->payloadSz - sizeof(PayloadHeader); cmdArgSz = domain->payloadSz - sizeof(PayloadHeader);
pointer += domain->payloadSz; pointer += cmdArgSz;
for (u8 index = 0; domain->inputCount > index; index++) { for (u8 index = 0; domain->inputCount > index; index++) {
domainObjects.push_back(*reinterpret_cast<KHandle *>(pointer)); domainObjects.push_back(*reinterpret_cast<KHandle *>(pointer));
@ -96,7 +98,7 @@ namespace skyline::kernel::ipc {
pointer += sizeof(PayloadHeader); pointer += sizeof(PayloadHeader);
cmdArg = pointer; cmdArg = pointer;
cmdArgSz = (header->rawSize * sizeof(u32)) - (constant::IpcPaddingSum + sizeof(PayloadHeader)); cmdArgSz = (header->rawSize * sizeof(u32)) - (constant::IpcPaddingSum + sizeof(PayloadHeader)) - cBufferLengthSize;
pointer += cmdArgSz; pointer += cmdArgSz;
} }
@ -105,7 +107,7 @@ namespace skyline::kernel::ipc {
if (payload->magic != util::MakeMagic<u32>("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext)) // SFCI is the magic in received IPC messages if (payload->magic != util::MakeMagic<u32>("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext)) // SFCI is the magic in received IPC messages
state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", u32(payload->magic)); state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", u32(payload->magic));
pointer += constant::IpcPaddingSum - padding; pointer += constant::IpcPaddingSum - padding + cBufferLengthSize;
if (header->cFlag == BufferCFlag::SingleDescriptor) { if (header->cFlag == BufferCFlag::SingleDescriptor) {
auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer); auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer);

View File

@ -189,7 +189,7 @@ namespace skyline::service {
break; break;
case ipc::ControlCommand::CloneCurrentObject: case ipc::ControlCommand::CloneCurrentObject:
case ipc::ControlCommand::CloneCurrentObjectEx: case ipc::ControlCommand::CloneCurrentObjectEx:
response.Push(state.process->InsertItem(session)); response.moveHandles.push_back(state.process->InsertItem(session));
break; break;
case ipc::ControlCommand::QueryPointerBufferSize: case ipc::ControlCommand::QueryPointerBufferSize:
response.Push<u32>(0x1000); response.Push<u32>(0x1000);