Add disassemblre group option

This commit is contained in:
hiperiondev
2023-08-28 23:46:02 -03:00
parent 6be29ed8c5
commit a9ccd65da1
5 changed files with 315 additions and 176 deletions

View File

@@ -175,7 +175,18 @@ typedef struct fun_code_s {
char *fun; char *fun;
} fun_code_t; } fun_code_t;
typedef struct lit_s {
char *fun;
char *str;
} *lit_t;
uint32_t jump_label; uint32_t jump_label;
uint32_t function_queue_len = 0;
uint32_t lit_fn_queue_len = 0;
queue_node_t *function_queue_front = NULL;
queue_node_t *function_queue_rear = NULL;
queue_node_t *lit_fn_queue_front = NULL;
queue_node_t *lit_fn_queue_rear = NULL;
static void dis_print_opcode(uint8_t op); static void dis_print_opcode(uint8_t op);
@@ -322,7 +333,7 @@ static void dis_print_opcode(uint8_t op) {
exit(1); \ exit(1); \
} }
static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t len, uint8_t spaces, bool is_function, bool alt_fmt) { static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t len, uint8_t spaces, bool is_function, options_t config) {
uint8_t opcode = 0; uint8_t opcode = 0;
uint16_t uint = 0; uint16_t uint = 0;
int32_t intg = 0; int32_t intg = 0;
@@ -334,7 +345,7 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
printf("\n"); printf("\n");
uint16_t args = readWord((*prg)->program, &pc); uint16_t args = readWord((*prg)->program, &pc);
uint16_t rets = readWord((*prg)->program, &pc); uint16_t rets = readWord((*prg)->program, &pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| "); printf("| ");
} else } else
@@ -346,7 +357,7 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
uint32_t labels_qty = 0; uint32_t labels_qty = 0;
uint16_t *label_line = NULL; uint16_t *label_line = NULL;
uint32_t *label_id = NULL; uint32_t *label_id = NULL;
if (alt_fmt) { if (config.alt_format_flag) {
// first pass: search jump labels // first pass: search jump labels
label_line = malloc(sizeof(uint16_t)); label_line = malloc(sizeof(uint16_t));
label_id = malloc(sizeof(uint32_t)); label_id = malloc(sizeof(uint32_t));
@@ -356,7 +367,7 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
label_id = realloc(label_id, (labels_qty + 1) * sizeof(uint32_t)); label_id = realloc(label_id, (labels_qty + 1) * sizeof(uint32_t));
opcode = (*prg)->program[pc]; opcode = (*prg)->program[pc];
if (alt_fmt && (opcode == 255 || opcode == 0)) { if (config.alt_format_flag && (opcode == 255 || opcode == 0)) {
++pc; ++pc;
continue; continue;
} }
@@ -383,7 +394,7 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
while (pc < len) { while (pc < len) {
opcode = (*prg)->program[pc]; opcode = (*prg)->program[pc];
if (alt_fmt) { if (config.alt_format_flag) {
for (uint32_t lbl = 0; lbl < labels_qty; lbl++) { for (uint32_t lbl = 0; lbl < labels_qty; lbl++) {
if (pc - pc_start == label_line[lbl]) { if (pc - pc_start == label_line[lbl]) {
printf("\nJL_%04d_:", label_id[lbl]); printf("\nJL_%04d_:", label_id[lbl]);
@@ -392,13 +403,13 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
} }
} }
if (alt_fmt && (opcode == 255 || opcode == 0)) { if (config.alt_format_flag && (opcode == 255 || opcode == 0)) {
++pc; ++pc;
continue; continue;
} }
printf("\n"); printf("\n");
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| "); printf("| ");
printf("[%05d](%03d) ", (pc++) - pc_start, opcode); printf("[%05d](%03d) ", (pc++) - pc_start, opcode);
@@ -412,7 +423,7 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
if (opcode >= DIS_OP_END_OPCODES) if (opcode >= DIS_OP_END_OPCODES)
continue; continue;
if (alt_fmt) { if (config.alt_format_flag) {
if (OP_ARGS[opcode][2]) { if (OP_ARGS[opcode][2]) {
uint = readWord((*prg)->program, &pc); uint = readWord((*prg)->program, &pc);
for (uint32_t lbl = 0; lbl < labels_qty; lbl++) { for (uint32_t lbl = 0; lbl < labels_qty; lbl++) {
@@ -429,43 +440,48 @@ static void dis_disassemble_section(dis_program_t **prg, uint32_t pc, uint32_t l
S_OP(1, 1); S_OP(1, 1);
} }
if (alt_fmt) { if (config.alt_format_flag) {
free(label_line); free(label_line);
free(label_id); free(label_id);
} }
if (alt_fmt && (*prg)->program[pc - 5] != DIS_OP_FN_RETURN) if (config.alt_format_flag && (*prg)->program[pc - 5] != DIS_OP_FN_RETURN)
printf("\n FN_RETURN w(0)"); printf("\n FN_RETURN w(0)");
} }
#define LIT_ADD(a, b, c) b[c] = a; ++c; #define LIT_ADD(a, b, c) b[c] = a; ++c;
static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uint8_t spaces, char *tree, bool alt_fmt) { static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uint8_t spaces, char *tree, options_t config) {
uint32_t literal_count = 0; uint32_t literal_count = 0;
uint8_t literal_type[65536]; uint8_t literal_type[65536];
char *lit_str = NULL;
const unsigned short literalCount = readWord((*prg)->program, pc); const unsigned short literalCount = readWord((*prg)->program, pc);
if(!config.group_flag)
printf("\n"); printf("\n");
if (!alt_fmt) {
if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| "); printf("| ");
printf(" "); printf(" ");
printf("--- ( Reading %d literals from cache ) ---\n", literalCount); printf("--- ( Reading %d literals from cache ) ---\n", literalCount);
} }
if (config.alt_format_flag)
lit_str = calloc(1, sizeof(char));
for (int i = 0; i < literalCount; i++) { for (int i = 0; i < literalCount; i++) {
const unsigned char literalType = readByte((*prg)->program, pc); const unsigned char literalType = readByte((*prg)->program, pc);
switch (literalType) { switch (literalType) {
case DIS_LITERAL_NULL: case DIS_LITERAL_NULL:
LIT_ADD(DIS_LITERAL_NULL, literal_type, literal_count); LIT_ADD(DIS_LITERAL_NULL, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( null )\n", i); printf("[%05d] ( null )\n", i);
} else { } else {
printf(" "); str_append(&lit_str, " .lit NULL\n");
printf(".lit NULL\n");
} }
break; break;
@@ -473,13 +489,15 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_BOOLEAN: { case DIS_LITERAL_BOOLEAN: {
const bool b = readByte((*prg)->program, pc); const bool b = readByte((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_BOOLEAN, literal_type, literal_count); LIT_ADD(DIS_LITERAL_BOOLEAN, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( boolean %s )\n", i, b ? "true" : "false"); printf("[%05d] ( boolean %s )\n", i, b ? "true" : "false");
} else { } else {
printf(" "); char bs[10];
printf(".lit BOOLEAN %s\n", b ? "true" : "false"); sprintf(bs, "%s\n", b ? "true" : "false");
str_append(&lit_str, " .lit BOOLEAN ");
str_append(&lit_str, bs);
} }
} }
break; break;
@@ -487,13 +505,15 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_INTEGER: { case DIS_LITERAL_INTEGER: {
const int d = readInt((*prg)->program, pc); const int d = readInt((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_INTEGER, literal_type, literal_count); LIT_ADD(DIS_LITERAL_INTEGER, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( integer %d )\n", i, d); printf("[%05d] ( integer %d )\n", i, d);
} else { } else {
printf(" "); char ds[20];
printf(".lit INTEGER %d\n", d); sprintf(ds, "%d\n", d);
str_append(&lit_str, " .lit INTEGER ");
str_append(&lit_str, ds);
} }
} }
break; break;
@@ -501,13 +521,15 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_FLOAT: { case DIS_LITERAL_FLOAT: {
const float f = readFloat((*prg)->program, pc); const float f = readFloat((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_FLOAT, literal_type, literal_count); LIT_ADD(DIS_LITERAL_FLOAT, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( float %f )\n", i, f); printf("[%05d] ( float %f )\n", i, f);
} else { } else {
printf(" "); char fs[20];
printf(".lit FLOAT %f\n", f); sprintf(fs, "%f\n", f);
str_append(&lit_str, " .lit FLOAT ");
str_append(&lit_str, fs);
} }
} }
break; break;
@@ -515,13 +537,14 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_STRING: { case DIS_LITERAL_STRING: {
const char *s = readString((*prg)->program, pc); const char *s = readString((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_STRING, literal_type, literal_count); LIT_ADD(DIS_LITERAL_STRING, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( string \"%s\" )\n", i, s); printf("[%05d] ( string \"%s\" )\n", i, s);
} else { } else {
printf(" "); str_append(&lit_str, " .lit STRING \"");
printf(".lit STRING \"%s\"\n", s); str_append(&lit_str, s);
str_append(&lit_str, "\"\n");
} }
} }
break; break;
@@ -529,32 +552,42 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_ARRAY_INTERMEDIATE: case DIS_LITERAL_ARRAY_INTERMEDIATE:
case DIS_LITERAL_ARRAY: { case DIS_LITERAL_ARRAY: {
unsigned short length = readWord((*prg)->program, pc); unsigned short length = readWord((*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( array ", i); printf("[%05d] ( array ", i);
} else { } else {
printf(" "); str_append(&lit_str, " .lit ARRAY ");
printf(".lit ARRAY ");
} }
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
int index = readWord((*prg)->program, pc); int index = readWord((*prg)->program, pc);
if (!config.alt_format_flag) {
printf("%d ", index); printf("%d ", index);
} else {
char ds[20];
sprintf(ds, "%d ", index);
str_append(&lit_str, ds);
}
LIT_ADD(DIS_LITERAL_NULL, literal_type, literal_count); LIT_ADD(DIS_LITERAL_NULL, literal_type, literal_count);
if (!(i % 15) && i != 0) { if (!(i % 15) && i != 0) {
if (!config.alt_format_flag) {
printf("\\\n"); printf("\\\n");
if (!alt_fmt) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
} else
printf(" ");
printf(" "); printf(" ");
} else {
str_append(&lit_str, "\\\n ");
} }
} }
if (!alt_fmt) }
if (!config.alt_format_flag) {
printf(")"); printf(")");
printf("\n"); printf("\n");
} else {
str_append(&lit_str, "\n");
}
LIT_ADD(DIS_LITERAL_ARRAY, literal_type, literal_count); LIT_ADD(DIS_LITERAL_ARRAY, literal_type, literal_count);
} }
@@ -563,36 +596,42 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_DICTIONARY_INTERMEDIATE: case DIS_LITERAL_DICTIONARY_INTERMEDIATE:
case DIS_LITERAL_DICTIONARY: { case DIS_LITERAL_DICTIONARY: {
unsigned short length = readWord((*prg)->program, pc); unsigned short length = readWord((*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( dictionary ", i); printf("[%05d] ( dictionary ", i);
} else { } else {
printf(" "); str_append(&lit_str, " .lit DICTIONARY ");
printf(".lit DICTIONARY ");
} }
for (int i = 0; i < length / 2; i++) { for (int i = 0; i < length / 2; i++) {
int key = readWord((*prg)->program, pc); int key = readWord((*prg)->program, pc);
int val = readWord((*prg)->program, pc); int val = readWord((*prg)->program, pc);
if (!alt_fmt) if (!config.alt_format_flag)
printf("(key: %d, val:%d) ", key, val); printf("(key: %d, val:%d) ", key, val);
else else {
printf("%d,%d ", key, val); char s[100];
sprintf(s, "%d,%d ", key, val);
str_append(&lit_str, s);
}
if (!(i % 5) && i != 0) { if (!(i % 5) && i != 0) {
if (!config.alt_format_flag) {
printf("\\\n"); printf("\\\n");
if (!alt_fmt) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
} else
printf(" ");
printf(" "); printf(" ");
} else {
str_append(&lit_str, "\\\n ");
} }
} }
if (!alt_fmt) }
if (!config.alt_format_flag) {
printf(")"); printf(")");
printf("\n"); printf("\n");
} else {
str_append(&lit_str, "\n");
}
LIT_ADD(DIS_LITERAL_DICTIONARY, literal_type, literal_count); LIT_ADD(DIS_LITERAL_DICTIONARY, literal_type, literal_count);
} }
break; break;
@@ -600,13 +639,14 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_FUNCTION: { case DIS_LITERAL_FUNCTION: {
unsigned short index = readWord((*prg)->program, pc); unsigned short index = readWord((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_FUNCTION_INTERMEDIATE, literal_type, literal_count); LIT_ADD(DIS_LITERAL_FUNCTION_INTERMEDIATE, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( function index: %d )\n", i, index); printf("[%05d] ( function index: %d )\n", i, index);
} else { } else {
printf(" "); char s[100];
printf(".lit FUNCTION %d\n", index); sprintf(s, " .lit FUNCTION %d\n", index);
str_append(&lit_str, s);
} }
} }
break; break;
@@ -614,13 +654,14 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_IDENTIFIER: { case DIS_LITERAL_IDENTIFIER: {
const char *str = readString((*prg)->program, pc); const char *str = readString((*prg)->program, pc);
LIT_ADD(DIS_LITERAL_IDENTIFIER, literal_type, literal_count); LIT_ADD(DIS_LITERAL_IDENTIFIER, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( identifier %s )\n", i, str); printf("[%05d] ( identifier %s )\n", i, str);
} else { } else {
printf(" "); str_append(&lit_str, " .lit IDENTIFIER ");
printf(".lit IDENTIFIER %s\n", str); str_append(&lit_str, str);
str_append(&lit_str, "\n");
} }
} }
break; break;
@@ -629,38 +670,46 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_TYPE_INTERMEDIATE: { case DIS_LITERAL_TYPE_INTERMEDIATE: {
uint8_t literalType = readByte((*prg)->program, pc); uint8_t literalType = readByte((*prg)->program, pc);
uint8_t constant = readByte((*prg)->program, pc); uint8_t constant = readByte((*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( type %s: %d)\n", i, (LIT_STR[literalType] + 12), constant); printf("[%05d] ( type %s: %d)\n", i, (LIT_STR[literalType] + 12), constant);
} else { } else {
printf(" "); char s[100];
printf(".lit TYPE %s %d", (LIT_STR[literalType] + 12), constant); sprintf(s, ".lit TYPE %s %d", (LIT_STR[literalType] + 12), constant);
str_append(&lit_str, s);
} }
if (literalType == DIS_LITERAL_ARRAY) { if (literalType == DIS_LITERAL_ARRAY) {
uint16_t vt = readWord((*prg)->program, pc); uint16_t vt = readWord((*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("\n ( subtype: %d)", vt); printf("\n ( subtype: %d)\n", vt);
} else {
char s[100];
sprintf(s, " SUBTYPE %d\n", vt);
str_append(&lit_str, s);
}
} else } else
printf(" SUBTYPE %d", vt); if (literalType == DIS_LITERAL_DICTIONARY) {
printf("\n");
} else if (literalType == DIS_LITERAL_DICTIONARY) {
uint8_t kt = readWord((*prg)->program, pc); uint8_t kt = readWord((*prg)->program, pc);
uint8_t vt = readWord((*prg)->program, pc); uint8_t vt = readWord((*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("\n ( subtype: [%d, %d] )", kt, vt); printf("\n ( subtype: [%d, %d] )\n\n\n", kt, vt);
} else } else {
printf(" SUBTYPE %d,%d", kt, vt); char s[100];
sprintf(s, " SUBTYPE %d,%d\n", kt, vt);
printf("\n"); str_append(&lit_str, s);
} else }
} else {
if (!config.alt_format_flag)
printf("\n"); printf("\n");
else
str_append(&lit_str, "\n");
}
LIT_ADD(literalType, literal_type, literal_count); LIT_ADD(literalType, literal_type, literal_count);
} }
@@ -668,21 +717,29 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
case DIS_LITERAL_INDEX_BLANK: case DIS_LITERAL_INDEX_BLANK:
LIT_ADD(DIS_LITERAL_INDEX_BLANK, literal_type, literal_count); LIT_ADD(DIS_LITERAL_INDEX_BLANK, literal_type, literal_count);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("[%05d] ( blank )\n", i); printf("[%05d] ( blank )\n", i);
} else { } else {
printf(" "); str_append(&lit_str, " .lit BLANK\n");
printf(".lit BLANK\n");
} }
break; break;
} }
} }
if (!config.group_flag) {
printf(lit_str);
} else {
lit_t fn_str = (lit_t)(lit_fn_queue_rear->data);
fn_str->str = calloc(1, strlen(lit_str) + 1);
strcpy(fn_str->str, lit_str);
}
free(lit_str);
consumeByte(DIS_OP_SECTION_END, (*prg)->program, pc); consumeByte(DIS_OP_SECTION_END, (*prg)->program, pc);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| "); printf("| ");
printf("--- ( end literal section ) ---\n"); printf("--- ( end literal section ) ---\n");
@@ -692,7 +749,7 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
int functionSize = readWord((*prg)->program, pc); int functionSize = readWord((*prg)->program, pc);
if (functionCount) { if (functionCount) {
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("|\n"); printf("|\n");
SPC(spaces); SPC(spaces);
@@ -711,7 +768,7 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
uint32_t fpc_end = *pc + size - 1; uint32_t fpc_end = *pc + size - 1;
tree_local[0] = '\0'; tree_local[0] = '\0';
if (!alt_fmt) { if (!config.alt_format_flag) {
sprintf(tree_local, "%s.%d", tree, fcnt); sprintf(tree_local, "%s.%d", tree, fcnt);
if (tree_local[0] == '_') if (tree_local[0] == '_')
memcpy(tree_local, tree_local + 1, strlen(tree_local)); memcpy(tree_local, tree_local + 1, strlen(tree_local));
@@ -721,29 +778,37 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
memcpy(tree_local, tree_local + 1, strlen(tree_local)); memcpy(tree_local, tree_local + 1, strlen(tree_local));
} }
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| |\n"); printf("| |\n");
SPC(spaces); SPC(spaces);
printf("| | "); printf("| | ");
printf("( fun %s [ start: %d, end: %d ] )", tree_local, fpc_start, fpc_end); printf("( fun %s [ start: %d, end: %d ] )", tree_local, fpc_start, fpc_end);
} else } else {
if (!config.group_flag)
printf("\nLIT_FUN_%s:", tree_local); printf("\nLIT_FUN_%s:", tree_local);
else {
lit_t new_lit = malloc(sizeof(struct lit_s));
new_lit->fun = calloc(1, strlen(tree_local) + 1);
strcpy(new_lit->fun, tree_local);
dis_enqueue((void*) new_lit, &lit_fn_queue_front, &lit_fn_queue_rear, &lit_fn_queue_len);
}
}
if ((*prg)->program[*pc + size - 1] != DIS_OP_FN_END) { if ((*prg)->program[*pc + size - 1] != DIS_OP_FN_END) {
printf("\nERROR: Failed to find function end\n"); printf("\nERROR: Failed to find function end\n");
exit(1); exit(1);
} }
dis_read_interpreter_sections(prg, &fpc_start, spaces + 4, tree_local, alt_fmt); dis_read_interpreter_sections(prg, &fpc_start, spaces + 4, tree_local, config);
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("| | |\n"); printf("| | |\n");
SPC(spaces + 4); SPC(spaces + 4);
printf("| "); printf("| ");
printf("--- ( reading code for %s ) ---", tree_local); printf("--- ( reading code for %s ) ---", tree_local);
dis_disassemble_section(prg, fpc_start, fpc_end, spaces + 4, true, alt_fmt); dis_disassemble_section(prg, fpc_start, fpc_end, spaces + 4, true, config);
printf("\n"); printf("\n");
SPC(spaces + 4); SPC(spaces + 4);
printf("| "); printf("| ");
@@ -754,7 +819,7 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
strcpy(fun->fun, tree_local); strcpy(fun->fun, tree_local);
fun->start = fpc_start; fun->start = fpc_start;
fun->len = fpc_end; fun->len = fpc_end;
disassembler_enqueue((void*) fun); dis_enqueue((void*) fun, &function_queue_front, &function_queue_rear, &function_queue_len);
} }
fcnt++; fcnt++;
@@ -762,7 +827,7 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
} }
} }
if (!alt_fmt) { if (!config.alt_format_flag) {
SPC(spaces); SPC(spaces);
printf("|\n"); printf("|\n");
SPC(spaces); SPC(spaces);
@@ -776,51 +841,104 @@ static void dis_read_interpreter_sections(dis_program_t **prg, uint32_t *pc, uin
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void disassemble(const char *filename, bool alt_fmt) { void disassemble(const char *filename, options_t config) {
dis_program_t *prg; dis_program_t *prg;
queue_front = NULL;
queue_rear = NULL;
jump_label = 0; jump_label = 0;
dis_disassembler_init(&prg); dis_disassembler_init(&prg);
if (dis_load_file(filename, &prg, alt_fmt)) { if (dis_load_file(filename, &prg, config.alt_format_flag)) {
dis_disassembler_deinit(&prg); dis_disassembler_deinit(&prg);
exit(1); exit(1);
} }
dis_read_header(&prg, alt_fmt); dis_read_header(&prg, config.alt_format_flag);
printf("\n.start MAIN\n"); printf("\n.start MAIN\n");
consumeByte(DIS_OP_SECTION_END, prg->program, &(prg->pc)); consumeByte(DIS_OP_SECTION_END, prg->program, &(prg->pc));
if (alt_fmt) if (!config.group_flag) {
if (config.alt_format_flag)
printf("\nLIT_MAIN:"); printf("\nLIT_MAIN:");
dis_read_interpreter_sections(&prg, &(prg->pc), 0, "", alt_fmt);
if (!alt_fmt) { dis_read_interpreter_sections(&prg, &(prg->pc), 0, "", config);
if (!config.alt_format_flag) {
printf("|\n| "); printf("|\n| ");
printf("--- ( reading main code ) ---"); printf("--- ( reading main code ) ---");
} else } else
printf("\nMAIN:"); printf("\nMAIN:");
dis_disassemble_section(&prg, prg->pc, prg->len, 0, false, alt_fmt);
if (!alt_fmt) { dis_disassemble_section(&prg, prg->pc, prg->len, 0, false, config);
if (!config.alt_format_flag) {
printf("\n| "); printf("\n| ");
printf("--- ( end main code section ) ---"); printf("--- ( end main code section ) ---");
} else } else
printf("\n"); printf("\n");
if (alt_fmt) { if (config.alt_format_flag) {
while (queue_front != NULL) { while (function_queue_front != NULL) {
fun_code_t *fun = (fun_code_t*) disassembler_front(); fun_code_t *fun = (fun_code_t*) function_queue_front->data;
printf("\nFUN_%s:", fun->fun); printf("\nFUN_%s:", fun->fun);
free(fun->fun); free(fun->fun);
dis_disassemble_section(&prg, fun->start, fun->len, 0, true, alt_fmt); dis_disassemble_section(&prg, fun->start, fun->len, 0, true, config);
disassembler_dequeue(); dis_dequeue(&function_queue_front, &function_queue_rear, &function_queue_len);
printf("\n"); printf("\n");
} }
}
} else {
config.alt_format_flag = true;
lit_t new_lit = malloc(sizeof(struct lit_s));
new_lit->fun = calloc(1, 6 * sizeof(char));
strcpy(new_lit->fun, "MAIN");
dis_enqueue((void*) new_lit, &lit_fn_queue_front, &lit_fn_queue_rear, &lit_fn_queue_len);
dis_read_interpreter_sections(&prg, &(prg->pc), 0, "", config);
printf("\n");
while (lit_fn_queue_front != NULL) {
lit_t litf = (lit_t) lit_fn_queue_front->data;
if (!strcmp(litf->fun, "MAIN")) {
printf("MAIN:\n");
printf("%s", litf->str);
dis_disassemble_section(&prg, prg->pc, prg->len, 0, false, config);
free(litf->fun);
free(litf->str);
dis_dequeue(&lit_fn_queue_front, &lit_fn_queue_rear, &lit_fn_queue_len);
printf("\n\n");
continue;
}
printf("FUNCTION_%s:\n", litf->fun);
printf("%s", litf->str);
queue_node_t *fqf = function_queue_front;
while (fqf != NULL) {
fun_code_t *fun = (fun_code_t*) fqf->data;
if (!strcmp(fun->fun, litf->fun)) {
dis_disassemble_section(&prg, fun->start, fun->len, 0, true, config);
break;
}
fqf = fqf->next;
}
free(litf->fun);
free(litf->str);
dis_dequeue(&lit_fn_queue_front, &lit_fn_queue_rear, &lit_fn_queue_len);
printf("\n\n");
}
while (function_queue_front != NULL) {
free(((fun_code_t*)(function_queue_front->data))->fun);
dis_dequeue(&function_queue_front, &function_queue_rear, &function_queue_len);
}
} }
printf("\n"); printf("\n");

View File

@@ -10,6 +10,11 @@
#ifndef DISASSEMBLER_H_ #ifndef DISASSEMBLER_H_
#define DISASSEMBLER_H_ #define DISASSEMBLER_H_
typedef struct options_s {
bool alt_format_flag;
bool group_flag;
} options_t;
typedef enum DIS_OPCODES { typedef enum DIS_OPCODES {
DIS_OP_EOF, // DIS_OP_EOF, //
@@ -123,6 +128,6 @@ typedef enum DIS_LITERAL_TYPE {
DIS_LITERAL_INDEX_BLANK, // for blank indexing i.e. arr[:] DIS_LITERAL_INDEX_BLANK, // for blank indexing i.e. arr[:]
} dis_literal_type_t; } dis_literal_type_t;
extern void disassemble(const char *filename, bool alt_fmt); extern void disassemble(const char *filename, options_t config);
#endif /* DISASSEMBLER_H_ */ #endif /* DISASSEMBLER_H_ */

View File

@@ -7,46 +7,54 @@
* Further modified by Kayne Ruse, and added to the Toy Programming Language tool repository. * Further modified by Kayne Ruse, and added to the Toy Programming Language tool repository.
*/ */
#include "stdio.h" #include <stdio.h>
#include "stdlib.h" #include <stdlib.h>
#include <string.h>
#include "disassembler_utils.h" #include "disassembler_utils.h"
struct disassembler_node_s *queue_front, *queue_rear; void dis_enqueue(void *x, queue_node_t **queue_front, queue_node_t **queue_rear, uint32_t *len) {
queue_node_t *temp;
void disassembler_enqueue(void *x) { temp = (queue_node_t*) malloc(sizeof(struct queue_node_s));
struct disassembler_node_s *temp;
temp = (struct disassembler_node_s*) malloc(sizeof(struct disassembler_node_s));
temp->data = x; temp->data = x;
temp->next = NULL; temp->next = NULL;
if (queue_front == NULL && queue_rear == NULL) { if ((*queue_front) == NULL && (*queue_rear) == NULL) {
queue_front = queue_rear = temp; (*queue_front) = (*queue_rear) = temp;
++(*len);
return; return;
} }
queue_rear->next = temp; (*queue_rear)->next = temp;
queue_rear = temp; (*queue_rear) = temp;
++(*len);
} }
void disassembler_dequeue(void) { void dis_dequeue(queue_node_t **queue_front, queue_node_t **queue_rear, uint32_t *len) {
struct disassembler_node_s *temp = queue_front; struct queue_node_s *temp = (*queue_front);
if (queue_front == NULL) { if ((*queue_front) == NULL) {
printf("Error : QUEUE is empty!!"); printf("Error : QUEUE is empty!!");
return; return;
} }
if (queue_front == queue_rear) if ((*queue_front) == (*queue_rear))
queue_front = queue_rear = NULL; (*queue_front) = (*queue_rear) = NULL;
else else
queue_front = queue_front->next; (*queue_front) = (*queue_front)->next;
--(*len);
free(temp->data); free(temp->data);
free(temp); free(temp);
} }
void* disassembler_front(void) { ///
return queue_front->data;
void str_append(char **str, const char *app) {
if ((*str) == NULL)
return;
*str = realloc(*str, (strlen(*str) + strlen(app) + 1) * sizeof(char));
memcpy((*str) + strlen(*str), app, strlen(app) + 1);
} }

View File

@@ -10,15 +10,16 @@
#ifndef UTILS_H_ #ifndef UTILS_H_
#define UTILS_H_ #define UTILS_H_
struct disassembler_node_s { #include <stdint.h>
typedef struct queue_node_s {
void *data; void *data;
struct disassembler_node_s *next; struct queue_node_s *next;
}; } queue_node_t;
extern struct disassembler_node_s *queue_front, *queue_rear; void dis_enqueue(void *x, queue_node_t **queue_front, queue_node_t **queue_rear, uint32_t *len);
void dis_dequeue(queue_node_t **queue_front, queue_node_t **queue_rear, uint32_t *len);
void disassembler_enqueue(void *x); void str_append(char **str, const char *app);
void disassembler_dequeue(void);
void* disassembler_front(void);
#endif /* UTILS_H_ */ #endif /* UTILS_H_ */

View File

@@ -10,6 +10,12 @@ static struct cag_option options[] = {
.access_name = NULL, .access_name = NULL,
.value_name = NULL, .value_name = NULL,
.description = "Alternate format" .description = "Alternate format"
}, {
.identifier = 'g',
.access_letters = "g",
.access_name = NULL,
.value_name = NULL,
.description = "Group literals with functions"
}, { }, {
.identifier = 'h', .identifier = 'h',
.access_letters = "h", .access_letters = "h",
@@ -18,21 +24,21 @@ static struct cag_option options[] = {
} }
}; };
struct options {
bool alternate_flag;
};
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
char identifier; char identifier;
cag_option_context context; cag_option_context context;
struct options config = { false }; options_t config = { false, false };
cag_option_prepare(&context, options, CAG_ARRAY_SIZE(options), argc, argv); cag_option_prepare(&context, options, CAG_ARRAY_SIZE(options), argc, argv);
while (cag_option_fetch(&context)) { while (cag_option_fetch(&context)) {
identifier = cag_option_get(&context); identifier = cag_option_get(&context);
switch (identifier) { switch (identifier) {
case 'a': case 'a':
config.alternate_flag = true; config.alt_format_flag = true;
break;
case 'g':
config.group_flag = true;
config.alt_format_flag = true;
break; break;
case 'h': case 'h':
printf("Usage: disassembler [OPTION] file\n"); printf("Usage: disassembler [OPTION] file\n");
@@ -41,6 +47,7 @@ int main(int argc, char *argv[]) {
} }
} }
disassemble(argv[context.index], config.alternate_flag); disassemble(argv[context.index], config);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }