include labels in disasm output.

This commit is contained in:
Kelvin Sherlock 2016-12-25 02:42:43 -05:00
parent 518233d71f
commit d991eabdfd

View File

@ -9,6 +9,8 @@
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <algorithm>
#include <iterator>
#include "obj816.h" #include "obj816.h"
#include "disassembler.h" #include "disassembler.h"
@ -129,6 +131,57 @@ std::string read_pstring(T &iter) {
return s; return s;
} }
struct symbol {
std::string name;
uint8_t type;
uint8_t flags;
uint8_t section;
uint32_t offset;
};
std::vector<symbol> read_symbols(const std::vector<uint8_t> &symbol_data) {
std::vector<symbol> 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<symbol> labels_for_section(const std::vector<symbol> &symbols, unsigned section) {
std::vector<symbol> 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<symbol> &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) void dump_obj(const char *name, int fd)
{ {
static const char *sections[] = { "PAGE0", "CODE", "KDATA", "DATA", "UDATA" }; 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); ok = read(fd, symbol_data.data(), h.h_symsize);
if (ok != h.h_symsize) errx(EX_DATAERR, "%s symbols truncated", name); if (ok != h.h_symsize) errx(EX_DATAERR, "%s symbols truncated", name);
std::vector<symbol> symbols = read_symbols(symbol_data);
unsigned section = 1; // default section = CODE.
std::vector<symbol> labels = labels_for_section(symbols, section);
uint8_t op = REC_END; uint8_t op = REC_END;
@ -201,6 +258,11 @@ void dump_obj(const char *name, int fd)
auto iter = data.begin(); auto iter = data.begin();
while (iter != data.end()) { 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); op = read_8(iter);
if (op == 0) break; if (op == 0) break;
if (op < 0xf0) { if (op < 0xf0) {
@ -232,11 +294,18 @@ void dump_obj(const char *name, int fd)
case OP_LOC: { case OP_LOC: {
uint8_t section = read_8(iter); uint8_t section = read_8(iter);
uint32_t offset = read_32(iter); uint32_t offset = read_32(iter);
if (section < sizeof(sections) / sizeof(sections[0]))
snprintf(buffer, sizeof(buffer), "%s+$%04x", sections[section], offset); symbol s = find_symbol(symbols, section, offset);
else if (s.type) {
snprintf(buffer, sizeof(buffer), "section %02x+$%04x", section, offset); stack.push_back(s.name);
stack.push_back(buffer); } 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; break;
} }
@ -245,10 +314,15 @@ void dump_obj(const char *name, int fd)
stack.push_back(buffer); stack.push_back(buffer);
break; break;
case OP_SYM: case OP_SYM: {
snprintf(buffer, sizeof(buffer), "symbol $%02x", read_16(iter)); uint16_t symbol = read_16(iter);
stack.push_back(buffer); if (symbol < symbols.size()) stack.push_back(symbols[symbol].name);
else {
snprintf(buffer, sizeof(buffer), "symbol $%02x", symbol);
stack.push_back(buffer);
}
break; break;
}
case OP_SHR: case OP_SHR:
case OP_SHL: case OP_SHL:
@ -350,8 +424,12 @@ void dump_obj(const char *name, int fd)
case REC_SECT: { case REC_SECT: {
d.flush(); d.flush();
uint8_t section = read_8(iter); uint8_t sec = read_8(iter);
printf("\t.sect\t%d\n", section); printf("\t.sect\t%d\n", sec);
if (sec != section) {
section = sec;
labels = labels_for_section(symbols, section);
}
break; break;
} }
case REC_ORG: { case REC_ORG: {
@ -359,6 +437,7 @@ void dump_obj(const char *name, int fd)
d.flush(); d.flush();
uint32_t org = read_32(iter); uint32_t org = read_32(iter);
printf("\t.org\t$%04x\n", org); printf("\t.org\t$%04x\n", org);
d.set_pc(org);
break; break;
} }