diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 3b1612bad..5f4521122 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -34,6 +34,7 @@ #include "core/hle/lock.h" #include "core/hle/result.h" #include "core/hle/service/service.h" +#include "core/settings.h" namespace Kernel { namespace { @@ -437,16 +438,42 @@ struct BreakReason { /// Break program execution static void Break(u32 reason, u64 info1, u64 info2) { BreakReason break_reason{reason}; + bool has_dumped_buffer{}; + const auto handle_debug_buffer = [&](VAddr addr, u64 sz) { + if (sz == 0 || addr == 0 || has_dumped_buffer) { + return; + } + + // This typically is an error code so we're going to assume this is the case + if (sz == sizeof(u32)) { + LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); + } else { + // We don't know what's in here so we'll hexdump it + std::vector<u8> debug_buffer(sz); + Memory::ReadBlock(addr, debug_buffer.data(), sz); + std::string hexdump; + for (std::size_t i = 0; i < debug_buffer.size(); i++) { + hexdump += fmt::format("{:02X} ", debug_buffer[i]); + if (i != 0 && i % 16 == 0) { + hexdump += '\n'; + } + } + LOG_CRITICAL(Debug_Emulated, "debug_buffer=\n{}", hexdump); + } + has_dumped_buffer = true; + }; switch (break_reason.break_type) { case BreakType::Panic: LOG_CRITICAL(Debug_Emulated, "Signalling debugger, PANIC! info1=0x{:016X}, info2=0x{:016X}", info1, info2); + handle_debug_buffer(info1, info2); break; case BreakType::AssertionFailed: LOG_CRITICAL(Debug_Emulated, "Signalling debugger, Assertion failed! info1=0x{:016X}, info2=0x{:016X}", info1, info2); + handle_debug_buffer(info1, info2); break; case BreakType::PreNROLoad: LOG_WARNING( @@ -475,6 +502,7 @@ static void Break(u32 reason, u64 info1, u64 info2) { Debug_Emulated, "Signalling debugger, Unknown break reason {}, info1=0x{:016X}, info2=0x{:016X}", static_cast<u32>(break_reason.break_type.Value()), info1, info2); + handle_debug_buffer(info1, info2); break; } @@ -483,6 +511,7 @@ static void Break(u32 reason, u64 info1, u64 info2) { Debug_Emulated, "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", reason, info1, info2); + handle_debug_buffer(info1, info2); ASSERT(false); Core::CurrentProcess()->PrepareForTermination(); @@ -572,7 +601,16 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = 0; break; case GetInfoType::RandomEntropy: - *result = 0; + if (handle != 0) { + return ERR_INVALID_HANDLE; + } + + if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { + return ERR_INVALID_COMBINATION_KERNEL; + } + + *result = current_process->GetRandomEntropy(info_sub_id); + return RESULT_SUCCESS; break; case GetInfoType::ASLRRegionBaseAddr: *result = vm_manager.GetASLRRegionBaseAddress(); |