mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
Merge pull request #22950 from hrydgard/imdebugger-func-scan
ImDebugger: Add scan/remove functions in range, reapply replacements
This commit is contained in:
6 files changed
+123
-53
No files matched your search
@@ -496,31 +496,8 @@ void WebSocketHLEFuncRemove(DebuggerRequest &req) {
|
||||
// (Note: this makes no checks whether the range is valid)
|
||||
// Returns the number of removed functions
|
||||
static u32 RemoveFuncSymbolsInRange(u32 addr, u32 size) {
|
||||
u32 func_address = g_symbolMap->GetFunctionStart(addr);
|
||||
if (func_address == SymbolMap::INVALID_ADDRESS) {
|
||||
func_address = g_symbolMap->GetNextSymbolAddress(addr, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
u32 counter = 0;
|
||||
while (func_address < addr + size && func_address != SymbolMap::INVALID_ADDRESS) {
|
||||
g_symbolMap->RemoveFunction(func_address, true);
|
||||
++counter;
|
||||
func_address = g_symbolMap->GetNextSymbolAddress(addr, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
u32 counter = MIPSAnalyst::RemoveFunctionsInRange(addr, size);
|
||||
if (counter) {
|
||||
MIPSAnalyst::ForgetFunctions(addr, addr + size);
|
||||
|
||||
// The following was copied from hle.func.remove:
|
||||
g_symbolMap->SortSymbols();
|
||||
|
||||
MIPSAnalyst::UpdateHashMap();
|
||||
MIPSAnalyst::ApplyHashMap();
|
||||
|
||||
if (g_Config.bFuncReplacements) {
|
||||
MIPSAnalyst::ReplaceFunctions();
|
||||
}
|
||||
|
||||
// Clear cache for branch lines and such.
|
||||
g_disassemblyManager.clear();
|
||||
}
|
||||
@@ -664,8 +641,8 @@ void WebSocketHLEFuncScan(DebuggerRequest &req) {
|
||||
RemoveFuncSymbolsInRange(addr, size);
|
||||
}
|
||||
|
||||
bool insertSymbols = MIPSAnalyst::ScanForFunctions(addr, addr + size, true);
|
||||
MIPSAnalyst::FinalizeScan(insertSymbols);
|
||||
MIPSAnalyst::ScanFunctionsInRange(addr, size);
|
||||
g_disassemblyManager.clear();
|
||||
|
||||
req.Respond();
|
||||
});
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Common/Log.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/System.h"
|
||||
@@ -1317,6 +1318,41 @@ namespace MIPSAnalyst {
|
||||
}
|
||||
}
|
||||
|
||||
void ScanFunctionsInRange(u32 addr, u32 size) {
|
||||
addr = RoundDownToMultipleOf(addr, 4);
|
||||
size = RoundUpToMultipleOf(size, 4);
|
||||
bool insertSymbols = ScanForFunctions(addr, addr + size, true);
|
||||
FinalizeScan(insertSymbols);
|
||||
}
|
||||
|
||||
u32 RemoveFunctionsInRange(u32 addr, u32 size) {
|
||||
addr = RoundDownToMultipleOf(addr, 4);
|
||||
size = RoundUpToMultipleOf(size, 4);
|
||||
|
||||
u32 funcAddr = g_symbolMap->GetFunctionStart(addr);
|
||||
if (funcAddr == SymbolMap::INVALID_ADDRESS) {
|
||||
funcAddr = g_symbolMap->GetNextSymbolAddress(addr, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
u32 count = 0;
|
||||
while (funcAddr < addr + size && funcAddr != SymbolMap::INVALID_ADDRESS) {
|
||||
g_symbolMap->RemoveFunction(funcAddr, true);
|
||||
++count;
|
||||
funcAddr = g_symbolMap->GetNextSymbolAddress(addr, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
if (count) {
|
||||
ForgetFunctions(addr, addr + size);
|
||||
g_symbolMap->SortSymbols();
|
||||
UpdateHashMap();
|
||||
ApplyHashMap();
|
||||
if (g_Config.bFuncReplacements) {
|
||||
ReplaceFunctions();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out) {
|
||||
std::lock_guard<std::recursive_mutex> guard(functions_lock);
|
||||
for (auto iter = functions.begin(), end = functions.end(); iter != end; ++iter) {
|
||||
|
||||
@@ -109,6 +109,13 @@ namespace MIPSAnalyst {
|
||||
void FinalizeScan(bool insertSymbols);
|
||||
void ForgetFunctions(u32 startAddr, u32 endAddr);
|
||||
|
||||
// Debugger helpers. The range is widened to whole instructions. Callers should clear
|
||||
// g_disassemblyManager afterwards.
|
||||
void ScanFunctionsInRange(u32 addr, u32 size);
|
||||
// Removes the function symbols starting in (or containing the start of) the range, forgets
|
||||
// them, and reapplies replacements. Returns the number removed.
|
||||
u32 RemoveFunctionsInRange(u32 addr, u32 size);
|
||||
|
||||
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out);
|
||||
// endAddr is exclusive.
|
||||
bool HasFunctionsInRange(u32 startAddr, u32 endAddr);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Math/geom2d.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/Debugger/DebugInterface.h"
|
||||
@@ -787,6 +788,7 @@ void ImDisasmView::RemoveFunction(u32 funcStart) {
|
||||
|
||||
void ImDisasmView::PopupMenu(MIPSState *mips, ImControl &control) {
|
||||
bool renameFunctionPopup = false;
|
||||
bool funcRangePopup = false;
|
||||
if (ImGui::BeginPopup("context")) {
|
||||
// The source location is the more useful heading when there is one, but keep the address:
|
||||
// it's what you paste into a bug report or another debugger.
|
||||
@@ -905,6 +907,24 @@ void ImDisasmView::PopupMenu(MIPSState *mips, ImControl &control) {
|
||||
mapReloaded_ = true;
|
||||
}
|
||||
}
|
||||
if (ImGui::MenuItem("Scan/remove functions in range...")) {
|
||||
// Prefill with the selection if there is one, otherwise the function we're in.
|
||||
if (selectRangeEnd_ - selectRangeStart_ > 4 || funcStart == -1) {
|
||||
funcRangeAddr_ = selectRangeStart_;
|
||||
funcRangeSize_ = selectRangeEnd_ - selectRangeStart_;
|
||||
} else {
|
||||
funcRangeAddr_ = funcStart;
|
||||
funcRangeSize_ = g_symbolMap->GetFunctionSize(funcStart);
|
||||
}
|
||||
funcRangeError_.clear();
|
||||
funcRangePopup = true;
|
||||
}
|
||||
if (ImGui::MenuItem("Reapply function replacements", nullptr, false, g_Config.bFuncReplacements)) {
|
||||
MIPSAnalyst::ReplaceFunctions();
|
||||
}
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Installs the HLE replacements (ReplaceTables) for every known function whose hash matches.");
|
||||
}
|
||||
if (prevBegin != -1) {
|
||||
u32 prevSize = g_symbolMap->GetFunctionSize(prevBegin);
|
||||
ShowInMemoryDumperMenuItem(prevBegin, prevSize, MemDumpMode::Disassembly, control);
|
||||
@@ -912,6 +932,55 @@ void ImDisasmView::PopupMenu(MIPSState *mips, ImControl &control) {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (funcRangePopup) {
|
||||
ImGui::OpenPopup("funcRange");
|
||||
}
|
||||
if (ImGui::BeginPopup("funcRange")) {
|
||||
ImGui::TextUnformatted("Scan or remove functions in range");
|
||||
if (ImGui::IsWindowAppearing()) {
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
}
|
||||
ImGui::InputScalar("Address", ImGuiDataType_U32, &funcRangeAddr_, nullptr, nullptr, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::InputScalar("Size", ImGuiDataType_U32, &funcRangeSize_, nullptr, nullptr, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
enum class RangeAction { NONE, SCAN, REMOVE, RESCAN };
|
||||
RangeAction action = RangeAction::NONE;
|
||||
if (ImGui::Button("Scan")) {
|
||||
action = RangeAction::SCAN;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Remove")) {
|
||||
action = RangeAction::REMOVE;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Remove and rescan")) {
|
||||
action = RangeAction::RESCAN;
|
||||
}
|
||||
if (action != RangeAction::NONE) {
|
||||
if (funcRangeSize_ == 0 || !Memory::IsValidRange(funcRangeAddr_, funcRangeSize_)) {
|
||||
funcRangeError_ = "Invalid range";
|
||||
} else {
|
||||
u32 removed = 0;
|
||||
if (action != RangeAction::SCAN) {
|
||||
removed = MIPSAnalyst::RemoveFunctionsInRange(funcRangeAddr_, funcRangeSize_);
|
||||
}
|
||||
if (action != RangeAction::REMOVE) {
|
||||
MIPSAnalyst::ScanFunctionsInRange(funcRangeAddr_, funcRangeSize_);
|
||||
}
|
||||
g_disassemblyManager.clear();
|
||||
mapReloaded_ = true;
|
||||
if (action == RangeAction::REMOVE) {
|
||||
statusBarText_ = StringFromFormat("Removed %d functions", removed);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
if (!funcRangeError_.empty()) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "%s", funcRangeError_.c_str());
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Sub popups here
|
||||
if (renameFunctionPopup) {
|
||||
ImGui::OpenPopup("renameFunction");
|
||||
|
||||
@@ -197,6 +197,11 @@ private:
|
||||
u32 funcBegin_ = 0;
|
||||
char funcNameTemp_[128]{};
|
||||
|
||||
// "Scan/remove functions in range" popup.
|
||||
u32 funcRangeAddr_ = 0;
|
||||
u32 funcRangeSize_ = 0;
|
||||
std::string funcRangeError_;
|
||||
|
||||
bool assemblePopup_ = false;
|
||||
u32 assembleAddress_ = 0;
|
||||
char assembleTemp_[256]{};
|
||||
|
||||
@@ -147,36 +147,12 @@ bool EditSymbolsWindow::exec() {
|
||||
}
|
||||
|
||||
void EditSymbolsWindow::Scan() {
|
||||
bool insertSymbols = MIPSAnalyst::ScanForFunctions(address_, address_ + size_ - 1, true);
|
||||
MIPSAnalyst::FinalizeScan(insertSymbols);
|
||||
MIPSAnalyst::ScanFunctionsInRange(address_, size_);
|
||||
g_disassemblyManager.clear();
|
||||
}
|
||||
|
||||
void EditSymbolsWindow::Remove() {
|
||||
u32 func_address = g_symbolMap->GetFunctionStart(address_);
|
||||
if (func_address == SymbolMap::INVALID_ADDRESS) {
|
||||
func_address = g_symbolMap->GetNextSymbolAddress(address_, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
u32 counter = 0;
|
||||
while (func_address < address_ + size_ && func_address != SymbolMap::INVALID_ADDRESS) {
|
||||
g_symbolMap->RemoveFunction(func_address, true);
|
||||
++counter;
|
||||
func_address = g_symbolMap->GetNextSymbolAddress(address_, SymbolType::ST_FUNCTION);
|
||||
}
|
||||
|
||||
if (counter) {
|
||||
MIPSAnalyst::ForgetFunctions(address_, address_ + size_);
|
||||
|
||||
// The following was copied from hle.func.remove:
|
||||
g_symbolMap->SortSymbols();
|
||||
|
||||
MIPSAnalyst::UpdateHashMap();
|
||||
MIPSAnalyst::ApplyHashMap();
|
||||
|
||||
if (g_Config.bFuncReplacements) {
|
||||
MIPSAnalyst::ReplaceFunctions();
|
||||
}
|
||||
|
||||
if (MIPSAnalyst::RemoveFunctionsInRange(address_, size_)) {
|
||||
// Clear cache for branch lines and such.
|
||||
g_disassemblyManager.clear();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user