breakpoints
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "window.h"
|
||||
#include "frontend.h"
|
||||
#include <algorithm>
|
||||
#include "imgui_internal.h"
|
||||
|
||||
using namespace dbgui;
|
||||
using namespace dbgui::frontend;
|
||||
@@ -18,6 +20,9 @@ bool Window::draw(Frontend &frontend)
|
||||
case disassembly:
|
||||
return std::get<DisasmWindow>(this->data).draw(frontend);
|
||||
break;
|
||||
case breakpoints:
|
||||
return std::get<BreakpointWindow>(this->data).draw(frontend);
|
||||
break;
|
||||
default: printf("Unhandled window draw: %u\n", this->type); exit(1);
|
||||
}
|
||||
}
|
||||
@@ -59,6 +64,15 @@ Window Window::create_disas(size_t id)
|
||||
DisasmWindow{.id = id_str, .open = true, .first = true}};
|
||||
}
|
||||
|
||||
Window Window::create_bp(size_t id)
|
||||
{
|
||||
auto id_str = std::string{"Breakpoints##"};
|
||||
id_str.append(std::to_string(id));
|
||||
|
||||
return Window{.type = WindowType::breakpoints,
|
||||
.data = BreakpointWindow{.id = id_str, .open = true}};
|
||||
}
|
||||
|
||||
bool RegWindow::draw(const Frontend &frontend)
|
||||
{
|
||||
//ImGui::SetNextWindowDockID(frontend.dock_id, ImGuiCond_Appearing);
|
||||
@@ -74,6 +88,12 @@ bool RegWindow::draw(const Frontend &frontend)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled));
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("table", 1,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
@@ -151,6 +171,11 @@ bool RegWindow::draw(const Frontend &frontend)
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
@@ -170,6 +195,12 @@ bool ThreadWindow::draw(const Frontend &frontend)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled));
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("table", 3,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
@@ -211,6 +242,11 @@ bool ThreadWindow::draw(const Frontend &frontend)
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
@@ -230,6 +266,12 @@ bool FrameWindow::draw(const Frontend &frontend)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled));
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("table", 1,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
@@ -262,6 +304,11 @@ bool FrameWindow::draw(const Frontend &frontend)
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
@@ -293,6 +340,12 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text,
|
||||
ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled));
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
auto found = false;
|
||||
@@ -343,12 +396,12 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
|
||||
auto pad = ImGui::GetStyle().CellPadding;
|
||||
pad.x += 10.f;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, pad);
|
||||
if (ImGui::BeginTable("table", 2,
|
||||
if (ImGui::BeginTable("table", 3,
|
||||
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY
|
||||
| ImGuiTableFlags_RowBg | ImGuiTableFlags_PadOuterX))
|
||||
{
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 10.f);
|
||||
ImGui::TableSetupColumn("Address");
|
||||
ImGui::TableSetupColumn("Instruction");
|
||||
ImGui::TableHeadersRow();
|
||||
@@ -360,6 +413,58 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
|
||||
ImGui::PushID(idx);
|
||||
// TODO: draw nice break sign
|
||||
auto &bps = frontend.target->breakpoints;
|
||||
const auto bp_it =
|
||||
std::find_if(bps.begin(), bps.end(),
|
||||
[inst](const auto &el) { return el.addr == inst.addr; });
|
||||
const auto is_bp = bp_it != bps.end() && !bp_it->removed;
|
||||
if (is_bp)
|
||||
{
|
||||
auto win_pos = ImGui::GetWindowPos();
|
||||
auto pos = ImGui::GetCursorPos();
|
||||
pos.x += win_pos.x;
|
||||
pos.y += win_pos.y - ImGui::GetScrollY();
|
||||
pos.y += (ImGui::GetTextLineHeight() - 10.f) / 2.f;
|
||||
auto end_pos = pos;
|
||||
end_pos.x += 10.f;
|
||||
end_pos.y += 10.f;
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, end_pos,
|
||||
IM_COL32(255, 0, 0, 255));
|
||||
}
|
||||
if (ImGui::InvisibleButton("Break",
|
||||
ImVec2{10.f, ImGui::GetTextLineHeight()}))
|
||||
{
|
||||
if (!is_bp)
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (; idx < bps.size(); ++idx)
|
||||
{
|
||||
if (bps[idx].removed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == bps.size())
|
||||
{
|
||||
bps.push_back(
|
||||
Target::Breakpoint{.removed = false, .addr = inst.addr});
|
||||
} else
|
||||
{
|
||||
bps[idx] = Target::Breakpoint{.removed = false, .addr = inst.addr};
|
||||
}
|
||||
frontend.target->backend->add_breakpoint(inst.addr, idx);
|
||||
} else
|
||||
{
|
||||
frontend.target->backend->remove_breakpoint(bp_it - bps.begin());
|
||||
bp_it->removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (!this->ip_unsuccessful && inst.addr == ip)
|
||||
{
|
||||
// TODO: color config
|
||||
@@ -374,7 +479,7 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
|
||||
// TODO: make some unified handler for int vars
|
||||
ImGui::PushID(idx);
|
||||
ImGui::Text("%lX", inst.addr);
|
||||
ImGui::Text("%lX ", inst.addr);
|
||||
if (ImGui::IsItemHovered()
|
||||
&& ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||
{
|
||||
@@ -397,13 +502,17 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
const int mnem_space = max_mnem_len - inst.mnem_len + 1;
|
||||
const int op_space = max_op_len - inst.op_len + 1;
|
||||
const int op_space = /*max_op_len - inst.op_len +*/ 1;
|
||||
ImGui::Text(inst.fmt_str.c_str(), mnem_space, ' ', op_space, ' ');
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (frontend.target->state == TargetState::running)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
@@ -411,6 +520,79 @@ bool DisasmWindow::draw(Frontend &frontend)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BreakpointWindow::draw(Frontend &frontend)
|
||||
{
|
||||
if (!ImGui::Begin(this->id.c_str()))
|
||||
{
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!frontend.target)
|
||||
{
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("table", 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
ImGui::TableSetupColumn("ID");
|
||||
ImGui::TableSetupColumn("Address");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
auto &bps = frontend.target->breakpoints;
|
||||
for (size_t idx = 0; idx < bps.size(); ++idx)
|
||||
{
|
||||
auto &bp = bps[idx];
|
||||
if (bp.removed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
|
||||
ImGui::PushID(idx);
|
||||
|
||||
ImGui::Text("%zu", idx);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Text("%lX", bp.addr);
|
||||
|
||||
auto min_pos =
|
||||
ImGui::TableGetCellBgRect(ImGui::GetCurrentTable(), 0).GetTL();
|
||||
auto max_pos =
|
||||
ImGui::TableGetCellBgRect(ImGui::GetCurrentTable(), 1).GetBR();
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)
|
||||
&& ImGui::IsMouseHoveringRect(min_pos, max_pos, false))
|
||||
{
|
||||
ImGui::OpenPopup("Context", ImGuiPopupFlags_NoOpenOverExistingPopup);
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("Context"))
|
||||
{
|
||||
if (ImGui::Selectable("Remove"))
|
||||
{
|
||||
printf("Removing bp %zu\n", idx);
|
||||
frontend.target->backend->remove_breakpoint(idx);
|
||||
bp.removed = true;
|
||||
}
|
||||
// TODO: disable/endable?
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::handle_data_res(const BackToFront::DataResult &result)
|
||||
{
|
||||
switch (this->type)
|
||||
|
||||
Reference in New Issue
Block a user