diff options
author | Oxore <oxore@protonmail.com> | 2025-01-04 16:07:56 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2025-01-07 14:39:01 +0300 |
commit | 07ff2ebf9b29084670fb3fa46f8427d3272117d5 (patch) | |
tree | d8dd69aa52800b6c17ec0bee78b840dc9784a74a /src | |
parent | cb96278e25140cfcc1afc22df2102bcf3b6ae38c (diff) |
Integrate the new trace table parser
Diffstat (limited to 'src')
-rw-r--r-- | src/disasm.cpp | 28 | ||||
-rw-r--r-- | src/disasm.h | 4 | ||||
-rw-r--r-- | src/main.cpp | 57 |
3 files changed, 46 insertions, 43 deletions
diff --git a/src/disasm.cpp b/src/disasm.cpp index 572030d..a7dc07b 100644 --- a/src/disasm.cpp +++ b/src/disasm.cpp @@ -5,8 +5,9 @@ #include "m68k.h" #include <cassert> -#include <cstring> #include <cerrno> +#include <cinttypes> +#include <cstring> void DisasmNode::AddReferencedBy(const uint32_t address_from, const ReferenceType ref_type) { @@ -150,6 +151,31 @@ bool DisasmMap::ApplySymbolsFromElf(const ELF::Image &elf) return true; } +void DisasmMap::ConsumeTraceTable(TraceTable &&tt) +{ + this->_tt = static_cast<TraceTable &&>(tt); + const size_t nodes_count = _tt.NodesCount(); + for (size_t n = 0; n < nodes_count; n++) { + const auto &node = _tt.Node(n); + if (node.kind == TraceNodeKind::kPc) { + if (node.address % 2) { + fprintf(stderr, + "Error: Uneven PC values are not supported " + "(got PC=0x%08" PRIu32 "), exiting\n", + node.address); + exit(1); + } else if (static_cast<unsigned long>(node.address) > kRomSizeBytes) { + fprintf(stderr, + "Error: PC values > 4MiB are not supported " + "(got PC=0x%08" PRIu32 "), exiting\n", + node.address); + exit(1); + } + insertNode(node.address, NodeType::kTracedInstruction); + } + } +} + static constexpr bool IsNextLikelyAnInstruction(const Op &op) { return (op.opcode != OpCode::kNone && diff --git a/src/disasm.h b/src/disasm.h index a805df6..5b1b4b9 100644 --- a/src/disasm.h +++ b/src/disasm.h @@ -6,6 +6,7 @@ #include "elf_image.h" #include "common.h" #include "m68k.h" +#include "tracetab.h" #include <cstdint> #include <cstddef> @@ -90,11 +91,11 @@ class DisasmMap { DisasmNode *_map[kDisasmMapSizeElements]{}; Symbol *_symtab{}; size_t _symtab_size{}; + TraceTable _tt{}; constexpr DisasmNode *findNodeByAddress(uint32_t address) const; constexpr size_t findFirstSymbolAtAddress( uint32_t address, bool return_last_considered=false) const; DisasmNode &insertNode(uint32_t address, NodeType); - void insertSymbol(uint32_t address, ReferenceType ref_type); DisasmNode &insertReferencedBy( const uint32_t by_addr, const uint32_t ref_addr, @@ -113,6 +114,7 @@ public: }; void InsertNode(uint32_t address, NodeType type); bool ApplySymbolsFromElf(const ELF::Image &); + void ConsumeTraceTable(TraceTable &&); void Disasm(const DataView &code, const Settings &, size_t from=0, bool nested=false); DisasmMap(DisasmMapType type): _type(type) {} ~DisasmMap(); diff --git a/src/main.cpp b/src/main.cpp index f952f38..338b92b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -679,43 +679,7 @@ static bool EmitDisassembly( return true; } -static void ParseTraceData(DisasmMap &disasm_map, const DataView &trace_data) -{ - bool parse = true; - for (size_t i = 0; i < trace_data.size; i++) { - if (trace_data.buffer[i] == '\n' || trace_data.buffer[i] == '\r') { - parse = true; - } else if (parse) { - errno = 0; - // Base 0 enabled strtol to parse octal and hexadecimal numbers with - // prefixes like 0 or 0x. See `man strtol.3p`. - constexpr int base = 0; - const char *startptr = reinterpret_cast<const char *>(trace_data.buffer + i); - char *endptr = nullptr; - const long address = strtol(startptr, &endptr, base); - if ((address == LONG_MAX || address == LONG_MIN) && errno == ERANGE) { - // Parsing error, just skip - } else if (startptr == endptr) { - // Parsing error, just skip - } else if (address % 2) { - fprintf(stderr, "Error: Uneven PC values are not supported (got PC=0x%08lx), exiting\n", address); - exit(1); - } else if (static_cast<unsigned long>(address) > kRomSizeBytes) { - fprintf(stderr, "Error: PC values > 4MiB are not supported (got PC=0x%08lx), exiting\n", address); - exit(1); - } else { - // Valid value - disasm_map.InsertNode(address, NodeType::kTracedInstruction); - } - if (startptr != endptr) { - i += endptr - startptr - 1; - } - parse = false; - } - } -} - -static DisasmMap *NewDisasmMap(FILE *trace_stream) +static DisasmMap *NewDisasmMap(FILE *trace_stream, const char *trace_file_name) { if (trace_stream == nullptr) { DisasmMap *disasm_map = new DisasmMap{DisasmMapType::kRaw}; @@ -733,12 +697,23 @@ static DisasmMap *NewDisasmMap(FILE *trace_stream) // Parse trace file into map DisasmMap *disasm_map = new DisasmMap{DisasmMapType::kTraced}; assert(disasm_map != nullptr); - ParseTraceData(*disasm_map, trace_data.View()); + TraceTable tt{}; + const bool ok = ParseTraceData( + tt, trace_data.buffer, trace_data.occupied_size, stderr, trace_file_name); + if (!ok) { + fprintf(stderr, "ParseTraceData(): Error: Failed to parse trace table\n"); + return nullptr; + } + disasm_map->ConsumeTraceTable(static_cast<TraceTable &&>(tt)); return disasm_map; } static int M68kDisasm( - FILE *input_stream, FILE *output_stream, FILE *trace_stream, const Settings &s) + FILE *input_stream, + FILE *output_stream, + FILE *trace_stream, + const Settings &s, + const char *trace_file_name) { // Read input file into buffer auto input = DataBuffer::FromStream(input_stream); @@ -763,7 +738,7 @@ static int M68kDisasm( fprintf(stderr, "M68kDisasm: Error: code blob must be of even size\n"); return EXIT_FAILURE; } - auto *disasm_map = NewDisasmMap(trace_stream); + auto *disasm_map = NewDisasmMap(trace_stream, trace_file_name); if (disasm_map == nullptr) { return EXIT_FAILURE; } @@ -1075,7 +1050,7 @@ int main(int, char* argv[]) } } // Run the program - const int ret = M68kDisasm(input_stream, output_stream, trace_stream, s); + const int ret = M68kDisasm(input_stream, output_stream, trace_stream, s, trace_file_name); if (trace_stream != nullptr) { fclose(trace_stream); } |