core: Define HAS_NCE macro
This commit is contained in:
parent
c37b5f431f
commit
3ec3cca4d8
|
@ -926,7 +926,8 @@ if (ENABLE_WEB_SERVICE)
|
||||||
target_link_libraries(core PRIVATE web_service)
|
target_link_libraries(core PRIVATE web_service)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_arm64)
|
if (ARCHITECTURE_arm64 AND (ANDROID OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
|
||||||
|
target_compile_definitions(core PRIVATE -DHAS_NCE)
|
||||||
enable_language(C ASM)
|
enable_language(C ASM)
|
||||||
set(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
|
set(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp")
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
constexpr size_t VirtualReserveSize = 1ULL << 38;
|
constexpr size_t VirtualReserveSize = 1ULL << 38;
|
||||||
#else
|
#else
|
||||||
constexpr size_t VirtualReserveSize = 1ULL << 39;
|
constexpr size_t VirtualReserveSize = 1ULL << 39;
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct CodeSet final {
|
||||||
return segments[2];
|
return segments[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_NCE
|
||||||
Segment& PatchSegment() {
|
Segment& PatchSegment() {
|
||||||
return patch_segment;
|
return patch_segment;
|
||||||
}
|
}
|
||||||
|
@ -82,13 +83,17 @@ struct CodeSet final {
|
||||||
const Segment& PatchSegment() const {
|
const Segment& PatchSegment() const {
|
||||||
return patch_segment;
|
return patch_segment;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The overall data that backs this code set.
|
/// The overall data that backs this code set.
|
||||||
Kernel::PhysicalMemory memory;
|
Kernel::PhysicalMemory memory;
|
||||||
|
|
||||||
/// The segments that comprise this code set.
|
/// The segments that comprise this code set.
|
||||||
std::array<Segment, 3> segments;
|
std::array<Segment, 3> segments;
|
||||||
|
|
||||||
|
#ifdef HAS_NCE
|
||||||
Segment patch_segment;
|
Segment patch_segment;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The entry point address for this code set.
|
/// The entry point address for this code set.
|
||||||
KProcessAddress entrypoint = 0;
|
KProcessAddress entrypoint = 0;
|
||||||
|
|
|
@ -25,7 +25,7 @@ constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{
|
||||||
{ .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, },
|
{ .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, },
|
||||||
{ .bit_width = 36, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, },
|
{ .bit_width = 36, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, },
|
||||||
{ .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, },
|
{ .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, },
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
// With NCE, we use a 38-bit address space due to memory limitations. This should (safely) truncate ASLR region.
|
// With NCE, we use a 38-bit address space due to memory limitations. This should (safely) truncate ASLR region.
|
||||||
{ .bit_width = 39, .address = 128_MiB , .size = 256_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, },
|
{ .bit_width = 39, .address = 128_MiB , .size = 256_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, },
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -96,7 +96,7 @@ constexpr Common::MemoryPermission ConvertToMemoryPermission(KMemoryPermission p
|
||||||
if (True(perm & KMemoryPermission::UserWrite)) {
|
if (True(perm & KMemoryPermission::UserWrite)) {
|
||||||
perms |= Common::MemoryPermission::Write;
|
perms |= Common::MemoryPermission::Write;
|
||||||
}
|
}
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
if (True(perm & KMemoryPermission::UserExecute)) {
|
if (True(perm & KMemoryPermission::UserExecute)) {
|
||||||
perms |= Common::MemoryPermission::Execute;
|
perms |= Common::MemoryPermission::Execute;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,6 @@ private:
|
||||||
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
|
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
|
||||||
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
|
||||||
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
|
std::map<KProcessAddress, u64> m_debug_page_refcounts{};
|
||||||
std::unordered_map<u64, u64> m_post_handlers{};
|
|
||||||
std::atomic<s64> m_cpu_time{};
|
std::atomic<s64> m_cpu_time{};
|
||||||
std::atomic<s64> m_num_process_switches{};
|
std::atomic<s64> m_num_process_switches{};
|
||||||
std::atomic<s64> m_num_thread_switches{};
|
std::atomic<s64> m_num_thread_switches{};
|
||||||
|
@ -121,6 +120,9 @@ private:
|
||||||
std::atomic<s64> m_num_ipc_messages{};
|
std::atomic<s64> m_num_ipc_messages{};
|
||||||
std::atomic<s64> m_num_ipc_replies{};
|
std::atomic<s64> m_num_ipc_replies{};
|
||||||
std::atomic<s64> m_num_ipc_receives{};
|
std::atomic<s64> m_num_ipc_receives{};
|
||||||
|
#ifdef HAS_NCE
|
||||||
|
std::unordered_map<u64, u64> m_post_handlers{};
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result StartTermination();
|
Result StartTermination();
|
||||||
|
@ -468,9 +470,11 @@ public:
|
||||||
|
|
||||||
static void Switch(KProcess* cur_process, KProcess* next_process);
|
static void Switch(KProcess* cur_process, KProcess* next_process);
|
||||||
|
|
||||||
|
#ifdef HAS_NCE
|
||||||
std::unordered_map<u64, u64>& GetPostHandlers() noexcept {
|
std::unordered_map<u64, u64>& GetPostHandlers() noexcept {
|
||||||
return m_post_handlers;
|
return m_post_handlers;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
|
// Attempts to insert a watchpoint into a free slot. Returns false if none are available.
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
||||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
#include "core/arm/nce/arm_nce.h"
|
#include "core/arm/nce/arm_nce.h"
|
||||||
#endif
|
#endif
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -33,7 +33,7 @@ PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, KSchedu
|
||||||
PhysicalCore::~PhysicalCore() = default;
|
PhysicalCore::~PhysicalCore() = default;
|
||||||
|
|
||||||
void PhysicalCore::Initialize(bool is_64_bit) {
|
void PhysicalCore::Initialize(bool is_64_bit) {
|
||||||
#if defined(ARCHITECTURE_arm64)
|
#if defined(HAS_NCE)
|
||||||
if (Settings::IsNceEnabled()) {
|
if (Settings::IsNceEnabled()) {
|
||||||
m_arm_interface = std::make_unique<Core::ARM_NCE>(m_system, m_system.Kernel().IsMulticore(),
|
m_arm_interface = std::make_unique<Core::ARM_NCE>(m_system, m_system.Kernel().IsMulticore(),
|
||||||
m_core_index);
|
m_core_index);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "core/loader/deconstructed_rom_directory.h"
|
#include "core/loader/deconstructed_rom_directory.h"
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
#include "core/arm/nce/patch.h"
|
#include "core/arm/nce/patch.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -141,12 +141,12 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
|
||||||
std::size_t code_size{};
|
std::size_t code_size{};
|
||||||
|
|
||||||
// Define an nce patch context for each potential module.
|
// Define an nce patch context for each potential module.
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
std::array<Core::NCE::Patcher, 13> module_patchers;
|
std::array<Core::NCE::Patcher, 13> module_patchers;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const auto GetPatcher = [&](size_t i) -> Core::NCE::Patcher* {
|
const auto GetPatcher = [&](size_t i) -> Core::NCE::Patcher* {
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
if (Settings::IsNceEnabled()) {
|
if (Settings::IsNceEnabled()) {
|
||||||
return &module_patchers[i];
|
return &module_patchers[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
#include "core/arm/nce/patch.h"
|
#include "core/arm/nce/patch.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
|
||||||
program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
|
program_image.resize(static_cast<u32>(program_image.size()) + bss_size);
|
||||||
size_t image_size = program_image.size();
|
size_t image_size = program_image.size();
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
const auto& code = codeset.CodeSegment();
|
const auto& code = codeset.CodeSegment();
|
||||||
|
|
||||||
// NROs always have a 39-bit address space.
|
// NROs always have a 39-bit address space.
|
||||||
|
@ -247,7 +247,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process,
|
||||||
|
|
||||||
// Relocate code patch and copy to the program_image if running under NCE.
|
// Relocate code patch and copy to the program_image if running under NCE.
|
||||||
// This needs to be after LoadFromMetadata so we can use the process entry point.
|
// This needs to be after LoadFromMetadata so we can use the process entry point.
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
if (Settings::IsNceEnabled()) {
|
if (Settings::IsNceEnabled()) {
|
||||||
patch.RelocateAndCopy(process.GetEntryPoint(), code, program_image,
|
patch.RelocateAndCopy(process.GetEntryPoint(), code, program_image,
|
||||||
&process.GetPostHandlers());
|
&process.GetPostHandlers());
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "core/loader/nso.h"
|
#include "core/loader/nso.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
#include "core/arm/nce/patch.h"
|
#include "core/arm/nce/patch.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||||
|
|
||||||
// Allocate some space at the beginning if we are patching in PreText mode.
|
// Allocate some space at the beginning if we are patching in PreText mode.
|
||||||
const size_t module_start = [&]() -> size_t {
|
const size_t module_start = [&]() -> size_t {
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PreText) {
|
if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::PreText) {
|
||||||
return patch->GetSectionSize();
|
return patch->GetSectionSize();
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
|
||||||
std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data());
|
std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef HAS_NCE
|
||||||
// If we are computing the process code layout and using nce backend, patch.
|
// If we are computing the process code layout and using nce backend, patch.
|
||||||
const auto& code = codeset.CodeSegment();
|
const auto& code = codeset.CodeSegment();
|
||||||
if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::None) {
|
if (patch && patch->GetPatchMode() == Core::NCE::PatchMode::None) {
|
||||||
|
|
Reference in New Issue