diff --git a/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp b/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp index e2a1684f..9e7510f1 100644 --- a/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp +++ b/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp @@ -92,6 +92,8 @@ namespace ams::kern::svc { constinit const std::array SvcTable64From32 = SvcTable64From32Impl; + void PatchSvcTableEntry(const SvcTableEntry *table, u32 id, SvcTableEntry entry); + namespace { /* NOTE: Although the SVC tables are constants, our global constructor will run before .rodata is protected R--. */ @@ -101,34 +103,33 @@ namespace ams::kern::svc { private: static SvcTablePatcher s_instance; private: - ALWAYS_INLINE volatile SvcTableEntry *GetEditableTable(const SvcTable *table) { + ALWAYS_INLINE const SvcTableEntry *GetTableData(const SvcTable *table) { if (table != nullptr) { - return const_cast(table->data()); + return table->data(); } else { return nullptr; } } - /* TODO: This should perhaps be implemented in assembly. */ - NOINLINE void PatchTables(volatile SvcTableEntry *table_64, volatile SvcTableEntry *table_64_from_32) { + NOINLINE void PatchTables(const SvcTableEntry *table_64, const SvcTableEntry *table_64_from_32) { /* Get the target firmware. */ const auto target_fw = kern::GetTargetFirmware(); /* 10.0.0 broke the ABI for QueryIoMapping. */ if (target_fw < TargetFirmware_10_0_0) { - if (table_64) { table_64[ svc::SvcId_QueryIoMapping] = LegacyQueryIoMapping::Call64; } - if (table_64_from_32) { table_64_from_32[svc::SvcId_QueryIoMapping] = LegacyQueryIoMapping::Call64From32; } + if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64); } + if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64From32); } } /* 3.0.0 broke the ABI for ContinueDebugEvent. */ if (target_fw < TargetFirmware_3_0_0) { - if (table_64) { table_64[ svc::SvcId_ContinueDebugEvent] = LegacyContinueDebugEvent::Call64; } - if (table_64_from_32) { table_64_from_32[svc::SvcId_ContinueDebugEvent] = LegacyContinueDebugEvent::Call64From32; } + if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_ContinueDebugEvent, LegacyContinueDebugEvent::Call64); } + if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_ContinueDebugEvent, LegacyContinueDebugEvent::Call64From32); } } } public: SvcTablePatcher(const SvcTable *table_64, const SvcTable *table_64_from_32) { - PatchTables(GetEditableTable(table_64), GetEditableTable(table_64_from_32)); + PatchTables(GetTableData(table_64), GetTableData(table_64_from_32)); } };