Logger Function Prefix Support

This commit is contained in:
PixelyIon 2021-03-18 14:33:50 +05:30 committed by ◱ Mark
parent 6c6e665569
commit 2b4a094cd8
9 changed files with 209 additions and 136 deletions

View File

@ -35,7 +35,7 @@ namespace skyline {
void Logger::WriteHeader(const std::string &str) { void Logger::WriteHeader(const std::string &str) {
__android_log_write(ANDROID_LOG_INFO, "emu-cpp", str.c_str()); __android_log_write(ANDROID_LOG_INFO, "emu-cpp", str.c_str());
std::lock_guard guard(mtx); std::lock_guard guard(mutex);
logFile << "\0360\035" << str << '\n'; logFile << "\0360\035" << str << '\n';
} }
@ -48,7 +48,7 @@ namespace skyline {
__android_log_write(levelAlog[static_cast<u8>(level)], logTag.c_str(), str.c_str()); __android_log_write(levelAlog[static_cast<u8>(level)], logTag.c_str(), str.c_str());
std::lock_guard guard(mtx); std::lock_guard guard(mutex);
logFile << "\0361\035" << levelCharacter[static_cast<u8>(level)] << '\035' << threadName << '\035' << str << '\n'; // We use RS (\036) and GS (\035) as our delimiters logFile << "\0361\035" << levelCharacter[static_cast<u8>(level)] << '\035' << threadName << '\035' << str << '\n'; // We use RS (\036) and GS (\035) as our delimiters
} }

View File

@ -152,10 +152,6 @@ namespace skyline {
*/ */
class exception : public std::runtime_error { class exception : public std::runtime_error {
public: public:
/**
* @param formatStr The exception string to be written, with {fmt} formatting
* @param args The arguments based on format_str
*/
template<typename S, typename... Args> template<typename S, typename... Args>
exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {} exception(const S &formatStr, Args &&... args) : runtime_error(fmt::format(formatStr, util::FmtCast(args)...)) {}
}; };
@ -451,7 +447,7 @@ namespace skyline {
class Logger { class Logger {
private: private:
std::ofstream logFile; //!< An output stream to the log file std::ofstream logFile; //!< An output stream to the log file
std::mutex mtx; //!< A mutex to lock before logging anything std::mutex mutex; //!< Synchronizes all output I/O to ensure there's no races
public: public:
enum class LogLevel { enum class LogLevel {
@ -487,34 +483,111 @@ namespace skyline {
void Write(LogLevel level, const std::string &str); void Write(LogLevel level, const std::string &str);
template<typename S, typename... Args> /**
void Error(const S &formatStr, Args &&... args) { * @brief A wrapper around a string which captures the calling function using Clang source location builtins
* @note A function needs to be declared for every argument template specialization as CTAD cannot work with implicit casting
* @url https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins
*/
template<typename S>
struct FunctionString {
S string;
const char *function;
FunctionString(S string, const char *function = __builtin_FUNCTION()) : string(std::move(string)), function(function) {}
std::string operator*() {
return std::string(function) + ": " + std::string(string);
}
};
template<typename... Args>
void Error(FunctionString<const char*> formatString, Args &&... args) {
if (LogLevel::Error <= configLevel) if (LogLevel::Error <= configLevel)
Write(LogLevel::Error, fmt::format(formatStr, util::FmtCast(args)...)); Write(LogLevel::Error, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Error(FunctionString<std::string> formatString, Args &&... args) {
if (LogLevel::Error <= configLevel)
Write(LogLevel::Error, fmt::format(*formatString, util::FmtCast(args)...));
} }
template<typename S, typename... Args> template<typename S, typename... Args>
void Warn(const S &formatStr, Args &&... args) { void ErrorNoPrefix(S formatString, Args &&... args) {
if (LogLevel::Error <= configLevel)
Write(LogLevel::Error, fmt::format(formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Warn(FunctionString<const char*> formatString, Args &&... args) {
if (LogLevel::Warn <= configLevel) if (LogLevel::Warn <= configLevel)
Write(LogLevel::Warn, fmt::format(formatStr, util::FmtCast(args)...)); Write(LogLevel::Warn, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Warn(FunctionString<std::string> formatString, Args &&... args) {
if (LogLevel::Warn <= configLevel)
Write(LogLevel::Warn, fmt::format(*formatString, util::FmtCast(args)...));
} }
template<typename S, typename... Args> template<typename S, typename... Args>
void Info(const S &formatStr, Args &&... args) { void WarnNoPrefix(S formatString, Args &&... args) {
if (LogLevel::Warn <= configLevel)
Write(LogLevel::Warn, fmt::format(formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Info(FunctionString<const char*> formatString, Args &&... args) {
if (LogLevel::Info <= configLevel) if (LogLevel::Info <= configLevel)
Write(LogLevel::Info, fmt::format(formatStr, util::FmtCast(args)...)); Write(LogLevel::Info, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Info(FunctionString<std::string> formatString, Args &&... args) {
if (LogLevel::Info <= configLevel)
Write(LogLevel::Info, fmt::format(*formatString, util::FmtCast(args)...));
} }
template<typename S, typename... Args> template<typename S, typename... Args>
void Debug(const S &formatStr, Args &&... args) { void InfoNoPrefix(S formatString, Args &&... args) {
if (LogLevel::Info <= configLevel)
Write(LogLevel::Info, fmt::format(formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Debug(FunctionString<const char*> formatString, Args &&... args) {
if (LogLevel::Debug <= configLevel) if (LogLevel::Debug <= configLevel)
Write(LogLevel::Debug, fmt::format(formatStr, util::FmtCast(args)...)); Write(LogLevel::Debug, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Debug(FunctionString<std::string> formatString, Args &&... args) {
if (LogLevel::Debug <= configLevel)
Write(LogLevel::Debug, fmt::format(*formatString, util::FmtCast(args)...));
} }
template<typename S, typename... Args> template<typename S, typename... Args>
void Verbose(const S &formatStr, Args &&... args) { void DebugNoPrefix(S formatString, Args &&... args) {
if (LogLevel::Debug <= configLevel)
Write(LogLevel::Debug, fmt::format(formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Verbose(FunctionString<const char*> formatString, Args &&... args) {
if (LogLevel::Verbose <= configLevel) if (LogLevel::Verbose <= configLevel)
Write(LogLevel::Verbose, fmt::format(formatStr, util::FmtCast(args)...)); Write(LogLevel::Verbose, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename... Args>
void Verbose(FunctionString<std::string> formatString, Args &&... args) {
if (LogLevel::Verbose <= configLevel)
Write(LogLevel::Verbose, fmt::format(*formatString, util::FmtCast(args)...));
}
template<typename S, typename... Args>
void VerboseNoPrefix(S formatString, Args &&... args) {
if (LogLevel::Verbose <= configLevel)
Write(LogLevel::Verbose, fmt::format(formatString, util::FmtCast(args)...));
} }
}; };

View File

@ -16,7 +16,7 @@ namespace skyline::kernel::svc {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.ctx->gpr.x1 = 0; state.ctx->gpr.x1 = 0;
state.logger->Warn("svcSetHeapSize: 'size' not divisible by 2MB: {}", size); state.logger->Warn("'size' not divisible by 2MB: {}", size);
return; return;
} }
@ -26,21 +26,21 @@ namespace skyline::kernel::svc {
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
state.ctx->gpr.x1 = reinterpret_cast<u64>(heap->ptr); state.ctx->gpr.x1 = reinterpret_cast<u64>(heap->ptr);
state.logger->Debug("svcSetHeapSize: Allocated at 0x{:X} - 0x{:X} (0x{:X} bytes)", heap->ptr, heap->ptr + heap->size, heap->size); state.logger->Debug("Allocated at 0x{:X} - 0x{:X} (0x{:X} bytes)", heap->ptr, heap->ptr + heap->size, heap->size);
} }
void SetMemoryAttribute(const DeviceState &state) { void SetMemoryAttribute(const DeviceState &state) {
auto pointer{reinterpret_cast<u8 *>(state.ctx->gpr.x0)}; auto pointer{reinterpret_cast<u8 *>(state.ctx->gpr.x0)};
if (!util::PageAligned(pointer)) { if (!util::PageAligned(pointer)) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: 'pointer' not page aligned: 0x{:X}", pointer); state.logger->Warn("'pointer' not page aligned: 0x{:X}", pointer);
return; return;
} }
size_t size{state.ctx->gpr.x1}; size_t size{state.ctx->gpr.x1};
if (!util::PageAligned(size)) { if (!util::PageAligned(size)) {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size); state.logger->Warn("'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
@ -50,20 +50,20 @@ namespace skyline::kernel::svc {
auto maskedValue{mask.value | value.value}; auto maskedValue{mask.value | value.value};
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) { if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
state.ctx->gpr.w0 = result::InvalidCombination; state.ctx->gpr.w0 = result::InvalidCombination;
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value); state.logger->Warn("'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
return; return;
} }
auto chunk{state.process->memory.Get(pointer)}; auto chunk{state.process->memory.Get(pointer)};
if (!chunk) { if (!chunk) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", pointer); state.logger->Warn("Cannot find memory region: 0x{:X}", pointer);
return; return;
} }
if (!chunk->state.attributeChangeAllowed) { if (!chunk->state.attributeChangeAllowed) {
state.ctx->gpr.w0 = result::InvalidState; state.ctx->gpr.w0 = result::InvalidState;
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", pointer); state.logger->Warn("Attribute change not allowed for chunk: 0x{:X}", pointer);
return; return;
} }
@ -73,7 +73,7 @@ namespace skyline::kernel::svc {
newChunk.attributes.isUncached = value.isUncached; newChunk.attributes.isUncached = value.isUncached;
state.process->memory.InsertChunk(newChunk); state.process->memory.InsertChunk(newChunk);
state.logger->Debug("svcSetMemoryAttribute: Set CPU caching to {} at 0x{:X} - 0x{:X} (0x{:X} bytes)", !static_cast<bool>(value.isUncached), pointer, pointer + size, size); state.logger->Debug("Set CPU caching to {} at 0x{:X} - 0x{:X} (0x{:X} bytes)", !static_cast<bool>(value.isUncached), pointer, pointer + size, size);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -84,32 +84,32 @@ namespace skyline::kernel::svc {
if (!util::PageAligned(destination) || !util::PageAligned(source)) { if (!util::PageAligned(destination) || !util::PageAligned(source)) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!util::PageAligned(size)) { if (!util::PageAligned(size)) {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.logger->Warn("svcMapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size); state.logger->Warn("'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
auto stack{state.process->memory.stack}; auto stack{state.process->memory.stack};
if (!stack.IsInside(destination)) { if (!stack.IsInside(destination)) {
state.ctx->gpr.w0 = result::InvalidMemoryRegion; state.ctx->gpr.w0 = result::InvalidMemoryRegion;
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
auto chunk{state.process->memory.Get(source)}; auto chunk{state.process->memory.Get(source)};
if (!chunk) { if (!chunk) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!chunk->state.mapAllowed) { if (!chunk->state.mapAllowed) {
state.ctx->gpr.w0 = result::InvalidState; state.ctx->gpr.w0 = result::InvalidState;
state.logger->Warn("svcMapMemory: Source doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X}, Size: 0x{:X}, MemoryState: 0x{:X}", source, destination, size, chunk->state.value); state.logger->Warn("Source doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X}, Size: 0x{:X}, MemoryState: 0x{:X}", source, destination, size, chunk->state.value);
return; return;
} }
@ -121,7 +121,7 @@ namespace skyline::kernel::svc {
throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", source); throw exception("svcMapMemory: Cannot find memory object in handle table for address 0x{:X}", source);
object->item->UpdatePermission(source, size, {false, false, false}); object->item->UpdatePermission(source, size, {false, false, false});
state.logger->Debug("svcMapMemory: Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size); state.logger->Debug("Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -132,20 +132,20 @@ namespace skyline::kernel::svc {
if (!util::PageAligned(destination) || !util::PageAligned(source)) { if (!util::PageAligned(destination) || !util::PageAligned(source)) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcUnmapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!util::PageAligned(size)) { if (!util::PageAligned(size)) {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.logger->Warn("svcUnmapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size); state.logger->Warn("'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
auto stack{state.process->memory.stack}; auto stack{state.process->memory.stack};
if (!stack.IsInside(source)) { if (!stack.IsInside(source)) {
state.ctx->gpr.w0 = result::InvalidMemoryRegion; state.ctx->gpr.w0 = result::InvalidMemoryRegion;
state.logger->Warn("svcUnmapMemory: Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
@ -153,13 +153,13 @@ namespace skyline::kernel::svc {
auto destChunk{state.process->memory.Get(destination)}; auto destChunk{state.process->memory.Get(destination)};
if (!sourceChunk || !destChunk) { if (!sourceChunk || !destChunk) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcUnmapMemory: Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size); state.logger->Warn("Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!destChunk->state.mapAllowed) { if (!destChunk->state.mapAllowed) {
state.ctx->gpr.w0 = result::InvalidState; state.ctx->gpr.w0 = result::InvalidState;
state.logger->Warn("svcUnmapMemory: Destination doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes) 0x{:X}", source, destination, size, destChunk->state.value); state.logger->Warn("Destination doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes) 0x{:X}", source, destination, size, destChunk->state.value);
return; return;
} }
@ -177,7 +177,7 @@ namespace skyline::kernel::svc {
state.process->CloseHandle(sourceObject->handle); state.process->CloseHandle(sourceObject->handle);
state.logger->Debug("svcUnmapMemory: Unmapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size); state.logger->Debug("Unmapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -198,7 +198,7 @@ namespace skyline::kernel::svc {
.ipcRefCount = 0, .ipcRefCount = 0,
}; };
state.logger->Debug("svcQueryMemory: Address: 0x{:X}, Region Start: 0x{:X}, Size: 0x{:X}, Type: 0x{:X}, Is Uncached: {}, Permissions: {}{}{}", pointer, memInfo.address, memInfo.size, memInfo.type, static_cast<bool>(chunk->attributes.isUncached), chunk->permission.r ? 'R' : '-', chunk->permission.w ? 'W' : '-', chunk->permission.x ? 'X' : '-'); state.logger->Debug("Address: 0x{:X}, Region Start: 0x{:X}, Size: 0x{:X}, Type: 0x{:X}, Is Uncached: {}, Permissions: {}{}{}", pointer, memInfo.address, memInfo.size, memInfo.type, static_cast<bool>(chunk->attributes.isUncached), chunk->permission.r ? 'R' : '-', chunk->permission.w ? 'W' : '-', chunk->permission.x ? 'X' : '-');
} else { } else {
auto addressSpaceEnd{reinterpret_cast<u64>(state.process->memory.addressSpace.address + state.process->memory.addressSpace.size)}; auto addressSpaceEnd{reinterpret_cast<u64>(state.process->memory.addressSpace.address + state.process->memory.addressSpace.size)};
@ -208,7 +208,7 @@ namespace skyline::kernel::svc {
.type = static_cast<u32>(memory::MemoryType::Reserved), .type = static_cast<u32>(memory::MemoryType::Reserved),
}; };
state.logger->Debug("svcQueryMemory: Trying to query memory outside of the application's address space: 0x{:X}", pointer); state.logger->Debug("Trying to query memory outside of the application's address space: 0x{:X}", pointer);
} }
*reinterpret_cast<memory::MemoryInfo *>(state.ctx->gpr.x0) = memInfo; *reinterpret_cast<memory::MemoryInfo *>(state.ctx->gpr.x0) = memInfo;
@ -217,7 +217,7 @@ namespace skyline::kernel::svc {
} }
void ExitProcess(const DeviceState &state) { void ExitProcess(const DeviceState &state) {
state.logger->Debug("svcExitProcess: Exiting process"); state.logger->Debug("Exiting process");
if (state.thread->id) if (state.thread->id)
state.process->Kill(false); state.process->Kill(false);
std::longjmp(state.thread->originalCtx, true); std::longjmp(state.thread->originalCtx, true);
@ -237,13 +237,13 @@ namespace skyline::kernel::svc {
idealCore = (idealCore == IdealCoreUseProcessValue) ? state.process->npdm.meta.idealCore : idealCore; idealCore = (idealCore == IdealCoreUseProcessValue) ? state.process->npdm.meta.idealCore : idealCore;
if (idealCore < 0 || idealCore >= constant::CoreCount) { if (idealCore < 0 || idealCore >= constant::CoreCount) {
state.ctx->gpr.w0 = result::InvalidCoreId; state.ctx->gpr.w0 = result::InvalidCoreId;
state.logger->Warn("svcCreateThread: 'idealCore' invalid: {}", idealCore); state.logger->Warn("'idealCore' invalid: {}", idealCore);
return; return;
} }
if (!state.process->npdm.threadInfo.priority.Valid(priority)) { if (!state.process->npdm.threadInfo.priority.Valid(priority)) {
state.ctx->gpr.w0 = result::InvalidPriority; state.ctx->gpr.w0 = result::InvalidPriority;
state.logger->Warn("svcCreateThread: 'priority' invalid: {}", priority); state.logger->Warn("'priority' invalid: {}", priority);
return; return;
} }
@ -253,12 +253,12 @@ namespace skyline::kernel::svc {
auto thread{state.process->CreateThread(entry, entryArgument, stackTop, priority, idealCore)}; auto thread{state.process->CreateThread(entry, entryArgument, stackTop, priority, idealCore)};
if (thread) { if (thread) {
state.logger->Debug("svcCreateThread: Created thread #{} with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", thread->id, thread->handle, entry, entryArgument, stackTop, priority, idealCore); state.logger->Debug("Created thread #{} with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", thread->id, thread->handle, entry, entryArgument, stackTop, priority, idealCore);
state.ctx->gpr.w1 = thread->handle; state.ctx->gpr.w1 = thread->handle;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} else { } else {
state.logger->Debug("svcCreateThread: Cannot create thread (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", entry, entryArgument, stackTop, priority, idealCore); state.logger->Debug("Cannot create thread (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, Ideal Core: {})", entry, entryArgument, stackTop, priority, idealCore);
state.ctx->gpr.w1 = 0; state.ctx->gpr.w1 = 0;
state.ctx->gpr.w0 = result::OutOfResource; state.ctx->gpr.w0 = result::OutOfResource;
} }
@ -268,17 +268,17 @@ namespace skyline::kernel::svc {
KHandle handle{state.ctx->gpr.w0}; KHandle handle{state.ctx->gpr.w0};
try { try {
auto thread{state.process->GetHandle<type::KThread>(handle)}; auto thread{state.process->GetHandle<type::KThread>(handle)};
state.logger->Debug("svcStartThread: Starting thread #{}: 0x{:X}", thread->id, handle); state.logger->Debug("Starting thread #{}: 0x{:X}", thread->id, handle);
thread->Start(); thread->Start();
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcStartThread: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
void ExitThread(const DeviceState &state) { void ExitThread(const DeviceState &state) {
state.logger->Debug("svcExitThread: Exiting current thread"); state.logger->Debug("Exiting current thread");
std::longjmp(state.thread->originalCtx, true); std::longjmp(state.thread->originalCtx, true);
} }
@ -291,7 +291,7 @@ namespace skyline::kernel::svc {
i64 in{static_cast<i64>(state.ctx->gpr.x0)}; i64 in{static_cast<i64>(state.ctx->gpr.x0)};
if (in > 0) { if (in > 0) {
state.logger->Debug("svcSleepThread: Sleeping for {}ns", in); state.logger->Debug("Sleeping for {}ns", in);
struct timespec spec{ struct timespec spec{
.tv_sec = static_cast<time_t>(in / 1000000000), .tv_sec = static_cast<time_t>(in / 1000000000),
@ -303,18 +303,18 @@ namespace skyline::kernel::svc {
} else { } else {
switch (in) { switch (in) {
case yieldWithCoreMigration: case yieldWithCoreMigration:
state.logger->Debug("svcSleepThread: Waking any appropriate parked threads and yielding"); state.logger->Debug("Waking any appropriate parked threads and yielding");
state.scheduler->WakeParkedThread(); state.scheduler->WakeParkedThread();
[[fallthrough]]; [[fallthrough]];
case yieldWithoutCoreMigration: case yieldWithoutCoreMigration:
if (in == yieldWithoutCoreMigration) if (in == yieldWithoutCoreMigration)
state.logger->Debug("svcSleepThread: Cooperative yield"); state.logger->Debug("Cooperative yield");
state.scheduler->Rotate(); state.scheduler->Rotate();
state.scheduler->WaitSchedule(); state.scheduler->WaitSchedule();
break; break;
case yieldToAnyThread: case yieldToAnyThread:
state.logger->Debug("svcSleepThread: Parking current thread"); state.logger->Debug("Parking current thread");
state.scheduler->ParkThread(); state.scheduler->ParkThread();
state.scheduler->WaitSchedule(false); state.scheduler->WaitSchedule(false);
break; break;
@ -330,12 +330,12 @@ namespace skyline::kernel::svc {
try { try {
auto thread{state.process->GetHandle<type::KThread>(handle)}; auto thread{state.process->GetHandle<type::KThread>(handle)};
u8 priority{thread->priority}; u8 priority{thread->priority};
state.logger->Debug("svcGetThreadPriority: Retrieving thread #{}'s priority: {}", thread->id, priority); state.logger->Debug("Retrieving thread #{}'s priority: {}", thread->id, priority);
state.ctx->gpr.w1 = priority; state.ctx->gpr.w1 = priority;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcGetThreadPriority: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -344,13 +344,13 @@ namespace skyline::kernel::svc {
KHandle handle{state.ctx->gpr.w0}; KHandle handle{state.ctx->gpr.w0};
u8 priority{static_cast<u8>(state.ctx->gpr.w1)}; u8 priority{static_cast<u8>(state.ctx->gpr.w1)};
if (!state.process->npdm.threadInfo.priority.Valid(priority)) { if (!state.process->npdm.threadInfo.priority.Valid(priority)) {
state.logger->Warn("svcSetThreadPriority: 'priority' invalid: 0x{:X}", priority); state.logger->Warn("'priority' invalid: 0x{:X}", priority);
state.ctx->gpr.w0 = result::InvalidPriority; state.ctx->gpr.w0 = result::InvalidPriority;
return; return;
} }
try { try {
auto thread{state.process->GetHandle<type::KThread>(handle)}; auto thread{state.process->GetHandle<type::KThread>(handle)};
state.logger->Debug("svcSetThreadPriority: Setting thread #{}'s priority to {}", thread->id, priority); state.logger->Debug("Setting thread #{}'s priority to {}", thread->id, priority);
if (thread->priority != priority) { if (thread->priority != priority) {
thread->basePriority = priority; thread->basePriority = priority;
u8 newPriority{}; u8 newPriority{};
@ -365,7 +365,7 @@ namespace skyline::kernel::svc {
} }
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcSetThreadPriority: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -376,13 +376,13 @@ namespace skyline::kernel::svc {
auto thread{state.process->GetHandle<type::KThread>(handle)}; auto thread{state.process->GetHandle<type::KThread>(handle)};
auto idealCore{thread->idealCore}; auto idealCore{thread->idealCore};
auto affinityMask{thread->affinityMask}; auto affinityMask{thread->affinityMask};
state.logger->Debug("svcGetThreadCoreMask: Getting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask); state.logger->Debug("Getting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
state.ctx->gpr.x2 = affinityMask.to_ullong(); state.ctx->gpr.x2 = affinityMask.to_ullong();
state.ctx->gpr.w1 = idealCore; state.ctx->gpr.w1 = idealCore;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcGetThreadCoreMask: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -405,25 +405,25 @@ namespace skyline::kernel::svc {
auto processMask{state.process->npdm.threadInfo.coreMask}; auto processMask{state.process->npdm.threadInfo.coreMask};
if ((processMask | affinityMask) != processMask) { if ((processMask | affinityMask) != processMask) {
state.logger->Warn("svcSetThreadCoreMask: 'affinityMask' invalid: {} (Process Mask: {})", affinityMask, processMask); state.logger->Warn("'affinityMask' invalid: {} (Process Mask: {})", affinityMask, processMask);
state.ctx->gpr.w0 = result::InvalidCoreId; state.ctx->gpr.w0 = result::InvalidCoreId;
return; return;
} }
if (affinityMask.none() || !affinityMask.test(idealCore)) { if (affinityMask.none() || !affinityMask.test(idealCore)) {
state.logger->Warn("svcSetThreadCoreMask: 'affinityMask' invalid: {} (Ideal Core: {})", affinityMask, idealCore); state.logger->Warn("'affinityMask' invalid: {} (Ideal Core: {})", affinityMask, idealCore);
state.ctx->gpr.w0 = result::InvalidCombination; state.ctx->gpr.w0 = result::InvalidCombination;
return; return;
} }
state.logger->Debug("svcSetThreadCoreMask: Setting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask); state.logger->Debug("Setting thread #{}'s Ideal Core ({}) + Affinity Mask ({})", thread->id, idealCore, affinityMask);
std::lock_guard guard(thread->coreMigrationMutex); std::lock_guard guard(thread->coreMigrationMutex);
thread->idealCore = idealCore; thread->idealCore = idealCore;
thread->affinityMask = affinityMask; thread->affinityMask = affinityMask;
if (!affinityMask.test(thread->coreId) && thread->coreId != constant::ParkedCoreId) { if (!affinityMask.test(thread->coreId) && thread->coreId != constant::ParkedCoreId) {
state.logger->Debug("svcSetThreadCoreMask: Migrating thread #{} to Ideal Core C{} -> C{}", thread->id, thread->coreId, idealCore); state.logger->Debug("Migrating thread #{} to Ideal Core C{} -> C{}", thread->id, thread->coreId, idealCore);
if (thread == state.thread) { if (thread == state.thread) {
state.scheduler->RemoveThread(); state.scheduler->RemoveThread();
@ -439,7 +439,7 @@ namespace skyline::kernel::svc {
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcSetThreadCoreMask: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -447,7 +447,7 @@ namespace skyline::kernel::svc {
void GetCurrentProcessorNumber(const DeviceState &state) { void GetCurrentProcessorNumber(const DeviceState &state) {
std::lock_guard guard(state.thread->coreMigrationMutex); std::lock_guard guard(state.thread->coreMigrationMutex);
auto coreId{state.thread->coreId}; auto coreId{state.thread->coreId};
state.logger->Debug("svcGetCurrentProcessorNumber: C{}", coreId); state.logger->Debug("C{}", coreId);
state.ctx->gpr.w0 = coreId; state.ctx->gpr.w0 = coreId;
} }
@ -455,10 +455,10 @@ namespace skyline::kernel::svc {
KHandle handle{state.ctx->gpr.w0}; KHandle handle{state.ctx->gpr.w0};
try { try {
std::static_pointer_cast<type::KEvent>(state.process->GetHandle(handle))->ResetSignal(); std::static_pointer_cast<type::KEvent>(state.process->GetHandle(handle))->ResetSignal();
state.logger->Debug("svcClearEvent: Clearing 0x{:X}", handle); state.logger->Debug("Clearing 0x{:X}", handle);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcClearEvent: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
return; return;
} }
@ -471,31 +471,31 @@ namespace skyline::kernel::svc {
if (!util::PageAligned(pointer)) { if (!util::PageAligned(pointer)) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcMapSharedMemory: 'pointer' not page aligned: 0x{:X}", pointer); state.logger->Warn("'pointer' not page aligned: 0x{:X}", pointer);
return; return;
} }
size_t size{state.ctx->gpr.x2}; size_t size{state.ctx->gpr.x2};
if (!util::PageAligned(size)) { if (!util::PageAligned(size)) {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.logger->Warn("svcMapSharedMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size); state.logger->Warn("'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
memory::Permission permission(state.ctx->gpr.w3); memory::Permission permission(state.ctx->gpr.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) { if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
state.logger->Warn("svcMapSharedMemory: 'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission; state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
return; return;
} }
state.logger->Debug("svcMapSharedMemory: Mapping shared memory at 0x{:X} - 0x{:X} (0x{:X} bytes) ({}{}{})", pointer, pointer + size, size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.logger->Debug("Mapping shared memory at 0x{:X} - 0x{:X} (0x{:X} bytes) ({}{}{})", pointer, pointer + size, size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
object->Map(pointer, size, permission); object->Map(pointer, size, permission);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcMapSharedMemory: 'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0)); state.logger->Warn("'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0));
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -504,26 +504,26 @@ namespace skyline::kernel::svc {
auto pointer{reinterpret_cast<u8 *>(state.ctx->gpr.x1)}; auto pointer{reinterpret_cast<u8 *>(state.ctx->gpr.x1)};
if (!util::PageAligned(pointer)) { if (!util::PageAligned(pointer)) {
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
state.logger->Warn("svcCreateTransferMemory: 'pointer' not page aligned: 0x{:X}", pointer); state.logger->Warn("'pointer' not page aligned: 0x{:X}", pointer);
return; return;
} }
size_t size{state.ctx->gpr.x2}; size_t size{state.ctx->gpr.x2};
if (!util::PageAligned(size)) { if (!util::PageAligned(size)) {
state.ctx->gpr.w0 = result::InvalidSize; state.ctx->gpr.w0 = result::InvalidSize;
state.logger->Warn("svcCreateTransferMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size); state.logger->Warn("'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
memory::Permission permission(state.ctx->gpr.w3); memory::Permission permission(state.ctx->gpr.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) { if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
state.logger->Warn("svcCreateTransferMemory: 'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.logger->Warn("'permission' invalid: {}{}{}", permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
state.ctx->gpr.w0 = result::InvalidNewMemoryPermission; state.ctx->gpr.w0 = result::InvalidNewMemoryPermission;
return; return;
} }
auto tmem{state.process->NewHandle<type::KTransferMemory>(pointer, size, permission)}; auto tmem{state.process->NewHandle<type::KTransferMemory>(pointer, size, permission)};
state.logger->Debug("svcCreateTransferMemory: Creating transfer memory at 0x{:X} - 0x{:X} (0x{:X} bytes) ({}{}{})", pointer, pointer + size, size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-'); state.logger->Debug("Creating transfer memory at 0x{:X} - 0x{:X} (0x{:X} bytes) ({}{}{})", pointer, pointer + size, size, permission.r ? 'R' : '-', permission.w ? 'W' : '-', permission.x ? 'X' : '-');
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
state.ctx->gpr.w1 = tmem.handle; state.ctx->gpr.w1 = tmem.handle;
@ -533,10 +533,10 @@ namespace skyline::kernel::svc {
KHandle handle{static_cast<KHandle>(state.ctx->gpr.w0)}; KHandle handle{static_cast<KHandle>(state.ctx->gpr.w0)};
try { try {
state.process->CloseHandle(handle); state.process->CloseHandle(handle);
state.logger->Debug("svcCloseHandle: Closing 0x{:X}", handle); state.logger->Debug("Closing 0x{:X}", handle);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -552,16 +552,16 @@ namespace skyline::kernel::svc {
break; break;
default: { default: {
state.logger->Warn("svcResetSignal: 'handle' type invalid: 0x{:X} ({})", handle, object->objectType); state.logger->Warn("'handle' type invalid: 0x{:X} ({})", handle, object->objectType);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
return; return;
} }
} }
state.logger->Debug("svcResetSignal: Resetting 0x{:X}", handle); state.logger->Debug("Resetting 0x{:X}", handle);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("'handle' invalid: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
return; return;
} }
@ -591,7 +591,7 @@ namespace skyline::kernel::svc {
break; break;
default: { default: {
state.logger->Debug("svcWaitSynchronization: An invalid handle was supplied: 0x{:X}", handle); state.logger->Debug("An invalid handle was supplied: 0x{:X}", handle);
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
return; return;
} }
@ -600,12 +600,12 @@ namespace skyline::kernel::svc {
i64 timeout{static_cast<i64>(state.ctx->gpr.x3)}; i64 timeout{static_cast<i64>(state.ctx->gpr.x3)};
if (waitHandles.size() == 1) { if (waitHandles.size() == 1) {
state.logger->Debug("svcWaitSynchronization: Waiting on 0x{:X} for {}ns", waitHandles[0], timeout); state.logger->Debug("Waiting on 0x{:X} for {}ns", waitHandles[0], timeout);
} else if (Logger::LogLevel::Debug <= state.logger->configLevel) { } else if (Logger::LogLevel::Debug <= state.logger->configLevel) {
std::string handleString; std::string handleString;
for (const auto &handle : waitHandles) for (const auto &handle : waitHandles)
handleString += fmt::format("* 0x{:X}\n", handle); handleString += fmt::format("* 0x{:X}\n", handle);
state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: {}ns", handleString, timeout); state.logger->Debug("Waiting on handles:\n{}Timeout: {}ns", handleString, timeout);
} }
std::unique_lock lock(type::KSyncObject::syncObjectMutex); std::unique_lock lock(type::KSyncObject::syncObjectMutex);
@ -618,7 +618,7 @@ namespace skyline::kernel::svc {
u32 index{}; u32 index{};
for (const auto &object : objectTable) { for (const auto &object : objectTable) {
if (object->signalled) { if (object->signalled) {
state.logger->Debug("svcWaitSynchronization: Signalled 0x{:X}", waitHandles[index]); state.logger->Debug("Signalled 0x{:X}", waitHandles[index]);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
state.ctx->gpr.w1 = index; state.ctx->gpr.w1 = index;
return; return;
@ -627,7 +627,7 @@ namespace skyline::kernel::svc {
} }
if (timeout == 0) { if (timeout == 0) {
state.logger->Debug("svcWaitSynchronization: No handle is currently signalled"); state.logger->Debug("No handle is currently signalled");
state.ctx->gpr.w0 = result::TimedOut; state.ctx->gpr.w0 = result::TimedOut;
return; return;
} }
@ -666,15 +666,15 @@ namespace skyline::kernel::svc {
} }
if (wakeObject) { if (wakeObject) {
state.logger->Debug("svcWaitSynchronization: Signalled 0x{:X}", waitHandles[wakeIndex]); state.logger->Debug("Signalled 0x{:X}", waitHandles[wakeIndex]);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
state.ctx->gpr.w1 = wakeIndex; state.ctx->gpr.w1 = wakeIndex;
} else if (state.thread->cancelSync) { } else if (state.thread->cancelSync) {
state.thread->cancelSync = false; state.thread->cancelSync = false;
state.logger->Debug("svcWaitSynchronization: Wait has been cancelled"); state.logger->Debug("Wait has been cancelled");
state.ctx->gpr.w0 = result::Cancelled; state.ctx->gpr.w0 = result::Cancelled;
} else { } else {
state.logger->Debug("svcWaitSynchronization: Wait has timed out"); state.logger->Debug("Wait has timed out");
state.ctx->gpr.w0 = result::TimedOut; state.ctx->gpr.w0 = result::TimedOut;
lock.unlock(); lock.unlock();
state.scheduler->InsertThread(state.thread); state.scheduler->InsertThread(state.thread);
@ -693,7 +693,7 @@ namespace skyline::kernel::svc {
} }
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0)); state.logger->Warn("'handle' invalid: 0x{:X}", static_cast<u32>(state.ctx->gpr.w0));
state.ctx->gpr.w0 = result::InvalidHandle; state.ctx->gpr.w0 = result::InvalidHandle;
} }
} }
@ -701,22 +701,22 @@ namespace skyline::kernel::svc {
void ArbitrateLock(const DeviceState &state) { void ArbitrateLock(const DeviceState &state) {
auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x1)}; auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x1)};
if (!util::WordAligned(mutex)) { if (!util::WordAligned(mutex)) {
state.logger->Warn("svcArbitrateLock: 'mutex' not word aligned: 0x{:X}", mutex); state.logger->Warn("'mutex' not word aligned: 0x{:X}", mutex);
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
return; return;
} }
state.logger->Debug("svcArbitrateLock: Locking 0x{:X}", mutex); state.logger->Debug("Locking 0x{:X}", mutex);
KHandle ownerHandle{state.ctx->gpr.w0}; KHandle ownerHandle{state.ctx->gpr.w0};
KHandle requesterHandle{state.ctx->gpr.w2}; KHandle requesterHandle{state.ctx->gpr.w2};
auto result{state.process->MutexLock(mutex, ownerHandle, requesterHandle)}; auto result{state.process->MutexLock(mutex, ownerHandle, requesterHandle)};
if (result == Result{}) if (result == Result{})
state.logger->Debug("svcArbitrateLock: Locked 0x{:X}", mutex); state.logger->Debug("Locked 0x{:X}", mutex);
else if (result == result::InvalidCurrentMemory) else if (result == result::InvalidCurrentMemory)
result = Result{}; // If the mutex value isn't expected then it's still successful result = Result{}; // If the mutex value isn't expected then it's still successful
else if (result == result::InvalidHandle) else if (result == result::InvalidHandle)
state.logger->Warn("svcArbitrateLock: 'ownerHandle' invalid: 0x{:X} (0x{:X})", ownerHandle, mutex); state.logger->Warn("'ownerHandle' invalid: 0x{:X} (0x{:X})", ownerHandle, mutex);
state.ctx->gpr.w0 = result; state.ctx->gpr.w0 = result;
} }
@ -724,14 +724,14 @@ namespace skyline::kernel::svc {
void ArbitrateUnlock(const DeviceState &state) { void ArbitrateUnlock(const DeviceState &state) {
auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x0)}; auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
if (!util::WordAligned(mutex)) { if (!util::WordAligned(mutex)) {
state.logger->Warn("svcArbitrateUnlock: 'mutex' not word aligned: 0x{:X}", mutex); state.logger->Warn("'mutex' not word aligned: 0x{:X}", mutex);
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
return; return;
} }
state.logger->Debug("svcArbitrateUnlock: Unlocking 0x{:X}", mutex); state.logger->Debug("Unlocking 0x{:X}", mutex);
state.process->MutexUnlock(mutex); state.process->MutexUnlock(mutex);
state.logger->Debug("svcArbitrateUnlock: Unlocked 0x{:X}", mutex); state.logger->Debug("Unlocked 0x{:X}", mutex);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -739,7 +739,7 @@ namespace skyline::kernel::svc {
void WaitProcessWideKeyAtomic(const DeviceState &state) { void WaitProcessWideKeyAtomic(const DeviceState &state) {
auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x0)}; auto mutex{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
if (!util::WordAligned(mutex)) { if (!util::WordAligned(mutex)) {
state.logger->Warn("svcWaitProcessWideKeyAtomic: 'mutex' not word aligned: 0x{:X}", mutex); state.logger->Warn("'mutex' not word aligned: 0x{:X}", mutex);
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
return; return;
} }
@ -748,13 +748,13 @@ namespace skyline::kernel::svc {
KHandle requesterHandle{state.ctx->gpr.w2}; KHandle requesterHandle{state.ctx->gpr.w2};
i64 timeout{static_cast<i64>(state.ctx->gpr.x3)}; i64 timeout{static_cast<i64>(state.ctx->gpr.x3)};
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waiting on 0x{:X} with 0x{:X} for {}ns", conditional, mutex, timeout); state.logger->Debug("Waiting on 0x{:X} with 0x{:X} for {}ns", conditional, mutex, timeout);
auto result{state.process->ConditionalVariableWait(conditional, mutex, requesterHandle, timeout)}; auto result{state.process->ConditionalVariableWait(conditional, mutex, requesterHandle, timeout)};
if (result == Result{}) if (result == Result{})
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for 0x{:X} and reacquired 0x{:X}", conditional, mutex); state.logger->Debug("Waited for 0x{:X} and reacquired 0x{:X}", conditional, mutex);
else if (result == result::TimedOut) else if (result == result::TimedOut)
state.logger->Debug("svcWaitProcessWideKeyAtomic: Wait on 0x{:X} has timed out after {}ns", conditional, timeout); state.logger->Debug("Wait on 0x{:X} has timed out after {}ns", conditional, timeout);
state.ctx->gpr.w0 = result; state.ctx->gpr.w0 = result;
} }
@ -762,7 +762,7 @@ namespace skyline::kernel::svc {
auto conditional{reinterpret_cast<u32 *>(state.ctx->gpr.x0)}; auto conditional{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
i32 count{static_cast<i32>(state.ctx->gpr.w1)}; i32 count{static_cast<i32>(state.ctx->gpr.w1)};
state.logger->Debug("svcSignalProcessWideKey: Signalling 0x{:X} for {} waiters", conditional, count); state.logger->Debug("Signalling 0x{:X} for {} waiters", conditional, count);
state.process->ConditionalVariableSignal(conditional, count); state.process->ConditionalVariableSignal(conditional, count);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -788,12 +788,12 @@ namespace skyline::kernel::svc {
if (port.compare("sm:") >= 0) { if (port.compare("sm:") >= 0) {
handle = state.process->NewHandle<type::KSession>(std::static_pointer_cast<service::BaseService>(state.os->serviceManager.smUserInterface)).handle; handle = state.process->NewHandle<type::KSession>(std::static_pointer_cast<service::BaseService>(state.os->serviceManager.smUserInterface)).handle;
} else { } else {
state.logger->Warn("svcConnectToNamedPort: Connecting to invalid port: '{}'", port); state.logger->Warn("Connecting to invalid port: '{}'", port);
state.ctx->gpr.w0 = result::NotFound; state.ctx->gpr.w0 = result::NotFound;
return; return;
} }
state.logger->Debug("svcConnectToNamedPort: Connecting to port '{}' at 0x{:X}", port, handle); state.logger->Debug("Connecting to port '{}' at 0x{:X}", port, handle);
state.ctx->gpr.w1 = handle; state.ctx->gpr.w1 = handle;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
@ -809,7 +809,7 @@ namespace skyline::kernel::svc {
KHandle handle{state.ctx->gpr.w1}; KHandle handle{state.ctx->gpr.w1};
size_t tid{state.process->GetHandle<type::KThread>(handle)->id}; size_t tid{state.process->GetHandle<type::KThread>(handle)->id};
state.logger->Debug("svcGetThreadId: Handle: 0x{:X}, TID: {}", handle, tid); state.logger->Debug("Handle: 0x{:X}, TID: {}", handle, tid);
state.ctx->gpr.x1 = tid; state.ctx->gpr.x1 = tid;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
@ -818,9 +818,9 @@ namespace skyline::kernel::svc {
void Break(const DeviceState &state) { void Break(const DeviceState &state) {
auto reason{state.ctx->gpr.x0}; auto reason{state.ctx->gpr.x0};
if (reason & (1ULL << 31)) { if (reason & (1ULL << 31)) {
state.logger->Debug("svcBreak: Debugger is being engaged ({})", reason); state.logger->Debug("Debugger is being engaged ({})", reason);
} else { } else {
state.logger->Error("svcBreak: Exit Stack Trace ({}){}", reason, state.loader->GetStackTrace()); state.logger->Error("Exit Stack Trace ({}){}", reason, state.loader->GetStackTrace());
if (state.thread->id) if (state.thread->id)
state.process->Kill(false); state.process->Kill(false);
std::longjmp(state.thread->originalCtx, true); std::longjmp(state.thread->originalCtx, true);
@ -828,12 +828,12 @@ namespace skyline::kernel::svc {
} }
void OutputDebugString(const DeviceState &state) { void OutputDebugString(const DeviceState &state) {
auto string{span(reinterpret_cast<u8 *>(state.ctx->gpr.x0), state.ctx->gpr.x1).as_string()}; auto string{span(reinterpret_cast<char *>(state.ctx->gpr.x0), state.ctx->gpr.x1).as_string()};
if (string.back() == '\n') if (string.back() == '\n')
string.remove_suffix(1); string.remove_suffix(1);
state.logger->Info("svcOutputDebugString: {}", string); state.logger->Info("{}", string);
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
} }
@ -960,12 +960,12 @@ namespace skyline::kernel::svc {
break; break;
default: default:
state.logger->Warn("svcGetInfo: Unimplemented case ID0: {}, ID1: {}", static_cast<u32>(info), id1); state.logger->Warn("Unimplemented case ID0: {}, ID1: {}", static_cast<u32>(info), id1);
state.ctx->gpr.w0 = result::InvalidEnumValue; state.ctx->gpr.w0 = result::InvalidEnumValue;
return; return;
} }
state.logger->Debug("svcGetInfo: ID0: {}, ID1: {}, Out: 0x{:X}", static_cast<u32>(info), id1, out); state.logger->Debug("ID0: {}, ID1: {}, Out: 0x{:X}", static_cast<u32>(info), id1, out);
state.ctx->gpr.x1 = out; state.ctx->gpr.x1 = out;
state.ctx->gpr.w0 = Result{}; state.ctx->gpr.w0 = Result{};
@ -1047,7 +1047,7 @@ namespace skyline::kernel::svc {
void WaitForAddress(const DeviceState &state) { void WaitForAddress(const DeviceState &state) {
auto address{reinterpret_cast<u32 *>(state.ctx->gpr.x0)}; auto address{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
if (!util::WordAligned(address)) [[unlikely]] { if (!util::WordAligned(address)) [[unlikely]] {
state.logger->Warn("svcWaitForAddress: 'address' not word aligned: 0x{:X}", address); state.logger->Warn("'address' not word aligned: 0x{:X}", address);
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
return; return;
} }
@ -1063,14 +1063,14 @@ namespace skyline::kernel::svc {
Result result; Result result;
switch (arbitrationType) { switch (arbitrationType) {
case ArbitrationType::WaitIfLessThan: case ArbitrationType::WaitIfLessThan:
state.logger->Debug("svcWaitForAddress: Waiting on 0x{:X} if less than {} for {}ns", address, value, timeout); state.logger->Debug("Waiting on 0x{:X} if less than {} for {}ns", address, value, timeout);
result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) { result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) {
return *address < value; return *address < value;
}); });
break; break;
case ArbitrationType::DecrementAndWaitIfLessThan: case ArbitrationType::DecrementAndWaitIfLessThan:
state.logger->Debug("svcWaitForAddress: Waiting on and decrementing 0x{:X} if less than {} for {}ns", address, value, timeout); state.logger->Debug("Waiting on and decrementing 0x{:X} if less than {} for {}ns", address, value, timeout);
result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) { result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) {
u32 userValue{__atomic_load_n(address, __ATOMIC_SEQ_CST)}; u32 userValue{__atomic_load_n(address, __ATOMIC_SEQ_CST)};
do { do {
@ -1082,7 +1082,7 @@ namespace skyline::kernel::svc {
break; break;
case ArbitrationType::WaitIfEqual: case ArbitrationType::WaitIfEqual:
state.logger->Debug("svcWaitForAddress: Waiting on 0x{:X} if equal to {} for {}ns", address, value, timeout); state.logger->Debug("Waiting on 0x{:X} if equal to {} for {}ns", address, value, timeout);
result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) { result = state.process->WaitForAddress(address, value, timeout, [](u32 *address, u32 value) {
return *address == value; return *address == value;
}); });
@ -1090,18 +1090,18 @@ namespace skyline::kernel::svc {
default: default:
[[unlikely]] [[unlikely]]
state.logger->Error("svcWaitForAddress: 'arbitrationType' invalid: {}", arbitrationType); state.logger->Error("'arbitrationType' invalid: {}", arbitrationType);
state.ctx->gpr.w0 = result::InvalidEnumValue; state.ctx->gpr.w0 = result::InvalidEnumValue;
return; return;
} }
if (result == Result{}) if (result == Result{})
[[likely]] [[likely]]
state.logger->Debug("svcWaitForAddress: Waited on 0x{:X} successfully", address); state.logger->Debug("Waited on 0x{:X} successfully", address);
else if (result == result::TimedOut) else if (result == result::TimedOut)
state.logger->Debug("svcWaitForAddress: Wait on 0x{:X} has timed out after {}ns", address, timeout); state.logger->Debug("Wait on 0x{:X} has timed out after {}ns", address, timeout);
else if (result == result::InvalidState) else if (result == result::InvalidState)
state.logger->Debug("svcWaitForAddress: The value at 0x{:X} did not satisfy the arbitration condition", address); state.logger->Debug("The value at 0x{:X} did not satisfy the arbitration condition", address);
state.ctx->gpr.w0 = result; state.ctx->gpr.w0 = result;
} }
@ -1109,7 +1109,7 @@ namespace skyline::kernel::svc {
void SignalToAddress(const DeviceState &state) { void SignalToAddress(const DeviceState &state) {
auto address{reinterpret_cast<u32 *>(state.ctx->gpr.x0)}; auto address{reinterpret_cast<u32 *>(state.ctx->gpr.x0)};
if (!util::WordAligned(address)) [[unlikely]] { if (!util::WordAligned(address)) [[unlikely]] {
state.logger->Warn("svcWaitForAddress: 'address' not word aligned: 0x{:X}", address); state.logger->Warn("'address' not word aligned: 0x{:X}", address);
state.ctx->gpr.w0 = result::InvalidAddress; state.ctx->gpr.w0 = result::InvalidAddress;
return; return;
} }
@ -1125,19 +1125,19 @@ namespace skyline::kernel::svc {
Result result; Result result;
switch (signalType) { switch (signalType) {
case SignalType::Signal: case SignalType::Signal:
state.logger->Debug("svcSignalToAddress: Signalling 0x{:X} for {} waiters", address, count); state.logger->Debug("Signalling 0x{:X} for {} waiters", address, count);
result = state.process->SignalToAddress(address, value, count); result = state.process->SignalToAddress(address, value, count);
break; break;
case SignalType::SignalAndIncrementIfEqual: case SignalType::SignalAndIncrementIfEqual:
state.logger->Debug("svcSignalToAddress: Signalling 0x{:X} and incrementing if equal to {} for {} waiters", address, value, count); state.logger->Debug("Signalling 0x{:X} and incrementing if equal to {} for {} waiters", address, value, count);
result = state.process->SignalToAddress(address, value, count, [](u32 *address, u32 value, u32) { result = state.process->SignalToAddress(address, value, count, [](u32 *address, u32 value, u32) {
return __atomic_compare_exchange_n(address, &value, value + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); return __atomic_compare_exchange_n(address, &value, value + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}); });
break; break;
case SignalType::SignalAndModifyBasedOnWaitingThreadCountIfEqual: case SignalType::SignalAndModifyBasedOnWaitingThreadCountIfEqual:
state.logger->Debug("svcSignalToAddress: Signalling 0x{:X} and setting to waiting thread count if equal to {} for {} waiters", address, value, count); state.logger->Debug("Signalling 0x{:X} and setting to waiting thread count if equal to {} for {} waiters", address, value, count);
result = state.process->SignalToAddress(address, value, count, [](u32 *address, u32 value, u32 waiterCount) { result = state.process->SignalToAddress(address, value, count, [](u32 *address, u32 value, u32 waiterCount) {
return __atomic_compare_exchange_n(address, &value, waiterCount, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); return __atomic_compare_exchange_n(address, &value, waiterCount, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
}); });
@ -1145,16 +1145,16 @@ namespace skyline::kernel::svc {
default: default:
[[unlikely]] [[unlikely]]
state.logger->Error("svcSignalToAddress: 'signalType' invalid: {}", signalType); state.logger->Error("'signalType' invalid: {}", signalType);
state.ctx->gpr.w0 = result::InvalidEnumValue; state.ctx->gpr.w0 = result::InvalidEnumValue;
return; return;
} }
if (result == Result{}) if (result == Result{})
[[likely]] [[likely]]
state.logger->Debug("svcSignalToAddress: Signalled 0x{:X} for {} successfully", address, count); state.logger->Debug("Signalled 0x{:X} for {} successfully", address, count);
else if (result == result::InvalidState) else if (result == result::InvalidState)
state.logger->Debug("svcSignalToAddress: The value at 0x{:X} did not satisfy the mutation condition", address); state.logger->Debug("The value at 0x{:X} did not satisfy the mutation condition", address);
state.ctx->gpr.w0 = result; state.ctx->gpr.w0 = result;
} }

View File

@ -11,7 +11,7 @@ namespace skyline::service::audio {
Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()}; IAudioRenderer::AudioRendererParameters params{request.Pop<IAudioRenderer::AudioRendererParameters>()};
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount); state.logger->Debug("Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response); manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response);

View File

@ -22,7 +22,7 @@ namespace skyline::service {
std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> function; std::pair<std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>, std::string_view> function;
try { try {
function = GetServiceFunction(request.payload->value); function = GetServiceFunction(request.payload->value);
state.logger->Debug("Service: {} @ {}", function.second, GetName()); state.logger->DebugNoPrefix("Service: {} @ {}", function.second, GetName());
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value)); state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value));
return {}; return {};

View File

@ -22,7 +22,7 @@ namespace skyline::service::hosbinder {
out.Push<u32>(0); out.Push<u32>(0);
out.Push(queue.at(slot)->gbpBuffer); out.Push(queue.at(slot)->gbpBuffer);
state.logger->Debug("RequestBuffer: Slot: {}", slot, sizeof(GbpBuffer)); state.logger->Debug("Slot: {}", slot, sizeof(GbpBuffer));
} }
void GraphicBufferProducer::DequeueBuffer(Parcel &in, Parcel &out) { void GraphicBufferProducer::DequeueBuffer(Parcel &in, Parcel &out) {
@ -46,7 +46,7 @@ namespace skyline::service::hosbinder {
out.Push(*slot); out.Push(*slot);
out.Push(std::array<u32, 13>{1, 0x24}); // Unknown out.Push(std::array<u32, 13>{1, 0x24}); // Unknown
state.logger->Debug("DequeueBuffer: Width: {}, Height: {}, Format: {}, Usage: {}, Slot: {}", width, height, format, usage, *slot); state.logger->Debug("Width: {}, Height: {}, Format: {}, Usage: {}, Slot: {}", width, height, format, usage, *slot);
} }
void GraphicBufferProducer::QueueBuffer(Parcel &in, Parcel &out) { void GraphicBufferProducer::QueueBuffer(Parcel &in, Parcel &out) {
@ -81,7 +81,7 @@ namespace skyline::service::hosbinder {
}; };
out.Push(output); out.Push(output);
state.logger->Debug("QueueBuffer: Timestamp: {}, Auto Timestamp: {}, Crop: [T: {}, B: {}, L: {}, R: {}], Scaling Mode: {}, Transform: {}, Sticky Transform: {}, Swap Interval: {}, Slot: {}", data.timestamp, data.autoTimestamp, data.crop.top, data.crop.bottom, data.crop.left, data.crop.right, data.scalingMode, data.transform, data.stickyTransform, data.swapInterval, data.slot); state.logger->Debug("Timestamp: {}, Auto Timestamp: {}, Crop: [T: {}, B: {}, L: {}, R: {}], Scaling Mode: {}, Transform: {}, Sticky Transform: {}, Swap Interval: {}, Slot: {}", data.timestamp, data.autoTimestamp, data.crop.top, data.crop.bottom, data.crop.left, data.crop.right, data.scalingMode, data.transform, data.stickyTransform, data.swapInterval, data.slot);
} }
void GraphicBufferProducer::CancelBuffer(Parcel &in) { void GraphicBufferProducer::CancelBuffer(Parcel &in) {
@ -90,7 +90,7 @@ namespace skyline::service::hosbinder {
queue.at(slot)->status = BufferStatus::Free; queue.at(slot)->status = BufferStatus::Free;
state.logger->Debug("CancelBuffer: Slot: {}", slot); state.logger->Debug("Slot: {}", slot);
} }
void GraphicBufferProducer::Connect(Parcel &out) { void GraphicBufferProducer::Connect(Parcel &out) {
@ -152,7 +152,7 @@ namespace skyline::service::hosbinder {
queue[data.slot] = std::make_shared<Buffer>(gbpBuffer, texture->InitializeTexture()); queue[data.slot] = std::make_shared<Buffer>(gbpBuffer, texture->InitializeTexture());
state.gpu->presentation.bufferEvent->Signal(); state.gpu->presentation.bufferEvent->Signal();
state.logger->Debug("SetPreallocatedBuffer: Slot: {}, Magic: 0x{:X}, Width: {}, Height: {}, Stride: {}, Format: {}, Usage: {}, Index: {}, ID: {}, Handle: {}, Offset: 0x{:X}, Block Height: {}, Size: 0x{:X}", data.slot, gbpBuffer.magic, gbpBuffer.width, gbpBuffer.height, gbpBuffer.stride, gbpBuffer.format, gbpBuffer.usage, gbpBuffer.index, gbpBuffer.nvmapId, gbpBuffer.nvmapHandle, gbpBuffer.offset, (1U << gbpBuffer.blockHeightLog2), gbpBuffer.size); state.logger->Debug("Slot: {}, Magic: 0x{:X}, Width: {}, Height: {}, Stride: {}, Format: {}, Usage: {}, Index: {}, ID: {}, Handle: {}, Offset: 0x{:X}, Block Height: {}, Size: 0x{:X}", data.slot, gbpBuffer.magic, gbpBuffer.width, gbpBuffer.height, gbpBuffer.stride, gbpBuffer.format, gbpBuffer.usage, gbpBuffer.index, gbpBuffer.nvmapId, gbpBuffer.nvmapHandle, gbpBuffer.offset, (1U << gbpBuffer.blockHeightLog2), gbpBuffer.size);
} }
void GraphicBufferProducer::OnTransact(TransactionCode code, Parcel &in, Parcel &out) { void GraphicBufferProducer::OnTransact(TransactionCode code, Parcel &in, Parcel &out) {

View File

@ -23,7 +23,7 @@ namespace skyline::service::hosbinder {
// If this was not done then we would need to maintain an array of GraphicBufferProducer objects for each layer and send the request for it specifically // If this was not done then we would need to maintain an array of GraphicBufferProducer objects for each layer and send the request for it specifically
// There would also need to be an external compositor which composites all the graphics buffers submitted to every GraphicBufferProducer // There would also need to be an external compositor which composites all the graphics buffers submitted to every GraphicBufferProducer
state.logger->Debug("TransactParcel: Layer ID: {}, Code: {}", layerId, code); state.logger->Debug("Layer ID: {}, Code: {}", layerId, code);
producer->OnTransact(code, in, out); producer->OnTransact(code, in, out);
out.WriteParcel(request.outputBuf.at(0)); out.WriteParcel(request.outputBuf.at(0));

View File

@ -76,7 +76,7 @@ namespace skyline::service::nvdrv {
if (event != nullptr) { if (event != nullptr) {
auto handle{state.process->InsertItem<type::KEvent>(event)}; auto handle{state.process->InsertItem<type::KEvent>(event)};
state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: 0x{:X}", fd, eventId, handle); state.logger->Debug("FD: {}, Event ID: {}, Handle: 0x{:X}", fd, eventId, handle);
response.copyHandles.push_back(handle); response.copyHandles.push_back(handle);
response.Push(device::NvStatus::Success); response.Push(device::NvStatus::Success);

View File

@ -33,7 +33,7 @@ namespace skyline::service::nvdrv::device {
std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> function; std::pair<std::function<NvStatus(IoctlType, span<u8>, span<u8>)>, std::string_view> function;
try { try {
function = GetIoctlFunction(cmd); function = GetIoctlFunction(cmd);
state.logger->Debug("{}: {} @ {}", typeString, GetName(), function.second); state.logger->DebugNoPrefix("{}: {} @ {}", typeString, GetName(), function.second);
} catch (std::out_of_range &) { } catch (std::out_of_range &) {
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd); state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
return NvStatus::NotImplemented; return NvStatus::NotImplemented;