diff --git a/app/src/main/cpp/skyline/common.cpp b/app/src/main/cpp/skyline/common.cpp index 3ff04704..caefd1e9 100644 --- a/app/src/main/cpp/skyline/common.cpp +++ b/app/src/main/cpp/skyline/common.cpp @@ -151,7 +151,7 @@ namespace skyline { character = '\\'; std::lock_guard guard(mtx); - logFile << "1|" << levelCharacter[static_cast(level)] << "|" << str << "\n"; + logFile << "1|" << levelCharacter[static_cast(level)] << '|' << std::dec << pthread_self() << '|' << str << '\n'; } DeviceState::DeviceState(kernel::OS *os, std::shared_ptr &process, std::shared_ptr jvmManager, std::shared_ptr settings, std::shared_ptr logger) diff --git a/app/src/main/cpp/skyline/kernel/svc.cpp b/app/src/main/cpp/skyline/kernel/svc.cpp index 80d9a83a..155ac8dd 100644 --- a/app/src/main/cpp/skyline/kernel/svc.cpp +++ b/app/src/main/cpp/skyline/kernel/svc.cpp @@ -261,7 +261,7 @@ namespace skyline::kernel::svc { state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->id); thread->Start(); state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcStartThread: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -301,7 +301,7 @@ namespace skyline::kernel::svc { state.ctx->gpr.w1 = priority; state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcGetThreadPriority: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -320,7 +320,7 @@ namespace skyline::kernel::svc { state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", thread->id, priority); thread->UpdatePriority(static_cast(priority)); state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcSetThreadPriority: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -337,7 +337,7 @@ namespace skyline::kernel::svc { state.ctx->gpr.x2 = affinityMask.to_ullong(); state.ctx->gpr.w1 = idealCore; state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcGetThreadCoreMask: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -371,7 +371,7 @@ namespace skyline::kernel::svc { thread->affinityMask = affinityMask; state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcSetThreadCoreMask: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -418,7 +418,7 @@ namespace skyline::kernel::svc { object->Map(pointer, size, permission); state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcMapSharedMemory: 'handle' invalid: 0x{:X}", static_cast(state.ctx->gpr.w0)); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -459,7 +459,7 @@ namespace skyline::kernel::svc { state.process->CloseHandle(handle); state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", handle); state.ctx->gpr.w0 = Result{}; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -560,7 +560,7 @@ namespace skyline::kernel::svc { void CancelSynchronization(const DeviceState &state) { try { state.process->GetHandle(state.ctx->gpr.w0)->cancelSync = true; - } catch (const std::exception &) { + } catch (const std::out_of_range &) { state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", static_cast(state.ctx->gpr.w0)); state.ctx->gpr.w0 = result::InvalidHandle; } @@ -708,34 +708,34 @@ namespace skyline::kernel::svc { void GetInfo(const DeviceState &state) { enum class InfoState : u32 { // 1.0.0+ - AllowedCpuIdBitmask = 0x0, - AllowedThreadPriorityMask = 0x1, - AliasRegionBaseAddr = 0x2, - AliasRegionSize = 0x3, - HeapRegionBaseAddr = 0x4, - HeapRegionSize = 0x5, - TotalMemoryAvailable = 0x6, - TotalMemoryUsage = 0x7, - IsCurrentProcessBeingDebugged = 0x8, - ResourceLimit = 0x9, - IdleTickCount = 0xA, - RandomEntropy = 0xB, + AllowedCpuIdBitmask = 0, + AllowedThreadPriorityMask = 1, + AliasRegionBaseAddr = 2, + AliasRegionSize = 3, + HeapRegionBaseAddr = 4, + HeapRegionSize = 5, + TotalMemoryAvailable = 6, + TotalMemoryUsage = 7, + IsCurrentProcessBeingDebugged = 8, + ResourceLimit = 9, + IdleTickCount = 10, + RandomEntropy = 11, // 2.0.0+ - AddressSpaceBaseAddr = 0xC, - AddressSpaceSize = 0xD, - StackRegionBaseAddr = 0xE, - StackRegionSize = 0xF, + AddressSpaceBaseAddr = 12, + AddressSpaceSize = 13, + StackRegionBaseAddr = 14, + StackRegionSize = 15, // 3.0.0+ - TotalSystemResourceAvailable = 0x10, - TotalSystemResourceUsage = 0x11, - TitleId = 0x12, + TotalSystemResourceAvailable = 16, + TotalSystemResourceUsage = 17, + TitleId = 18, // 4.0.0+ - PrivilegedProcessId = 0x13, + PrivilegedProcessId = 19, // 5.0.0+ - UserExceptionContextAddr = 0x14, + UserExceptionContextAddr = 20, // 6.0.0+ - TotalMemoryAvailableWithoutSystemResource = 0x15, - TotalMemoryUsageWithoutSystemResource = 0x16, + TotalMemoryAvailableWithoutSystemResource = 21, + TotalMemoryUsageWithoutSystemResource = 22, }; InfoState info{static_cast(state.ctx->gpr.w1)}; diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.h b/app/src/main/cpp/skyline/kernel/types/KProcess.h index e099590c..369e40a6 100644 --- a/app/src/main/cpp/skyline/kernel/types/KProcess.h +++ b/app/src/main/cpp/skyline/kernel/types/KProcess.h @@ -163,7 +163,7 @@ namespace skyline { else throw exception("Tried to get kernel object (0x{:X}) with different type: {} when object is {}", handle, objectType, item->objectType); } catch (std::out_of_range) { - throw exception("GetHandle was called with an invalid handle: 0x{:X}", handle); + throw std::out_of_range(fmt::format("GetHandle was called with an invalid handle: 0x{:X}", handle)); } } diff --git a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h index 6327b620..556b85c4 100644 --- a/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h +++ b/app/src/main/cpp/skyline/kernel/types/KSharedMemory.h @@ -22,7 +22,7 @@ namespace skyline::kernel::type { constexpr bool Valid() { return ptr && size; } - } kernel, guest; + } kernel, guest{}; KSharedMemory(const DeviceState &state, size_t size, memory::MemoryState memState = memory::states::SharedMemory, KType type = KType::KSharedMemory); diff --git a/app/src/main/cpp/skyline/loader/loader.cpp b/app/src/main/cpp/skyline/loader/loader.cpp index c7492b71..b1b34233 100644 --- a/app/src/main/cpp/skyline/loader/loader.cpp +++ b/app/src/main/cpp/skyline/loader/loader.cpp @@ -29,7 +29,7 @@ namespace skyline::loader { process->NewHandle(base + patch.size + executable.text.offset, textSize, memory::Permission{true, false, true}, memory::states::CodeStatic); // R-X state.logger->Debug("Successfully mapped section .text @ 0x{:X}, Size = 0x{:X}", base + patch.size + executable.text.offset, textSize); - process->NewHandle(base + patch.size + executable.ro.offset, roSize, memory::Permission{true, false, false}, memory::states::CodeReadOnly); // R-- + process->NewHandle(base + patch.size + executable.ro.offset, roSize, memory::Permission{true, false, false}, memory::states::CodeStatic); // R-- state.logger->Debug("Successfully mapped section .rodata @ 0x{:X}, Size = 0x{:X}", base + patch.size + executable.ro.offset, roSize); process->NewHandle(base + patch.size + executable.data.offset, dataSize, memory::Permission{true, true, false}, memory::states::CodeMutable); // RW- diff --git a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp index cbf69f3d..7b95e5bb 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/voice.cpp @@ -43,7 +43,7 @@ namespace skyline::service::audio::IAudioRenderer { if (input.format == skyline::audio::AudioFormat::ADPCM) { std::vector> adpcmCoefficients(input.adpcmCoeffsSize / (sizeof(u16) * 2)); - span(adpcmCoefficients).copy_from(span(input.adpcmCoeffs, input.adpcmCoeffsSize)); + span(adpcmCoefficients).copy_from(span(input.adpcmCoeffs, input.adpcmCoeffsSize / sizeof(u32))); adpcmDecoder = skyline::audio::AdpcmDecoder(adpcmCoefficients); } diff --git a/app/src/main/cpp/skyline/services/lm/ILogger.cpp b/app/src/main/cpp/skyline/services/lm/ILogger.cpp index b8539145..88ab58fd 100644 --- a/app/src/main/cpp/skyline/services/lm/ILogger.cpp +++ b/app/src/main/cpp/skyline/services/lm/ILogger.cpp @@ -6,31 +6,6 @@ namespace skyline::service::lm { ILogger::ILogger(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager) {} - std::string ILogger::GetFieldName(LogFieldType type) { - switch (type) { - case LogFieldType::Message: - return "Message"; - case LogFieldType::Line: - return "Line"; - case LogFieldType::Filename: - return "Filename"; - case LogFieldType::Function: - return "Function"; - case LogFieldType::Module: - return "Module"; - case LogFieldType::Thread: - return "Thread"; - case LogFieldType::DropCount: - return "DropCount"; - case LogFieldType::Time: - return "Time"; - case LogFieldType::ProgramName: - return "ProgramName"; - default: - return ""; - } - } - Result ILogger::Log(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { struct Data { u64 pid; @@ -41,8 +16,17 @@ namespace skyline::service::lm { u32 payloadLength; } &data = request.inputBuf.at(0).as(); - std::ostringstream logMessage; - logMessage << "Guest log:"; + struct LogMessage { + std::string_view message; + u32 line; + std::string_view filename; + std::string_view function; + std::string_view module; + std::string_view thread; + u64 dropCount; + u64 time; + std::string_view program; + } logMessage{}; u64 offset{sizeof(Data)}; while (offset < request.inputBuf[0].size()) { @@ -50,50 +34,90 @@ namespace skyline::service::lm { auto length{request.inputBuf[0].subspan(offset++).as()}; auto object{request.inputBuf[0].subspan(offset, length)}; - logMessage << " "; - switch (fieldType) { case LogFieldType::Start: offset += length; continue; + case LogFieldType::Stop: + break; + case LogFieldType::Message: + logMessage.message = object.as_string(); + offset += length; + continue; case LogFieldType::Line: - logMessage << GetFieldName(fieldType) << ": " << object.as(); + logMessage.line = object.as(); offset += sizeof(u32); continue; + case LogFieldType::Filename: { + logMessage.filename = object.as_string(); + auto position{logMessage.filename.find_last_of('/')}; + logMessage.filename.remove_prefix(position != std::string::npos ? position + 1 : 0); + offset += length; + continue; + } + case LogFieldType::Function: + logMessage.function = object.as_string(); + offset += length; + continue; + case LogFieldType::Module: + logMessage.module = object.as_string(); + offset += length; + continue; + case LogFieldType::Thread: + logMessage.thread = object.as_string(); + offset += length; + continue; case LogFieldType::DropCount: - logMessage << GetFieldName(fieldType) << ": " << object.as(); + logMessage.dropCount = object.as(); offset += sizeof(u64); continue; case LogFieldType::Time: - logMessage << GetFieldName(fieldType) << ": " << object.as() << "s"; + logMessage.time = object.as(); offset += sizeof(u64); continue; - case LogFieldType::Stop: - break; - default: - logMessage << GetFieldName(fieldType) << ": " << object.as_string(); + case LogFieldType::ProgramName: + logMessage.program = object.as_string(); offset += length; continue; } - break; } - switch (data.level) { - case LogLevel::Trace: - state.logger->Debug("{}", logMessage.str()); - break; - case LogLevel::Info: - state.logger->Info("{}", logMessage.str()); - break; - case LogLevel::Warning: - state.logger->Warn("{}", logMessage.str()); - break; - case LogLevel::Error: - case LogLevel::Critical: - state.logger->Error("{}", logMessage.str()); - break; - } + Logger::LogLevel hostLevel{[&data]() { + switch (data.level) { + case LogLevel::Trace: + return Logger::LogLevel::Debug; + case LogLevel::Info: + return Logger::LogLevel::Info; + case LogLevel::Warning: + return Logger::LogLevel::Warn; + case LogLevel::Error: + case LogLevel::Critical: + return Logger::LogLevel::Error; + } + }()}; + + std::ostringstream message; + if (!logMessage.filename.empty()) + message << logMessage.filename << ':'; + if (logMessage.line) + message << 'L' << std::dec << logMessage.line << ':'; + if (!logMessage.program.empty()) + message << logMessage.program << ':'; + if (!logMessage.module.empty()) + message << logMessage.module << ':'; + if (!logMessage.function.empty()) + message << logMessage.function << "():"; + if (!logMessage.thread.empty()) + message << logMessage.thread << ':'; + if (logMessage.time) + message << logMessage.time << "s:"; + if (!logMessage.message.empty()) + message << ' ' << logMessage.message; + if (logMessage.dropCount) + message << " (Dropped Messages: " << logMessage.time << ')'; + + state.logger->Write(hostLevel, message.str()); return {}; } diff --git a/app/src/main/cpp/skyline/services/lm/ILogger.h b/app/src/main/cpp/skyline/services/lm/ILogger.h index 77d590a3..40372cfb 100644 --- a/app/src/main/cpp/skyline/services/lm/ILogger.h +++ b/app/src/main/cpp/skyline/services/lm/ILogger.h @@ -34,13 +34,6 @@ namespace skyline::service::lm { Critical, }; - /** - * @brief Obtains a string containing the name of the given field type - * @param type The field type to return the name of - * @return The name of the given field type - */ - std::string GetFieldName(LogFieldType type); - public: ILogger(const DeviceState &state, ServiceManager &manager); diff --git a/app/src/main/cpp/skyline/services/serviceman.cpp b/app/src/main/cpp/skyline/services/serviceman.cpp index 70a8e415..8fca286d 100644 --- a/app/src/main/cpp/skyline/services/serviceman.cpp +++ b/app/src/main/cpp/skyline/services/serviceman.cpp @@ -80,7 +80,8 @@ namespace skyline::service { SERVICE_CASE(ssl::ISslService, "ssl") SERVICE_CASE(prepo::IPrepoService, "prepo:u") default: - throw exception("CreateService called with an unknown service name: {}", name); + std::string_view nameString(span(reinterpret_cast(&name), sizeof(name)).as_string(true)); + throw std::out_of_range(fmt::format("CreateService called with an unknown service name: {}", nameString)); } } diff --git a/app/src/main/cpp/skyline/services/sm/IUserInterface.cpp b/app/src/main/cpp/skyline/services/sm/IUserInterface.cpp index 1183668c..8c9fb66f 100644 --- a/app/src/main/cpp/skyline/services/sm/IUserInterface.cpp +++ b/app/src/main/cpp/skyline/services/sm/IUserInterface.cpp @@ -18,11 +18,11 @@ namespace skyline::service::sm { try { manager.NewService(name, session, response); + return {}; } catch (std::out_of_range &) { std::string_view stringName(reinterpret_cast(&name), sizeof(u64)); state.logger->Warn("Service has not been implemented: \"{}\"", stringName); + return result::InvalidServiceName; } - - return {}; } } diff --git a/app/src/main/java/emu/skyline/LogActivity.kt b/app/src/main/java/emu/skyline/LogActivity.kt index 3cdda6f8..64919ecb 100644 --- a/app/src/main/java/emu/skyline/LogActivity.kt +++ b/app/src/main/java/emu/skyline/LogActivity.kt @@ -74,7 +74,7 @@ class LogActivity : AppCompatActivity() { val level = logMeta[1].toInt() if (level > logLevel) return@forEachLine - adapter.addItem(LogViewItem(compact, logMeta[2].replace('\\', '\n'), logLevels[level])) + adapter.addItem(LogViewItem(compact, "(" + logMeta[2] + ") " + logMeta[3].replace('\\', '\n'), logLevels[level])) } else { adapter.addItem(HeaderViewItem(logMeta[1])) }