mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2024-12-12 04:29:05 +00:00
include labels in disasm output.
This commit is contained in:
parent
518233d71f
commit
d991eabdfd
87
dumpobj.cpp
87
dumpobj.cpp
@ -9,6 +9,8 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#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<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)
|
||||
{
|
||||
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<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;
|
||||
@ -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);
|
||||
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user