summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/am/am.cpp4
-rw-r--r--src/core/hle/service/audio/audout_u.cpp2
-rw-r--r--src/core/hle/service/audio/audren_u.cpp13
-rw-r--r--src/core/hle/service/es/es.cpp1
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp4
-rw-r--r--src/core/hle/service/hid/hid.cpp5
-rw-r--r--src/core/hle/service/hid/irs.cpp6
-rw-r--r--src/core/hle/service/ldr/ldr.cpp362
-rw-r--r--src/core/hle/service/lm/lm.cpp8
-rw-r--r--src/core/hle/service/ns/pl_u.cpp12
-rw-r--r--src/core/hle/service/time/standard_network_system_clock_core.h2
-rw-r--r--src/core/hle/service/time/steady_clock_core.h1
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.h2
-rw-r--r--src/core/hle/service/time/system_clock_core.cpp2
-rw-r--r--src/core/hle/service/time/system_clock_core.h2
-rw-r--r--src/core/hle/service/time/time_sharedmemory.cpp5
16 files changed, 247 insertions, 184 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 557608e76..3ece2cf3c 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -903,7 +903,7 @@ private:
void PopOutData(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
- const auto storage = applet->GetBroker().PopNormalDataToGame();
+ auto storage = applet->GetBroker().PopNormalDataToGame();
if (storage == nullptr) {
LOG_ERROR(Service_AM,
"storage is a nullptr. There is no data in the current normal channel");
@@ -934,7 +934,7 @@ private:
void PopInteractiveOutData(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
- const auto storage = applet->GetBroker().PopInteractiveDataToGame();
+ auto storage = applet->GetBroker().PopInteractiveDataToGame();
if (storage == nullptr) {
LOG_ERROR(Service_AM,
"storage is a nullptr. There is no data in the current interactive channel");
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 4fb2cbc4b..106e89743 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -210,7 +210,7 @@ private:
/// This is the event handle used to check if the audio buffer was released
Kernel::EventPair buffer_event;
- Memory::Memory& main_memory;
+ Core::Memory::Memory& main_memory;
};
AudOutU::AudOutU(Core::System& system_) : ServiceFramework("audout:u"), system{system_} {
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 175cabf45..d8359abaa 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -92,11 +92,16 @@ private:
}
void RequestUpdateImpl(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_Audio, "(STUBBED) called");
+ LOG_DEBUG(Service_Audio, "(STUBBED) called");
+
+ auto result = renderer->UpdateAudioRenderer(ctx.ReadBuffer());
+
+ if (result.Succeeded()) {
+ ctx.WriteBuffer(result.Unwrap());
+ }
- ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer()));
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
+ rb.Push(result.Code());
}
void Start(Kernel::HLERequestContext& ctx) {
@@ -252,8 +257,6 @@ private:
}
void GetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
-
const auto device_name_buffer = ctx.ReadBuffer();
const std::string name = Common::StringFromBuffer(device_name_buffer);
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index df00ae625..86f36915a 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -76,7 +76,6 @@ private:
}
void ImportTicket(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
const auto ticket = ctx.ReadBuffer();
const auto cert = ctx.ReadBuffer(1);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index c1e32b28c..c55d900e2 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -107,6 +107,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
switch (controller_type) {
case NPadControllerType::None:
UNREACHABLE();
+ break;
case NPadControllerType::Handheld:
controller.joy_styles.handheld.Assign(1);
controller.device_type.handheld.Assign(1);
@@ -363,6 +364,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
switch (controller_type) {
case NPadControllerType::None:
UNREACHABLE();
+ break;
case NPadControllerType::Handheld:
handheld_entry.connection_status.raw = 0;
handheld_entry.connection_status.IsWired.Assign(1);
@@ -500,7 +502,7 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
const std::vector<Vibration>& vibrations) {
- LOG_WARNING(Service_HID, "(STUBBED) called");
+ LOG_DEBUG(Service_HID, "(STUBBED) called");
if (!can_controllers_vibrate) {
return;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index d6ed5f304..d6031a987 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -14,6 +14,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/writable_event.h"
@@ -53,9 +54,7 @@ IAppletResource::IAppletResource(Core::System& system)
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- shared_mem = Kernel::SharedMemory::Create(
- kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
- Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
+ shared_mem = SharedFrom(&kernel.GetHidSharedMem());
MakeController<Controller_DebugPad>(HidController::DebugPad);
MakeController<Controller_Touchscreen>(HidController::Touchscreen);
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 5e79e2c1a..36ed6f7da 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -6,6 +6,7 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/hid/irs.h"
@@ -38,9 +39,8 @@ IRS::IRS(Core::System& system) : ServiceFramework{"irs"}, system(system) {
RegisterHandlers(functions);
auto& kernel = system.Kernel();
- shared_mem = Kernel::SharedMemory::Create(
- kernel, nullptr, 0x8000, Kernel::MemoryPermission::ReadWrite,
- Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "IRS:SharedMemory");
+
+ shared_mem = SharedFrom(&kernel.GetIrsSharedMem());
}
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 647943020..0cde7a557 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -8,14 +8,21 @@
#include "common/alignment.h"
#include "common/hex_util.h"
+#include "common/scope_exit.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/errors.h"
+#include "core/hle/kernel/memory/page_table.h"
+#include "core/hle/kernel/memory/system_control.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/ldr/ldr.h"
#include "core/hle/service/service.h"
#include "core/loader/nro.h"
+#include "core/memory.h"
namespace Service::LDR {
+constexpr ResultCode ERROR_INSUFFICIENT_ADDRESS_SPACE{ErrorModule::RO, 2};
+
constexpr ResultCode ERROR_INVALID_MEMORY_STATE{ErrorModule::Loader, 51};
constexpr ResultCode ERROR_INVALID_NRO{ErrorModule::Loader, 52};
constexpr ResultCode ERROR_INVALID_NRR{ErrorModule::Loader, 53};
@@ -29,7 +36,61 @@ constexpr ResultCode ERROR_INVALID_NRO_ADDRESS{ErrorModule::Loader, 84};
constexpr ResultCode ERROR_INVALID_NRR_ADDRESS{ErrorModule::Loader, 85};
constexpr ResultCode ERROR_NOT_INITIALIZED{ErrorModule::Loader, 87};
-constexpr u64 MAXIMUM_LOADED_RO = 0x40;
+constexpr std::size_t MAXIMUM_LOADED_RO{0x40};
+constexpr std::size_t MAXIMUM_MAP_RETRIES{0x200};
+
+struct NRRHeader {
+ u32_le magic;
+ INSERT_PADDING_BYTES(12);
+ u64_le title_id_mask;
+ u64_le title_id_pattern;
+ INSERT_PADDING_BYTES(16);
+ std::array<u8, 0x100> modulus;
+ std::array<u8, 0x100> signature_1;
+ std::array<u8, 0x100> signature_2;
+ u64_le title_id;
+ u32_le size;
+ INSERT_PADDING_BYTES(4);
+ u32_le hash_offset;
+ u32_le hash_count;
+ INSERT_PADDING_BYTES(8);
+};
+static_assert(sizeof(NRRHeader) == 0x350, "NRRHeader has incorrect size.");
+
+struct NROHeader {
+ INSERT_PADDING_WORDS(1);
+ u32_le mod_offset;
+ INSERT_PADDING_WORDS(2);
+ u32_le magic;
+ u32_le version;
+ u32_le nro_size;
+ u32_le flags;
+ u32_le text_offset;
+ u32_le text_size;
+ u32_le ro_offset;
+ u32_le ro_size;
+ u32_le rw_offset;
+ u32_le rw_size;
+ u32_le bss_size;
+ INSERT_PADDING_WORDS(1);
+ std::array<u8, 0x20> build_id;
+ INSERT_PADDING_BYTES(0x20);
+};
+static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size.");
+
+using SHA256Hash = std::array<u8, 0x20>;
+
+struct NROInfo {
+ SHA256Hash hash{};
+ VAddr nro_address{};
+ std::size_t nro_size{};
+ VAddr bss_address{};
+ std::size_t bss_size{};
+ std::size_t text_size{};
+ std::size_t ro_size{};
+ std::size_t data_size{};
+ VAddr src_addr{};
+};
class DebugMonitor final : public ServiceFramework<DebugMonitor> {
public:
@@ -84,7 +145,7 @@ public:
{0, &RelocatableObject::LoadNro, "LoadNro"},
{1, &RelocatableObject::UnloadNro, "UnloadNro"},
{2, &RelocatableObject::LoadNrr, "LoadNrr"},
- {3, &RelocatableObject::UnloadNrr, "UnloadNrr"},
+ {3, nullptr, "UnloadNrr"},
{4, &RelocatableObject::Initialize, "Initialize"},
{10, nullptr, "LoadNrrEx"},
};
@@ -190,46 +251,125 @@ public:
rb.Push(RESULT_SUCCESS);
}
- void UnloadNrr(Kernel::HLERequestContext& ctx) {
- if (!initialized) {
- LOG_ERROR(Service_LDR, "LDR:RO not initialized before use!");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERROR_NOT_INITIALIZED);
- return;
+ bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start,
+ std::size_t size) const {
+ constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize};
+ const auto start_info{page_table.QueryInfo(start - 1)};
+
+ if (start_info.state != Kernel::Memory::MemoryState::Free) {
+ return {};
}
- struct Parameters {
- u64_le process_id;
- u64_le nrr_address;
- };
+ if (start_info.GetAddress() > (start - padding_size)) {
+ return {};
+ }
- IPC::RequestParser rp{ctx};
- const auto [process_id, nrr_address] = rp.PopRaw<Parameters>();
+ const auto end_info{page_table.QueryInfo(start + size)};
- LOG_DEBUG(Service_LDR, "called with process_id={:016X}, nrr_addr={:016X}", process_id,
- nrr_address);
+ if (end_info.state != Kernel::Memory::MemoryState::Free) {
+ return {};
+ }
- if (!Common::Is4KBAligned(nrr_address)) {
- LOG_ERROR(Service_LDR, "NRR Address has invalid alignment (actual {:016X})!",
- nrr_address);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERROR_INVALID_ALIGNMENT);
- return;
+ return (start + size + padding_size) <= (end_info.GetAddress() + end_info.GetSize());
+ }
+
+ VAddr GetRandomMapRegion(const Kernel::Memory::PageTable& page_table, std::size_t size) const {
+ VAddr addr{};
+ const std::size_t end_pages{(page_table.GetAliasCodeRegionSize() - size) >>
+ Kernel::Memory::PageBits};
+ do {
+ addr = page_table.GetAliasCodeRegionStart() +
+ (Kernel::Memory::SystemControl::GenerateRandomRange(0, end_pages)
+ << Kernel::Memory::PageBits);
+ } while (!page_table.IsInsideAddressSpace(addr, size) ||
+ page_table.IsInsideHeapRegion(addr, size) ||
+ page_table.IsInsideAliasRegion(addr, size));
+ return addr;
+ }
+
+ ResultVal<VAddr> MapProcessCodeMemory(Kernel::Process* process, VAddr baseAddress,
+ u64 size) const {
+ for (int retry{}; retry < MAXIMUM_MAP_RETRIES; retry++) {
+ auto& page_table{process->PageTable()};
+ const VAddr addr{GetRandomMapRegion(page_table, size)};
+ const ResultCode result{page_table.MapProcessCodeMemory(addr, baseAddress, size)};
+
+ if (result == Kernel::ERR_INVALID_ADDRESS_STATE) {
+ continue;
+ }
+
+ CASCADE_CODE(result);
+
+ if (ValidateRegionForMap(page_table, addr, size)) {
+ return MakeResult<VAddr>(addr);
+ }
}
- const auto iter = nrr.find(nrr_address);
- if (iter == nrr.end()) {
- LOG_ERROR(Service_LDR,
- "Attempting to unload NRR which has not been loaded! (addr={:016X})",
- nrr_address);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERROR_INVALID_NRR_ADDRESS);
- return;
+ return ERROR_INSUFFICIENT_ADDRESS_SPACE;
+ }
+
+ ResultVal<VAddr> MapNro(Kernel::Process* process, VAddr nro_addr, std::size_t nro_size,
+ VAddr bss_addr, std::size_t bss_size, std::size_t size) const {
+
+ for (int retry{}; retry < MAXIMUM_MAP_RETRIES; retry++) {
+ auto& page_table{process->PageTable()};
+ VAddr addr{};
+
+ CASCADE_RESULT(addr, MapProcessCodeMemory(process, nro_addr, nro_size));
+
+ if (bss_size) {
+ auto block_guard = detail::ScopeExit([&] {
+ page_table.UnmapProcessCodeMemory(addr + nro_size, bss_addr, bss_size);
+ page_table.UnmapProcessCodeMemory(addr, nro_addr, nro_size);
+ });
+
+ const ResultCode result{
+ page_table.MapProcessCodeMemory(addr + nro_size, bss_addr, bss_size)};
+
+ if (result == Kernel::ERR_INVALID_ADDRESS_STATE) {
+ continue;
+ }
+
+ if (result.IsError()) {
+ return result;
+ }
+
+ block_guard.Cancel();
+ }
+
+ if (ValidateRegionForMap(page_table, addr, size)) {
+ return MakeResult<VAddr>(addr);
+ }
}
- nrr.erase(iter);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
+ return ERROR_INSUFFICIENT_ADDRESS_SPACE;
+ }
+
+ ResultCode LoadNro(Kernel::Process* process, const NROHeader& nro_header, VAddr nro_addr,
+ VAddr start) const {
+ const VAddr text_start{start + nro_header.text_offset};
+ const VAddr ro_start{start + nro_header.ro_offset};
+ const VAddr data_start{start + nro_header.rw_offset};
+ const VAddr bss_start{data_start + nro_header.rw_size};
+ const VAddr bss_end_addr{
+ Common::AlignUp(bss_start + nro_header.bss_size, Kernel::Memory::PageSize)};
+
+ auto CopyCode{[&](VAddr src_addr, VAddr dst_addr, u64 size) {
+ std::vector<u8> source_data(size);
+ system.Memory().ReadBlock(src_addr, source_data.data(), source_data.size());
+ system.Memory().WriteBlock(dst_addr, source_data.data(), source_data.size());
+ }};
+ CopyCode(nro_addr + nro_header.text_offset, text_start, nro_header.text_size);
+ CopyCode(nro_addr + nro_header.ro_offset, ro_start, nro_header.ro_size);
+ CopyCode(nro_addr + nro_header.rw_offset, data_start, nro_header.rw_size);
+
+ CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(
+ text_start, ro_start - text_start, Kernel::Memory::MemoryPermission::ReadAndExecute));
+ CASCADE_CODE(process->PageTable().SetCodeMemoryPermission(
+ ro_start, data_start - ro_start, Kernel::Memory::MemoryPermission::Read));
+
+ return process->PageTable().SetCodeMemoryPermission(
+ data_start, bss_end_addr - data_start, Kernel::Memory::MemoryPermission::ReadAndWrite);
}
void LoadNro(Kernel::HLERequestContext& ctx) {
@@ -317,9 +457,9 @@ public:
return;
}
- NROHeader header;
+ // Load and validate the NRO header
+ NROHeader header{};
std::memcpy(&header, nro_data.data(), sizeof(NROHeader));
-
if (!IsValidNRO(header, nro_size, bss_size)) {
LOG_ERROR(Service_LDR, "NRO was invalid!");
IPC::ResponseBuilder rb{ctx, 2};
@@ -327,62 +467,48 @@ public:
return;
}
- // Load NRO as new executable module
- auto* process = system.CurrentProcess();
- auto& vm_manager = process->VMManager();
- auto map_address = vm_manager.FindFreeRegion(nro_size + bss_size);
-
- if (!map_address.Succeeded() ||
- *map_address + nro_size + bss_size > vm_manager.GetAddressSpaceEndAddress()) {
-
- LOG_ERROR(Service_LDR,
- "General error while allocation memory or no available memory to allocate!");
+ // Map memory for the NRO
+ const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address,
+ bss_size, nro_size + bss_size)};
+ if (map_result.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERROR_INVALID_MEMORY_STATE);
- return;
+ rb.Push(map_result.Code());
}
- // Mark text and read-only region as ModuleCode
- ASSERT(vm_manager
- .MirrorMemory(*map_address, nro_address, header.text_size + header.ro_size,
- Kernel::MemoryState::ModuleCode)
- .IsSuccess());
- // Mark read/write region as ModuleCodeData, which is necessary if this region is used for
- // TransferMemory (e.g. Final Fantasy VIII Remastered does this)
- ASSERT(vm_manager
- .MirrorMemory(*map_address + header.rw_offset, nro_address + header.rw_offset,
- header.rw_size, Kernel::MemoryState::ModuleCodeData)
- .IsSuccess());
- // Revoke permissions from the old memory region
- ASSERT(vm_manager.ReprotectRange(nro_address, nro_size, Kernel::VMAPermission::None)
- .IsSuccess());
-
- if (bss_size > 0) {
- // Mark BSS region as ModuleCodeData, which is necessary if this region is used for
- // TransferMemory (e.g. Final Fantasy VIII Remastered does this)
- ASSERT(vm_manager
- .MirrorMemory(*map_address + nro_size, bss_address, bss_size,
- Kernel::MemoryState::ModuleCodeData)
- .IsSuccess());
- ASSERT(vm_manager.ReprotectRange(bss_address, bss_size, Kernel::VMAPermission::None)
- .IsSuccess());
+ // Load the NRO into the mapped memory
+ if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)};
+ result.IsError()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(map_result.Code());
}
- vm_manager.ReprotectRange(*map_address, header.text_size,
- Kernel::VMAPermission::ReadExecute);
- vm_manager.ReprotectRange(*map_address + header.ro_offset, header.ro_size,
- Kernel::VMAPermission::Read);
- vm_manager.ReprotectRange(*map_address + header.rw_offset, header.rw_size,
- Kernel::VMAPermission::ReadWrite);
+ // Track the loaded NRO
+ nro.insert_or_assign(*map_result, NROInfo{hash, *map_result, nro_size, bss_address,
+ bss_size, header.text_size, header.ro_size,
+ header.rw_size, nro_address});
+ // Invalidate JIT caches for the newly mapped process code
system.InvalidateCpuInstructionCaches();
- nro.insert_or_assign(*map_address,
- NROInfo{hash, nro_address, nro_size, bss_address, bss_size});
-
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(*map_address);
+ rb.Push(*map_result);
+ }
+
+ ResultCode UnmapNro(const NROInfo& info) {
+ // Each region must be unmapped separately to validate memory state
+ auto& page_table{system.CurrentProcess()->PageTable()};
+ CASCADE_CODE(page_table.UnmapProcessCodeMemory(info.nro_address + info.text_size +
+ info.ro_size + info.data_size,
+ info.bss_address, info.bss_size));
+ CASCADE_CODE(page_table.UnmapProcessCodeMemory(
+ info.nro_address + info.text_size + info.ro_size,
+ info.src_addr + info.text_size + info.ro_size, info.data_size));
+ CASCADE_CODE(page_table.UnmapProcessCodeMemory(
+ info.nro_address + info.text_size, info.src_addr + info.text_size, info.ro_size));
+ CASCADE_CODE(
+ page_table.UnmapProcessCodeMemory(info.nro_address, info.src_addr, info.text_size));
+ return RESULT_SUCCESS;
}
void UnloadNro(Kernel::HLERequestContext& ctx) {
@@ -422,30 +548,15 @@ public:
return;
}
- auto& vm_manager = system.CurrentProcess()->VMManager();
- const auto& nro_info = iter->second;
-
- // Unmap the mirrored memory
- ASSERT(
- vm_manager.UnmapRange(nro_address, nro_info.nro_size + nro_info.bss_size).IsSuccess());
-
- // Reprotect the source memory
- ASSERT(vm_manager
- .ReprotectRange(nro_info.nro_address, nro_info.nro_size,
- Kernel::VMAPermission::ReadWrite)
- .IsSuccess());
- if (nro_info.bss_size > 0) {
- ASSERT(vm_manager
- .ReprotectRange(nro_info.bss_address, nro_info.bss_size,
- Kernel::VMAPermission::ReadWrite)
- .IsSuccess());
- }
+ const auto result{UnmapNro(iter->second)};
system.InvalidateCpuInstructionCaches();
nro.erase(iter);
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
+
+ rb.Push(result);
}
void Initialize(Kernel::HLERequestContext& ctx) {
@@ -458,56 +569,7 @@ public:
}
private:
- using SHA256Hash = std::array<u8, 0x20>;
-
- struct NROHeader {
- INSERT_PADDING_WORDS(1);
- u32_le mod_offset;
- INSERT_PADDING_WORDS(2);
- u32_le magic;
- u32_le version;
- u32_le nro_size;
- u32_le flags;
- u32_le text_offset;
- u32_le text_size;
- u32_le ro_offset;
- u32_le ro_size;
- u32_le rw_offset;
- u32_le rw_size;
- u32_le bss_size;
- INSERT_PADDING_WORDS(1);
- std::array<u8, 0x20> build_id;
- INSERT_PADDING_BYTES(0x20);
- };
- static_assert(sizeof(NROHeader) == 0x80, "NROHeader has invalid size.");
-
- struct NRRHeader {
- u32_le magic;
- INSERT_PADDING_BYTES(12);
- u64_le title_id_mask;
- u64_le title_id_pattern;
- INSERT_PADDING_BYTES(16);
- std::array<u8, 0x100> modulus;
- std::array<u8, 0x100> signature_1;
- std::array<u8, 0x100> signature_2;
- u64_le title_id;
- u32_le size;
- INSERT_PADDING_BYTES(4);
- u32_le hash_offset;
- u32_le hash_count;
- INSERT_PADDING_BYTES(8);
- };
- static_assert(sizeof(NRRHeader) == 0x350, "NRRHeader has incorrect size.");
-
- struct NROInfo {
- SHA256Hash hash;
- VAddr nro_address;
- u64 nro_size;
- VAddr bss_address;
- u64 bss_size;
- };
-
- bool initialized = false;
+ bool initialized{};
std::map<VAddr, NROInfo> nro;
std::map<VAddr, std::vector<SHA256Hash>> nrr;
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 346c8f899..dec96b771 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -17,7 +17,7 @@ namespace Service::LM {
class ILogger final : public ServiceFramework<ILogger> {
public:
- explicit ILogger(Manager& manager_, Memory::Memory& memory_)
+ explicit ILogger(Manager& manager_, Core::Memory::Memory& memory_)
: ServiceFramework("ILogger"), manager{manager_}, memory{memory_} {
static const FunctionInfo functions[] = {
{0, &ILogger::Log, "Log"},
@@ -75,12 +75,12 @@ private:
}
Manager& manager;
- Memory::Memory& memory;
+ Core::Memory::Memory& memory;
};
class LM final : public ServiceFramework<LM> {
public:
- explicit LM(Manager& manager_, Memory::Memory& memory_)
+ explicit LM(Manager& manager_, Core::Memory::Memory& memory_)
: ServiceFramework{"lm"}, manager{manager_}, memory{memory_} {
// clang-format off
static const FunctionInfo functions[] = {
@@ -101,7 +101,7 @@ private:
}
Manager& manager;
- Memory::Memory& memory;
+ Core::Memory::Memory& memory;
};
void InstallInterfaces(Core::System& system) {
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 8da4e52c5..ab1746d28 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -19,6 +19,7 @@
#include "core/file_sys/romfs.h"
#include "core/file_sys/system_archive/system_archive.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_memory.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/filesystem/filesystem.h"
@@ -265,16 +266,13 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// Map backing memory for the font data
LOG_DEBUG(Service_NS, "called");
- system.CurrentProcess()->VMManager().MapMemoryBlock(SHARED_FONT_MEM_VADDR, impl->shared_font, 0,
- SHARED_FONT_MEM_SIZE,
- Kernel::MemoryState::Shared);
// Create shared font memory object
auto& kernel = system.Kernel();
- impl->shared_font_mem = Kernel::SharedMemory::Create(
- kernel, system.CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
- Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
- "PL_U:shared_font_mem");
+ impl->shared_font_mem = SharedFrom(&kernel.GetFontSharedMem());
+
+ std::memcpy(impl->shared_font_mem->GetPointer(), impl->shared_font->data(),
+ impl->shared_font->size());
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/time/standard_network_system_clock_core.h b/src/core/hle/service/time/standard_network_system_clock_core.h
index 3f505c37c..c993bdf79 100644
--- a/src/core/hle/service/time/standard_network_system_clock_core.h
+++ b/src/core/hle/service/time/standard_network_system_clock_core.h
@@ -23,7 +23,7 @@ public:
standard_network_clock_sufficient_accuracy = value;
}
- bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) {
+ bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) const {
SystemClockContext context{};
if (GetClockContext(system, context) != RESULT_SUCCESS) {
return {};
diff --git a/src/core/hle/service/time/steady_clock_core.h b/src/core/hle/service/time/steady_clock_core.h
index 84af3d105..d80a2385f 100644
--- a/src/core/hle/service/time/steady_clock_core.h
+++ b/src/core/hle/service/time/steady_clock_core.h
@@ -16,6 +16,7 @@ namespace Service::Time::Clock {
class SteadyClockCore {
public:
SteadyClockCore() = default;
+ virtual ~SteadyClockCore() = default;
const Common::UUID& GetClockSourceId() const {
return clock_source_id;
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h
index 6260de6c3..2b0fa7e75 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.h
+++ b/src/core/hle/service/time/system_clock_context_update_callback.h
@@ -20,7 +20,7 @@ namespace Service::Time::Clock {
class SystemClockContextUpdateCallback {
public:
SystemClockContextUpdateCallback();
- ~SystemClockContextUpdateCallback();
+ virtual ~SystemClockContextUpdateCallback();
bool NeedUpdate(const SystemClockContext& value) const;
diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp
index 1a3ab8cfa..d31d4e2ca 100644
--- a/src/core/hle/service/time/system_clock_core.cpp
+++ b/src/core/hle/service/time/system_clock_core.cpp
@@ -9,7 +9,7 @@
namespace Service::Time::Clock {
SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core)
- : steady_clock_core{steady_clock_core}, is_initialized{} {
+ : steady_clock_core{steady_clock_core} {
context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId();
}
diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h
index 54407a6c5..608dd3b2e 100644
--- a/src/core/hle/service/time/system_clock_core.h
+++ b/src/core/hle/service/time/system_clock_core.h
@@ -22,7 +22,7 @@ class SystemClockContextUpdateCallback;
class SystemClockCore {
public:
explicit SystemClockCore(SteadyClockCore& steady_clock_core);
- ~SystemClockCore();
+ virtual ~SystemClockCore();
SteadyClockCore& GetSteadyClockCore() const {
return steady_clock_core;
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp
index fdaef233f..999ec1e51 100644
--- a/src/core/hle/service/time/time_sharedmemory.cpp
+++ b/src/core/hle/service/time/time_sharedmemory.cpp
@@ -6,6 +6,7 @@
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hardware_properties.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/steady_clock_core.h"
#include "core/hle/service/time/time_sharedmemory.h"
@@ -15,9 +16,7 @@ namespace Service::Time {
static constexpr std::size_t SHARED_MEMORY_SIZE{0x1000};
SharedMemory::SharedMemory(Core::System& system) : system(system) {
- shared_memory_holder = Kernel::SharedMemory::Create(
- system.Kernel(), nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
- Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "Time:SharedMemory");
+ shared_memory_holder = SharedFrom(&system.Kernel().GetTimeSharedMem());
std::memset(shared_memory_holder->GetPointer(), 0, SHARED_MEMORY_SIZE);
}