From d991eabdfdc5bc0291e9a79557332bf83a27d950 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 25 Dec 2016 02:42:43 -0500 Subject: [PATCH] include labels in disasm output. --- dumpobj.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 10 deletions(-) diff --git a/dumpobj.cpp b/dumpobj.cpp index 1a35da7..95463b7 100644 --- a/dumpobj.cpp +++ b/dumpobj.cpp @@ -9,6 +9,8 @@ #include #include +#include +#include #include "obj816.h" #include "disassembler.h" @@ -129,6 +131,57 @@ std::string read_pstring(T &iter) { return s; } + +struct symbol { + std::string name; + uint8_t type; + uint8_t flags; + uint8_t section; + uint32_t offset; +}; + + +std::vector read_symbols(const std::vector &symbol_data) { + + std::vector symbols; + + auto iter = symbol_data.begin(); + while (iter != symbol_data.end()) { + uint8_t type = read_8(iter); + uint8_t flags = read_8(iter); + uint8_t section = read_8(iter); + uint32_t offset = type == S_UND ? 0 : read_32(iter); + std::string name = read_cstring(iter); + + + symbols.emplace_back(symbol{name, type, flags, section, offset}); + } + + return symbols; +} + +std::vector labels_for_section(const std::vector &symbols, unsigned section) { + std::vector out; + std::copy_if(symbols.begin(), symbols.end(), std::back_inserter(out), + [section](const symbol &s) { return s.section == section && s.type != S_UND; } + ); + + std::sort(out.begin(), out.end(), [](const symbol &a, const symbol &b){ + return a.offset > b.offset; + }); + + return out; +} + +symbol find_symbol(const std::vector &symbols, unsigned section, unsigned offset) { + auto iter = std::find_if(symbols.begin(), symbols.end(), [section, offset](const symbol &s){ + return s.section == section && s.offset == offset && s.type != S_UND; + }); + if (iter != symbols.end()) return *iter; + return symbol{"", S_UND, 0, 0xff, 0}; +} + + void dump_obj(const char *name, int fd) { static const char *sections[] = { "PAGE0", "CODE", "KDATA", "DATA", "UDATA" }; @@ -192,6 +245,10 @@ void dump_obj(const char *name, int fd) ok = read(fd, symbol_data.data(), h.h_symsize); if (ok != h.h_symsize) errx(EX_DATAERR, "%s symbols truncated", name); + std::vector symbols = read_symbols(symbol_data); + + unsigned section = 1; // default section = CODE. + std::vector labels = labels_for_section(symbols, section); uint8_t op = REC_END; @@ -201,6 +258,11 @@ void dump_obj(const char *name, int fd) auto iter = data.begin(); while (iter != data.end()) { + while (!labels.empty() && labels.back().offset == d.pc()) { + printf("%s:\n", labels.back().name.c_str()); + labels.pop_back(); + } + op = read_8(iter); if (op == 0) break; if (op < 0xf0) { @@ -232,11 +294,18 @@ void dump_obj(const char *name, int fd) case OP_LOC: { uint8_t section = read_8(iter); uint32_t offset = read_32(iter); - if (section < sizeof(sections) / sizeof(sections[0])) - snprintf(buffer, sizeof(buffer), "%s+$%04x", sections[section], offset); - else - snprintf(buffer, sizeof(buffer), "section %02x+$%04x", section, offset); - stack.push_back(buffer); + + symbol s = find_symbol(symbols, section, offset); + if (s.type) { + stack.push_back(s.name); + } else { + + if (section < sizeof(sections) / sizeof(sections[0])) + snprintf(buffer, sizeof(buffer), "%s+$%04x", sections[section], offset); + else + snprintf(buffer, sizeof(buffer), "section %02x+$%04x", section, offset); + stack.push_back(buffer); + } break; } @@ -245,10 +314,15 @@ void dump_obj(const char *name, int fd) stack.push_back(buffer); break; - case OP_SYM: - snprintf(buffer, sizeof(buffer), "symbol $%02x", read_16(iter)); - stack.push_back(buffer); + case OP_SYM: { + uint16_t symbol = read_16(iter); + if (symbol < symbols.size()) stack.push_back(symbols[symbol].name); + else { + snprintf(buffer, sizeof(buffer), "symbol $%02x", symbol); + stack.push_back(buffer); + } break; + } case OP_SHR: case OP_SHL: @@ -350,8 +424,12 @@ void dump_obj(const char *name, int fd) case REC_SECT: { d.flush(); - uint8_t section = read_8(iter); - printf("\t.sect\t%d\n", section); + uint8_t sec = read_8(iter); + printf("\t.sect\t%d\n", sec); + if (sec != section) { + section = sec; + labels = labels_for_section(symbols, section); + } break; } case REC_ORG: { @@ -359,6 +437,7 @@ void dump_obj(const char *name, int fd) d.flush(); uint32_t org = read_32(iter); printf("\t.org\t$%04x\n", org); + d.set_pc(org); break; }