[memdump] Make it work on fields of type (array basic) (#620)

* use `std::function` for this because that's what you're meant to do

* [memdump] Analyze fields of type `(array basic)`

* fix test

* Massively simplify things.
This commit is contained in:
ManDude 2021-06-24 03:07:17 +01:00 committed by GitHub
parent fc105e1f55
commit 997d5b57db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 47 deletions

View file

@ -4070,7 +4070,7 @@
(deftype load-dir-art-group (load-dir)
()
:flag-assert #xb00000010
(:methods
(:methods
(new (symbol type int basic) _type_ 0)
)
)
@ -4520,7 +4520,7 @@
(dummy-25 () none 25)
(dummy-26 () none 26)
(dummy-27 () none 27)
(dummy-28 () none 28)
(dummy-28 (_type_ string) symbol 28)
)
)
@ -4563,7 +4563,7 @@
(dummy-18 (_type_ symbol) none 18)
(dummy-19 (_type_ pair) none 19)
(dummy-20 () none 20)
(dummy-21 () none 21)
(dummy-21 (_type_ level-group int) pair 21)
(dummy-22 () none 22)
(dummy-23 () none 23)
(dummy-24 () none 24)

View file

@ -4,6 +4,7 @@
*/
#include "gfx.h"
#include <functional>
#include "common/log/log.h"
#include "game/runtime.h"
#include "display.h"
@ -35,6 +36,30 @@ u32 Init() {
return 0;
}
void Loop(std::function<bool()> f) {
while (f()) {
// run display-specific things
if (Display::display) {
// lg::debug("run display");
glfwMakeContextCurrent(Display::display);
// render graphics
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(Display::display);
// poll events TODO integrate input with cpad
glfwPollEvents();
// exit if display window was closed
if (glfwWindowShouldClose(Display::display)) {
// Display::KillDisplay(Display::display);
MasterExit = 1;
}
}
}
}
u32 Exit() {
lg::debug("gfx exit");
Display::KillDisplay(Display::display);

View file

@ -8,6 +8,7 @@
#ifndef RUNTIME_GFX_H
#define RUNTIME_GFX_H
#include <functional>
#include "common/common_types.h"
#include "display.h"
#include "game/kernel/kboot.h"
@ -15,33 +16,9 @@
namespace Gfx {
u32 Init();
void Loop(std::function<bool()> f);
u32 Exit();
template <typename T>
void Loop(T f) {
while (f()) {
// run display-specific things
if (Display::display) {
// lg::debug("run display");
glfwMakeContextCurrent(Display::display);
// render graphics
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(Display::display);
// poll events TODO integrate input with cpad
glfwPollEvents();
// exit if display window was closed
if (glfwWindowShouldClose(Display::display)) {
// Display::KillDisplay(Display::display);
MasterExit = 1;
}
}
}
}
} // namespace Gfx
#endif // RUNTIME_GFX_H

View file

@ -320,7 +320,7 @@ u32 exec_runtime(int argc, char** argv) {
// TODO also sync this up with how the game actually renders things (this is just a placeholder)
if (enable_display) {
Gfx::Init();
Gfx::Loop([&tm] { return !tm.all_threads_exiting(); });
Gfx::Loop([&tm]() { return !tm.all_threads_exiting(); });
Gfx::Exit();
}

View file

@ -159,7 +159,7 @@
(dummy-25 () none 25)
(dummy-26 () none 26)
(dummy-27 () none 27)
(dummy-28 () none 28)
(dummy-28 (_type_ string) symbol 28)
)
)
@ -207,7 +207,7 @@
(dummy-18 (_type_ symbol) none 18)
(dummy-19 (_type_ pair) none 19)
(dummy-20 () none 20)
(dummy-21 () none 21)
(dummy-21 (_type_ level-group int) pair 21)
(dummy-22 () none 22)
(dummy-23 () none 23)
(dummy-24 () none 24)

View file

@ -225,7 +225,7 @@ void inspect_basics(const Ram& ram,
auto type = dynamic_cast<BasicType*>(type_system.lookup_type(name));
if (!type) {
fmt::print("Could not cast Type! Skipping!!");
fmt::print("Could not cast Type! Skipping!!\n");
type_results["__metadata"]["failedToCast?"] = true;
results[name] = type_results;
continue;
@ -234,7 +234,8 @@ void inspect_basics(const Ram& ram,
for (auto& field : type->fields()) {
if (!field.is_inline() && !field.is_dynamic() &&
(field.type() == TypeSpec("basic") || field.type() == TypeSpec("object") ||
field.type() == TypeSpec("uint32"))) {
field.type() == TypeSpec("uint32") ||
field.type() == TypeSpec("array", {TypeSpec("basic")}))) {
int array_size = field.is_array() ? field.array_size() : 1;
fmt::print(" field {}\n", field.name());
@ -245,34 +246,60 @@ void inspect_basics(const Ram& ram,
field_results = {};
}
bool goal_array = field.type() == TypeSpec("array", {TypeSpec("basic")});
std::unordered_map<std::string, int> type_frequency;
int array_max_elts = 0;
for (auto base_addr : basics.at(name)) {
for (int elt_idx = 0; elt_idx < array_size; elt_idx++) {
int field_addr = base_addr + field.offset() + 4 * elt_idx;
if (ram.word_in_memory(field_addr)) {
auto field_val = ram.word(field_addr);
if ((field_val & 0x7) == 4 && ram.word_in_memory(field_val - 4)) {
auto type_tag = ram.word(field_val - 4);
auto iter = types.find(type_tag);
if (iter != types.end()) {
if (iter->second == "symbol") {
auto sym_iter = symbols.addr_to_name.find(field_val);
if (sym_iter != symbols.addr_to_name.end()) {
type_frequency[fmt::format("(symbol {})", sym_iter->second)]++;
auto array_addr = field_val;
int goal_array_length = 1;
if (goal_array) {
if (ram.word_in_memory(field_val)) {
goal_array_length = ram.word(field_val);
} else {
array_addr = 0xBAADBEEF;
}
}
for (int arr_idx = 0; arr_idx < goal_array_length; ++arr_idx) {
if (goal_array) {
field_val = array_addr + 12 + arr_idx * 4;
if (ram.word_in_memory(field_val)) {
field_val = ram.word(field_val);
} else {
field_val = 0xBAADBEEF;
}
}
if ((field_val & 0x7) == 4 && ram.word_in_memory(field_val - 4)) {
auto type_tag = ram.word(field_val - 4);
auto iter = types.find(type_tag);
if (iter != types.end()) {
if (iter->second == "symbol") {
auto sym_iter = symbols.addr_to_name.find(field_val);
if (sym_iter != symbols.addr_to_name.end()) {
type_frequency[fmt::format("(symbol {})", sym_iter->second)]++;
} else {
type_frequency[iter->second]++;
}
} else {
type_frequency[iter->second]++;
}
} else {
type_frequency[iter->second]++;
type_frequency["_bad-type"]++;
}
} else if (field_val == 0) {
type_frequency["0"]++;
} else {
type_frequency["_bad-type"]++;
type_frequency["_not-basic-ptr"]++;
}
} else if (field_val == 0) {
type_frequency["0"]++;
} else {
type_frequency["_not-basic-ptr"]++;
if (!goal_array)
break;
}
} else {
type_frequency["_bad-field-memory"]++;