// HLE JDI. Some commands available only after emulation has been started. #include "pch.h" using namespace Debug; namespace HLE { // Ask the emulator whether it is loaded or not. static bool IsLoaded() { Json::Value* loaded = JDI::Hub.ExecuteFast("IsLoaded"); if (!loaded) return false; bool isLoaded = loaded->value.AsBool; delete loaded; return isLoaded; } static Json::Value* cmd_syms(std::vector& args) { SYMList(args[1].c_str()); return nullptr; } static Json::Value* cmd_name(std::vector& args) { uint32_t address = strtoul(args[1].c_str(), NULL, 0); if (address != 0) { Report(Channel::HLE, "New symbol: %08X %s\n", address, args[2].c_str()); SYMAddNew(address, args[2].c_str()); } else Report(Channel::HLE, "Wrong address!\n"); return nullptr; } static Json::Value* cmd_savemap(std::vector& args) { if (!strcmp(args[1].c_str(), ".")) SaveMAP(nullptr); else SaveMAP(args[1].c_str()); return nullptr; } static Json::Value* DumpThreads(std::vector& args) { if (!IsLoaded()) return nullptr; bool display = true; if (args.size() >= 2) { display = atoi(args[1].c_str()) != 0 ? true : false; } return DumpDolphinOsThreads(display); } static Json::Value* DumpContext(std::vector& args) { if (!IsLoaded()) return nullptr; uint32_t effectiveAddr = strtoul(args[1].c_str(), nullptr, 0); bool display = true; if (args.size() >= 3) { display = atoi(args[2].c_str()) != 0 ? true : false; } return DumpDolphinOsContext(effectiveAddr, display); } static Json::Value* UnloadMap(std::vector& args) { SYMKill(); hle.mapfile[0] = 0; return nullptr; } static Json::Value* LoadMap(std::vector& args) { SYMKill(); hle.mapfile[0] = 0; LoadMAP(args[1].c_str(), false); return nullptr; } static Json::Value* AddMap(std::vector& args) { if (hle.mapfile[0] == 0) { LoadMAP(args[1].c_str(), false); } else { LoadMAP(args[1].c_str(), true); } return nullptr; } static Json::Value* AddressByName(std::vector& args) { uint32_t address; if (IsLoaded()) { address = SYMAddress(args[1].c_str()); } else { address = 0; } Json::Value* output = new Json::Value(); output->type = Json::ValueType::Int; output->value.AsInt = 0; output->value.AsUint32 = address; return output; } static Json::Value* NameByAddress(std::vector& args) { char* name = nullptr; if (IsLoaded()) { name = SYMName(strtoul(args[1].c_str(), nullptr, 0)); } Json::Value* output = new Json::Value(); output->type = Json::ValueType::Array; output->AddAnsiString(nullptr, name ? name : ""); return output; } static Json::Value* OSDateTimeInternal(std::vector& args) { std::string timeStr; if (args.size() > 1) { timeStr = OSTimeFormat(strtoull(args[1].c_str(), nullptr, 0), false); } else { timeStr = OSTimeFormat(Core->GetTicks(), false); } Json::Value* output = new Json::Value(); output->type = Json::ValueType::Array; output->AddAnsiString(nullptr, timeStr.c_str()); return output; } static Json::Value* OSTimeInternal(std::vector& args) { std::string timeStr; if (args.size() > 1) { timeStr = OSTimeFormat(strtoull(args[1].c_str(), nullptr, 0), true); } else { timeStr = OSTimeFormat(Core->GetTicks(), true); } Json::Value* output = new Json::Value(); output->type = Json::ValueType::Array; output->AddAnsiString(nullptr, timeStr.c_str()); return output; } static Json::Value* GetNearestNameInternal(std::vector& args) { uint32_t address = strtoul(args[1].c_str(), nullptr, 0); size_t offset = 0; char* nearestName = SYMGetNearestName(address, offset); if (!nearestName) return nullptr; Json::Value* output = new Json::Value(); output->type = Json::ValueType::Object; output->AddAnsiString("name", nearestName); output->AddInt("offset", (int)offset); return output; } void JdiReflector() { JDI::Hub.AddCmd("syms", cmd_syms); JDI::Hub.AddCmd("name", cmd_name); JDI::Hub.AddCmd("savemap", cmd_savemap); JDI::Hub.AddCmd("DumpThreads", DumpThreads); JDI::Hub.AddCmd("DumpContext", DumpContext); JDI::Hub.AddCmd("UnloadMap", UnloadMap); JDI::Hub.AddCmd("LoadMap", LoadMap); JDI::Hub.AddCmd("AddMap", AddMap); JDI::Hub.AddCmd("AddressByName", AddressByName); JDI::Hub.AddCmd("NameByAddress", NameByAddress); JDI::Hub.AddCmd("OSDateTime", OSDateTimeInternal); JDI::Hub.AddCmd("OSTime", OSTimeInternal); JDI::Hub.AddCmd("GetNearestName", GetNearestNameInternal); } }