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.cpp27
-rw-r--r--src/core/arm/arm_interface.h8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp50
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h8
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp16
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h3
6 files changed, 63 insertions, 49 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 372612c9b..7e846ddd5 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -13,7 +13,6 @@
#include "core/memory.h"
namespace Core {
-
namespace {
constexpr u64 ELF_DYNAMIC_TAG_NULL = 0;
@@ -61,15 +60,15 @@ static_assert(sizeof(ELFSymbol) == 0x18, "ELFSymbol has incorrect size.");
using Symbols = std::vector<std::pair<ELFSymbol, std::string>>;
-Symbols GetSymbols(VAddr text_offset) {
- const auto mod_offset = text_offset + Memory::Read32(text_offset + 4);
+Symbols GetSymbols(VAddr text_offset, Memory::Memory& memory) {
+ const auto mod_offset = text_offset + memory.Read32(text_offset + 4);
if (mod_offset < text_offset || (mod_offset & 0b11) != 0 ||
- Memory::Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) {
+ memory.Read32(mod_offset) != Common::MakeMagic('M', 'O', 'D', '0')) {
return {};
}
- const auto dynamic_offset = Memory::Read32(mod_offset + 0x4) + mod_offset;
+ const auto dynamic_offset = memory.Read32(mod_offset + 0x4) + mod_offset;
VAddr string_table_offset{};
VAddr symbol_table_offset{};
@@ -77,8 +76,8 @@ Symbols GetSymbols(VAddr text_offset) {
VAddr dynamic_index = dynamic_offset;
while (true) {
- const auto tag = Memory::Read64(dynamic_index);
- const auto value = Memory::Read64(dynamic_index + 0x8);
+ const u64 tag = memory.Read64(dynamic_index);
+ const u64 value = memory.Read64(dynamic_index + 0x8);
dynamic_index += 0x10;
if (tag == ELF_DYNAMIC_TAG_NULL) {
@@ -106,11 +105,11 @@ Symbols GetSymbols(VAddr text_offset) {
VAddr symbol_index = symbol_table_address;
while (symbol_index < string_table_address) {
ELFSymbol symbol{};
- Memory::ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol));
+ memory.ReadBlock(symbol_index, &symbol, sizeof(ELFSymbol));
VAddr string_offset = string_table_address + symbol.name_index;
std::string name;
- for (u8 c = Memory::Read8(string_offset); c != 0; c = Memory::Read8(++string_offset)) {
+ for (u8 c = memory.Read8(string_offset); c != 0; c = memory.Read8(++string_offset)) {
name += static_cast<char>(c);
}
@@ -142,28 +141,28 @@ constexpr u64 SEGMENT_BASE = 0x7100000000ull;
std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
std::vector<BacktraceEntry> out;
+ auto& memory = system.Memory();
auto fp = GetReg(29);
auto lr = GetReg(30);
-
while (true) {
out.push_back({"", 0, lr, 0});
if (!fp) {
break;
}
- lr = Memory::Read64(fp + 8) - 4;
- fp = Memory::Read64(fp);
+ lr = memory.Read64(fp + 8) - 4;
+ fp = memory.Read64(fp);
}
std::map<VAddr, std::string> modules;
- auto& loader{System::GetInstance().GetAppLoader()};
+ auto& loader{system.GetAppLoader()};
if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) {
return {};
}
std::map<std::string, Symbols> symbols;
for (const auto& module : modules) {
- symbols.insert_or_assign(module.second, GetSymbols(module.first));
+ symbols.insert_or_assign(module.second, GetSymbols(module.first, memory));
}
for (auto& entry : out) {
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 45e94e625..47b964eb7 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -17,11 +17,13 @@ enum class VMAPermission : u8;
}
namespace Core {
+class System;
/// Generic ARMv8 CPU interface
class ARM_Interface : NonCopyable {
public:
- virtual ~ARM_Interface() {}
+ explicit ARM_Interface(System& system_) : system{system_} {}
+ virtual ~ARM_Interface() = default;
struct ThreadContext {
std::array<u64, 31> cpu_registers;
@@ -163,6 +165,10 @@ public:
/// fp+0 : pointer to previous frame record
/// fp+8 : value of lr for frame
void LogBacktrace() const;
+
+protected:
+ /// System context that this ARM interface is running under.
+ System& system;
};
} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 700c4afff..f8c7f0efd 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -28,36 +28,38 @@ public:
explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {}
u8 MemoryRead8(u64 vaddr) override {
- return Memory::Read8(vaddr);
+ return parent.system.Memory().Read8(vaddr);
}
u16 MemoryRead16(u64 vaddr) override {
- return Memory::Read16(vaddr);
+ return parent.system.Memory().Read16(vaddr);
}
u32 MemoryRead32(u64 vaddr) override {
- return Memory::Read32(vaddr);
+ return parent.system.Memory().Read32(vaddr);
}
u64 MemoryRead64(u64 vaddr) override {
- return Memory::Read64(vaddr);
+ return parent.system.Memory().Read64(vaddr);
}
Vector MemoryRead128(u64 vaddr) override {
- return {Memory::Read64(vaddr), Memory::Read64(vaddr + 8)};
+ auto& memory = parent.system.Memory();
+ return {memory.Read64(vaddr), memory.Read64(vaddr + 8)};
}
void MemoryWrite8(u64 vaddr, u8 value) override {
- Memory::Write8(vaddr, value);
+ parent.system.Memory().Write8(vaddr, value);
}
void MemoryWrite16(u64 vaddr, u16 value) override {
- Memory::Write16(vaddr, value);
+ parent.system.Memory().Write16(vaddr, value);
}
void MemoryWrite32(u64 vaddr, u32 value) override {
- Memory::Write32(vaddr, value);
+ parent.system.Memory().Write32(vaddr, value);
}
void MemoryWrite64(u64 vaddr, u64 value) override {
- Memory::Write64(vaddr, value);
+ parent.system.Memory().Write64(vaddr, value);
}
void MemoryWrite128(u64 vaddr, Vector value) override {
- Memory::Write64(vaddr, value[0]);
- Memory::Write64(vaddr + 8, value[1]);
+ auto& memory = parent.system.Memory();
+ memory.Write64(vaddr, value[0]);
+ memory.Write64(vaddr + 8, value[1]);
}
void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
@@ -67,7 +69,7 @@ public:
ARM_Interface::ThreadContext ctx;
parent.SaveContext(ctx);
parent.inner_unicorn.LoadContext(ctx);
- parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions));
+ parent.inner_unicorn.ExecuteInstructions(num_instructions);
parent.inner_unicorn.SaveContext(ctx);
parent.LoadContext(ctx);
num_interpreted_instructions += num_instructions;
@@ -171,9 +173,10 @@ void ARM_Dynarmic::Step() {
ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor,
std::size_t core_index)
- : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
- core_index{core_index}, system{system},
- exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
+ : ARM_Interface{system},
+ cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
+ core_index{core_index}, exclusive_monitor{
+ dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -264,7 +267,9 @@ void ARM_Dynarmic::PageTableChanged(Common::PageTable& page_table,
jit = MakeJit(page_table, new_address_space_size_in_bits);
}
-DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(std::size_t core_count) : monitor(core_count) {}
+DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count)
+ : monitor(core_count), memory{memory_} {}
+
DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
void DynarmicExclusiveMonitor::SetExclusive(std::size_t core_index, VAddr addr) {
@@ -277,29 +282,28 @@ void DynarmicExclusiveMonitor::ClearExclusive() {
}
bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) {
- return monitor.DoExclusiveOperation(core_index, vaddr, 1,
- [&] { Memory::Write8(vaddr, value); });
+ return monitor.DoExclusiveOperation(core_index, vaddr, 1, [&] { memory.Write8(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 2,
- [&] { Memory::Write16(vaddr, value); });
+ [&] { memory.Write16(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite32(std::size_t core_index, VAddr vaddr, u32 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 4,
- [&] { Memory::Write32(vaddr, value); });
+ [&] { memory.Write32(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite64(std::size_t core_index, VAddr vaddr, u64 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 8,
- [&] { Memory::Write64(vaddr, value); });
+ [&] { memory.Write64(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite128(std::size_t core_index, VAddr vaddr, u128 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] {
- Memory::Write64(vaddr + 0, value[0]);
- Memory::Write64(vaddr + 8, value[1]);
+ memory.Write64(vaddr + 0, value[0]);
+ memory.Write64(vaddr + 8, value[1]);
});
}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 504d46c68..9cd475cfb 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -12,6 +12,10 @@
#include "core/arm/exclusive_monitor.h"
#include "core/arm/unicorn/arm_unicorn.h"
+namespace Memory {
+class Memory;
+}
+
namespace Core {
class ARM_Dynarmic_Callbacks;
@@ -58,13 +62,12 @@ private:
ARM_Unicorn inner_unicorn;
std::size_t core_index;
- System& system;
DynarmicExclusiveMonitor& exclusive_monitor;
};
class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
public:
- explicit DynarmicExclusiveMonitor(std::size_t core_count);
+ explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count);
~DynarmicExclusiveMonitor() override;
void SetExclusive(std::size_t core_index, VAddr addr) override;
@@ -79,6 +82,7 @@ public:
private:
friend class ARM_Dynarmic;
Dynarmic::A64::ExclusiveMonitor monitor;
+ Memory::Memory& memory;
};
} // namespace Core
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index d4f41bfc1..48182c99a 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -60,17 +60,18 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
return false;
}
-ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {
+ARM_Unicorn::ARM_Unicorn(System& system) : ARM_Interface{system} {
CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
auto fpv = 3 << 20;
CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv));
uc_hook hook{};
- CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1));
- CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, -1));
+ CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, UINT64_MAX));
+ CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0,
+ UINT64_MAX));
if (GDBStub::IsServerEnabled()) {
- CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1));
+ CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, UINT64_MAX));
last_bkpt_hit = false;
}
}
@@ -154,9 +155,10 @@ void ARM_Unicorn::SetTPIDR_EL0(u64 value) {
void ARM_Unicorn::Run() {
if (GDBStub::IsServerEnabled()) {
- ExecuteInstructions(std::max(4000000, 0));
+ ExecuteInstructions(std::max(4000000U, 0U));
} else {
- ExecuteInstructions(std::max(system.CoreTiming().GetDowncount(), s64{0}));
+ ExecuteInstructions(
+ std::max(std::size_t(system.CoreTiming().GetDowncount()), std::size_t{0}));
}
}
@@ -166,7 +168,7 @@ void ARM_Unicorn::Step() {
MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));
-void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
+void ARM_Unicorn::ExecuteInstructions(std::size_t num_instructions) {
MICROPROFILE_SCOPE(ARM_Jit_Unicorn);
CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
system.CoreTiming().AddTicks(num_instructions);
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index fe2ffd70c..3c5b155f9 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -34,7 +34,7 @@ public:
void LoadContext(const ThreadContext& ctx) override;
void PrepareReschedule() override;
void ClearExclusiveState() override;
- void ExecuteInstructions(int num_instructions);
+ void ExecuteInstructions(std::size_t num_instructions);
void Run() override;
void Step() override;
void ClearInstructionCache() override;
@@ -45,7 +45,6 @@ private:
static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
uc_engine* uc{};
- System& system;
GDBStub::BreakpointAddress last_bkpt{};
bool last_bkpt_hit = false;
};