From 091731f1caf81ab689f601beb1e837d35845face Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Tue, 31 Aug 2021 18:32:45 -0400 Subject: [PATCH] try to find structures (#797) --- tools/MemoryDumpTool/main.cpp | 82 ++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/tools/MemoryDumpTool/main.cpp b/tools/MemoryDumpTool/main.cpp index b462391207..df96ac6d87 100644 --- a/tools/MemoryDumpTool/main.cpp +++ b/tools/MemoryDumpTool/main.cpp @@ -234,6 +234,80 @@ void inspect_process_self(const Ram& ram, } } +void follow_references_to_find_pointers( + const Ram& ram, + const TypeSystem& type_system, + std::unordered_map>& basics_in, + u32 st_addr) { + // all the objects. + std::unordered_map> found; + // things to check. + std::vector> stack; + + // insert the basics + for (auto& kv : basics_in) { + for (auto addr : kv.second) { + found[kv.first].insert(addr); + stack.push_back({kv.first, addr}); + } + } + + // dfs + while (!stack.empty()) { + auto to_check = stack.back(); + stack.pop_back(); + + if (type_system.fully_defined_type_exists(to_check.first)) { + auto type_info = dynamic_cast(type_system.lookup_type(to_check.first)); + assert(type_info); + for (auto& field : type_info->fields()) { + if (type_system.fully_defined_type_exists(field.type())) { + auto field_info = type_system.lookup_type(field.type()); + auto field_as_structure = dynamic_cast(field_info); + auto field_as_basic = dynamic_cast(field_info); + if (field_as_structure && !field_as_basic) { + u32 field_address = to_check.second + field.offset(); + if (field.is_inline()) { + if (ram.word_in_memory(field_address) && field_address > st_addr) { + if (found[field.type().base_type()].insert(field_address).second) { + // fmt::print("In type {} field {} (inline), found an {} at {} {}\n", + // to_check.first, + // field.name(), field.type().print(), field_address, + // field_address & 0xf); + stack.push_back({field.type().base_type(), field_address}); + } + } + + } else { + if (ram.word_in_memory(field_address)) { + u32 field_value = ram.word(field_address); + if (ram.word_in_memory(field_value) && field_value > st_addr) { + if (found[field.type().base_type()].insert(field_value).second) { + // fmt::print("In type {} field {}, found an {} at {} {}\n", to_check.first, + // field.name(), field.type().print(), field_value, field_value & + // 0xf); + stack.push_back({field.type().base_type(), field_value}); + } + } + } + } + } + } + } + } + } + + int total_found = 0; + for (const auto& kv : found) { + for (auto addr : kv.second) { + basics_in[kv.first].push_back(addr); + total_found++; + } + } + + fmt::print("Following points found {} objects.\n", total_found++); +} + void inspect_basics(const Ram& ram, const std::unordered_map>& basics, const std::unordered_map& types, @@ -271,7 +345,7 @@ void inspect_basics(const Ram& ram, continue; } - auto type = dynamic_cast(type_system.lookup_type(name)); + auto type = dynamic_cast(type_system.lookup_type(name)); if (!type) { fmt::print("Could not cast Type! Skipping!!\n"); type_results["__metadata"]["failedToCast?"] = true; @@ -279,6 +353,10 @@ void inspect_basics(const Ram& ram, continue; } + if (!dynamic_cast(type)) { + fmt::print("NOTE: Not a basic.\n"); + } + for (auto& field : type->fields()) { if (!field.is_inline() && !field.is_dynamic() && (field.type() == TypeSpec("basic") || field.type() == TypeSpec("object") || @@ -482,6 +560,8 @@ int main(int argc, char** argv) { auto types = build_type_map(ram, symbol_map, s7); auto basics = find_basics(ram, types); + follow_references_to_find_pointers(ram, dts.ts, basics, s7 + 0x100); + inspect_basics(ram, basics, types, symbol_map, dts.ts, results); inspect_symbols(ram, types, symbol_map); inspect_process_self(ram, basics, types, dts.ts);