summaryrefslogtreecommitdiffstats
path: root/src/core/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm')
-rw-r--r--src/core/arm/arm_interface.cpp2
-rw-r--r--src/core/arm/arm_interface.h2
-rw-r--r--src/core/arm/debug.cpp14
-rw-r--r--src/core/arm/debug.h6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp49
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h20
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp11
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp11
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/arm/nce/arm_nce.cpp2
-rw-r--r--src/core/arm/nce/interpreter_visitor.cpp5
-rw-r--r--src/core/arm/nce/visitor_base.h6
13 files changed, 108 insertions, 24 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 698c9c8ad..5dc7e5d59 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -9,7 +9,7 @@
namespace Core {
-void ArmInterface::LogBacktrace(const Kernel::KProcess* process) const {
+void ArmInterface::LogBacktrace(Kernel::KProcess* process) const {
Kernel::Svc::ThreadContext ctx;
this->GetContext(ctx);
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 806c7c9e9..495963eef 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -95,7 +95,7 @@ public:
virtual void SignalInterrupt(Kernel::KThread* thread) = 0;
// Stack trace generation.
- void LogBacktrace(const Kernel::KProcess* process) const;
+ void LogBacktrace(Kernel::KProcess* process) const;
// Debug functionality.
virtual const Kernel::DebugWatchpoint* HaltedWatchpoint() const = 0;
diff --git a/src/core/arm/debug.cpp b/src/core/arm/debug.cpp
index af1c34bc3..854509463 100644
--- a/src/core/arm/debug.cpp
+++ b/src/core/arm/debug.cpp
@@ -79,7 +79,7 @@ constexpr std::array<u64, 2> SegmentBases{
0x7100000000ULL,
};
-void SymbolicateBacktrace(const Kernel::KProcess* process, std::vector<BacktraceEntry>& out) {
+void SymbolicateBacktrace(Kernel::KProcess* process, std::vector<BacktraceEntry>& out) {
auto modules = FindModules(process);
const bool is_64 = process->Is64Bit();
@@ -118,7 +118,7 @@ void SymbolicateBacktrace(const Kernel::KProcess* process, std::vector<Backtrace
}
}
-std::vector<BacktraceEntry> GetAArch64Backtrace(const Kernel::KProcess* process,
+std::vector<BacktraceEntry> GetAArch64Backtrace(Kernel::KProcess* process,
const Kernel::Svc::ThreadContext& ctx) {
std::vector<BacktraceEntry> out;
auto& memory = process->GetMemory();
@@ -144,7 +144,7 @@ std::vector<BacktraceEntry> GetAArch64Backtrace(const Kernel::KProcess* process,
return out;
}
-std::vector<BacktraceEntry> GetAArch32Backtrace(const Kernel::KProcess* process,
+std::vector<BacktraceEntry> GetAArch32Backtrace(Kernel::KProcess* process,
const Kernel::Svc::ThreadContext& ctx) {
std::vector<BacktraceEntry> out;
auto& memory = process->GetMemory();
@@ -173,7 +173,7 @@ std::vector<BacktraceEntry> GetAArch32Backtrace(const Kernel::KProcess* process,
} // namespace
std::optional<std::string> GetThreadName(const Kernel::KThread* thread) {
- const auto* process = thread->GetOwnerProcess();
+ auto* process = thread->GetOwnerProcess();
if (process->Is64Bit()) {
return GetNameFromThreadType64(process->GetMemory(), *thread);
} else {
@@ -248,7 +248,7 @@ Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process,
return cur_addr - 1;
}
-Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process) {
+Loader::AppLoader::Modules FindModules(Kernel::KProcess* process) {
Loader::AppLoader::Modules modules;
auto& page_table = process->GetPageTable();
@@ -312,7 +312,7 @@ Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process) {
return modules;
}
-Kernel::KProcessAddress FindMainModuleEntrypoint(const Kernel::KProcess* process) {
+Kernel::KProcessAddress FindMainModuleEntrypoint(Kernel::KProcess* process) {
// Do we have any loaded executable sections?
auto modules = FindModules(process);
@@ -337,7 +337,7 @@ void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 addres
}
}
-std::vector<BacktraceEntry> GetBacktraceFromContext(const Kernel::KProcess* process,
+std::vector<BacktraceEntry> GetBacktraceFromContext(Kernel::KProcess* process,
const Kernel::Svc::ThreadContext& ctx) {
if (process->Is64Bit()) {
return GetAArch64Backtrace(process, ctx);
diff --git a/src/core/arm/debug.h b/src/core/arm/debug.h
index c542633db..3cd671365 100644
--- a/src/core/arm/debug.h
+++ b/src/core/arm/debug.h
@@ -14,9 +14,9 @@ std::optional<std::string> GetThreadName(const Kernel::KThread* thread);
std::string_view GetThreadWaitReason(const Kernel::KThread* thread);
std::string GetThreadState(const Kernel::KThread* thread);
-Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process);
+Loader::AppLoader::Modules FindModules(Kernel::KProcess* process);
Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process, Kernel::KProcessAddress base);
-Kernel::KProcessAddress FindMainModuleEntrypoint(const Kernel::KProcess* process);
+Kernel::KProcessAddress FindMainModuleEntrypoint(Kernel::KProcess* process);
void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 address, u64 size);
@@ -28,7 +28,7 @@ struct BacktraceEntry {
std::string name;
};
-std::vector<BacktraceEntry> GetBacktraceFromContext(const Kernel::KProcess* process,
+std::vector<BacktraceEntry> GetBacktraceFromContext(Kernel::KProcess* process,
const Kernel::Svc::ThreadContext& ctx);
std::vector<BacktraceEntry> GetBacktrace(const Kernel::KThread* thread);
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
new file mode 100644
index 000000000..e6e9fc45b
--- /dev/null
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifdef __linux__
+
+#include "common/signal_chain.h"
+
+#include "core/arm/dynarmic/arm_dynarmic.h"
+#include "core/hle/kernel/k_process.h"
+#include "core/memory.h"
+
+namespace Core {
+
+namespace {
+
+thread_local Core::Memory::Memory* g_current_memory{};
+std::once_flag g_registered{};
+struct sigaction g_old_segv {};
+
+void HandleSigSegv(int sig, siginfo_t* info, void* ctx) {
+ if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) {
+ return;
+ }
+
+ return g_old_segv.sa_sigaction(sig, info, ctx);
+}
+
+} // namespace
+
+ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) {
+ g_current_memory = std::addressof(process->GetMemory());
+}
+
+ScopedJitExecution::~ScopedJitExecution() {
+ g_current_memory = nullptr;
+}
+
+void ScopedJitExecution::RegisterHandler() {
+ std::call_once(g_registered, [] {
+ struct sigaction sa {};
+ sa.sa_sigaction = &HandleSigSegv;
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv));
+ });
+}
+
+} // namespace Core
+
+#endif
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index eef7c3116..53dd18815 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -26,4 +26,24 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) {
return static_cast<HaltReason>(hr);
}
+#ifdef __linux__
+
+class ScopedJitExecution {
+public:
+ explicit ScopedJitExecution(Kernel::KProcess* process);
+ ~ScopedJitExecution();
+ static void RegisterHandler();
+};
+
+#else
+
+class ScopedJitExecution {
+public:
+ explicit ScopedJitExecution(Kernel::KProcess* process) {}
+ ~ScopedJitExecution() {}
+ static void RegisterHandler() {}
+};
+
+#endif
+
} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index f34865e26..36478f722 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -15,7 +15,7 @@ using namespace Common::Literals;
class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
public:
- explicit DynarmicCallbacks32(ArmDynarmic32& parent, const Kernel::KProcess* process)
+ explicit DynarmicCallbacks32(ArmDynarmic32& parent, Kernel::KProcess* process)
: m_parent{parent}, m_memory(process->GetMemory()),
m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()},
m_check_memory_access{m_debugger_enabled ||
@@ -169,7 +169,7 @@ public:
ArmDynarmic32& m_parent;
Core::Memory::Memory& m_memory;
- const Kernel::KProcess* m_process{};
+ Kernel::KProcess* m_process{};
const bool m_debugger_enabled{};
const bool m_check_memory_access{};
static constexpr u64 MinimumRunCycles = 10000U;
@@ -331,11 +331,15 @@ bool ArmDynarmic32::IsInThumbMode() const {
}
HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -370,13 +374,14 @@ void ArmDynarmic32::RewindBreakpointInstruction() {
this->SetContext(m_breakpoint_context);
}
-ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, const Kernel::KProcess* process,
+ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProcess* process,
DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index)
: ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor},
m_cb(std::make_unique<DynarmicCallbacks32>(*this, process)),
m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} {
auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl();
m_jit = MakeJit(&page_table_impl);
+ ScopedJitExecution::RegisterHandler();
}
ArmDynarmic32::~ArmDynarmic32() = default;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index 185ac7cbf..b580efe61 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -20,7 +20,7 @@ class System;
class ArmDynarmic32 final : public ArmInterface {
public:
- ArmDynarmic32(System& system, bool uses_wall_clock, const Kernel::KProcess* process,
+ ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProcess* process,
DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index);
~ArmDynarmic32() override;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index dff14756e..c811c8ad5 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -15,7 +15,7 @@ using namespace Common::Literals;
class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
public:
- explicit DynarmicCallbacks64(ArmDynarmic64& parent, const Kernel::KProcess* process)
+ explicit DynarmicCallbacks64(ArmDynarmic64& parent, Kernel::KProcess* process)
: m_parent{parent}, m_memory(process->GetMemory()),
m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()},
m_check_memory_access{m_debugger_enabled ||
@@ -216,7 +216,7 @@ public:
Core::Memory::Memory& m_memory;
u64 m_tpidrro_el0{};
u64 m_tpidr_el0{};
- const Kernel::KProcess* m_process{};
+ Kernel::KProcess* m_process{};
const bool m_debugger_enabled{};
const bool m_check_memory_access{};
static constexpr u64 MinimumRunCycles = 10000U;
@@ -362,11 +362,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
}
HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -399,13 +403,14 @@ void ArmDynarmic64::RewindBreakpointInstruction() {
this->SetContext(m_breakpoint_context);
}
-ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, const Kernel::KProcess* process,
+ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProcess* process,
DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index)
: ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor},
m_cb(std::make_unique<DynarmicCallbacks64>(*this, process)), m_core_index{core_index} {
auto& page_table = process->GetPageTable().GetBasePageTable();
auto& page_table_impl = page_table.GetImpl();
m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth());
+ ScopedJitExecution::RegisterHandler();
}
ArmDynarmic64::~ArmDynarmic64() = default;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 4f3dd026f..08cd982b3 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -25,7 +25,7 @@ class System;
class ArmDynarmic64 final : public ArmInterface {
public:
- ArmDynarmic64(System& system, bool uses_wall_clock, const Kernel::KProcess* process,
+ ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProcess* process,
DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index);
~ArmDynarmic64() override;
diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp
index 1311e66a9..123b3da7e 100644
--- a/src/core/arm/nce/arm_nce.cpp
+++ b/src/core/arm/nce/arm_nce.cpp
@@ -39,7 +39,7 @@ fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
}
using namespace Common::Literals;
-constexpr u32 StackSize = 32_KiB;
+constexpr u32 StackSize = 128_KiB;
} // namespace
diff --git a/src/core/arm/nce/interpreter_visitor.cpp b/src/core/arm/nce/interpreter_visitor.cpp
index 8e81c66a5..def888d15 100644
--- a/src/core/arm/nce/interpreter_visitor.cpp
+++ b/src/core/arm/nce/interpreter_visitor.cpp
@@ -5,8 +5,6 @@
#include "common/bit_cast.h"
#include "core/arm/nce/interpreter_visitor.h"
-#include <dynarmic/frontend/A64/decoder/a64.h>
-
namespace Core {
template <u32 BitSize>
@@ -249,6 +247,7 @@ bool InterpreterVisitor::LDR_lit_fpsimd(Imm<2> opc, Imm<19> imm19, Vec Vt) {
return false;
}
+ // Size in bytes
const u64 size = 4 << opc.ZeroExtend();
const u64 offset = imm19.SignExtend<u64>() << 2;
const u64 address = this->GetPc() + offset;
@@ -530,7 +529,7 @@ bool InterpreterVisitor::SIMDImmediate(bool wback, bool postindex, size_t scale,
}
case MemOp::Load: {
u128 data{};
- m_memory.ReadBlock(address, &data, datasize);
+ m_memory.ReadBlock(address, &data, datasize / 8);
this->SetVec(Vt, data);
break;
}
diff --git a/src/core/arm/nce/visitor_base.h b/src/core/arm/nce/visitor_base.h
index 8fb032912..6a2be3d9b 100644
--- a/src/core/arm/nce/visitor_base.h
+++ b/src/core/arm/nce/visitor_base.h
@@ -4,9 +4,15 @@
#pragma once
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+
#include <dynarmic/frontend/A64/a64_types.h>
+#include <dynarmic/frontend/A64/decoder/a64.h>
#include <dynarmic/frontend/imm.h>
+#pragma GCC diagnostic pop
+
namespace Core {
class VisitorBase {