kern: implement SvcUnmapMemory, more of SvcGetInfo
This commit is contained in:
@@ -34,6 +34,10 @@ namespace ams::kern::svc {
|
||||
case ams::svc::InfoType_AslrRegionSize:
|
||||
case ams::svc::InfoType_StackRegionAddress:
|
||||
case ams::svc::InfoType_StackRegionSize:
|
||||
case ams::svc::InfoType_ProgramId:
|
||||
case ams::svc::InfoType_InitialProcessIdRange:
|
||||
case ams::svc::InfoType_UserExceptionContextAddress:
|
||||
case ams::svc::InfoType_TotalNonSystemMemorySize:
|
||||
{
|
||||
/* These info types don't support non-zero subtypes. */
|
||||
R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination());
|
||||
@@ -67,6 +71,18 @@ namespace ams::kern::svc {
|
||||
case ams::svc::InfoType_StackRegionSize:
|
||||
*out = process->GetPageTable().GetStackRegionSize();
|
||||
break;
|
||||
case ams::svc::InfoType_ProgramId:
|
||||
*out = process->GetProgramId();
|
||||
break;
|
||||
case ams::svc::InfoType_InitialProcessIdRange:
|
||||
/* TODO: Detect exactly 4.0.0 target firmware, do the right thing. */
|
||||
return svc::ResultInvalidEnumValue();
|
||||
case ams::svc::InfoType_UserExceptionContextAddress:
|
||||
*out = GetInteger(process->GetProcessLocalRegionAddress());
|
||||
break;
|
||||
case ams::svc::InfoType_TotalNonSystemMemorySize:
|
||||
*out = process->GetTotalNonSystemUserPhysicalMemorySize();
|
||||
break;
|
||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,32 @@ namespace ams::kern::svc {
|
||||
|
||||
namespace {
|
||||
|
||||
Result UnmapMemory(uintptr_t dst_address, uintptr_t src_address, size_t size) {
|
||||
/* Log the call parameters for debugging. */
|
||||
MESOSPHERE_LOG("UnmapMemory(%zx, %zx, %zx)\n", dst_address, src_address, size);
|
||||
|
||||
/* Validate that addresses are page aligned. */
|
||||
R_UNLESS(util::IsAligned(dst_address, PageSize), svc::ResultInvalidAddress());
|
||||
R_UNLESS(util::IsAligned(src_address, PageSize), svc::ResultInvalidAddress());
|
||||
|
||||
/* Validate that size is positive and page aligned. */
|
||||
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||
|
||||
/* Ensure that neither mapping overflows. */
|
||||
R_UNLESS(src_address < src_address + size, svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS(dst_address < dst_address + size, svc::ResultInvalidCurrentMemory());
|
||||
|
||||
/* Get the page table we're operating on. */
|
||||
auto &page_table = GetCurrentProcess().GetPageTable();
|
||||
|
||||
/* Ensure that the memory we're unmapping is in range. */
|
||||
R_UNLESS(page_table.Contains(src_address, size), svc::ResultInvalidCurrentMemory());
|
||||
R_UNLESS(page_table.CanContain(dst_address, size, KMemoryState_Stack), svc::ResultInvalidMemoryRegion());
|
||||
|
||||
/* Unmap the memory. */
|
||||
return page_table.UnmapMemory(dst_address, src_address, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +65,7 @@ namespace ams::kern::svc {
|
||||
}
|
||||
|
||||
Result UnmapMemory64(ams::svc::Address dst_address, ams::svc::Address src_address, ams::svc::Size size) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcUnmapMemory64 was called.");
|
||||
return UnmapMemory(dst_address, src_address, size);
|
||||
}
|
||||
|
||||
/* ============================= 64From32 ABI ============================= */
|
||||
@@ -58,7 +83,7 @@ namespace ams::kern::svc {
|
||||
}
|
||||
|
||||
Result UnmapMemory64From32(ams::svc::Address dst_address, ams::svc::Address src_address, ams::svc::Size size) {
|
||||
MESOSPHERE_PANIC("Stubbed SvcUnmapMemory64From32 was called.");
|
||||
return UnmapMemory(dst_address, src_address, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user