gintrace/src/main.c

103 lines
2.5 KiB
C

#include "gintrace/gui/menu.h"
#include "gintrace/menu/disasm.h"
#include "gintrace/menu/context.h"
#include "gintrace/menu/hexdump.h"
#include "gintrace/menu/callgraph.h"
#include "gintrace/ubc.h"
#include <gint/gint.h>
#include <gint/keyboard.h>
#include <gint/display.h>
#include <gint/bfile.h>
/* workaround test */
extern struct tracer tracer;
/* save the selected menu */
static struct menu_group *gmenu = NULL;
/* syscall address */
static void *syscall = NULL;
/* gintrac_handler(): UBC handler
* @note:
* To force generate the callgraph, we use a dirty workaround to force break
* at each instruction. But, the disassembler menu can skip one instruction
* using OPTN key, so you should not "unskip" the user action. */
static void gintrace_handler(struct ucontext *context)
{
static uintptr_t breakpoint = 0x00000000;
static uintptr_t spc = 0x00000000;
/* force disable the UBC to avoid error */
ubc_block();
/* check callgraph job */
if (breakpoint != 0x00000000
&& spc != 0x00000000
&& spc != breakpoint) {
menu_callgraph.init(context);
spc = context->spc;
ubc_set_breakpoint(0, (void*)context->spc, NULL);
ubc_unblock();
return;
}
/* user break point */
gint_switch_to_gint();
menu_init(gmenu, context);
while (menu_is_open(gmenu) == 0) {
menu_draw(gmenu);
menu_keyboard(gmenu);
}
/* if no instruction skip, restore */
spc = context->spc;
ubc_set_breakpoint(0, (void*)context->spc, NULL);
breakpoint = tracer.next_break;
/* unblock UBC interrupt */
ubc_unblock();
gint_switch_to_casio();
}
/* casio_handler(): Casio handler */
static void casio_handler(void)
{
#if 0
void (*bfile_openfile_os)(const uint16_t *filename, int mode, int p3);
bfile_openfile_os = syscall;
bfile_openfile_os(u"\\fls0\\dyntest", BFile_ReadOnly, 0);
#endif
void (*debug_menu_filesystem)(void) = syscall;
debug_menu_filesystem();
}
/* main(): User entry */
int main(void)
{
/* initialize all internal menu and get the "first" menu to display */
menu_create(&gmenu);
menu_register(gmenu, &menu_disasm, "Disasm");
menu_register(gmenu, &menu_context, "Context");
menu_register(gmenu, &menu_hexdump, "Hexdump");
menu_register(gmenu, &menu_callgraph, "CallG");
/* get syscall address */
void **systab = *(void ***)0x8002007c;
syscall = systab[0x1e48];
/* intialize UBC information */
ubc_install();
ubc_set_handler(&gintrace_handler);
ubc_set_breakpoint(0, syscall, NULL);
/* try to trace the function */
gint_switch((void*)&casio_handler);
//TODO : destructor part !!
return (0);
}