107 lines
2.6 KiB
C
107 lines
2.6 KiB
C
#include "gintrace/menu/hexdump.h"
|
|
#include "gintrace/ubc.h"
|
|
#include "gintrace/tracer.h"
|
|
#include "gintrace/gui/menu.h"
|
|
#include "gintrace/gui/display.h"
|
|
#include "gintrace/gui/input.h"
|
|
|
|
#include <gint/std/stdio.h>
|
|
#include <gint/std/string.h>
|
|
#include <gint/keyboard.h>
|
|
|
|
/* hexdump_ctor: Menu constructor */
|
|
static void hexdump_ctor(struct tsession *session)
|
|
{
|
|
session->menu.hexdump.cursor.hoffset = 0;
|
|
session->menu.hexdump.cursor.voffset = 0;
|
|
session->menu.hexdump.addr = (void*)0x88000000;
|
|
}
|
|
|
|
/* hexdump_display(); Display trace information */
|
|
static void hexdump_display(struct tsession *session)
|
|
{
|
|
uint8_t *record;
|
|
int x;
|
|
int y;
|
|
|
|
record = session->menu.hexdump.addr;
|
|
x = session->menu.hexdump.cursor.hoffset;
|
|
y = session->menu.hexdump.cursor.voffset;
|
|
for (int i = 0; i < GUI_DISP_NB_ROW; ++i) {
|
|
gprintXY(x - 2, y + i, "%p", record);
|
|
for (int j = 0; j < 8; ++j) {
|
|
gprintXY(x + 9 + (j * 3), y + i, "%.2x", record[j]);
|
|
if (record[j] < 0x20 || record[j] > 0x7e) {
|
|
gtextXY(x + 34 + j, y + i, ".");
|
|
continue;
|
|
}
|
|
gprintXY(x + 34 + j, y + i, "%c", record[j]);
|
|
}
|
|
gtextXY(x + 33, y + i, "|");
|
|
gtextXY(x + 42, y + i, "|");
|
|
record = &record[8];
|
|
}
|
|
}
|
|
|
|
/* hexdump_keyboard(): Handle one key event */
|
|
static int hexdump_keyboard(struct tsession *session, int key)
|
|
{
|
|
if (key == KEY_LEFT)
|
|
session->menu.hexdump.cursor.hoffset += 1;
|
|
if (key == KEY_RIGHT)
|
|
session->menu.hexdump.cursor.hoffset -= 1;
|
|
|
|
if (key == KEY_UP)
|
|
session->menu.hexdump.addr = &session->menu.hexdump.addr[-8];
|
|
if (key == KEY_DOWN)
|
|
session->menu.hexdump.addr = &session->menu.hexdump.addr[8];
|
|
|
|
return (0);
|
|
}
|
|
|
|
/* hexdump_command(): Handle user command */
|
|
static void hexdump_command(struct tsession *session, int argc, char **argv)
|
|
{
|
|
uintptr_t address;
|
|
int i;
|
|
|
|
if (argc != 2)
|
|
return;
|
|
if (strcmp(argv[0], "jmp") != 0) {
|
|
input_write("unknown '%s' command", argv[0]);
|
|
return;
|
|
}
|
|
i = -1;
|
|
address = 0x00000000;
|
|
while (++i < 8 && argv[1][i] != '\0') {
|
|
address = address << 4;
|
|
if (argv[1][i] >= '0' && argv[1][i] <= '9') {
|
|
address = address + argv[1][i] - '0';
|
|
continue;
|
|
}
|
|
if (argv[1][i] >= 'a' && argv[1][i] <= 'f') {
|
|
address = address + argv[1][i] - 'a' + 10;
|
|
continue;
|
|
}
|
|
if (argv[1][i] >= 'A' && argv[1][i] <= 'F') {
|
|
address = address + argv[1][i] - 'A' + 10;
|
|
continue;
|
|
}
|
|
input_write("'%s': second argument error", argv[0]);
|
|
return;
|
|
}
|
|
session->menu.hexdump.addr = (void*)(address & ~3);
|
|
}
|
|
|
|
//---
|
|
// Define the menu
|
|
//---
|
|
struct menu menu_hexdump = {
|
|
.ctor = (void*)&hexdump_ctor,
|
|
.init = NULL,
|
|
.display = (void*)&hexdump_display,
|
|
.keyboard = (void*)&hexdump_keyboard,
|
|
.command = (void*)&hexdump_command,
|
|
.dtor = NULL
|
|
};
|