diff options
author | Oxore <oxore@protonmail.com> | 2023-04-24 01:13:28 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-04-24 01:13:28 +0300 |
commit | af46d6991ceb719ac59d6218791c41fa3978e695 (patch) | |
tree | c82f390402e0000a5a2d9bc88045b91a8810213a /main.cpp | |
parent | 30f24b179ced1bf47deb9edfbd4128f16dad42dd (diff) |
Impl some feature flags
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 140 |
1 files changed, 102 insertions, 38 deletions
@@ -18,19 +18,6 @@ #include <cerrno> #include <climits> -/* - * We need to be able to modify output to place a mark when some jumping back - * is found, hence we should build output table instead of emitting asm right - * away into the output stream. - * - * I think the output should be an ordered map of decoded instructions. When the - * output is built according to the map we must walk through all the binary file - * again alongside with the output map and emit the final output right into the - * output stream. - * - * Trace data parser is needed. Maybe just using atol(3) will be ok. - */ - class DisasmMap { DisasmNode *_map[kDisasmMapSizeElements]{}; DisasmNode *findNodeByOffset(uint32_t offset) const; @@ -127,34 +114,43 @@ static const char *ReferenceTypeToString(ReferenceType type) } static void RenderDisassembly( - FILE *output, const DisasmMap &disasm_map, const DataBuffer &code, const Settings &) + FILE *output, const DisasmMap &disasm_map, const DataBuffer &code, const Settings &s) { for (size_t i = 0; i < code.occupied_size;) { const DisasmNode *node = disasm_map.FindNodeByOffset(i); if (node) { - char comment[100]{}; - RenderRawDataComment(comment, sizeof(comment) - 1, node->offset, node->size, code); if (node->ref_by) { - fprintf(output, "| XREFS:\n"); - for (ReferenceNode *ref{node->ref_by}; ref; ref = ref->next) { - if (ref->refs_count == 0) { - continue; - } - fprintf(output, "|"); - for (size_t i = 0; i < ref->refs_count; i++) { - const ReferenceRecord r = ref->refs[i]; - fprintf(output, " %s @%08x", ReferenceTypeToString(r.type), r.address); + if (s.xrefs_from) { + fprintf(output, "| XREFS:\n"); + for (ReferenceNode *ref{node->ref_by}; ref; ref = ref->next) { + if (ref->refs_count == 0) { + continue; + } + fprintf(output, "|"); + for (size_t i = 0; i < ref->refs_count; i++) { + const ReferenceRecord r = ref->refs[i]; + fprintf(output, " %s @%08x", ReferenceTypeToString(r.type), r.address); + } + fprintf(output, "\n"); } - fprintf(output, "\n"); } - fprintf(output, ".L%08x:\n", node->offset); + if (s.marks) { + fprintf(output, ".L%08x:\n", node->offset); + } } - char branch_addr[12]{}; - if (node->has_branch_addr) { + const char *const delimiter = node->arguments[0] != '\0' ? " " : ""; + fprintf(output, " %s%s%s", node->mnemonic, delimiter, node->arguments); + if (node->has_branch_addr && s.xrefs_to) { + char branch_addr[12]{}; snprintf(branch_addr, sizeof(branch_addr), " .L%08x", node->branch_addr); + fprintf(output, " |%s", branch_addr); } - const char *const delimiter = node->arguments[0] != '\0' ? " " : ""; - fprintf(output, " %s%s%s |%s%s\n", node->mnemonic, delimiter, node->arguments, branch_addr, comment); + if (s.raw_data_comment) { + char raw_data_comment[100]{}; + RenderRawDataComment(raw_data_comment, sizeof(raw_data_comment) - 1, node->offset, node->size, code); + fprintf(output, " |%s", raw_data_comment); + } + fprintf(output, "\n"); i += node->size; } else { fprintf(output, " .short 0x%02x%02x\n", code.buffer[i], code.buffer[i + 1]); @@ -274,13 +270,73 @@ static int M68kDisasmAll(FILE *input_stream, FILE *output_stream, const Settings return 0; } -static void PrintUsage(FILE *stream, const char *argv0) +static bool IsValidFeature(const char *feature) +{ + constexpr size_t sizeof_no_prefix = strlen("no-"); + if (0 == memcmp(feature, "no-", sizeof_no_prefix)) { + feature += sizeof_no_prefix; + } + if (0 == strcmp(feature, "rdc")) { + return true; + } else if (0 == strcmp(feature, "marks")) { + return true; + } else if (0 == strcmp(feature, "rel-marks")) { + return true; + } else if (0 == strcmp(feature, "abs-marks")) { + return true; + } else if (0 == strcmp(feature, "xrefs-from")) { + return true; + } else if (0 == strcmp(feature, "xrefs-to")) { + return true; + } + return false; +} + +static void ApplyFeature(Settings& s, const char *feature) +{ + bool disable{}; + constexpr size_t sizeof_no_prefix = strlen("no-"); + if (0 == memcmp(feature, "no-", sizeof_no_prefix)) { + disable = true; + feature += sizeof_no_prefix; + } + if (0 == strcmp(feature, "rdc")) { + s.raw_data_comment = !disable; + } else if (0 == strcmp(feature, "marks")) { + s.marks = !disable; + } else if (0 == strcmp(feature, "rel-marks")) { + s.rel_marks = !disable; + } else if (0 == strcmp(feature, "abs-marks")) { + s.abs_marks = !disable; + } else if (0 == strcmp(feature, "xrefs-from")) { + s.xrefs_from = !disable; + } else if (0 == strcmp(feature, "xrefs-to")) { + s.xrefs_to = !disable; + } +} + +static void PrintUsage(FILE *s, const char *argv0) { - fprintf(stream, "Usage: %s [options] [<input-file-name>]\n", argv0); - fprintf(stream, " -h, --help, Show this message\n"); - fprintf(stream, " -o, --output, Where to write disassembly to (stdout if not set)\n"); - fprintf(stream, " -t, --pc-trace, File containing PC trace\n"); - fprintf(stream, " <input_file_name> Binary file with machine code (stdin if not set)\n"); + fprintf(s, "Usage: %s [options] [<input-file-name>]\n", argv0); + fprintf(s, "Options:\n"); + fprintf(s, " -h, --help, Show this message\n"); + fprintf(s, " -o, --output, Where to write disassembly to (stdout if not set)\n"); + fprintf(s, " -t, --pc-trace, File containing PC trace\n"); + fprintf(s, " -f, --feature=[no-]<feature>\n"); + fprintf(s, " Enable or disable (with \"no-\" prefix) a feature\n"); + fprintf(s, " Available features:\n"); + fprintf(s, " rdc print raw data comment\n"); + fprintf(s, " marks print marks above all places that have jumps\n"); + fprintf(s, " from somewhere\n"); + fprintf(s, " rel-marks use mark instead of number on relative\n"); + fprintf(s, " branch or call\n"); + fprintf(s, " abs-marks use mark instead of number on absolute\n"); + fprintf(s, " branch or call\n"); + fprintf(s, " xrefs-from print xrefs comments above all places that\n"); + fprintf(s, " have xrefs\n"); + fprintf(s, " xrefs-to print xrefs comments after all branch \n"); + fprintf(s, " instructions\n"); + fprintf(s, " <input_file_name> Binary file with machine code (stdin if not set)\n"); } int main(int, char* argv[]) @@ -289,11 +345,13 @@ int main(int, char* argv[]) {"help", 'h', OPTPARSE_NONE}, {"output", 'o', OPTPARSE_REQUIRED}, {"pc-trace", 't', OPTPARSE_REQUIRED}, + {"feature", 'f', OPTPARSE_OPTIONAL}, {}, }; const char *trace_file_name = nullptr; const char *output_file_name = nullptr; const char *input_file_name = nullptr; + Settings s{}; struct optparse options; optparse_init(&options, argv); // Parse opts @@ -310,6 +368,13 @@ int main(int, char* argv[]) case 't': trace_file_name = options.optarg; break; + case 'f': + if (!IsValidFeature(options.optarg)) { + fprintf(stderr, "main: Error: Unknown feature \"%s\", exiting\n", options.optarg); + return EXIT_FAILURE; + } + ApplyFeature(s, options.optarg); + break; case '?': fprintf(stderr, "main: optparse_long: Error: \"%s\"\n", options.errmsg); return EXIT_FAILURE; @@ -353,7 +418,6 @@ int main(int, char* argv[]) return EXIT_FAILURE; } } - Settings s{}; // Run the program const int ret = trace_stream ? M68kDisasmByTrace(input_stream, output_stream, trace_stream, s) |