debug.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/demangle.h"
  4. #include "core/arm/debug.h"
  5. #include "core/arm/symbols.h"
  6. #include "core/hle/kernel/k_process.h"
  7. #include "core/hle/kernel/k_thread.h"
  8. #include "core/memory.h"
  9. namespace Core {
  10. namespace {
  11. std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory,
  12. const Kernel::KThread& thread) {
  13. // Read thread type from TLS
  14. const VAddr tls_thread_type{memory.Read64(thread.GetTlsAddress() + 0x1f8)};
  15. const VAddr argument_thread_type{thread.GetArgument()};
  16. if (argument_thread_type && tls_thread_type != argument_thread_type) {
  17. // Probably not created by nnsdk, no name available.
  18. return std::nullopt;
  19. }
  20. if (!tls_thread_type) {
  21. return std::nullopt;
  22. }
  23. const u16 version{memory.Read16(tls_thread_type + 0x46)};
  24. VAddr name_pointer{};
  25. if (version == 1) {
  26. name_pointer = memory.Read64(tls_thread_type + 0x1a0);
  27. } else {
  28. name_pointer = memory.Read64(tls_thread_type + 0x1a8);
  29. }
  30. if (!name_pointer) {
  31. // No name provided.
  32. return std::nullopt;
  33. }
  34. return memory.ReadCString(name_pointer, 256);
  35. }
  36. std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory,
  37. const Kernel::KThread& thread) {
  38. // Read thread type from TLS
  39. const VAddr tls_thread_type{memory.Read32(thread.GetTlsAddress() + 0x1fc)};
  40. const VAddr argument_thread_type{thread.GetArgument()};
  41. if (argument_thread_type && tls_thread_type != argument_thread_type) {
  42. // Probably not created by nnsdk, no name available.
  43. return std::nullopt;
  44. }
  45. if (!tls_thread_type) {
  46. return std::nullopt;
  47. }
  48. const u16 version{memory.Read16(tls_thread_type + 0x26)};
  49. VAddr name_pointer{};
  50. if (version == 1) {
  51. name_pointer = memory.Read32(tls_thread_type + 0xe4);
  52. } else {
  53. name_pointer = memory.Read32(tls_thread_type + 0xe8);
  54. }
  55. if (!name_pointer) {
  56. // No name provided.
  57. return std::nullopt;
  58. }
  59. return memory.ReadCString(name_pointer, 256);
  60. }
  61. constexpr std::array<u64, 2> SegmentBases{
  62. 0x60000000ULL,
  63. 0x7100000000ULL,
  64. };
  65. void SymbolicateBacktrace(Kernel::KProcess* process, std::vector<BacktraceEntry>& out) {
  66. auto modules = FindModules(process);
  67. const bool is_64 = process->Is64Bit();
  68. std::map<std::string, Symbols::Symbols> symbols;
  69. for (const auto& module : modules) {
  70. symbols.insert_or_assign(module.second,
  71. Symbols::GetSymbols(module.first, process->GetMemory(), is_64));
  72. }
  73. for (auto& entry : out) {
  74. VAddr base = 0;
  75. for (auto iter = modules.rbegin(); iter != modules.rend(); ++iter) {
  76. const auto& module{*iter};
  77. if (entry.original_address >= module.first) {
  78. entry.module = module.second;
  79. base = module.first;
  80. break;
  81. }
  82. }
  83. entry.offset = entry.original_address - base;
  84. entry.address = SegmentBases[is_64] + entry.offset;
  85. if (entry.module.empty()) {
  86. entry.module = "unknown";
  87. }
  88. const auto symbol_set = symbols.find(entry.module);
  89. if (symbol_set != symbols.end()) {
  90. const auto symbol = Symbols::GetSymbolName(symbol_set->second, entry.offset);
  91. if (symbol) {
  92. entry.name = Common::DemangleSymbol(*symbol);
  93. }
  94. }
  95. }
  96. }
  97. std::vector<BacktraceEntry> GetAArch64Backtrace(Kernel::KProcess* process,
  98. const Kernel::Svc::ThreadContext& ctx) {
  99. std::vector<BacktraceEntry> out;
  100. auto& memory = process->GetMemory();
  101. auto pc = ctx.pc, lr = ctx.lr, fp = ctx.fp;
  102. out.push_back({"", 0, pc, 0, ""});
  103. // fp (= x29) points to the previous frame record.
  104. // Frame records are two words long:
  105. // fp+0 : pointer to previous frame record
  106. // fp+8 : value of lr for frame
  107. for (size_t i = 0; i < 256; i++) {
  108. out.push_back({"", 0, lr, 0, ""});
  109. if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) {
  110. break;
  111. }
  112. lr = memory.Read64(fp + 8);
  113. fp = memory.Read64(fp);
  114. }
  115. SymbolicateBacktrace(process, out);
  116. return out;
  117. }
  118. std::vector<BacktraceEntry> GetAArch32Backtrace(Kernel::KProcess* process,
  119. const Kernel::Svc::ThreadContext& ctx) {
  120. std::vector<BacktraceEntry> out;
  121. auto& memory = process->GetMemory();
  122. auto pc = ctx.pc, lr = ctx.lr, fp = ctx.fp;
  123. out.push_back({"", 0, pc, 0, ""});
  124. // fp (= r11) points to the last frame record.
  125. // Frame records are two words long:
  126. // fp+0 : pointer to previous frame record
  127. // fp+4 : value of lr for frame
  128. for (size_t i = 0; i < 256; i++) {
  129. out.push_back({"", 0, lr, 0, ""});
  130. if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) {
  131. break;
  132. }
  133. lr = memory.Read32(fp + 4);
  134. fp = memory.Read32(fp);
  135. }
  136. SymbolicateBacktrace(process, out);
  137. return out;
  138. }
  139. } // namespace
  140. std::optional<std::string> GetThreadName(const Kernel::KThread* thread) {
  141. auto* process = thread->GetOwnerProcess();
  142. if (process->Is64Bit()) {
  143. return GetNameFromThreadType64(process->GetMemory(), *thread);
  144. } else {
  145. return GetNameFromThreadType32(process->GetMemory(), *thread);
  146. }
  147. }
  148. std::string_view GetThreadWaitReason(const Kernel::KThread* thread) {
  149. switch (thread->GetWaitReasonForDebugging()) {
  150. case Kernel::ThreadWaitReasonForDebugging::Sleep:
  151. return "Sleep";
  152. case Kernel::ThreadWaitReasonForDebugging::IPC:
  153. return "IPC";
  154. case Kernel::ThreadWaitReasonForDebugging::Synchronization:
  155. return "Synchronization";
  156. case Kernel::ThreadWaitReasonForDebugging::ConditionVar:
  157. return "ConditionVar";
  158. case Kernel::ThreadWaitReasonForDebugging::Arbitration:
  159. return "Arbitration";
  160. case Kernel::ThreadWaitReasonForDebugging::Suspended:
  161. return "Suspended";
  162. default:
  163. return "Unknown";
  164. }
  165. }
  166. std::string GetThreadState(const Kernel::KThread* thread) {
  167. switch (thread->GetState()) {
  168. case Kernel::ThreadState::Initialized:
  169. return "Initialized";
  170. case Kernel::ThreadState::Waiting:
  171. return fmt::format("Waiting ({})", GetThreadWaitReason(thread));
  172. case Kernel::ThreadState::Runnable:
  173. return "Runnable";
  174. case Kernel::ThreadState::Terminated:
  175. return "Terminated";
  176. default:
  177. return "Unknown";
  178. }
  179. }
  180. Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process,
  181. Kernel::KProcessAddress base) {
  182. Kernel::KMemoryInfo mem_info;
  183. Kernel::Svc::MemoryInfo svc_mem_info;
  184. Kernel::Svc::PageInfo page_info;
  185. VAddr cur_addr{GetInteger(base)};
  186. auto& page_table = process->GetPageTable();
  187. // Expect: r-x Code (.text)
  188. R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
  189. svc_mem_info = mem_info.GetSvcMemoryInfo();
  190. cur_addr = svc_mem_info.base_address + svc_mem_info.size;
  191. if (svc_mem_info.state != Kernel::Svc::MemoryState::Code ||
  192. svc_mem_info.permission != Kernel::Svc::MemoryPermission::ReadExecute) {
  193. return cur_addr - 1;
  194. }
  195. // Expect: r-- Code (.rodata)
  196. R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
  197. svc_mem_info = mem_info.GetSvcMemoryInfo();
  198. cur_addr = svc_mem_info.base_address + svc_mem_info.size;
  199. if (svc_mem_info.state != Kernel::Svc::MemoryState::Code ||
  200. svc_mem_info.permission != Kernel::Svc::MemoryPermission::Read) {
  201. return cur_addr - 1;
  202. }
  203. // Expect: rw- CodeData (.data)
  204. R_ASSERT(page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
  205. svc_mem_info = mem_info.GetSvcMemoryInfo();
  206. cur_addr = svc_mem_info.base_address + svc_mem_info.size;
  207. return cur_addr - 1;
  208. }
  209. Loader::AppLoader::Modules FindModules(Kernel::KProcess* process) {
  210. Loader::AppLoader::Modules modules;
  211. auto& page_table = process->GetPageTable();
  212. auto& memory = process->GetMemory();
  213. VAddr cur_addr = 0;
  214. // Look for executable sections in Code or AliasCode regions.
  215. while (true) {
  216. Kernel::KMemoryInfo mem_info{};
  217. Kernel::Svc::PageInfo page_info{};
  218. R_ASSERT(
  219. page_table.QueryInfo(std::addressof(mem_info), std::addressof(page_info), cur_addr));
  220. auto svc_mem_info = mem_info.GetSvcMemoryInfo();
  221. if (svc_mem_info.permission == Kernel::Svc::MemoryPermission::ReadExecute &&
  222. (svc_mem_info.state == Kernel::Svc::MemoryState::Code ||
  223. svc_mem_info.state == Kernel::Svc::MemoryState::AliasCode)) {
  224. // Try to read the module name from its path.
  225. constexpr s32 PathLengthMax = 0x200;
  226. struct {
  227. u32 zero;
  228. s32 path_length;
  229. std::array<char, PathLengthMax> path;
  230. } module_path;
  231. if (memory.ReadBlock(svc_mem_info.base_address + svc_mem_info.size, &module_path,
  232. sizeof(module_path))) {
  233. if (module_path.zero == 0 && module_path.path_length > 0) {
  234. // Truncate module name.
  235. module_path.path[PathLengthMax - 1] = '\0';
  236. // Ignore leading directories.
  237. char* path_pointer = module_path.path.data();
  238. char* path_end =
  239. path_pointer + std::min(PathLengthMax, module_path.path_length);
  240. for (s32 i = 0; i < std::min(PathLengthMax, module_path.path_length) &&
  241. module_path.path[i] != '\0';
  242. i++) {
  243. if (module_path.path[i] == '/' || module_path.path[i] == '\\') {
  244. path_pointer = module_path.path.data() + i + 1;
  245. }
  246. }
  247. // Insert output.
  248. modules.emplace(svc_mem_info.base_address,
  249. std::string_view(path_pointer, path_end));
  250. }
  251. }
  252. }
  253. // Check if we're done.
  254. const uintptr_t next_address = svc_mem_info.base_address + svc_mem_info.size;
  255. if (next_address <= cur_addr) {
  256. break;
  257. }
  258. cur_addr = next_address;
  259. }
  260. return modules;
  261. }
  262. Kernel::KProcessAddress FindMainModuleEntrypoint(Kernel::KProcess* process) {
  263. // Do we have any loaded executable sections?
  264. auto modules = FindModules(process);
  265. if (modules.size() >= 2) {
  266. // If we have two or more, the first one is rtld and the second is main.
  267. return std::next(modules.begin())->first;
  268. } else if (!modules.empty()) {
  269. // If we only have one, this is the main module.
  270. return modules.begin()->first;
  271. }
  272. // As a last resort, use the start of the code region.
  273. return GetInteger(process->GetPageTable().GetCodeRegionStart());
  274. }
  275. void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 address, u64 size) {
  276. for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
  277. auto* interface = process->GetArmInterface(i);
  278. if (interface) {
  279. interface->InvalidateCacheRange(address, size);
  280. }
  281. }
  282. }
  283. std::vector<BacktraceEntry> GetBacktraceFromContext(Kernel::KProcess* process,
  284. const Kernel::Svc::ThreadContext& ctx) {
  285. if (process->Is64Bit()) {
  286. return GetAArch64Backtrace(process, ctx);
  287. } else {
  288. return GetAArch32Backtrace(process, ctx);
  289. }
  290. }
  291. std::vector<BacktraceEntry> GetBacktrace(const Kernel::KThread* thread) {
  292. Kernel::Svc::ThreadContext ctx = thread->GetContext();
  293. return GetBacktraceFromContext(thread->GetOwnerProcess(), ctx);
  294. }
  295. } // namespace Core