mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-06 05:48:04 +03:00
aindump: add "raw" code dumping mode
Add mode which prints all arguments as numbers and does not generate labels. This is for debugging.
This commit is contained in:
+11
-3
@@ -27,7 +27,7 @@
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
|
||||
void disassemble_ain(struct ain *ain, FILE *out);
|
||||
void disassemble_ain(FILE *out, struct ain *ain, bool raw);
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
@@ -36,6 +36,7 @@ static void usage(void)
|
||||
puts("");
|
||||
puts(" -h, --help Display this message and exit");
|
||||
puts(" -c, --code Dump code section");
|
||||
puts(" -C, --raw-code Dump code section (raw)");
|
||||
puts(" -f, --functions Dump functions section");
|
||||
puts(" -g, --globals Dump globals section");
|
||||
puts(" -S, --structures Dump structures section");
|
||||
@@ -247,6 +248,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
bool dump_version = false;
|
||||
bool dump_code = false;
|
||||
bool dump_raw_code = false;
|
||||
bool dump_functions = false;
|
||||
bool dump_globals = false;
|
||||
bool dump_structures = false;
|
||||
@@ -268,6 +270,7 @@ int main(int argc, char *argv[])
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "ain-version", no_argument, 0, 'V' },
|
||||
{ "code", no_argument, 0, 'c' },
|
||||
{ "raw-code", no_argument, 0, 'C' },
|
||||
{ "functions", no_argument, 0, 'f' },
|
||||
{ "globals", no_argument, 0, 'g' },
|
||||
{ "structures", no_argument, 0, 'S' },
|
||||
@@ -284,7 +287,7 @@ int main(int argc, char *argv[])
|
||||
int option_index = 0;
|
||||
int c;
|
||||
|
||||
c = getopt_long(argc, argv, "hVcfgSmlsFeAo:", long_options, &option_index);
|
||||
c = getopt_long(argc, argv, "hVcCfgSmlsFeAo:", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
@@ -298,6 +301,9 @@ int main(int argc, char *argv[])
|
||||
case 'c':
|
||||
dump_code = true;
|
||||
break;
|
||||
case 'C':
|
||||
dump_raw_code = true;
|
||||
break;
|
||||
case 'f':
|
||||
dump_functions = true;
|
||||
break;
|
||||
@@ -382,7 +388,9 @@ int main(int argc, char *argv[])
|
||||
if (dump_enums)
|
||||
ain_dump_enums(output, ain);
|
||||
if (dump_code)
|
||||
disassemble_ain(ain, output);
|
||||
disassemble_ain(output, ain, false);
|
||||
if (dump_raw_code)
|
||||
disassemble_ain(output, ain, true);
|
||||
if (audit)
|
||||
ain_audit(output, ain);
|
||||
|
||||
|
||||
+26
-15
@@ -29,6 +29,7 @@ struct dasm_state {
|
||||
FILE *out;
|
||||
size_t addr;
|
||||
int func;
|
||||
bool raw;
|
||||
};
|
||||
|
||||
#define NR_LABEL_BUCKETS 128
|
||||
@@ -136,6 +137,10 @@ static void print_string(struct dasm_state *dasm, struct string *s)
|
||||
|
||||
static void print_argument(struct dasm_state *dasm, int32_t arg, enum instruction_argtype type)
|
||||
{
|
||||
if (dasm->raw) {
|
||||
fprintf(dasm->out, "0x%x", arg);
|
||||
return;
|
||||
}
|
||||
char *label;
|
||||
struct ain *ain = dasm->ain;
|
||||
switch (type) {
|
||||
@@ -227,6 +232,9 @@ static void print_arguments(struct dasm_state *dasm, const struct instruction *i
|
||||
|
||||
static void print_instruction(struct dasm_state *dasm, const struct instruction *instr)
|
||||
{
|
||||
if (dasm->raw) {
|
||||
fprintf(dasm->out, "0x%08lX:\t", dasm->addr);
|
||||
}
|
||||
switch (instr->opcode) {
|
||||
case FUNC:
|
||||
dasm->func = LittleEndian_getDW(dasm->ain->code, dasm->addr + 2);
|
||||
@@ -266,29 +274,32 @@ static char *genlabel(size_t addr)
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
void disassemble_ain(struct ain *ain, FILE *out)
|
||||
void disassemble_ain(FILE *out, struct ain *ain, bool raw)
|
||||
{
|
||||
struct dasm_state dasm = {
|
||||
.ain = ain,
|
||||
.out = out,
|
||||
.addr = 0,
|
||||
.func = -1
|
||||
.func = -1,
|
||||
.raw = raw
|
||||
};
|
||||
|
||||
// first pass to generate labels
|
||||
for (dasm.addr = 0; dasm.addr < dasm.ain->code_size;) {
|
||||
const struct instruction *instr = get_instruction(&dasm);
|
||||
switch (instr->opcode) {
|
||||
case JUMP:
|
||||
case IFZ:
|
||||
case IFNZ: {
|
||||
int32_t arg = LittleEndian_getDW(dasm.ain->code, dasm.addr + 2);
|
||||
add_label(genlabel(arg), arg);
|
||||
break;
|
||||
if (!raw) {
|
||||
// first pass to generate labels
|
||||
for (dasm.addr = 0; dasm.addr < dasm.ain->code_size;) {
|
||||
const struct instruction *instr = get_instruction(&dasm);
|
||||
switch (instr->opcode) {
|
||||
case JUMP:
|
||||
case IFZ:
|
||||
case IFNZ: {
|
||||
int32_t arg = LittleEndian_getDW(dasm.ain->code, dasm.addr + 2);
|
||||
add_label(genlabel(arg), arg);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
dasm.addr += instruction_width(instr->opcode);
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
dasm.addr += instruction_width(instr->opcode);
|
||||
}
|
||||
|
||||
for (dasm.addr = 0; dasm.addr < dasm.ain->code_size;) {
|
||||
|
||||
Reference in New Issue
Block a user