summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/disasm.cpp28
-rw-r--r--src/disasm.h4
-rw-r--r--src/main.cpp57
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);
}