Add trace function for debugging

This commit is contained in:
rkx1209 2018-03-11 07:14:59 +09:00
parent 7454916a8d
commit 99d3ca8f30
8 changed files with 65 additions and 22 deletions

View file

@ -9,7 +9,7 @@ void Init() {
Interpreter::create ();
cpu_engine = Interpreter::get_instance ();
PC = 0x0;
SP = 0x30000;
SP = 0x3100000;
}
void RunLoop() {
@ -32,4 +32,22 @@ void Dump() {
ns_print ("NZCV\t0x%016lx\n", NZCV);
}
static uint64_t counter;
void DumpJson(FILE *fp) {
if (counter >= 243)
return;
file_print (fp, "%lu : {\n", counter++);
for (int r = 0; r <= GPR_DUMMY; r++) {
if (r == GPR_LR && X(r))
file_print (fp, "\"X%d\" : \"0x%016lx\"", r, X(r) + 4);
else
file_print (fp, "\"X%d\" : \"0x%016lx\"", r, X(r));
if (r == GPR_DUMMY)
file_print (fp, "\n");
else
file_print (fp, ",\n");
}
file_print (fp, "},\n");
}
}

View file

@ -19,14 +19,14 @@ void Interpreter::Run() {
while (Cpu::GetState () == Cpu::State::Running) {
char c;
//scanf("%c", &c);
Cpu::DumpMachine ();
SingleStep ();
//Cpu::DumpMachine ();
if (PC == 0x34) {
SingleStep ();
Cpu::DumpMachine ();
debug_print("Reach\n");
break;
}
// if (PC == 0x2d54) {
// SingleStep ();
// Cpu::DumpMachine ();
// debug_print("Reach\n");
// break;
// }
}
}

View file

@ -3,6 +3,7 @@
namespace Cpu {
static State state = State::PowerDown;
FILE *TraceOut;
void Init() {
ARMv8::Init ();
@ -27,7 +28,9 @@ State GetState() {
}
void DumpMachine() {
ARMv8::Dump ();
//ARMv8::Dump ();
if (TraceOut)
ARMv8::DumpJson (TraceOut);
}
}

View file

@ -51,14 +51,26 @@ struct Arg : public option::Arg {
}
};
void InitTrace(const char *fname) {
if ((Cpu::TraceOut = fopen(fname, "w")) == NULL) {
ns_abort ("Can not open output file for trace\n");
}
}
void FinTrace() {
if (Cpu::TraceOut)
fclose (Cpu::TraceOut);
}
enum optionIndex {
UNKNOWN, HELP
UNKNOWN, HELP, ENABLE_TRACE
};
const option::Descriptor usage[] =
{
{ UNKNOWN, 0, "", "", Arg::None, "USAGE: nsemu [options] <nso-binary>\n\n"
"Options:" },
{ HELP, 0, "", "help", Arg::None, " --help \tUnsurprisingly, print this message." },
{ HELP, 0, "", "help", Arg::None, " --help \tPrint help message" },
{ ENABLE_TRACE, 0, "t","enable-trace", Arg::None, " --enable-trace, -t \tEnable Trace" },
{ 0, 0, nullptr, nullptr, nullptr, nullptr }
};
@ -81,6 +93,9 @@ printUsage:
option::printUsage (cout, usage);
return 0;
}
if (options[ENABLE_TRACE].count () > 0) {
InitTrace ("nsemu_trace.json");
}
#if 0
if (options[NSO].count () > 0) {
if (options[NSO].count () != 1) {
@ -104,12 +119,13 @@ printUsage:
}
} else {
}
#endif
#endif
if (parse.nonOptionsCount () != 1) {
goto printUsage;
}
}
nsemu->BootUp (parse.nonOption (0));
Nsemu::destroy ();
FinTrace ();
return 0;
}

View file

@ -18,15 +18,15 @@ namespace Memory
uint8_t *pRAM; // XXX: Replace raw pointer to View wrapper.
static RAMBlock mem_map[] =
{
RAMBlock (".text", 0x0, 0x10000, PROT_READ | PROT_WRITE | PROT_EXEC),
RAMBlock (".rdata", 0x10000, 0x10000, PROT_READ | PROT_WRITE),
RAMBlock (".data", 0x20000, 0x10000, PROT_READ | PROT_WRITE),
RAMBlock ("[stack]", 0x30000, 0x4000000, PROT_READ | PROT_WRITE),
RAMBlock (".text", 0x0, 0x1000000, PROT_READ | PROT_WRITE | PROT_EXEC),
RAMBlock (".rdata", 0x1000000, 0x1000000, PROT_READ | PROT_WRITE),
RAMBlock (".data", 0x2000000, 0x1000000, PROT_READ | PROT_WRITE),
RAMBlock ("[stack]", 0x3000000, 0x6000000, PROT_READ | PROT_WRITE),
};
void InitMemmap(Nsemu *nsemu) {
void *data;
if ((data = mmap (nullptr, 0x5000000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
if ((data = mmap (nullptr, 0x10000000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
ns_abort ("Failed to allocate host memory\n");
}
pRAM = (uint8_t *) data;

View file

@ -67,6 +67,8 @@ void RunLoop();
void Dump();
void DumpJson(FILE *fp);
}
#endif

View file

@ -20,5 +20,7 @@ State GetState();
void DumpMachine();
extern FILE *TraceOut;
}
#endif

View file

@ -16,18 +16,20 @@ enum RunLevel {
//static RunLevel curlevel = RUN_LEVEL_DEBUG;
static RunLevel curlevel = RUN_LEVEL_RELEASE;
static void util_print(RunLevel level, const char *format, ...) {
static void util_print(RunLevel level, FILE *fp, const char *format, ...) {
if (curlevel >= level) {
va_list va;
va_start (va, format);
vprintf (format, va);
vfprintf (fp, format, va);
va_end (va);
}
fflush(stdout);
fflush(fp);
}
#define debug_print(format, ...) util_print (RUN_LEVEL_DEBUG, format, ## __VA_ARGS__)
#define ns_print(format, ...) util_print (RUN_LEVEL_RELEASE, format, ## __VA_ARGS__)
#define debug_print(format, ...) util_print (RUN_LEVEL_DEBUG, stdout, format, ## __VA_ARGS__)
#define ns_print(format, ...) util_print (RUN_LEVEL_RELEASE, stdout, format, ## __VA_ARGS__)
#define file_print(fp, format, ...) util_print (RUN_LEVEL_RELEASE, fp, format, ## __VA_ARGS__)
#define ns_abort(format, ...) \
ns_print ("%s: ", __func__); \
ns_print (format, ## __VA_ARGS__);\