Fix CR issues and Game Duplication + Move to Vector for Memory Map

This commit fixed the issues outlined in the CR (Mainly correlated to formatting), moves to a sorted vector from a sorted list for the memory map in addition to using binary search for sorting through rather than iteratively and fixes item duplication in the game list when directory is changed in Settings.
This commit is contained in:
◱ PixelyIon
2020-02-15 15:08:17 +05:30
committed by ◱ PixelyIon
parent 66d20a9429
commit 08bbc66b09
31 changed files with 418 additions and 355 deletions

View File

@ -12,88 +12,88 @@ namespace skyline::kernel::ipc {
OutputBuffer::OutputBuffer(kernel::ipc::BufferDescriptorC *cBuf) : IpcBuffer(cBuf->address, cBuf->size, IpcBufferType::C) {}
IpcRequest::IpcRequest(bool isDomain, const DeviceState &state) : isDomain(isDomain), state(state), tls() {
u8 *currPtr = tls.data();
state.process->ReadMemory(currPtr, state.thread->tls, constant::TlsIpcSize);
IpcRequest::IpcRequest(bool isDomain, const DeviceState &state) : isDomain(isDomain), state(state) {
u8 *tls = state.process->GetPointer<u8>(state.thread->tls);
u8 *pointer = tls;
header = reinterpret_cast<CommandHeader *>(currPtr);
currPtr += sizeof(CommandHeader);
header = reinterpret_cast<CommandHeader *>(pointer);
pointer += sizeof(CommandHeader);
if (header->handleDesc) {
handleDesc = reinterpret_cast<HandleDescriptor *>(currPtr);
currPtr += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0);
handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0);
for (uint index = 0; handleDesc->copyCount > index; index++) {
copyHandles.push_back(*reinterpret_cast<handle_t *>(currPtr));
currPtr += sizeof(handle_t);
copyHandles.push_back(*reinterpret_cast<handle_t *>(pointer));
pointer += sizeof(handle_t);
}
for (uint index = 0; handleDesc->moveCount > index; index++) {
moveHandles.push_back(*reinterpret_cast<handle_t *>(currPtr));
currPtr += sizeof(handle_t);
moveHandles.push_back(*reinterpret_cast<handle_t *>(pointer));
pointer += sizeof(handle_t);
}
}
for (uint index = 0; header->xNo > index; index++) {
auto bufX = reinterpret_cast<BufferDescriptorX *>(currPtr);
auto bufX = reinterpret_cast<BufferDescriptorX *>(pointer);
if (bufX->Address()) {
inputBuf.emplace_back(bufX);
state.logger->Debug("Buf X #{} AD: 0x{:X} SZ: 0x{:X} CTR: {}", index, u64(bufX->Address()), u16(bufX->size), u16(bufX->Counter()));
}
currPtr += sizeof(BufferDescriptorX);
pointer += sizeof(BufferDescriptorX);
}
for (uint index = 0; header->aNo > index; index++) {
auto bufA = reinterpret_cast<BufferDescriptorABW *>(currPtr);
auto bufA = reinterpret_cast<BufferDescriptorABW *>(pointer);
if (bufA->Address()) {
inputBuf.emplace_back(bufA);
state.logger->Debug("Buf A #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufA->Address()), u64(bufA->Size()));
}
currPtr += sizeof(BufferDescriptorABW);
pointer += sizeof(BufferDescriptorABW);
}
for (uint index = 0; header->bNo > index; index++) {
auto bufB = reinterpret_cast<BufferDescriptorABW *>(currPtr);
auto bufB = reinterpret_cast<BufferDescriptorABW *>(pointer);
if (bufB->Address()) {
outputBuf.emplace_back(bufB);
state.logger->Debug("Buf B #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufB->Address()), u64(bufB->Size()));
}
currPtr += sizeof(BufferDescriptorABW);
pointer += sizeof(BufferDescriptorABW);
}
for (uint index = 0; header->wNo > index; index++) {
auto bufW = reinterpret_cast<BufferDescriptorABW *>(currPtr);
auto bufW = reinterpret_cast<BufferDescriptorABW *>(pointer);
if (bufW->Address()) {
inputBuf.emplace_back(bufW, IpcBufferType::W);
outputBuf.emplace_back(bufW, IpcBufferType::W);
state.logger->Debug("Buf W #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufW->Address()), u16(bufW->Size()));
}
currPtr += sizeof(BufferDescriptorABW);
pointer += sizeof(BufferDescriptorABW);
}
u64 padding = ((((reinterpret_cast<u64>(currPtr) - reinterpret_cast<u64>(tls.data())) - 1U) & ~(constant::IpcPaddingSum - 1U)) + constant::IpcPaddingSum + (reinterpret_cast<u64>(tls.data()) - reinterpret_cast<u64>(currPtr))); // Calculate the amount of padding at the front
currPtr += padding;
u64 padding = ((((reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(tls)) - 1U) & ~(constant::IpcPaddingSum - 1U)) + constant::IpcPaddingSum + (reinterpret_cast<u64>(tls) - reinterpret_cast<u64>(pointer))); // Calculate the amount of padding at the front
pointer += padding;
if (isDomain && (header->type == CommandType::Request)) {
domain = reinterpret_cast<DomainHeaderRequest *>(currPtr);
currPtr += sizeof(DomainHeaderRequest);
domain = reinterpret_cast<DomainHeaderRequest *>(pointer);
pointer += sizeof(DomainHeaderRequest);
payload = reinterpret_cast<PayloadHeader *>(currPtr);
currPtr += sizeof(PayloadHeader);
payload = reinterpret_cast<PayloadHeader *>(pointer);
pointer += sizeof(PayloadHeader);
cmdArg = currPtr;
cmdArg = pointer;
cmdArgSz = domain->payloadSz - sizeof(PayloadHeader);
currPtr += domain->payloadSz;
pointer += domain->payloadSz;
for (uint index = 0; domain->inputCount > index; index++) {
domainObjects.push_back(*reinterpret_cast<handle_t *>(currPtr));
currPtr += sizeof(handle_t);
domainObjects.push_back(*reinterpret_cast<handle_t *>(pointer));
pointer += sizeof(handle_t);
}
} else {
payload = reinterpret_cast<PayloadHeader *>(currPtr);
currPtr += sizeof(PayloadHeader);
payload = reinterpret_cast<PayloadHeader *>(pointer);
pointer += sizeof(PayloadHeader);
cmdArg = currPtr;
cmdArg = pointer;
cmdArgSz = (header->rawSize * sizeof(u32)) - (constant::IpcPaddingSum + sizeof(PayloadHeader));
currPtr += cmdArgSz;
pointer += cmdArgSz;
}
payloadOffset = cmdArg;
@ -101,22 +101,22 @@ namespace skyline::kernel::ipc {
if (payload->magic != constant::SfciMagic && header->type != CommandType::Control)
state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", u32(payload->magic));
currPtr += constant::IpcPaddingSum - padding;
pointer += constant::IpcPaddingSum - padding;
if (header->cFlag == BufferCFlag::SingleDescriptor) {
auto bufC = reinterpret_cast<BufferDescriptorC *>(currPtr);
auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer);
if (bufC->address) {
outputBuf.emplace_back(bufC);
state.logger->Debug("Buf C: AD: 0x{:X} SZ: 0x{:X}", u64(bufC->address), u16(bufC->size));
}
} else if (header->cFlag > BufferCFlag::SingleDescriptor) {
for (uint index = 0; (static_cast<u8>(header->cFlag) - 2) > index; index++) { // (cFlag - 2) C descriptors are present
auto bufC = reinterpret_cast<BufferDescriptorC *>(currPtr);
auto bufC = reinterpret_cast<BufferDescriptorC *>(pointer);
if (bufC->address) {
outputBuf.emplace_back(bufC);
state.logger->Debug("Buf C #{} AD: 0x{:X} SZ: 0x{:X}", index, u64(bufC->address), u16(bufC->size));
}
currPtr += sizeof(BufferDescriptorC);
pointer += sizeof(BufferDescriptorC);
}
}
@ -133,63 +133,57 @@ namespace skyline::kernel::ipc {
IpcResponse::IpcResponse(bool isDomain, const DeviceState &state) : isDomain(isDomain), state(state) {}
void IpcResponse::WriteResponse() {
std::array<u8, constant::TlsIpcSize> tls{};
u8 *currPtr = tls.data();
auto header = reinterpret_cast<CommandHeader *>(currPtr);
auto tls = state.process->GetPointer<u8>(state.thread->tls);
u8 *pointer = tls;
memset(tls, 0, constant::TlsIpcSize);
auto header = reinterpret_cast<CommandHeader *>(pointer);
header->rawSize = static_cast<u32>((sizeof(PayloadHeader) + argVec.size() + (domainObjects.size() * sizeof(handle_t)) + constant::IpcPaddingSum + (isDomain ? sizeof(DomainHeaderRequest) : 0)) / sizeof(u32)); // Size is in 32-bit units because Nintendo
header->handleDesc = (!copyHandles.empty() || !moveHandles.empty());
currPtr += sizeof(CommandHeader);
pointer += sizeof(CommandHeader);
if (header->handleDesc) {
auto handleDesc = reinterpret_cast<HandleDescriptor *>(currPtr);
auto handleDesc = reinterpret_cast<HandleDescriptor *>(pointer);
handleDesc->copyCount = static_cast<u8>(copyHandles.size());
handleDesc->moveCount = static_cast<u8>(moveHandles.size());
currPtr += sizeof(HandleDescriptor);
pointer += sizeof(HandleDescriptor);
for (unsigned int copyHandle : copyHandles) {
*reinterpret_cast<handle_t *>(currPtr) = copyHandle;
currPtr += sizeof(handle_t);
*reinterpret_cast<handle_t *>(pointer) = copyHandle;
pointer += sizeof(handle_t);
}
for (unsigned int moveHandle : moveHandles) {
*reinterpret_cast<handle_t *>(currPtr) = moveHandle;
currPtr += sizeof(handle_t);
*reinterpret_cast<handle_t *>(pointer) = moveHandle;
pointer += sizeof(handle_t);
}
}
u64 padding = ((((reinterpret_cast<u64>(currPtr) - reinterpret_cast<u64>(tls.data())) - 1U) & ~(constant::IpcPaddingSum - 1U)) + constant::IpcPaddingSum + (reinterpret_cast<u64>(tls.data()) - reinterpret_cast<u64>(currPtr))); // Calculate the amount of padding at the front
currPtr += padding;
u64 padding = ((((reinterpret_cast<u64>(pointer) - reinterpret_cast<u64>(tls)) - 1U) & ~(constant::IpcPaddingSum - 1U)) + constant::IpcPaddingSum + (reinterpret_cast<u64>(tls) - reinterpret_cast<u64>(pointer))); // Calculate the amount of padding at the front
pointer += padding;
if (isDomain) {
auto domain = reinterpret_cast<DomainHeaderResponse *>(currPtr);
auto domain = reinterpret_cast<DomainHeaderResponse *>(pointer);
domain->outputCount = static_cast<u32>(domainObjects.size());
currPtr += sizeof(DomainHeaderResponse);
pointer += sizeof(DomainHeaderResponse);
}
auto payload = reinterpret_cast<PayloadHeader *>(currPtr);
auto payload = reinterpret_cast<PayloadHeader *>(pointer);
payload->magic = constant::SfcoMagic;
payload->version = 1;
payload->value = errorCode;
currPtr += sizeof(PayloadHeader);
pointer += sizeof(PayloadHeader);
if (!argVec.empty())
memcpy(currPtr, argVec.data(), argVec.size());
currPtr += argVec.size();
memcpy(pointer, argVec.data(), argVec.size());
pointer += argVec.size();
if (isDomain) {
for (auto &domainObject : domainObjects) {
*reinterpret_cast<handle_t *>(currPtr) = domainObject;
currPtr += sizeof(handle_t);
*reinterpret_cast<handle_t *>(pointer) = domainObject;
pointer += sizeof(handle_t);
}
}
state.logger->Debug("Output: Raw Size: {}, Command ID: 0x{:X}, Copy Handles: {}, Move Handles: {}", u32(header->rawSize), u32(payload->value), copyHandles.size(), moveHandles.size());
state.process->WriteMemory(tls.data(), state.thread->tls, constant::TlsIpcSize);
}
std::vector<u8> BufferDescriptorABW::Read(const DeviceState &state) {
std::vector<u8> vec(Size());
state.process->ReadMemory(vec.data(), Address(), Size());
return std::move(vec);
}
}