|
|
@@ -267,7 +267,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
|
|
|
|
|
|
// Reserve a new session from the process resource limit.
|
|
|
// FIXME: LimitableResource_SessionCountMax
|
|
|
- KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions);
|
|
|
+ KScopedResourceReservation session_reservation(&process, LimitableResource::SessionCountMax);
|
|
|
if (session_reservation.Succeeded()) {
|
|
|
session = T::Create(system.Kernel());
|
|
|
} else {
|
|
|
@@ -298,7 +298,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
|
|
|
|
|
|
// We successfully allocated a session, so add the object we allocated to the resource
|
|
|
// limit.
|
|
|
- // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1);
|
|
|
+ // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::SessionCountMax, 1);
|
|
|
}
|
|
|
|
|
|
// Check that we successfully created a session.
|
|
|
@@ -656,27 +656,12 @@ static Result ArbitrateUnlock32(Core::System& system, u32 address) {
|
|
|
return ArbitrateUnlock(system, address);
|
|
|
}
|
|
|
|
|
|
-enum class BreakType : u32 {
|
|
|
- Panic = 0,
|
|
|
- AssertionFailed = 1,
|
|
|
- PreNROLoad = 3,
|
|
|
- PostNROLoad = 4,
|
|
|
- PreNROUnload = 5,
|
|
|
- PostNROUnload = 6,
|
|
|
- CppException = 7,
|
|
|
-};
|
|
|
-
|
|
|
-struct BreakReason {
|
|
|
- union {
|
|
|
- u32 raw;
|
|
|
- BitField<0, 30, BreakType> break_type;
|
|
|
- BitField<31, 1, u32> signal_debugger;
|
|
|
- };
|
|
|
-};
|
|
|
-
|
|
|
/// Break program execution
|
|
|
static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
|
|
|
- BreakReason break_reason{reason};
|
|
|
+ BreakReason break_reason =
|
|
|
+ static_cast<BreakReason>(reason & ~static_cast<u32>(BreakReason::NotificationOnlyFlag));
|
|
|
+ bool notification_only = (reason & static_cast<u32>(BreakReason::NotificationOnlyFlag)) != 0;
|
|
|
+
|
|
|
bool has_dumped_buffer{};
|
|
|
std::vector<u8> debug_buffer;
|
|
|
|
|
|
@@ -705,57 +690,56 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
|
|
|
}
|
|
|
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);
|
|
|
+ switch (break_reason) {
|
|
|
+ case BreakReason::Panic:
|
|
|
+ LOG_CRITICAL(Debug_Emulated, "Userspace 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}",
|
|
|
+ case BreakReason::Assert:
|
|
|
+ LOG_CRITICAL(Debug_Emulated, "Userspace Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
|
|
|
info1, info2);
|
|
|
handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
- case BreakType::PreNROLoad:
|
|
|
- LOG_WARNING(
|
|
|
- Debug_Emulated,
|
|
|
- "Signalling debugger, Attempting to load an NRO at 0x{:016X} with size 0x{:016X}",
|
|
|
- info1, info2);
|
|
|
+ case BreakReason::User:
|
|
|
+ LOG_WARNING(Debug_Emulated, "Userspace Break! 0x{:016X} with size 0x{:016X}", info1, info2);
|
|
|
+ handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
- case BreakType::PostNROLoad:
|
|
|
- LOG_WARNING(Debug_Emulated,
|
|
|
- "Signalling debugger, Loaded an NRO at 0x{:016X} with size 0x{:016X}", info1,
|
|
|
- info2);
|
|
|
+ case BreakReason::PreLoadDll:
|
|
|
+ LOG_INFO(Debug_Emulated,
|
|
|
+ "Userspace Attempting to load an NRO at 0x{:016X} with size 0x{:016X}", info1,
|
|
|
+ info2);
|
|
|
break;
|
|
|
- case BreakType::PreNROUnload:
|
|
|
- LOG_WARNING(
|
|
|
- Debug_Emulated,
|
|
|
- "Signalling debugger, Attempting to unload an NRO at 0x{:016X} with size 0x{:016X}",
|
|
|
- info1, info2);
|
|
|
+ case BreakReason::PostLoadDll:
|
|
|
+ LOG_INFO(Debug_Emulated, "Userspace Loaded an NRO at 0x{:016X} with size 0x{:016X}", info1,
|
|
|
+ info2);
|
|
|
break;
|
|
|
- case BreakType::PostNROUnload:
|
|
|
- LOG_WARNING(Debug_Emulated,
|
|
|
- "Signalling debugger, Unloaded an NRO at 0x{:016X} with size 0x{:016X}", info1,
|
|
|
- info2);
|
|
|
+ case BreakReason::PreUnloadDll:
|
|
|
+ LOG_INFO(Debug_Emulated,
|
|
|
+ "Userspace Attempting to unload an NRO at 0x{:016X} with size 0x{:016X}", info1,
|
|
|
+ info2);
|
|
|
break;
|
|
|
- case BreakType::CppException:
|
|
|
+ case BreakReason::PostUnloadDll:
|
|
|
+ LOG_INFO(Debug_Emulated, "Userspace Unloaded an NRO at 0x{:016X} with size 0x{:016X}",
|
|
|
+ info1, info2);
|
|
|
+ break;
|
|
|
+ case BreakReason::CppException:
|
|
|
LOG_CRITICAL(Debug_Emulated, "Signalling debugger. Uncaught C++ exception encountered.");
|
|
|
break;
|
|
|
default:
|
|
|
LOG_WARNING(
|
|
|
Debug_Emulated,
|
|
|
- "Signalling debugger, Unknown break reason {}, info1=0x{:016X}, info2=0x{:016X}",
|
|
|
- static_cast<u32>(break_reason.break_type.Value()), info1, info2);
|
|
|
+ "Signalling debugger, Unknown break reason {:#X}, info1=0x{:016X}, info2=0x{:016X}",
|
|
|
+ reason, info1, info2);
|
|
|
handle_debug_buffer(info1, info2);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- system.GetReporter().SaveSvcBreakReport(
|
|
|
- static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger.As<bool>(),
|
|
|
- info1, info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
|
|
|
+ system.GetReporter().SaveSvcBreakReport(reason, notification_only, info1, info2,
|
|
|
+ has_dumped_buffer ? std::make_optional(debug_buffer)
|
|
|
+ : std::nullopt);
|
|
|
|
|
|
- if (!break_reason.signal_debugger) {
|
|
|
+ if (!notification_only) {
|
|
|
LOG_CRITICAL(
|
|
|
Debug_Emulated,
|
|
|
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
|
|
|
@@ -1716,13 +1700,13 @@ static Result QueryProcessMemory(Core::System& system, VAddr memory_info_address
|
|
|
auto& memory{system.Memory()};
|
|
|
const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()};
|
|
|
|
|
|
- memory.Write64(memory_info_address + 0x00, memory_info.addr);
|
|
|
+ memory.Write64(memory_info_address + 0x00, memory_info.base_address);
|
|
|
memory.Write64(memory_info_address + 0x08, memory_info.size);
|
|
|
memory.Write32(memory_info_address + 0x10, static_cast<u32>(memory_info.state) & 0xff);
|
|
|
- memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attr));
|
|
|
- memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.perm));
|
|
|
- memory.Write32(memory_info_address + 0x1c, memory_info.ipc_refcount);
|
|
|
- memory.Write32(memory_info_address + 0x20, memory_info.device_refcount);
|
|
|
+ memory.Write32(memory_info_address + 0x14, static_cast<u32>(memory_info.attribute));
|
|
|
+ memory.Write32(memory_info_address + 0x18, static_cast<u32>(memory_info.permission));
|
|
|
+ memory.Write32(memory_info_address + 0x1c, memory_info.ipc_count);
|
|
|
+ memory.Write32(memory_info_address + 0x20, memory_info.device_count);
|
|
|
memory.Write32(memory_info_address + 0x24, 0);
|
|
|
|
|
|
// Page info appears to be currently unused by the kernel and is always set to zero.
|
|
|
@@ -1943,7 +1927,7 @@ static Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry
|
|
|
|
|
|
// Reserve a new thread from the process resource limit (waiting up to 100ms).
|
|
|
KScopedResourceReservation thread_reservation(
|
|
|
- kernel.CurrentProcess(), LimitableResource::Threads, 1,
|
|
|
+ kernel.CurrentProcess(), LimitableResource::ThreadCountMax, 1,
|
|
|
system.CoreTiming().GetGlobalTimeNs().count() + 100000000);
|
|
|
if (!thread_reservation.Succeeded()) {
|
|
|
LOG_ERROR(Kernel_SVC, "Could not reserve a new thread");
|
|
|
@@ -2344,7 +2328,7 @@ static Result CreateTransferMemory(Core::System& system, Handle* out, VAddr addr
|
|
|
|
|
|
// Reserve a new transfer memory from the process resource limit.
|
|
|
KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(),
|
|
|
- LimitableResource::TransferMemory);
|
|
|
+ LimitableResource::TransferMemoryCountMax);
|
|
|
R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached);
|
|
|
|
|
|
// Create the transfer memory.
|
|
|
@@ -2496,7 +2480,7 @@ static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_r
|
|
|
|
|
|
// Reserve a new event from the process resource limit
|
|
|
KScopedResourceReservation event_reservation(kernel.CurrentProcess(),
|
|
|
- LimitableResource::Events);
|
|
|
+ LimitableResource::EventCountMax);
|
|
|
R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
|
|
|
|
|
|
// Create a new event.
|
|
|
@@ -2539,11 +2523,6 @@ static Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out
|
|
|
static Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
|
|
|
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
|
|
|
|
|
|
- // This function currently only allows retrieving a process' status.
|
|
|
- enum class InfoType {
|
|
|
- Status,
|
|
|
- };
|
|
|
-
|
|
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
|
|
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
|
|
|
if (process.IsNull()) {
|
|
|
@@ -2552,9 +2531,9 @@ static Result GetProcessInfo(Core::System& system, u64* out, Handle process_hand
|
|
|
return ResultInvalidHandle;
|
|
|
}
|
|
|
|
|
|
- const auto info_type = static_cast<InfoType>(type);
|
|
|
- if (info_type != InfoType::Status) {
|
|
|
- LOG_ERROR(Kernel_SVC, "Expected info_type to be Status but got {} instead", type);
|
|
|
+ const auto info_type = static_cast<ProcessInfoType>(type);
|
|
|
+ if (info_type != ProcessInfoType::ProcessState) {
|
|
|
+ LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", type);
|
|
|
return ResultInvalidEnumValue;
|
|
|
}
|
|
|
|