Skip to content

Commit

Permalink
WIP on register coloring
Browse files Browse the repository at this point in the history
  • Loading branch information
emoon committed Mar 31, 2024
1 parent 77a715e commit 27f5cb7
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 49 deletions.
1 change: 1 addition & 0 deletions external/capstone/SStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
typedef struct SStream {
char buffer[512];
int index;
int index_temp;
bool is_closed;
} SStream;

Expand Down
51 changes: 25 additions & 26 deletions external/capstone/arch/M68K/M68KInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ static const char* const s_reg_names[] = {
"sr", "ccr", "sfc", "dfc", "usp", "vbr", "cacr",
"caar", "msp", "isp", "tc", "itt0", "itt1", "dtt0",
"dtt1", "mmusr", "urp", "srp",

"fpcr", "fpsr", "fpiar",
};

Expand Down Expand Up @@ -124,35 +123,33 @@ static void registerBits(cs_detail* detail, SStream* O, const cs_m68k_op* op, bo
RegisterStringInfo* info = NULL;

if (write_reg) {
int i = detail->regs_write_string_count++;
info = &detail->regs_write_string_info[i];
info = &detail->regs_write_string_info[0];
} else {
int i = detail->regs_read_string_count++;
info = &detail->regs_read_string_info[i];
info = &detail->regs_read_string_info[0];
}

info->type = REGISTER_STRING_INFO_REG_BITS;
info->used = 1;
info->length = strlen(buffer);
info->offset = O->index;

SStream_concat(O, "%s", buffer);
}

static void addStringInfo(cs_detail* detail, SStream* O, int adjust_offset, bool is_write, uint8_t length)
static void addStringInfo(cs_detail* detail, SStream* O, int register_id, int adjust_offset, bool is_write, uint8_t length)
{
RegisterStringInfo* info = NULL;

if (is_write) {
int i = detail->regs_write_string_count++;
info = &detail->regs_write_string_info[i];
info = &detail->regs_write_string_info[register_id];
} else {
int i = detail->regs_read_string_count++;
info = &detail->regs_read_string_info[i];
info = &detail->regs_read_string_info[register_id];
}

info->type = REGISTER_STRING_INFO_REGISTER;
info->used = 1;
info->length = length;
info->offset = O->index + adjust_offset;
info->offset = (O->index - O->index_temp) + adjust_offset;
}

static void registerPair(SStream* O, const cs_m68k_op* op)
Expand All @@ -173,8 +170,8 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,
registerPair(O, op);
break;
case M68K_OP_REG:
addStringInfo(detail, O, op->reg, 0, is_write, strlen(s_reg_names[op->reg]));
SStream_concat(O, "%s", s_reg_names[op->reg]);
addStringInfo(detail, O, 0, is_write, strlen(s_reg_names[op->reg]));
break;
default:
break;
Expand All @@ -183,43 +180,43 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,

case M68K_AM_REG_DIRECT_DATA:
{
addStringInfo(detail, O, 0, is_write, 2);
addStringInfo(detail, O, op->reg, 0, is_write, 2);
SStream_concat(O, "d%d", (op->reg - M68K_REG_D0));
break;
}

case M68K_AM_REG_DIRECT_ADDR:
{
addStringInfo(detail, O, 0, is_write, 2);
addStringInfo(detail, O, op->reg, 0, is_write, 2);
SStream_concat(O, "a%d", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR:
{
addStringInfo(detail, O, 1, is_write, 2);
addStringInfo(detail, O, op->reg, 1, is_write, 2);
SStream_concat(O, "(a%d)", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_POST_INC:
{
addStringInfo(detail, O, 1, true, 2);
addStringInfo(detail, O, op->reg, 1, true, 2);
SStream_concat(O, "(a%d)+", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_PRE_DEC:
{
addStringInfo(detail, O, 2, true, 2);
addStringInfo(detail, O, op->reg, 2, true, 2);
SStream_concat(O, "-(a%d)", (op->reg - M68K_REG_A0));
break;
}

case M68K_AM_REGI_ADDR_DISP:
{
SStream_concat(O, "%s$%x(a%d)", op->mem.disp < 0 ? "-" : "", abs(op->mem.disp), (op->mem.base_reg - M68K_REG_A0));
addStringInfo(detail, O, -2, false, 2);
addStringInfo(detail, O, op->mem.base_reg, -2, false, 2);
break;
}

Expand Down Expand Up @@ -255,7 +252,7 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,
pc + 2 + op->mem.disp,
getRegName(op->mem.index_reg),
op->mem.index_size ? 'l' : 'w');
addStringInfo(detail, O, -3, false, 2);
addStringInfo(detail, O, op->mem.index_reg, -3, false, 2);
break;
}
case M68K_AM_AREGI_INDEX_8_BIT_DISP:
Expand All @@ -266,8 +263,8 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,
getRegName(op->mem.base_reg),
getRegName(op->mem.index_reg),
op->mem.index_size ? 'l' : 'w');
addStringInfo(detail, O, -5, false, 2);
addStringInfo(detail, O, -3, false, 2);
addStringInfo(detail, O, op->mem.base_reg, -5, false, 2);
addStringInfo(detail, O, op->mem.index_reg, -3, false, 2);
break;
}
case M68K_AM_PCI_INDEX_BASE_DISP:
Expand All @@ -287,11 +284,11 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,
} else {
if (op->mem.base_reg != M68K_REG_INVALID)
{
addStringInfo(detail, O, 0, false, 2);
SStream_concat(O, "a%d,%s", op->mem.base_reg - M68K_REG_A0, s_spacing);
addStringInfo(detail, O, op->mem.base_reg, 0, false, 2);
SStream_concat(O, "a%d,%s", op->mem.base_reg, s_spacing);
}

addStringInfo(detail, O, 0, false, 2);
addStringInfo(detail, O, op->mem.index_reg, 0, false, 2);
SStream_concat(O, "%s.%c", getRegName(op->mem.index_reg), op->mem.index_size ? 'l' : 'w');
}

Expand Down Expand Up @@ -319,12 +316,12 @@ static void printAddressingMode(cs_detail* detail, SStream* O, unsigned int pc,
if (op->mem.base_reg != M68K_REG_INVALID) {
if (op->mem.in_disp > 0)
{
addStringInfo(detail, O, 1, false, 2);
addStringInfo(detail, O, op->mem.base_reg, 1, false, 2);
SStream_concat(O, ",%s", getRegName(op->mem.base_reg));
}
else
{
addStringInfo(detail, O, 0, false, 2);
addStringInfo(detail, O, op->mem.base_reg, 0, false, 2);
SStream_concat(O, "%s", getRegName(op->mem.base_reg));
}
}
Expand Down Expand Up @@ -421,6 +418,8 @@ void M68K_printInst(MCInst* MI, SStream* O, void* PrinterInfo)

SStream_concat0(O, " ");

O->index_temp = O->index;

// this one is a bit spacial so we do special things

if (MI->Opcode == M68K_INS_CAS2) {
Expand Down
12 changes: 5 additions & 7 deletions external/capstone/include/capstone/capstone.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,10 @@ typedef struct cs_opt_skipdata {
#define REGISTER_STRING_INFO_REG_BITS 1

typedef struct RegisterStringInfo {
uint16_t offset;
uint8_t length;
int16_t offset;
int16_t length;
uint8_t type;
uint8_t used;
} RegisterStringInfo;

/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
Expand All @@ -392,11 +393,8 @@ typedef struct RegisterStringInfo {
/// if cs_detail changes, in particular if a field is added after the union,
/// then update arch/ARCH/ARCHDisassembler.c accordingly
typedef struct cs_detail {
RegisterStringInfo regs_read_string_info[MAX_IMPL_R_REGS];
uint8_t regs_read_string_count;

RegisterStringInfo regs_write_string_info[MAX_IMPL_W_REGS];
uint8_t regs_write_string_count;
RegisterStringInfo regs_read_string_info[64];
RegisterStringInfo regs_write_string_info[64];

uint16_t regs_read[MAX_IMPL_R_REGS]; ///< list of implicit registers read by this insn
uint8_t regs_read_count; ///< number of implicit registers read by this insn
Expand Down
90 changes: 74 additions & 16 deletions src/debugger/disassembly_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
static SelectedRegisters s_selected_registers;

static uint32_t s_colors[] = {
0xffb27474, 0xffb28050, 0xffa9b250, 0xff60b250,
0xff4fb292, 0xff4f71b2, 0xff8850b2, 0xffb25091,
0xb274747f, 0xb280507f, 0xa9b2507f, 0x60b2507f,
0x4fb2927f, 0x4f71b27f, 0x8850b27f, 0xb250917f,
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -46,29 +46,36 @@ static void draw_disassembly(DisassemblyView* self) {
uae_u8* pc_addr = memory_get_real_address(pc);
uae_u32 start_disasm = pc - offset;

#define M68K_CODE "\x38\x38"

cs_insn* insn = nullptr;
size_t count = cs_disasm(self->capstone, pc_addr - offset, count_bytes, start_disasm, 0, &insn);
//size_t count = cs_disasm(self->capstone, (unsigned char*)M68K_CODE, 2, 0, 0, &insn);

//pc = 0;

int color_index = 0;

memset(&s_selected_registers, 0, sizeof(s_selected_registers));

for (size_t j = 0; j < count; j++) {
cs_detail* detail = insn[j].detail;
if (insn[j].address == pc) {

if (insn[j].address != pc) {
continue;
}

for (int i = 0; i < detail->regs_read_count; i++) {
int c = s_selected_registers.read_register_count++;
s_selected_registers.read_registers[c] = detail->regs_read[i];
s_selected_registers.read_registers_colors[c] = s_colors[color_index & 7];
int reg_id = detail->regs_read[i];
s_selected_registers.read_registers[reg_id] = 1;
s_selected_registers.read_registers_colors[reg_id] = s_colors[color_index & 7];
color_index++;
}

for (int i = 0; i < detail->regs_write_count; i++) {
int c = s_selected_registers.write_register_count++;
s_selected_registers.write_registers[c] = detail->regs_write[i];
s_selected_registers.write_register_colors[c] = s_colors[color_index & 7];
int reg_id = detail->regs_write[i];
s_selected_registers.write_registers[reg_id] = 1;
s_selected_registers.write_register_colors[reg_id] = s_colors[color_index & 7];
color_index++;
}
}
Expand All @@ -84,6 +91,7 @@ static void draw_disassembly(DisassemblyView* self) {
char buffer[512];

float text_height = ImGui::GetTextLineHeight();
float text_char_width = ImGui::CalcTextSize("F").x;

if (ImGui::BeginTable("disassembly", 4, flags)) {
ImGui::TableSetupColumn("Loc");
Expand All @@ -93,19 +101,22 @@ static void draw_disassembly(DisassemblyView* self) {
ImGui::TableHeadersRow();

for (size_t j = 0; j < count; j++) {
cs_detail* detail = insn[j].detail;

// Assuming we're rendering the triangle in the first column
ImGui::TableNextColumn();
if (insn[j].address == pc) {
//ImGui::TableSetColumnIndex(0);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
ImVec2 p = ImGui::GetCursorScreenPos();
// Define triangle vertices
ImVec2 tri[3] = {
ImVec2(p.x, p.y),
ImVec2(p.x + text_height / 2, p.y + text_height / 2),
ImVec2(p.x, p.y + text_height)
};

ImU32 row_bg_color = ImGui::GetColorU32(ImVec4(0.25f, 0.50f, 0.25f, 0.25f));
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color);

draw_list->AddTriangleFilled(tri[0], tri[1], tri[2], IM_COL32(255, 255, 0, 255));
}

Expand All @@ -119,14 +130,61 @@ static void draw_disassembly(DisassemblyView* self) {
for (int i = 0; i < max_instruction_width - width; i++) {
buffer[width + i] = ' ';
}

ImVec2 p = ImGui::GetCursorScreenPos();

strcpy(buffer + max_instruction_width, insn[j].op_str);

ImGui::Text("%s", buffer);

//ImDrawList* draw_list = ImGui::GetWindowDrawList();
//ImVec2 p = ImGui::GetCursorScreenPos();
//AddRect
ImDrawList* draw_list = ImGui::GetWindowDrawList();
float op_str_start = p.x + ((max_instruction_width - 1) * text_char_width);

/*
for (int i = 0; i < detail->regs_read_string_count; i++) {
const RegisterStringInfo* reg = &detail->regs_read_string_info[i];
ImVec2 start_pos = ImVec2(op_str_start + (reg->offset * text_char_width), p.y);
ImVec2 end_pos = ImVec2(start_pos.x + (reg->length * text_char_width), p.y + text_height);
draw_list->AddRectFilled(start_pos, end_pos, IM_COL32(0, 127, 0, 100));
}
for (int i = 0; i < detail->regs_write_string_count; i++) {
const RegisterStringInfo* reg = &detail->regs_write_string_info[i];
ImVec2 start_pos = ImVec2(op_str_start + (reg->offset * text_char_width), p.y);
ImVec2 end_pos = ImVec2(start_pos.x + (reg->length * text_char_width), p.y + text_height);
draw_list->AddRectFilled(start_pos, end_pos, IM_COL32(127, 0, 0, 100));
}
*/

// Check if the current instruction includes any of the selected registers
for (int i = 0; i < detail->regs_read_count; i++) {
int reg_id = detail->regs_read[i];
if (s_selected_registers.read_registers[reg_id]) {
const uint32_t color = s_selected_registers.read_registers_colors[reg_id];
const RegisterStringInfo* reg = &detail->regs_read_string_info[reg_id];
ImVec2 start_pos = ImVec2(op_str_start + (reg->offset * text_char_width), p.y);
ImVec2 end_pos = ImVec2(start_pos.x + (reg->length * text_char_width), p.y + text_height);
draw_list->AddRectFilled(start_pos, end_pos, IM_COL32(0, 127, 0, 127));
}
}

for (int i = 0; i < detail->regs_write_count; i++) {
int reg_id = detail->regs_write[i];
if (s_selected_registers.write_registers[reg_id]) {
const uint32_t color = s_selected_registers.write_registers[reg_id];
const RegisterStringInfo* reg = &detail->regs_write_string_info[reg_id];
ImVec2 start_pos = ImVec2(op_str_start + (reg->offset * text_char_width), p.y);
ImVec2 end_pos = ImVec2(start_pos.x + (reg->length * text_char_width), p.y + text_height);
printf("start_pos: %f %f\n", start_pos.x, start_pos.y);
printf("end_pos: %f %f\n", end_pos.x, end_pos.y);
draw_list->AddRectFilled(start_pos, end_pos, IM_COL32(127, 0, 0, 127));
}
}

//ImVec2 start_pos = ImVec2(op_str_start, p.y);
//ImVec2 end_pos = ImVec2(start_pos.x + 2.0f * text_char_width, p.y + text_height);
//draw_list->AddRectFilled(start_pos, end_pos, IM_COL32(127, 127, 127, 127));

//draw_list->AddRectFilled(p, ImVec2(p.x, p.y + text_height), IM_COL32(127, 127, 127, 127));

ImGui::TableNextColumn();
}
Expand Down

0 comments on commit 27f5cb7

Please sign in to comment.