Gintracer v0.8.1 - World independent

@update
<> Now, the tracer have it own world (a copy of gint world), so this allows the
   tracer to be completely independent vis-à-vis the traced world. The world can
   be analyzed with a menu (not implemented but noted in the TODO)
This commit is contained in:
Yatis 2021-03-13 17:48:37 +01:00
parent 88bf3b7d29
commit ef933ff508
11 changed files with 110 additions and 45 deletions

View File

@ -238,14 +238,14 @@ ifeq ($1,fx)
target-$(tname)-cflags += -D FX9860G -m3
target-$(tname)-ldflags += -T fx9860g.ld
target-$(tname)-libs := -L. -L $(GCC_INCLUDE_FX)
target-$(tname)-libs += -lgintrace-fx -lgint-fx -lgcc
target-$(tname)-libs += -lgint-fx -lgintrace-fx -lgint-fx -lgcc
target-$(tname)-exec := $3.g1a
endif
ifeq ($1,cg)
target-$(tname)-cflags += -D FXCG50 -m4-nofpu
target-$(tname)-ldflags += -T fxcg50.ld
target-$(tname)-libs := -L. -L $(GCC_INCLUDE_CG)
target-$(tname)-libs += -lgintrace-cg -lgint-cg -lgcc
target-$(tname)-libs += -lgint-cg -lgintrace-cg -lgint-cg -lgcc
target-$(tname)-exec := $3.g3a
endif

12
TODO
View File

@ -3,17 +3,19 @@
* fix fx9860 support
@update
* makefile: generate the demo
* makefile: handle header dependencies
* makefile: handle dynamic lib generation
* makefile: generate the documentation
* context: refacto printXY() !
* hexdump: search commands
* callgraph: improve user interface.
* disasm: set manually multiple breakpoint
* savefile
* load saved file
* list color scheme on SMEM.
* icon
@feature
* add documentation
* switch to justUI
* add drivers menu
* savefile
* load saved file
* list color scheme on SMEM.
* disasm: set manually multiple breakpoint

View File

@ -5,6 +5,9 @@
#include <gint/keyboard.h>
#include <gint/gint.h>
extern void *kernel_env_gint;
extern void *kernel_env_casio;
extern void *gint_switch_to_world(void *buffctx);
/* main(): User entry */
int main(void)
@ -13,6 +16,26 @@ int main(void)
void **systab;
void *syscall;
#if 0
int x = 0;
int key = 0;
while (1) {
dclear(C_WHITE);
dtext(0, 0, C_BLACK, "Unable to create tracer session");
dtext(0, 10, C_BLACK, "Press [MENU]...");
dprint(x, 20, C_BLACK, "buffctx: %p", drivers_get_current());
dprint(x, 30, C_BLACK, "gintctx: %p", kernel_env_gint);
dprint(x, 40, C_BLACK, "casioctx: %p", kernel_env_casio);
dupdate();
key = getkey().key;
if (key == KEY_LEFT)
x = x + 10;
if (key == KEY_RIGHT)
x = x - 10;
}
#endif
/* get syscall address */
systab = *(void ***)0x8002007c;
//syscall = systab[0x1e48]; // Fugue_debug_menu
@ -38,10 +61,10 @@ int main(void)
//---
void (*bfile_openfile_os)(const uint16_t *filename, int mode, int p3);
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
bfile_openfile_os = syscall;
bfile_openfile_os(u"\\\\fls0\\abcdefgijklmn", BFile_ReadOnly, 0);
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);

Binary file not shown.

View File

@ -15,6 +15,7 @@ struct tsession {
/* session information */
struct {
void *starting;
void *removed;
struct ucontext *context;
} info;

Binary file not shown.

View File

@ -4,44 +4,54 @@
#include <gint/atomic.h>
#include <gint/defs/attributes.h>
#include <gint/drivers.h>
#include <gint/display.h>
/* external symbols */
extern void *kernel_env_casio;
extern void *kernel_env_gint;
extern void *kernel_env_tracer;
/* gint_switch(): Temporarily switch out of gint */
void gint_switch(void (*function)(void))
{
void *buffctx_current;
void *buffctx;
/* check useless action */
if (function == NULL)
return;
/* check useless world switch */
buffctx_current = drivers_get_current();
if (kernel_env_casio == buffctx_current) {
function();
return;
}
/* Switch from gint to the OS after a short wait */
ubc_uninstall();
drivers_wait();
drivers_switch(kernel_env_gint, kernel_env_casio);
buffctx = drivers_switch(kernel_env_casio);
ubc_install();
if(function != NULL)
function();
/* involve the function */
function();
/* then switch back to gint once the os finishes working */
ubc_uninstall();
drivers_wait();
drivers_switch(kernel_env_casio, kernel_env_gint);
drivers_switch(buffctx);
ubc_install();
}
/* Switch from gint to the OS after a short wait */
void gint_switch_to_casio(void)
void *gint_switch_to_world(void *buffctx)
{
ubc_uninstall();
drivers_wait();
drivers_switch(kernel_env_gint, kernel_env_casio);
ubc_install();
}
void *buffctx_current;
/* Switch from gint to the OS after a short wait */
void gint_switch_to_gint(void)
{
ubc_uninstall();
drivers_wait();
drivers_switch(kernel_env_casio, kernel_env_gint);
ubc_install();
buffctx_current = drivers_get_current();
if (buffctx != buffctx_current) {
ubc_uninstall();
drivers_switch(buffctx);
ubc_install();
}
return (buffctx_current);
}

View File

@ -14,6 +14,11 @@
#include "./src/menu/internal/dictionary.h"
/* internal info (TODO: move me) */
extern void *kernel_env_gint;
extern void *kernel_env_casio;
extern void *gint_switch_to_world(void *buffctx);
//---
// callode management
//---
@ -321,11 +326,11 @@ static void callgraph_command(struct tsession *session, int argc, char **argv)
/* check if the file exist */
input_write_noint("Check if the file exist");
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
char line[256];
int fd = BFile_Open(pathname, BFile_ReadOnly);
if (fd >= 0) {
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
while (1) {
if (input_read(line, 3, "'%s' exist, erase ? [n/Y]:",
argv[1]) <= 0) {
@ -338,39 +343,39 @@ static void callgraph_command(struct tsession *session, int argc, char **argv)
}
if (line[0] != 'Y')
continue;
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
BFile_Remove(pathname);
break;
}
}
/* create the file then dump information */
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
int size = callnode_export(-1, session->menu.callgraph.root, line);
input_write_noint("Create the file (%d)", size);
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
fd = BFile_Create(pathname, BFile_File, &size);
if (fd != 0) {
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
input_write("Bfile_Create: error %d", fd);
return;
}
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
input_write_noint("Create success");
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
fd = BFile_Open(pathname, BFile_ReadWrite);
if (fd < 0) {
BFile_Remove(pathname);
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
input_write("BFile_Open: error %d", fd);
return;
}
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
input_write_noint("Open success, now write...");
gint_switch_to_casio();
gint_switch_to_world(kernel_env_casio);
callnode_export(fd, session->menu.callgraph.root, line);
BFile_Close(fd);
gint_switch_to_gint();
gint_switch_to_world(kernel_env_gint);
input_write("success");
}

View File

@ -12,6 +12,7 @@ struct tsession *tracer_create_session(void *address, int menu)
extern void gintrace_handler(struct ucontext *context);
struct tsession *session;
/* check error */
if (address == NULL || (menu & (TRACER_DISASM
| TRACER_CONTEXT
| TRACER_HEXDUMP
@ -19,6 +20,7 @@ struct tsession *tracer_create_session(void *address, int menu)
return(NULL);
}
/* try to create the session */
session = calloc(sizeof(struct tsession), 1);
if (session == NULL)
return (NULL);
@ -35,6 +37,7 @@ struct tsession *tracer_create_session(void *address, int menu)
if ((menu & TRACER_CALLGRAPH) != 0)
menu_register(session->display.gmenu, &menu_callgraph, "CallG");
/* force install the UBC driver */
ubc_install();
ubc_set_handler(&gintrace_handler);
ubc_set_breakpoint(0, address, NULL);
@ -53,6 +56,11 @@ struct tsession *tracer_set_session(struct tsession *new)
void *old;
old = session;
//FIXME: save current trace info
session = new;
//FIXME: restore current trace info
//ubc_install();
//ubc_set_handler(&gintrace_handler);
//ubc_set_breakpoint(0, address, NULL);
return (old);
}

View File

@ -8,6 +8,11 @@
#include <gint/gint.h>
// custom function
extern void *kernel_env_gint;
extern void *kernel_env_tracer;
extern void *gint_switch_to_world(void *buffctx);
/* gintrac_handler(): UBC handler
* @note:
* To force generate the callgraph, we use a dirty workaround to force break
@ -20,6 +25,7 @@ void gintrace_handler(struct ucontext *context)
static uintptr_t breakpoint = 0x00000000;
static uintptr_t spc = 0x00000000;
struct tsession *session;
void *buffctx;
/* force disable the UBC to avoid error */
ubc_block();
@ -33,6 +39,7 @@ void gintrace_handler(struct ucontext *context)
session->info.context = context;
/* check callgraph job */
//FIXME: move me
if (breakpoint != 0x00000000
&& spc != 0x00000000
&& spc != breakpoint) {
@ -44,7 +51,7 @@ void gintrace_handler(struct ucontext *context)
}
/* user break point */
gint_switch_to_gint();
buffctx = gint_switch_to_world(kernel_env_tracer);
menu_init(session->display.gmenu);
while (menu_is_open(session->display.gmenu) == 0) {
menu_draw(session->display.gmenu);
@ -52,6 +59,7 @@ void gintrace_handler(struct ucontext *context)
}
/* if no instruction skip, restore */
//FIXME: move me
if (session->menu.disasm.skip == 0) {
spc = context->spc;
ubc_set_breakpoint(0, (void*)context->spc, NULL);
@ -62,8 +70,7 @@ void gintrace_handler(struct ucontext *context)
spc = breakpoint;
}
/* unblock UBC interrupt */
ubc_unblock();
gint_switch_to_casio();
gint_switch_to_world(buffctx);
}

View File

@ -1,11 +1,16 @@
#include "gintrace/ubc.h"
#include <gint/mpu/power.h>
/* internal saved driver state */
#include <gint/mpu/power.h>
#include <gint/drivers.h>
/* internal UBC driver information */
struct sh7305_ubc_context ubctx;
void (*ubc_handler)(struct ucontext *ctx) = NULL;
int ubc_driver_installed = 0;
extern void *kernel_env_gint;
void *kernel_env_tracer = NULL;
/* ubc_install(): Install the UBC driver */
void ubc_install(void)
@ -42,6 +47,10 @@ void ubc_install(void)
SH7305_UBC.CBR1.CE = 0;
SH7305_UBC.CBCR.UBDE = 1;
/* generate the "tracer" tmp context */
if (kernel_env_tracer == NULL)
drivers_context_duplicate(&kernel_env_tracer, kernel_env_gint);
/* indicate that the UBC driver is installed */
ubc_driver_installed = 1;
}