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:
parent
88bf3b7d29
commit
ef933ff508
4
Makefile
4
Makefile
|
@ -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
12
TODO
|
@ -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
|
||||
|
|
27
demo/main.c
27
demo/main.c
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
BIN
gintrace.g3a
BIN
gintrace.g3a
Binary file not shown.
|
@ -15,6 +15,7 @@ struct tsession {
|
|||
/* session information */
|
||||
struct {
|
||||
void *starting;
|
||||
void *removed;
|
||||
struct ucontext *context;
|
||||
} info;
|
||||
|
||||
|
|
BIN
libgintrace-cg.a
BIN
libgintrace-cg.a
Binary file not shown.
48
src/gint.c
48
src/gint.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue