diff options
Diffstat (limited to 'src/core/arm/arm_interface.cpp')
| -rw-r--r-- | src/core/arm/arm_interface.cpp | 97 |
1 files changed, 14 insertions, 83 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 08bf1201d..2a9390e26 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp | |||
| @@ -14,96 +14,28 @@ | |||
| 14 | #include "core/loader/loader.h" | 14 | #include "core/loader/loader.h" |
| 15 | #include "core/memory.h" | 15 | #include "core/memory.h" |
| 16 | 16 | ||
| 17 | #include "core/arm/dynarmic/arm_dynarmic_32.h" | ||
| 18 | #include "core/arm/dynarmic/arm_dynarmic_64.h" | ||
| 19 | |||
| 17 | namespace Core { | 20 | namespace Core { |
| 18 | 21 | ||
| 19 | constexpr u64 SEGMENT_BASE = 0x7100000000ull; | 22 | constexpr u64 SEGMENT_BASE = 0x7100000000ull; |
| 20 | 23 | ||
| 21 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( | 24 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( |
| 22 | System& system, const ThreadContext64& ctx) { | 25 | Core::System& system, const ARM_Interface::ThreadContext32& ctx) { |
| 23 | std::vector<BacktraceEntry> out; | 26 | return ARM_Dynarmic_32::GetBacktraceFromContext(system, ctx); |
| 24 | auto& memory = system.Memory(); | ||
| 25 | |||
| 26 | auto fp = ctx.cpu_registers[29]; | ||
| 27 | auto lr = ctx.cpu_registers[30]; | ||
| 28 | while (true) { | ||
| 29 | out.push_back({ | ||
| 30 | .module = "", | ||
| 31 | .address = 0, | ||
| 32 | .original_address = lr, | ||
| 33 | .offset = 0, | ||
| 34 | .name = {}, | ||
| 35 | }); | ||
| 36 | |||
| 37 | if (fp == 0) { | ||
| 38 | break; | ||
| 39 | } | ||
| 40 | |||
| 41 | lr = memory.Read64(fp + 8) - 4; | ||
| 42 | fp = memory.Read64(fp); | ||
| 43 | } | ||
| 44 | |||
| 45 | std::map<VAddr, std::string> modules; | ||
| 46 | auto& loader{system.GetAppLoader()}; | ||
| 47 | if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { | ||
| 48 | return {}; | ||
| 49 | } | ||
| 50 | |||
| 51 | std::map<std::string, Symbols::Symbols> symbols; | ||
| 52 | for (const auto& module : modules) { | ||
| 53 | symbols.insert_or_assign(module.second, | ||
| 54 | Symbols::GetSymbols(module.first, system.Memory(), | ||
| 55 | system.CurrentProcess()->Is64BitProcess())); | ||
| 56 | } | ||
| 57 | |||
| 58 | for (auto& entry : out) { | ||
| 59 | VAddr base = 0; | ||
| 60 | for (auto iter = modules.rbegin(); iter != modules.rend(); ++iter) { | ||
| 61 | const auto& module{*iter}; | ||
| 62 | if (entry.original_address >= module.first) { | ||
| 63 | entry.module = module.second; | ||
| 64 | base = module.first; | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | entry.offset = entry.original_address - base; | ||
| 70 | entry.address = SEGMENT_BASE + entry.offset; | ||
| 71 | |||
| 72 | if (entry.module.empty()) | ||
| 73 | entry.module = "unknown"; | ||
| 74 | |||
| 75 | const auto symbol_set = symbols.find(entry.module); | ||
| 76 | if (symbol_set != symbols.end()) { | ||
| 77 | const auto symbol = Symbols::GetSymbolName(symbol_set->second, entry.offset); | ||
| 78 | if (symbol.has_value()) { | ||
| 79 | // TODO(DarkLordZach): Add demangling of symbol names. | ||
| 80 | entry.name = *symbol; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | return out; | ||
| 86 | } | 27 | } |
| 87 | 28 | ||
| 88 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { | 29 | std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktraceFromContext( |
| 89 | std::vector<BacktraceEntry> out; | 30 | Core::System& system, const ARM_Interface::ThreadContext64& ctx) { |
| 90 | auto& memory = system.Memory(); | 31 | return ARM_Dynarmic_64::GetBacktraceFromContext(system, ctx); |
| 91 | 32 | } | |
| 92 | auto fp = GetReg(29); | ||
| 93 | auto lr = GetReg(30); | ||
| 94 | while (true) { | ||
| 95 | out.push_back({"", 0, lr, 0, ""}); | ||
| 96 | if (!fp) { | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | lr = memory.Read64(fp + 8) - 4; | ||
| 100 | fp = memory.Read64(fp); | ||
| 101 | } | ||
| 102 | 33 | ||
| 34 | void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<BacktraceEntry>& out) { | ||
| 103 | std::map<VAddr, std::string> modules; | 35 | std::map<VAddr, std::string> modules; |
| 104 | auto& loader{system.GetAppLoader()}; | 36 | auto& loader{system.GetAppLoader()}; |
| 105 | if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { | 37 | if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) { |
| 106 | return {}; | 38 | return; |
| 107 | } | 39 | } |
| 108 | 40 | ||
| 109 | std::map<std::string, Symbols::Symbols> symbols; | 41 | std::map<std::string, Symbols::Symbols> symbols; |
| @@ -127,8 +59,9 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { | |||
| 127 | entry.offset = entry.original_address - base; | 59 | entry.offset = entry.original_address - base; |
| 128 | entry.address = SEGMENT_BASE + entry.offset; | 60 | entry.address = SEGMENT_BASE + entry.offset; |
| 129 | 61 | ||
| 130 | if (entry.module.empty()) | 62 | if (entry.module.empty()) { |
| 131 | entry.module = "unknown"; | 63 | entry.module = "unknown"; |
| 64 | } | ||
| 132 | 65 | ||
| 133 | const auto symbol_set = symbols.find(entry.module); | 66 | const auto symbol_set = symbols.find(entry.module); |
| 134 | if (symbol_set != symbols.end()) { | 67 | if (symbol_set != symbols.end()) { |
| @@ -139,12 +72,10 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const { | |||
| 139 | } | 72 | } |
| 140 | } | 73 | } |
| 141 | } | 74 | } |
| 142 | |||
| 143 | return out; | ||
| 144 | } | 75 | } |
| 145 | 76 | ||
| 146 | void ARM_Interface::LogBacktrace() const { | 77 | void ARM_Interface::LogBacktrace() const { |
| 147 | const VAddr sp = GetReg(13); | 78 | const VAddr sp = GetSP(); |
| 148 | const VAddr pc = GetPC(); | 79 | const VAddr pc = GetPC(); |
| 149 | LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc); | 80 | LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc); |
| 150 | LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", | 81 | LOG_ERROR(Core_ARM, "{:20}{:20}{:20}{:20}{}", "Module Name", "Address", "Original Address", |