Add "plugins details" command

This commit is contained in:
Maschell
2026-02-16 17:09:44 +01:00
parent e1efc665ca
commit ace0b9a0b3
9 changed files with 513 additions and 6 deletions

View File

@@ -1,8 +1,14 @@
#include "ShellCommands.h"
#include "globals.h"
#include "plugin/ButtonComboManager.h"
#include "plugin/FunctionData.h"
#include "plugin/HookData.h"
#include "plugin/PluginContainer.h"
#include "plugin/PluginData.h"
#include "plugin/SectionInfo.h"
#include "utils/StringTools.h"
#include "utils/utils.h"
#include <iopshell/api.h>
@@ -11,7 +17,327 @@
#include <memory>
#include <numeric>
#include <optional>
#include <zconf.h>
namespace {
std::string toString(WUPSButtonCombo_ComboType type) {
switch (type) {
case WUPS_BUTTON_COMBO_COMBO_TYPE_INVALID:
return "Invalid";
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD:
return "Hold";
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD_OBSERVER:
return "Hold (Observer)";
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN:
return "Press Down";
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN_OBSERVER:
return "Press Down (Observer)";
}
return "invalid";
}
std::string toString(WUPSButtonCombo_ComboStatus type) {
switch (type) {
case WUPS_BUTTON_COMBO_COMBO_STATUS_INVALID_STATUS:
return "Invalid";
case WUPS_BUTTON_COMBO_COMBO_STATUS_VALID:
return "Valid";
case WUPS_BUTTON_COMBO_COMBO_STATUS_CONFLICT:
return "Conflict";
}
return "Invalid";
}
std::string toString(const function_replacement_library_type_t type) {
switch (type) {
case LIBRARY_AVM:
return "AVM";
case LIBRARY_CAMERA:
return "CAMERA";
case LIBRARY_COREINIT:
return "COREINIT";
case LIBRARY_DC:
return "DC";
case LIBRARY_DMAE:
return "DMAE";
case LIBRARY_DRMAPP:
return "DRMAPP";
case LIBRARY_ERREULA:
return "ERREULA";
case LIBRARY_GX2:
return "GX2";
case LIBRARY_H264:
return "H264";
case LIBRARY_LZMA920:
return "LZMA920";
case LIBRARY_MIC:
return "MIC";
case LIBRARY_NFC:
return "NFC";
case LIBRARY_NIO_PROF:
return "NIO_PROF";
case LIBRARY_NLIBCURL:
return "NLIBCURL";
case LIBRARY_NLIBNSS:
return "NLIBNSS";
case LIBRARY_NLIBNSS2:
return "NLIBNSS2";
case LIBRARY_NN_AC:
return "NN_AC";
case LIBRARY_NN_ACP:
return "NN_ACP";
case LIBRARY_NN_ACT:
return "NN_ACT";
case LIBRARY_NN_AOC:
return "NN_AOC";
case LIBRARY_NN_BOSS:
return "NN_BOSS";
case LIBRARY_NN_CCR:
return "NN_CCR";
case LIBRARY_NN_CMPT:
return "NN_CMPT";
case LIBRARY_NN_DLP:
return "NN_DLP";
case LIBRARY_NN_EC:
return "NN_EC";
case LIBRARY_NN_FP:
return "NN_FP";
case LIBRARY_NN_HAI:
return "NN_HAI";
case LIBRARY_NN_HPAD:
return "NN_HPAD";
case LIBRARY_NN_IDBE:
return "NN_IDBE";
case LIBRARY_NN_NDM:
return "NN_NDM";
case LIBRARY_NN_NETS2:
return "NN_NETS2";
case LIBRARY_NN_NFP:
return "NN_NFP";
case LIBRARY_NN_NIM:
return "NN_NIM";
case LIBRARY_NN_OLV:
return "NN_OLV";
case LIBRARY_NN_PDM:
return "NN_PDM";
case LIBRARY_NN_SAVE:
return "NN_SAVE";
case LIBRARY_NN_SL:
return "NN_SL";
case LIBRARY_NN_SPM:
return "NN_SPM";
case LIBRARY_NN_TEMP:
return "NN_TEMP";
case LIBRARY_NN_UDS:
return "NN_UDS";
case LIBRARY_NN_VCTL:
return "NN_VCTL";
case LIBRARY_NSYSCCR:
return "NSYSCCR";
case LIBRARY_NSYSHID:
return "NSYSHID";
case LIBRARY_NSYSKBD:
return "NSYSKBD";
case LIBRARY_NSYSNET:
return "NSYSNET";
case LIBRARY_NSYSUHS:
return "NSYSUHS";
case LIBRARY_NSYSUVD:
return "NSYSUVD";
case LIBRARY_NTAG:
return "NTAG";
case LIBRARY_PADSCORE:
return "PADSCORE";
case LIBRARY_PROC_UI:
return "PROC_UI";
case LIBRARY_SND_CORE:
return "SND_CORE";
case LIBRARY_SND_USER:
return "SND_USER";
case LIBRARY_SNDCORE2:
return "SNDCORE2";
case LIBRARY_SNDUSER2:
return "SNDUSER2";
case LIBRARY_SWKBD:
return "SWKBD";
case LIBRARY_SYSAPP:
return "SYSAPP";
case LIBRARY_TCL:
return "TCL";
case LIBRARY_TVE:
return "TVE";
case LIBRARY_UAC:
return "UAC";
case LIBRARY_UAC_RPL:
return "UAC_RPL";
case LIBRARY_USB_MIC:
return "USB_MIC";
case LIBRARY_UVC:
return "UVC";
case LIBRARY_UVD:
return "UVD";
case LIBRARY_VPAD:
return "VPAD";
case LIBRARY_VPADBASE:
return "VPADBASE";
case LIBRARY_ZLIB125:
return "ZLIB125";
case LIBRARY_OTHER:
return "OTHER";
}
return "OTHER";
}
const char *getButtonChar(const WUPSButtonCombo_Buttons value) {
std::string combo;
if (value & WUPS_BUTTON_COMBO_BUTTON_A) {
return "A";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_B) {
return "B";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_X) {
return "X";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_Y) {
return "Y";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_L) {
return "L";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_R) {
return "R";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_ZL) {
return "ZL";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_ZR) {
return "ZR";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_UP) {
return "UP";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_DOWN) {
return "DOWN";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_LEFT) {
return "LEFT";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_RIGHT) {
return "RIGHT";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_STICK_L) {
return "STICK-L";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_STICK_R) {
return "STICK-R";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_PLUS) {
return "PLUS";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_MINUS) {
return "MINUS";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_TV) {
return "TV";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_RESERVED_BIT) {
return "RESERVED-BIT";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_1) {
return "1";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_2) {
return "2";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_C) {
return "C";
}
if (value & WUPS_BUTTON_COMBO_BUTTON_Z) {
return "Z";
}
return "";
}
std::string getComboAsString(const uint32_t value) {
char comboString[60] = {};
for (uint32_t i = 0; i < 32; i++) {
uint32_t bitMask = 1 << i;
if (value & bitMask) {
auto val = getButtonChar(static_cast<WUPSButtonCombo_Buttons>(bitMask));
if (val[0] != '\0') {
strcat(comboString, val);
strcat(comboString, "+");
}
}
}
std::string res(comboString);
if (res.ends_with("+")) {
res.pop_back();
}
return res;
}
std::string getMaskAsString(WUPSButtonCombo_ControllerTypes controller_mask) {
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_NONE) {
return "NONE";
}
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_ALL) {
return "ALL";
}
// Optional: Check strictly for full groups if you prefer that over listing individual bits
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_VPAD) {
return "VPAD (All)";
}
if (controller_mask == WUPS_BUTTON_COMBO_CONTROLLER_WPAD) {
return "WPAD (All)";
}
std::vector<std::string> parts;
// VPADs
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_VPAD_0) parts.emplace_back("VPAD_0");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_VPAD_1) parts.emplace_back("VPAD_1");
// WPADs
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_0) parts.emplace_back("WPAD_0");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_1) parts.emplace_back("WPAD_1");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_2) parts.emplace_back("WPAD_2");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_3) parts.emplace_back("WPAD_3");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_4) parts.emplace_back("WPAD_4");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_5) parts.emplace_back("WPAD_5");
if (controller_mask & WUPS_BUTTON_COMBO_CONTROLLER_WPAD_6) parts.emplace_back("WPAD_6");
if (parts.empty()) {
return "UNKNOWN";
}
std::string result;
for (size_t i = 0; i < parts.size(); ++i) {
if (i > 0) {
result += " | ";
}
result += parts[i];
}
return result;
}
bool isHoldCombo(WUPSButtonCombo_ComboType type) {
switch (type) {
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD:
case WUPS_BUTTON_COMBO_COMBO_TYPE_HOLD_OBSERVER:
return true;
case WUPS_BUTTON_COMBO_COMBO_TYPE_INVALID:
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN:
case WUPS_BUTTON_COMBO_COMBO_TYPE_PRESS_DOWN_OBSERVER:
return false;
}
return false;
}
} // namespace
namespace ShellCommands {
namespace {
class ConsoleTable {
@@ -164,7 +490,6 @@ namespace ShellCommands {
table.Print();
}
void ListPlugins(int argc, char **argv) {
bool showAll = false;
if (argc > 1 && (std::string_view(argv[1]) == "-a" || std::string_view(argv[1]) == "--all")) {
@@ -173,7 +498,7 @@ namespace ShellCommands {
ConsoleTable table;
// Define Columns
table.AddColumn("Index", ConsoleTable::LEFT);
table.AddColumn("Name", ConsoleTable::LEFT);
table.AddColumn("Author", ConsoleTable::LEFT);
table.AddColumn("Version", ConsoleTable::LEFT);
@@ -184,13 +509,15 @@ namespace ShellCommands {
table.AddColumn("Memory footprint", ConsoleTable::RIGHT);
table.AddColumn("Heap usage", ConsoleTable::RIGHT);
uint32_t totalSizeOther = 0;
uint32_t id = 0;
for (const auto &plugin : gLoadedPlugins) {
if (!showAll && !plugin.isLinkedAndLoaded()) {
totalSizeOther += plugin.getMemoryFootprint();
id++;
continue;
}
auto meta = plugin.getMetaInformation();
auto &meta = plugin.getMetaInformation();
std::string heapUsage = "unknown";
if (const auto tracking = plugin.getTrackingMemoryAllocator()) {
@@ -202,6 +529,7 @@ namespace ShellCommands {
}
std::vector<std::string> rowData;
rowData.emplace_back(std::to_string(id));
rowData.emplace_back(meta.getName());
rowData.emplace_back(meta.getAuthor());
rowData.emplace_back(meta.getVersion());
@@ -213,6 +541,7 @@ namespace ShellCommands {
rowData.emplace_back(heapUsage);
table.AddRow(rowData);
id++;
}
if (totalSizeOther > 0 && !showAll) {
@@ -231,12 +560,111 @@ namespace ShellCommands {
table.Print();
}
void PluginDetails(std::optional<uint32_t> idOpt) {
uint32_t id = 0;
for (const auto &plugin : gLoadedPlugins) {
if (idOpt) {
if (*idOpt != id) {
id++;
continue;
}
}
auto &meta = plugin.getMetaInformation();
OSReport("\n");
OSReport("Index: %d\n", id);
OSReport("Name: %s\n", meta.getName().c_str());
OSReport("Description: %s\n", meta.getDescription().c_str());
OSReport("Author: %s\n", meta.getAuthor().c_str());
OSReport("Version: %s\n", meta.getVersion().c_str());
OSReport("Build date: %s\n", meta.getBuildTimestamp().c_str());
OSReport("Storage Id: %s\n", meta.getStorageId().c_str());
OSReport("Active: %s\n", plugin.isLinkedAndLoaded() ? "Yes" : "No");
OSReport("API: %s\n", meta.getWUPSVersion().toString().c_str());
const auto memoryFootprint = plugin.getMemoryFootprint();
const auto pluginSize = plugin.getPluginDataCopy()->getBuffer().size_bytes();
size_t textSize = 0;
size_t dataSize = 0;
OSReport("Memory footprint: ~%s\n", BytesToHumanReadable(memoryFootprint).c_str());
OSReport("\t- .wps: ~%s\n", BytesToHumanReadable(pluginSize).c_str());
if (plugin.isLinkedAndLoaded()) {
textSize = plugin.getPluginLinkInformation().getTextMemory().size();
dataSize = plugin.getPluginLinkInformation().getDataMemory().size();
OSReport("\t- CODE: ~%s\n", BytesToHumanReadable(textSize).c_str());
OSReport("\t- DATA: ~%s\n", BytesToHumanReadable(dataSize).c_str());
}
const auto otherSize = memoryFootprint - pluginSize - textSize - dataSize;
OSReport("\t- Other: ~%s\n", BytesToHumanReadable(otherSize).c_str());
OSReport("\n");
const auto &sectionInfoList = plugin.getPluginLinkInformation().getSectionInfoList();
OSReport("Sections: %d\n", sectionInfoList.size());
for (const auto &sectionInfo : sectionInfoList) {
OSReport("\t- 0x%08X - 0x%08X %-15s %-11s\n", sectionInfo.second.getAddress(), sectionInfo.second.getAddress() + sectionInfo.second.getSize(), sectionInfo.first.c_str(), BytesToHumanReadable(sectionInfo.second.getSize()).c_str());
}
OSReport("\n");
const auto &hookList = plugin.getPluginLinkInformation().getHookDataList();
OSReport("WUPS Hooks: %d\n", hookList.size());
for (const auto &hook : hookList) {
OSReport("\t- %p - %s\n", hook.getFunctionPointer(), hookNameToString(hook.getType()).c_str());
}
OSReport("\n");
const auto &buttonCombos = plugin.GetButtonComboData();
OSReport("Button combos: %d\n", buttonCombos.size());
for (const auto &combo : buttonCombos) {
OSReport("\t- \"%s\" \n", combo.label.c_str());
OSReport("\t\tStatus: %s\n", toString(combo.status).c_str());
OSReport("\t\tCallback: %p (%s)\n", combo.callbackOptions.callback, combo.callbackOptions.callback != nullptr ? getModuleAndSymbolName(reinterpret_cast<uint32_t>(combo.callbackOptions.callback)).c_str() : "");
OSReport("\t\tContext: %p\n", combo.callbackOptions.context);
OSReport("\t\tType: %s\n", toString(combo.buttonComboOptions.type).c_str());
if (isHoldCombo(combo.buttonComboOptions.type)) {
OSReport("\t\tHold duration: %d\n", combo.buttonComboOptions.optionalHoldForXMs);
}
OSReport("\t\tCombo: %s\n", getComboAsString(combo.buttonComboOptions.basicCombo.combo).c_str());
OSReport("\t\tController Mask: %s\n", getMaskAsString(combo.buttonComboOptions.basicCombo.controllerMask).c_str());
}
OSReport("\n");
const auto &functionPatches = plugin.getPluginLinkInformation().getFunctionDataList();
OSReport("Function patches: %d\n", functionPatches.size());
for (const auto &function : functionPatches) {
if (function.getPhysicalAddress() != nullptr) {
OSReport("\t- Hook: %p - PA: %p VA: %p\n", function.getReplaceAddress(), function.getPhysicalAddress(), function.getVirtualAddress());
} else {
OSReport("\t- Hook: %p - %-9s - %s\n", function.getReplaceAddress(), toString(function.getLibrary()).c_str(), function.getName().c_str());
}
}
OSReport("\n");
OSReport("Heap usage:\n");
if (const auto tracking = plugin.getTrackingMemoryAllocator(); tracking != nullptr) {
if (const auto stats = tracking->GetHeapMemoryUsageSnapshot(); stats) {
OSReport("\t- Currently allocated: %s\n", BytesToHumanReadable(stats->currentAllocated).c_str());
OSReport("\t- Peak allocated: %s\n", BytesToHumanReadable(stats->peakAllocated).c_str());
OSReport("\t- Current allocations: %d\n", stats->allocationMap.size());
OSReport("\t- Total allocations: %d\n", stats->allocCount);
OSReport("\t- Total frees: %d\n", stats->freeCount);
}
} else {
OSReport("\t Not tracked.\n");
}
OSReport("\n=================\n");
id++;
if (idOpt) {
break;
}
}
}
void Init() {
sPluginGroup = std::make_unique<IOPShellModule::CommandGroup>("plugins", "Manage aroma plugins");
sPluginGroup->AddCommand("heap_usage", PrintHeapUsage, "Show current heap usage for tracked plugins");
sPluginGroup->AddRawCommand("list", ListPlugins, "Lists active plugins", "Usage: \"list -a\" to list all plugins");
sPluginGroup->AddCommand("details", PluginDetails, "Shows details for plugins");
sPluginCmdHandle = sPluginGroup->Register();
}

View File

@@ -598,4 +598,28 @@ WUPSButtonCombo_Error ButtonComboManager::ExecuteForWrapper(const WUPSButtonComb
uint32_t ButtonComboManager::getHandle() const {
return *mHandle;
}
std::vector<ButtonComboInfo> ButtonComboManager::GetButtonCombos() const {
std::vector<ButtonComboInfo> result;
for (auto &wrapper : mComboWrappers) {
ButtonComboInfo res;
char text[256] = {};
WUPSButtonCombo_MetaOptionsOut meta = {text, sizeof(text)};
if (wrapper.GetButtonComboCallback(res.callbackOptions) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
continue;
}
if (wrapper.GetButtonComboInfoEx(res.buttonComboOptions) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
continue;
}
if (wrapper.GetButtonComboMeta(meta) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
continue;
}
if (wrapper.GetButtonComboStatus(res.status) != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
continue;
}
res.label = text;
result.push_back(res);
}
return result;
}

View File

@@ -10,12 +10,18 @@
class ButtonComboWrapper;
struct ButtonComboInfo {
std::string label;
WUPSButtonCombo_CallbackOptions callbackOptions;
WUPSButtonCombo_ButtonComboInfoEx buttonComboOptions;
WUPSButtonCombo_ComboStatus status;
};
class ButtonComboManager {
public:
explicit ButtonComboManager();
~ButtonComboManager();
ButtonComboManager(const ButtonComboManager &) = delete;
ButtonComboManager(ButtonComboManager &&src) noexcept;
@@ -67,6 +73,8 @@ public:
[[nodiscard]] uint32_t getHandle() const;
[[nodiscard]] std::vector<ButtonComboInfo> GetButtonCombos() const;
private:
std::forward_list<ButtonComboWrapper> mComboWrappers;
std::unique_ptr<uint32_t> mHandle = std::make_unique<uint32_t>();

View File

@@ -1,5 +1,6 @@
#include "PluginContainer.h"
#include "plugin/ButtonComboManager.h"
#include "plugin/FunctionData.h"
#include "plugin/HookData.h"
#include "plugin/PluginConfigData.h"
@@ -8,6 +9,7 @@
#include "plugin/RelocationData.h"
#include "plugin/SectionInfo.h"
#include "plugin/ButtonComboManager.h"
#include "utils/buttoncombo/ButtonComboUtils.h"
#include "utils/logger.h"
#include "utils/storage/StorageUtils.h"
@@ -135,6 +137,7 @@ void PluginContainer::InitButtonComboData() {
}
mButtonComboManagerHandle = ButtonComboUtils::API::Internal::CreateButtonComboData();
}
void PluginContainer::DeinitButtonComboData() {
if (getMetaInformation().getWUPSVersion() < WUPSVersion(0, 8, 2)) {
return;
@@ -142,6 +145,14 @@ void PluginContainer::DeinitButtonComboData() {
ButtonComboUtils::API::Internal::RemoveButtonComboData(mButtonComboManagerHandle);
}
std::vector<ButtonComboInfo> PluginContainer::GetButtonComboData() const {
if (getMetaInformation().getWUPSVersion() < WUPSVersion(0, 8, 2)) {
return {};
}
return ButtonComboUtils::API::Internal::GetButtonComboData(mButtonComboManagerHandle);
}
uint32_t PluginContainer::getButtonComboManagerHandle() const {
return mButtonComboManagerHandle;
}

View File

@@ -27,6 +27,8 @@
#include <memory>
#include <optional>
struct ButtonComboInfo;
class PluginData;
class PluginContainer {
@@ -67,6 +69,7 @@ public:
void InitButtonComboData();
void DeinitButtonComboData();
std::vector<ButtonComboInfo> GetButtonComboData() const;
[[nodiscard]] uint32_t getButtonComboManagerHandle() const;

View File

@@ -24,6 +24,16 @@ namespace ButtonComboUtils::API {
DEBUG_FUNCTION_LINE_WARN("Tried to remove ButtonComboManager by invalid handle: %08X", buttonComboManagerHandle);
}
}
std::vector<ButtonComboInfo> GetButtonComboData(uint32_t buttonComboManagerHandle) {
std::lock_guard lock(sButtonComboMutex);
for (auto &manager : sButtonComboManager) {
if (manager.getHandle() == buttonComboManagerHandle) {
return manager.GetButtonCombos();
}
}
return {};
}
} // namespace Internal
namespace {

View File

@@ -3,11 +3,15 @@
#include <wups/button_combo/defines.h>
#include <cstdint>
#include <vector>
struct ButtonComboInfo;
namespace ButtonComboUtils::API {
namespace Internal {
uint32_t CreateButtonComboData();
void RemoveButtonComboData(uint32_t buttonComboManagerHandle);
std::vector<ButtonComboInfo> GetButtonComboData(uint32_t buttonComboManagerHandle);
} // namespace Internal
WUPSButtonCombo_Error AddButtonCombo(void *identifier,

View File

@@ -236,6 +236,23 @@ CaptureStackTrace(uint32_t maxDepth) {
#define SC17_FindClosestSymbol ((uint32_t(*)(uint32_t addr, int32_t * outDistance, char *symbolNameBuffer, uint32_t symbolNameBufferLength, char *moduleNameBuffer, uint32_t moduleNameBufferLength))(0x101C400 + 0x1f934))
std::string getModuleAndSymbolName(uint32_t addr) {
int distance = 0;
char moduleName[50] = {};
char symbolName[256] = {};
if (SC17_FindClosestSymbol(addr, &distance, symbolName, sizeof(symbolName) - 1, moduleName, sizeof(moduleName) - 1) != 0) {
return string_format("0x%08X", addr);
} else {
moduleName[sizeof(moduleName) - 1] = '\0';
symbolName[sizeof(symbolName) - 1] = '\0';
return string_format("%s|%s+0x%X",
moduleName,
symbolName,
distance);
}
}
void PrintCapturedStackTrace(std::span<uint32_t> trace) {
if (trace.empty()) {
DEBUG_FUNCTION_LINE_INFO("┌────────────────────── CAPTURED TRACE ──────────────────────┐");
@@ -248,8 +265,8 @@ void PrintCapturedStackTrace(std::span<uint32_t> trace) {
for (size_t i = 0; i < trace.size(); ++i) {
uint32_t addr = trace[i];
int distance = 0;
char moduleName[100] = {};
char symbolName[100] = {};
char moduleName[50] = {};
char symbolName[256] = {};
if (SC17_FindClosestSymbol(addr, &distance, symbolName, sizeof(symbolName) - 1, moduleName, sizeof(moduleName) - 1) != 0) {
DEBUG_FUNCTION_LINE_INFO("│ [%02d] 0x%08X", i, addr);

View File

@@ -167,6 +167,8 @@ std::vector<std::string> getNonBaseAromaPluginFilenames(std::string_view basePat
std::vector<uint32_t> CaptureStackTrace(uint32_t maxDepth);
std::string getModuleAndSymbolName(uint32_t addr);
void PrintCapturedStackTrace(std::span<uint32_t> trace);
std::string hookNameToString(wups_loader_hook_type_t type);