mirror of
https://github.com/ksherlock/wdc-utils.git
synced 2024-12-12 19:30:38 +00:00
better code/data support.
This commit is contained in:
parent
ad187b4bf3
commit
8581381e69
@ -377,31 +377,13 @@ void disassembler::flush() {
|
|||||||
if (_st) dump();
|
if (_st) dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassembler::data(uint8_t byte) {
|
|
||||||
if (_type == 0) {
|
void disassembler::operator()(const std::string &expr, unsigned size) {
|
||||||
flush();
|
|
||||||
_type = 1;
|
if (!_code) {
|
||||||
|
dump(expr, size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
_bytes[_st++] = byte;
|
|
||||||
if (_st == 4) dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void disassembler::data(const std::string &expr, unsigned size) {
|
|
||||||
if (_type == 0 || _st) {
|
|
||||||
flush();
|
|
||||||
_type = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dump(expr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void disassembler::code(const std::string &expr, unsigned size) {
|
|
||||||
|
|
||||||
if (_type) { flush(); _type = 0; }
|
|
||||||
|
|
||||||
if (_st != 1 || size != _size) {
|
if (_st != 1 || size != _size) {
|
||||||
dump(expr, size);
|
dump(expr, size);
|
||||||
@ -413,9 +395,13 @@ void disassembler::code(const std::string &expr, unsigned size) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void disassembler::code(uint8_t byte) {
|
void disassembler::operator()(uint8_t byte) {
|
||||||
|
|
||||||
if (_type) { flush(); _type = 0; }
|
if (!_code) {
|
||||||
|
_bytes[_st++] = byte;
|
||||||
|
if (_st == 4) dump();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_bytes[_st++] = byte;
|
_bytes[_st++] = byte;
|
||||||
if (_st == 1) {
|
if (_st == 1) {
|
||||||
|
@ -9,23 +9,18 @@ class disassembler {
|
|||||||
public:
|
public:
|
||||||
disassembler() = default;
|
disassembler() = default;
|
||||||
|
|
||||||
void code(uint8_t byte);
|
void operator()(uint8_t byte);
|
||||||
void code(const std::string &expr, unsigned size);
|
void operator()(const std::string &expr, unsigned size);
|
||||||
|
|
||||||
template<class Iter>
|
template<class Iter>
|
||||||
void code(Iter begin, Iter end) { while (begin != end) code(*begin++); }
|
void operator()(Iter begin, Iter end) { while (begin != end) code(*begin++); }
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void code(const T &t) { code(std::begin(t), std::end(t)); }
|
void operator()(const T &t) { code(std::begin(t), std::end(t)); }
|
||||||
|
|
||||||
|
|
||||||
void data(uint8_t byte);
|
|
||||||
void data(const std::string &expr, unsigned size);
|
|
||||||
|
|
||||||
|
|
||||||
bool m() const { return _flags & 0x20; }
|
bool m() const { return _flags & 0x20; }
|
||||||
bool x() const { return _flags & 0x10; }
|
bool x() const { return _flags & 0x10; }
|
||||||
uint32_t pc() const { return _pc; }
|
|
||||||
|
|
||||||
void set_m(bool x) {
|
void set_m(bool x) {
|
||||||
if (x) _flags |= 0x20;
|
if (x) _flags |= 0x20;
|
||||||
@ -37,10 +32,16 @@ class disassembler {
|
|||||||
else _flags &= ~0x10;
|
else _flags &= ~0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_pc(uint32_t pc) { _pc = pc; }
|
uint32_t pc() const { return _pc; }
|
||||||
|
void set_pc(uint32_t pc) { if (_pc != pc) { flush(); _pc = pc; } }
|
||||||
|
|
||||||
|
bool code() const { return _code; }
|
||||||
|
void set_code(bool code) { if (_code != code) { flush(); _code = code; } }
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -65,7 +66,7 @@ class disassembler {
|
|||||||
unsigned _pc = 0;
|
unsigned _pc = 0;
|
||||||
unsigned _arg = 0;
|
unsigned _arg = 0;
|
||||||
|
|
||||||
unsigned _type = 0; // code / data.
|
bool _code = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
34
dumpobj.cpp
34
dumpobj.cpp
@ -199,7 +199,7 @@ void place_labels(std::vector<symbol> &labels, uint32_t pc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_obj(const char *name, int fd)
|
bool 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" };
|
||||||
static const char *types[] = { "S_UND", "S_ABS", "S_REL", "S_EXP", "S_REG", "S_FREG" };
|
static const char *types[] = { "S_UND", "S_ABS", "S_REL", "S_EXP", "S_REG", "S_FREG" };
|
||||||
@ -208,6 +208,8 @@ void dump_obj(const char *name, int fd)
|
|||||||
ssize_t ok;
|
ssize_t ok;
|
||||||
|
|
||||||
ok = read(fd, &h, sizeof(h));
|
ok = read(fd, &h, sizeof(h));
|
||||||
|
if (ok == 0) return false;
|
||||||
|
|
||||||
if (ok != sizeof(h))
|
if (ok != sizeof(h))
|
||||||
errx(EX_DATAERR, "%s is not an object file", name);
|
errx(EX_DATAERR, "%s is not an object file", name);
|
||||||
|
|
||||||
@ -272,6 +274,9 @@ void dump_obj(const char *name, int fd)
|
|||||||
|
|
||||||
disassembler d;
|
disassembler d;
|
||||||
|
|
||||||
|
d.set_pc(0);
|
||||||
|
d.set_code(true);
|
||||||
|
|
||||||
auto iter = data.begin();
|
auto iter = data.begin();
|
||||||
while (iter != data.end()) {
|
while (iter != data.end()) {
|
||||||
|
|
||||||
@ -282,7 +287,7 @@ void dump_obj(const char *name, int fd)
|
|||||||
if (op < 0xf0) {
|
if (op < 0xf0) {
|
||||||
auto end = iter + op;
|
auto end = iter + op;
|
||||||
while (iter != end) {
|
while (iter != end) {
|
||||||
d.code(*iter++);
|
d(*iter++);
|
||||||
place_labels(labels, d.pc());
|
place_labels(labels, d.pc());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -361,7 +366,7 @@ void dump_obj(const char *name, int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stack.size() != 1) errx(EX_DATAERR, "%s stack overflow error.", name);
|
if (stack.size() != 1) errx(EX_DATAERR, "%s stack overflow error.", name);
|
||||||
d.code(stack.front(), bytes);
|
d(stack.front(), bytes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -459,6 +464,7 @@ void dump_obj(const char *name, int fd)
|
|||||||
if (sec != section) {
|
if (sec != section) {
|
||||||
section = sec;
|
section = sec;
|
||||||
labels = labels_for_section(symbols, section);
|
labels = labels_for_section(symbols, section);
|
||||||
|
d.set_code(section == 1 || section > 4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -471,7 +477,14 @@ void dump_obj(const char *name, int fd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case REC_SPACE:
|
case REC_SPACE: {
|
||||||
|
d.flush();
|
||||||
|
uint16_t count = read_32(iter);
|
||||||
|
printf("\tds\t$%04x\n", count);
|
||||||
|
d.set_pc(d.pc() + count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case REC_RELEXP:
|
case REC_RELEXP:
|
||||||
case REC_LINE:
|
case REC_LINE:
|
||||||
default:
|
default:
|
||||||
@ -559,7 +572,7 @@ void dump_obj(const char *name, int fd)
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -623,11 +636,6 @@ void dump_lib(const char *name, int fd)
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
for (int i = 0; i < h.l_numfiles; ++i) {
|
|
||||||
dump_obj(name, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump(const char *name) {
|
void dump(const char *name) {
|
||||||
@ -651,8 +659,10 @@ void dump(const char *name) {
|
|||||||
errx(EX_DATAERR, "%s is not an object file", name);
|
errx(EX_DATAERR, "%s is not an object file", name);
|
||||||
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
if (h.h_filtyp == 1) dump_obj(name, fd);
|
if (h.h_filtyp == 2) dump_lib(name, fd);
|
||||||
else dump_lib(name, fd);
|
|
||||||
|
// files may contain multiple modules.
|
||||||
|
while (dump_obj(name, fd)) /* ... */;
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user