regs and we can step into!
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "frontend.h"
|
||||
#include "backend/lldb/lldb_backend.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
@@ -6,134 +7,287 @@
|
||||
using namespace dbgui;
|
||||
using namespace dbgui::frontend;
|
||||
|
||||
void Frontend::run_frame() {
|
||||
this->draw_open_popup();
|
||||
this->draw_header();
|
||||
|
||||
// main window
|
||||
float height = ImGui::GetFrameHeight();
|
||||
|
||||
const auto vp_size = ImGui::GetMainViewport()->Size;
|
||||
const auto win_pos = ImVec2{0, height*2};
|
||||
const auto win_size = ImVec2{vp_size.x, vp_size.y - height*3};
|
||||
|
||||
const auto win_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
ImGui::SetNextWindowPos(win_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(win_size, ImGuiCond_Always);
|
||||
|
||||
if (ImGui::Begin("Test", nullptr, win_flags)) {
|
||||
_dock_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(_dock_id, ImVec2{0, 0}, ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
this->draw_status();
|
||||
Target::Target(std::string filename)
|
||||
{
|
||||
state = TargetState::startup;
|
||||
this->filename = filename;
|
||||
id = 0;
|
||||
backend = std::make_shared<backend::LLDBBackend>(this->filename.c_str());
|
||||
}
|
||||
|
||||
void Frontend::draw_header() {
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_MenuBar;
|
||||
float height = ImGui::GetFrameHeight();
|
||||
void Frontend::run_frame()
|
||||
{
|
||||
this->handle_msgs();
|
||||
this->draw_open_popup();
|
||||
this->draw_header();
|
||||
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if (ImGui::MenuItem("Open")) {
|
||||
_draw_open_popup = true;
|
||||
ImGui::OpenPopup(_open_popup_id);
|
||||
}
|
||||
// main window
|
||||
float height = ImGui::GetFrameHeight();
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
const auto vp_size = ImGui::GetMainViewport()->Size;
|
||||
const auto win_pos = ImVec2{0, height * 2};
|
||||
const auto win_size = ImVec2{vp_size.x, vp_size.y - height * 3};
|
||||
|
||||
if (ImGui::BeginViewportSideBar("##SecondaryMenuBar", NULL, ImGuiDir_Up, height, window_flags)) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
const auto orig_cursor_x = ImGui::GetCursorPosX();
|
||||
if (_target) {
|
||||
switch (_target->state) {
|
||||
using enum backend::TargetState;
|
||||
const auto win_flags =
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoNav
|
||||
| ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollWithMouse
|
||||
| ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
case stopped:
|
||||
ImGui::Button("Run");
|
||||
break;
|
||||
case paused:
|
||||
ImGui::Button("Continue");
|
||||
break;
|
||||
case running:
|
||||
ImGui::Button("Pause");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button("Continue");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::SetNextWindowPos(win_pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(win_size, ImGuiCond_Always);
|
||||
|
||||
// TODO: this depends on font-size, we just want to make sure the the other buttons don't flicker even if the state is changed
|
||||
ImGui::SetCursorPosX(orig_cursor_x + 71.f);
|
||||
if (ImGui::Begin("Test", nullptr, win_flags))
|
||||
{
|
||||
this->dock_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(this->dock_id, ImVec2{0, 0},
|
||||
ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical, 2.f);
|
||||
for (auto &window : _windows)
|
||||
{
|
||||
window.draw(*this);
|
||||
}
|
||||
|
||||
const auto is_paused = _target && _target->state == backend::TargetState::paused;
|
||||
const auto is_running = _target && _target->state == backend::TargetState::running;
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (!is_paused) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::Button("Step Over");
|
||||
ImGui::Button("Step Into");
|
||||
ImGui::Button("Step Out");
|
||||
|
||||
if (!is_paused) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical, 2.f);
|
||||
|
||||
if (!is_paused && !is_running) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::Button("Stop");
|
||||
ImGui::Button("Restart");
|
||||
|
||||
if (!is_paused && !is_running) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
this->draw_status();
|
||||
}
|
||||
|
||||
void Frontend::draw_status() {
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_MenuBar;
|
||||
float height = ImGui::GetFrameHeight();
|
||||
void Frontend::draw_header()
|
||||
{
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings
|
||||
| ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_MenuBar;
|
||||
float height = ImGui::GetFrameHeight();
|
||||
|
||||
if (ImGui::BeginViewportSideBar("##MainStatusBar", NULL, ImGuiDir_Down, height, window_flags)) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
ImGui::Text("Happy status bar");
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Open"))
|
||||
{
|
||||
_draw_open_popup = true;
|
||||
ImGui::OpenPopup(_open_popup_id);
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Window"))
|
||||
{
|
||||
if (ImGui::MenuItem("Registers"))
|
||||
{
|
||||
_windows.push_back(Window::create_regs(this->window_id++));
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
if (ImGui::BeginViewportSideBar("##SecondaryMenuBar", NULL, ImGuiDir_Up,
|
||||
height, window_flags))
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
const auto orig_cursor_x = ImGui::GetCursorPosX();
|
||||
if (this->target)
|
||||
{
|
||||
switch (this->target->state)
|
||||
{
|
||||
using enum TargetState;
|
||||
|
||||
case startup:
|
||||
ImGui::BeginDisabled();
|
||||
// buttons shouldn't flicker that way
|
||||
ImGui::Button("Continue");
|
||||
ImGui::EndDisabled();
|
||||
break;
|
||||
|
||||
case stopped: ImGui::Button("Run"); break;
|
||||
case paused: ImGui::Button("Continue"); break;
|
||||
case running: ImGui::Button("Pause"); break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button("Continue");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
// TODO: this depends on font-size, we just want to make sure the the other buttons don't flicker even if the state is changed
|
||||
ImGui::SetCursorPosX(orig_cursor_x + 71.f);
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical, 2.f);
|
||||
|
||||
const auto is_paused =
|
||||
this->target && this->target->state == TargetState::paused;
|
||||
const auto is_running =
|
||||
this->target && this->target->state == TargetState::running;
|
||||
|
||||
if (!is_paused)
|
||||
{
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Step Over")) {}
|
||||
if (ImGui::Button("Step Into"))
|
||||
{
|
||||
if (this->target->backend->step_into())
|
||||
{
|
||||
// TODO: already disable the UI into running mode
|
||||
}
|
||||
}
|
||||
ImGui::Button("Step Out");
|
||||
|
||||
if (!is_paused)
|
||||
{
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical, 2.f);
|
||||
|
||||
if (!is_paused && !is_running)
|
||||
{
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::Button("Stop");
|
||||
ImGui::Button("Restart");
|
||||
|
||||
if (!is_paused && !is_running)
|
||||
{
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void Frontend::draw_open_popup() {
|
||||
if (!_open_popup_id) {
|
||||
_open_popup_id = ImGui::GetID("Open Executable##OpenPopup");
|
||||
}
|
||||
if (ImGui::BeginPopupModal("Open Executable##OpenPopup", &_draw_open_popup, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::InputText("File Path", _open_popup_name_buf.data(), _open_popup_name_buf.size());
|
||||
void Frontend::draw_status()
|
||||
{
|
||||
ImGuiWindowFlags window_flags =
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings
|
||||
| ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_MenuBar;
|
||||
float height = ImGui::GetFrameHeight();
|
||||
|
||||
if (ImGui::Button("Start")) {
|
||||
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::BeginViewportSideBar("##MainStatusBar", NULL, ImGuiDir_Down,
|
||||
height, window_flags))
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
ImGui::Text("Happy status bar");
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void Frontend::draw_open_popup()
|
||||
{
|
||||
if (!_open_popup_id)
|
||||
{
|
||||
_open_popup_id = ImGui::GetID("Open Executable##OpenPopup");
|
||||
}
|
||||
if (ImGui::BeginPopupModal("Open Executable##OpenPopup", &_draw_open_popup,
|
||||
ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::InputText("File Path", _open_popup_name_buf.data(),
|
||||
_open_popup_name_buf.size());
|
||||
|
||||
if (ImGui::Button("Start"))
|
||||
{
|
||||
this->target = Target{_open_popup_name_buf.data()};
|
||||
this->target->backend->start();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void Frontend::handle_msgs()
|
||||
{
|
||||
if (!this->target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto opt = this->target->backend->retrieve_msg_for_frontend();
|
||||
if (!opt)
|
||||
{
|
||||
break;
|
||||
}
|
||||
auto *msg = opt->get();
|
||||
|
||||
printf("Got msg %u\n", msg->type);
|
||||
|
||||
switch (msg->type)
|
||||
{
|
||||
using enum BackToFront::MsgType;
|
||||
|
||||
case state_change:
|
||||
{
|
||||
const auto &info = std::get<BackToFront::StateChange>(msg->data);
|
||||
this->handle_state_change(info);
|
||||
break;
|
||||
}
|
||||
case ip_change:
|
||||
// TODO
|
||||
break;
|
||||
case initial_proc_info:
|
||||
this->handle_proc_info(
|
||||
std::move(std::get<BackToFront::InitialProcessInfo>(msg->data)));
|
||||
break;
|
||||
case regs_changed:
|
||||
this->handle_reg_change(std::get<BackToFront::RegsChanged>(msg->data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Frontend::handle_state_change(const BackToFront::StateChange &info)
|
||||
{
|
||||
this->target->state = info.new_state;
|
||||
|
||||
// TODO: display in status bar
|
||||
printf("State changed to %u because %u\n", info.new_state, info.reason);
|
||||
}
|
||||
|
||||
void Frontend::handle_proc_info(BackToFront::InitialProcessInfo &&info)
|
||||
{
|
||||
this->target->arch = info.arch;
|
||||
this->target->id = info.pid;
|
||||
|
||||
auto &sets = this->target->reg_sets;
|
||||
printf("RegSet Size: %lu\n", info.reg_sets.size());
|
||||
for (size_t set_idx = 0; set_idx < info.reg_sets.size(); ++set_idx)
|
||||
{
|
||||
sets.emplace_back();
|
||||
auto &set = sets.back();
|
||||
printf("Got set %s\n", info.reg_sets[set_idx].name.c_str());
|
||||
set.name = std::move(info.reg_sets[set_idx].name);
|
||||
|
||||
for (size_t i = 0; i < info.reg_sets[set_idx].reg_names.size(); ++i)
|
||||
{
|
||||
set.regs.emplace_back();
|
||||
printf(" Got reg %s\n", info.reg_sets[set_idx].reg_names[i].c_str());
|
||||
set.regs.back().name = std::move(info.reg_sets[set_idx].reg_names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Frontend::handle_reg_change(const BackToFront::RegsChanged &info)
|
||||
{
|
||||
auto &set = this->target->reg_sets[info.set_idx];
|
||||
for (const auto &[idx, val] : info.changes)
|
||||
{
|
||||
auto ® = set.regs[idx];
|
||||
reg.bytes.resize(val.size());
|
||||
|
||||
// TODO: opt for uint64?
|
||||
std::copy(val.begin(), val.end(), reg.bytes.begin());
|
||||
}
|
||||
}
|
||||
@@ -5,39 +5,47 @@
|
||||
#include <optional>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "frontend/target.h"
|
||||
#include "backend/debug_backend.h"
|
||||
#include "frontend/window.h"
|
||||
|
||||
namespace dbgui::frontend {
|
||||
namespace dbgui::frontend
|
||||
{
|
||||
|
||||
struct Target {
|
||||
backend::TargetState state = backend::TargetState::stopped;
|
||||
std::string filename;
|
||||
uint64_t id;
|
||||
struct Frontend
|
||||
{
|
||||
Frontend()
|
||||
{
|
||||
_open_popup_name_buf.resize(512);
|
||||
const char *str = "/home/klee/projects/dbgui/tmp/main";
|
||||
std::memcpy(_open_popup_name_buf.data(), str, strlen(str) + 1);
|
||||
}
|
||||
|
||||
std::unique_ptr<backend::Backend> backend = nullptr;
|
||||
};
|
||||
void run_frame();
|
||||
|
||||
struct Frontend {
|
||||
Frontend() {
|
||||
_open_popup_name_buf.resize(512);
|
||||
}
|
||||
std::optional<Target> target = {};
|
||||
ImGuiID dock_id = 0;
|
||||
uint64_t window_id = 0;
|
||||
|
||||
void run_frame();
|
||||
private:
|
||||
void draw_header();
|
||||
void draw_open_popup();
|
||||
void draw_status();
|
||||
|
||||
private:
|
||||
void draw_header();
|
||||
void draw_open_popup();
|
||||
void draw_status();
|
||||
void handle_msgs();
|
||||
void handle_state_change(const BackToFront::StateChange &);
|
||||
void handle_proc_info(BackToFront::InitialProcessInfo &&);
|
||||
void handle_reg_change(const BackToFront::RegsChanged &);
|
||||
|
||||
bool _draw_second = false;
|
||||
ImGuiID _dock_id = 0;
|
||||
bool _draw_second = false;
|
||||
|
||||
bool _draw_open_popup = false;
|
||||
ImGuiID _open_popup_id = 0;
|
||||
std::vector<char> _open_popup_name_buf = {};
|
||||
bool _draw_open_popup = false;
|
||||
ImGuiID _open_popup_id = 0;
|
||||
std::vector<char> _open_popup_name_buf = {};
|
||||
|
||||
std::optional<Target> _target = {};
|
||||
};
|
||||
}
|
||||
std::vector<Window> _windows = {};
|
||||
};
|
||||
} // namespace dbgui::frontend
|
||||
39
src/frontend/target.h
Normal file
39
src/frontend/target.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
#include "backend/debug_backend.h"
|
||||
|
||||
namespace dbgui::frontend
|
||||
{
|
||||
struct Target
|
||||
{
|
||||
struct Reg
|
||||
{
|
||||
std::string name;
|
||||
// TODO: handle registers as sets of 64bit?
|
||||
std::vector<uint8_t> bytes;
|
||||
};
|
||||
|
||||
struct RegSet
|
||||
{
|
||||
std::string name;
|
||||
std::vector<Reg> regs;
|
||||
};
|
||||
|
||||
Target(std::string filename);
|
||||
|
||||
TargetState state = TargetState::stopped;
|
||||
std::string filename;
|
||||
uint64_t id;
|
||||
Arch arch;
|
||||
|
||||
std::vector<RegSet> reg_sets;
|
||||
|
||||
std::shared_ptr<backend::Backend> backend = nullptr;
|
||||
};
|
||||
} // namespace dbgui::frontend
|
||||
101
src/frontend/window.cpp
Normal file
101
src/frontend/window.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "window.h"
|
||||
#include "frontend.h"
|
||||
|
||||
using namespace dbgui;
|
||||
using namespace dbgui::frontend;
|
||||
|
||||
void Window::draw(const Frontend &frontend)
|
||||
{
|
||||
switch (this->type)
|
||||
{
|
||||
using enum WindowType;
|
||||
|
||||
case regs: std::get<RegWindow>(this->data).draw(frontend); break;
|
||||
default: printf("Unhandled window draw: %u\n", this->type); exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Window Window::create_regs(size_t id)
|
||||
{
|
||||
auto id_str = std::string{"Registers##"};
|
||||
id_str.append(std::to_string(id));
|
||||
|
||||
return Window{.type = WindowType::regs,
|
||||
.data = RegWindow{.id = id_str, .open = true}};
|
||||
}
|
||||
|
||||
void RegWindow::draw(const Frontend &frontend)
|
||||
{
|
||||
ImGui::SetNextWindowDockID(frontend.dock_id, ImGuiCond_Appearing);
|
||||
if (!ImGui::Begin(this->id.c_str()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frontend.target)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("table", 1,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
const auto &sets = frontend.target->reg_sets;
|
||||
for (size_t set_idx = 0; set_idx < sets.size(); ++set_idx)
|
||||
{
|
||||
const auto &set = sets[set_idx];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text(set.name.c_str());
|
||||
|
||||
char buf[20];
|
||||
std::snprintf(buf, sizeof(buf), "nested_%lu", set_idx);
|
||||
if (ImGui::BeginTable(buf, 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
||||
{
|
||||
for (size_t i = 0; i < set.regs.size(); ++i)
|
||||
{
|
||||
const auto ® = set.regs[i];
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text(reg.name.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (reg.bytes.size() == 0)
|
||||
{
|
||||
ImGui::Text("<unk>");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (reg.bytes.size())
|
||||
{
|
||||
case 1: std::snprintf(buf, sizeof(buf), "%X", reg.bytes[0]); break;
|
||||
case 2:
|
||||
std::snprintf(
|
||||
buf, sizeof(buf), "%X",
|
||||
*reinterpret_cast<const uint16_t *>(reg.bytes.data()));
|
||||
break;
|
||||
case 4:
|
||||
std::snprintf(
|
||||
buf, sizeof(buf), "%X",
|
||||
*reinterpret_cast<const uint32_t *>(reg.bytes.data()));
|
||||
break;
|
||||
case 8:
|
||||
std::snprintf(
|
||||
buf, sizeof(buf), "%lX",
|
||||
*reinterpret_cast<const uint64_t *>(reg.bytes.data()));
|
||||
break;
|
||||
default: std::snprintf(buf, sizeof(buf), "<val too large>"); break;
|
||||
}
|
||||
|
||||
ImGui::Text(buf);
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -3,29 +3,40 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include "msg.h"
|
||||
#include "frontend/target.h"
|
||||
|
||||
namespace dbgui::frontend {
|
||||
enum class WindowType : uint8_t {
|
||||
regs,
|
||||
source,
|
||||
memory,
|
||||
variables,
|
||||
stack,
|
||||
threads,
|
||||
disassembly,
|
||||
};
|
||||
namespace dbgui::frontend
|
||||
{
|
||||
struct Frontend;
|
||||
|
||||
struct RegWindow {
|
||||
enum class RegValType : uint8_t {
|
||||
flag,
|
||||
u64,
|
||||
u128,
|
||||
u256,
|
||||
u512,
|
||||
};
|
||||
enum class WindowType : uint8_t
|
||||
{
|
||||
regs,
|
||||
source,
|
||||
memory,
|
||||
variables,
|
||||
stack,
|
||||
threads,
|
||||
disassembly,
|
||||
};
|
||||
|
||||
struct Reg {
|
||||
std::string name;
|
||||
struct RegWindow
|
||||
{
|
||||
enum class RegValType : uint8_t
|
||||
{
|
||||
flag,
|
||||
u64,
|
||||
u128,
|
||||
u256,
|
||||
u512,
|
||||
};
|
||||
|
||||
// TODO: store last_drawn val and which regs we should draw
|
||||
/*struct Reg {
|
||||
uint16_t set_idx;
|
||||
uint16_t reg_idx;
|
||||
RegValType type;
|
||||
union {
|
||||
bool bval;
|
||||
@@ -36,12 +47,21 @@ namespace dbgui::frontend {
|
||||
};
|
||||
};
|
||||
|
||||
std::vector<Reg> regs;
|
||||
std::vector<Reg> regs;*/
|
||||
|
||||
void draw();
|
||||
};
|
||||
void draw(const Frontend &);
|
||||
|
||||
struct Window {
|
||||
WindowType type;
|
||||
};
|
||||
}
|
||||
std::string id;
|
||||
bool open;
|
||||
};
|
||||
|
||||
struct Window
|
||||
{
|
||||
WindowType type;
|
||||
std::variant<std::monostate, RegWindow> data;
|
||||
|
||||
void draw(const Frontend &);
|
||||
|
||||
static Window create_regs(size_t window_id);
|
||||
};
|
||||
} // namespace dbgui::frontend
|
||||
Reference in New Issue
Block a user