diff --git a/disassembler.cpp b/disassembler.cpp index 5e9221d..178a71c 100644 --- a/disassembler.cpp +++ b/disassembler.cpp @@ -377,31 +377,13 @@ void disassembler::flush() { if (_st) dump(); } -void disassembler::data(uint8_t byte) { - if (_type == 0) { - flush(); - _type = 1; + +void disassembler::operator()(const std::string &expr, unsigned size) { + + 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) { 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; if (_st == 1) { diff --git a/disassembler.h b/disassembler.h index 31c9475..1a41c48 100644 --- a/disassembler.h +++ b/disassembler.h @@ -9,23 +9,18 @@ class disassembler { public: disassembler() = default; - void code(uint8_t byte); - void code(const std::string &expr, unsigned size); + void operator()(uint8_t byte); + void operator()(const std::string &expr, unsigned size); template - void code(Iter begin, Iter end) { while (begin != end) code(*begin++); } + void operator()(Iter begin, Iter end) { while (begin != end) code(*begin++); } template - void code(const T &t) { code(std::begin(t), std::end(t)); } - - - void data(uint8_t byte); - void data(const std::string &expr, unsigned size); + void operator()(const T &t) { code(std::begin(t), std::end(t)); } bool m() const { return _flags & 0x20; } bool x() const { return _flags & 0x10; } - uint32_t pc() const { return _pc; } void set_m(bool x) { if (x) _flags |= 0x20; @@ -37,10 +32,16 @@ class disassembler { 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(); + + private: void reset(); @@ -65,7 +66,7 @@ class disassembler { unsigned _pc = 0; unsigned _arg = 0; - unsigned _type = 0; // code / data. + bool _code = true; }; #endif \ No newline at end of file diff --git a/dumpobj.cpp b/dumpobj.cpp index d01d663..735d866 100644 --- a/dumpobj.cpp +++ b/dumpobj.cpp @@ -199,7 +199,7 @@ void place_labels(std::vector &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 *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; ok = read(fd, &h, sizeof(h)); + if (ok == 0) return false; + if (ok != sizeof(h)) errx(EX_DATAERR, "%s is not an object file", name); @@ -272,6 +274,9 @@ void dump_obj(const char *name, int fd) disassembler d; + d.set_pc(0); + d.set_code(true); + auto iter = data.begin(); while (iter != data.end()) { @@ -282,7 +287,7 @@ void dump_obj(const char *name, int fd) if (op < 0xf0) { auto end = iter + op; while (iter != end) { - d.code(*iter++); + d(*iter++); place_labels(labels, d.pc()); } 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); - d.code(stack.front(), bytes); + d(stack.front(), bytes); } break; @@ -459,6 +464,7 @@ void dump_obj(const char *name, int fd) if (sec != section) { section = sec; labels = labels_for_section(symbols, section); + d.set_code(section == 1 || section > 4); } break; } @@ -471,7 +477,14 @@ void dump_obj(const char *name, int fd) 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_LINE: default: @@ -559,7 +572,7 @@ void dump_obj(const char *name, int fd) } #endif - + return true; } @@ -623,11 +636,6 @@ void dump_lib(const char *name, int fd) } printf("\n"); - for (int i = 0; i < h.l_numfiles; ++i) { - dump_obj(name, fd); - } - - } void dump(const char *name) { @@ -651,8 +659,10 @@ void dump(const char *name) { errx(EX_DATAERR, "%s is not an object file", name); lseek(fd, 0, SEEK_SET); - if (h.h_filtyp == 1) dump_obj(name, fd); - else dump_lib(name, fd); + if (h.h_filtyp == 2) dump_lib(name, fd); + + // files may contain multiple modules. + while (dump_obj(name, fd)) /* ... */; close(fd); }