diff --git a/src/65816.h b/src/65816.h new file mode 100644 index 0000000..f3f8f95 --- /dev/null +++ b/src/65816.h @@ -0,0 +1,317 @@ +/** @copyright 2020 Sean Kasun */ +#pragma once + +#include "disasm.h" + +enum Addressing { + IMP, IMM, IMMM, IMMX, IMMS, ABS, ABL, ABX, ABY, ABLX, AIX, + ZP, ZPX, ZPY, ZPS, IND, INZ, INL, INX, INY, INLY, INS, REL, RELL, + BANK, DB, DW, DD, +}; + +struct Opcode { + const char *inst; + Addressing addressing; + InsType type; +}; + +#define op(a, b, c) {#a, b, InsType::c} + +static const Opcode opcodes[] = { + op(brk, IMP, Return), // 00 + op(ora, INX, Normal), // 01 + op(cop, IMP, Normal), // 02 + op(ora, ZPS, Normal), // 03 + op(tsb, ZP, Normal), // 04 + op(ora, ZP, Normal), // 05 + op(asl, ZP, Normal), // 06 + op(ora, INL, Normal), // 07 + op(php, IMP, Normal), // 08 + op(ora, IMMM, Normal), // 09 + op(asl, IMP, Normal), // 0a + op(phd, IMP, Normal), // 0b + op(tsb, ABS, Normal), // 0c + op(ora, ABS, Normal), // 0d + op(asl, ABS, Normal), // 0e + op(ora, ABL, Normal), // 0f + op(bpl, REL, Branch), // 10 + op(ora, INY, Normal), // 11 + op(ora, INZ, Normal), // 12 + op(ora, INS, Normal), // 13 + op(trb, ZP, Normal), // 14 + op(ora, ZPX, Normal), // 15 + op(asl, ZPX, Normal), // 16 + op(ora, INLY, Normal), // 17 + op(clc, IMP, Normal), // 18 + op(ora, ABY, Normal), // 19 + op(inc, IMP, Normal), // 1a + op(tcs, IMP, Normal), // 1b + op(trb, ABS, Normal), // 1c + op(ora, ABX, Normal), // 1d + op(asl, ABX, Normal), // 1e + op(ora, ABLX, Normal), // 1f + op(jsr, ABS, Call), // 20 + op(and, INX, Normal), // 21 + op(jsl, ABL, Call), // 22 + op(and, ZPS, Normal), // 23 + op(bit, ZP, Normal), // 24 + op(and, ZP, Normal), // 25 + op(rol, ZP, Normal), // 26 + op(and, INL, Normal), // 27 + op(plp, IMP, Normal), // 28 + op(and, IMMM, Normal), // 29 + op(rol, IMP, Normal), // 2a + op(pld, IMP, Normal), // 2b + op(bit, ABS, Normal), // 2c + op(and, ABS, Normal), // 2d + op(rol, ABS, Normal), // 2e + op(and, ABL, Normal), // 2f + op(bmi, REL, Branch), // 30 + op(and, INY, Normal), // 31 + op(and, INZ, Normal), // 32 + op(and, INS, Normal), // 33 + op(bit, ZPX, Normal), // 34 + op(and, ZPX, Normal), // 35 + op(rol, ZPX, Normal), // 36 + op(and, INLY, Normal), // 37 + op(sec, IMP, Normal), // 38 + op(and, ABY, Normal), // 39 + op(dec, IMP, Normal), // 3a + op(tsc, IMP, Normal), // 3b + op(bit, ABX, Normal), // 3c + op(and, ABX, Normal), // 3d + op(rol, ABX, Normal), // 3e + op(and, ABLX, Normal), // 3f + op(rti, IMP, Return), // 40 + op(eor, INX, Normal), // 41 + op(db, DB, Invalid), // 42 + op(eor, ZPS, Normal), // 43 + op(mvp, BANK, Normal), // 44 + op(eor, ZP, Normal), // 45 + op(lsr, ZP, Normal), // 46 + op(eor, INL, Normal), // 47 + op(pha, IMP, Normal), // 48 + op(eor, IMMM, Normal), // 49 + op(lsr, IMP, Normal), // 4a + op(phk, IMP, Normal), // 4b + op(jmp, ABS, Jump), // 4c + op(eor, ABS, Normal), // 4d + op(lsr, ABS, Normal), // 4e + op(eor, ABL, Normal), // 4f + op(bvc, REL, Branch), // 50 + op(eor, INY, Normal), // 51 + op(eor, INZ, Normal), // 52 + op(eor, INS, Normal), // 53 + op(mvn, BANK, Normal), // 54 + op(eor, ZPX, Normal), // 55 + op(lsr, ZPX, Normal), // 56 + op(eor, INLY, Normal), // 57 + op(cli, IMP, Normal), // 58 + op(eor, ABY, Normal), // 59 + op(phy, IMP, Normal), // 5a + op(tcd, IMP, Normal), // 5b + op(jmp, ABL, Jump), // 5c + op(eor, ABX, Normal), // 5d + op(lsr, ABX, Normal), // 5e + op(eor, ABLX, Normal), // 5f + op(rts, IMP, Return), // 60 + op(adc, INX, Normal), // 61 + op(per, REL, Normal), // 62 + op(adc, ZPS, Normal), // 63 + op(stz, ZP, Normal), // 64 + op(adc, ZP, Normal), // 65 + op(ror, ZP, Normal), // 66 + op(adc, INL, Normal), // 67 + op(pla, IMP, Normal), // 68 + op(adc, IMMM, Normal), // 69 + op(ror, IMP, Normal), // 6a + op(rtl, IMP, Return), // 6b + op(jmp, IND, Jump), // 6c + op(adc, ABS, Normal), // 6d + op(ror, ABS, Normal), // 6e + op(adc, ABL, Normal), // 6f + op(bvs, REL, Branch), // 70 + op(adc, INY, Normal), // 71 + op(adc, INZ, Normal), // 72 + op(adc, INS, Normal), // 73 + op(stz, ZPX, Normal), // 74 + op(adc, ZPX, Normal), // 75 + op(ror, ZPX, Normal), // 76 + op(adc, INLY, Normal), // 77 + op(sei, IMP, Normal), // 78 + op(adc, ABY, Normal), // 79 + op(ply, IMP, Normal), // 7a + op(tdc, IMP, Normal), // 7b + op(jmp, AIX, Jump), // 7c + op(adc, ABX, Normal), // 7d + op(ror, ABX, Normal), // 7e + op(adc, ABLX, Normal), // 7f + op(bra, REL, Jump), // 80 + op(sta, INX, Normal), // 81 + op(brl, RELL, Jump), // 82 + op(sta, ZPS, Normal), // 83 + op(sty, ZP, Normal), // 84 + op(sta, ZP, Normal), // 85 + op(stx, ZP, Normal), // 86 + op(sta, INL, Normal), // 87 + op(dey, IMP, Normal), // 88 + op(bit, IMMM, Normal), // 89 + op(txa, IMP, Normal), // 8a + op(phb, IMP, Normal), // 8b + op(sty, ABS, Normal), // 8c + op(sta, ABS, Normal), // 8d + op(stx, ABS, Normal), // 8e + op(sta, ABL, Normal), // 8f + op(bcc, REL, Branch), // 90 + op(sta, INY, Normal), // 91 + op(sta, INZ, Normal), // 92 + op(sta, INS, Normal), // 93 + op(sty, ZPX, Normal), // 94 + op(sta, ZPX, Normal), // 95 + op(stx, ZPY, Normal), // 96 + op(sta, INLY, Normal), // 97 + op(tya, IMP, Normal), // 98 + op(sta, ABY, Normal), // 99 + op(txs, IMP, Normal), // 9a + op(txy, IMP, Normal), // 9b + op(stz, ABS, Normal), // 9c + op(sta, ABX, Normal), // 9d + op(stz, ABX, Normal), // 9e + op(sta, ABLX, Normal), // 9f + op(ldy, IMMX, Normal), // a0 + op(lda, INX, Normal), // a1 + op(ldx, IMMX, Normal), // a2 + op(lda, ZPS, Normal), // a3 + op(ldy, ZP, Normal), // a4 + op(lda, ZP, Normal), // a5 + op(ldx, ZP, Normal), // a6 + op(lda, INL, Normal), // a7 + op(tay, IMP, Normal), // a8 + op(lda, IMMM, Normal), // a9 + op(tax, IMP, Normal), // aa + op(plb, IMP, Normal), // ab + op(ldy, ABS, Normal), // ac + op(lda, ABS, Normal), // ad + op(ldx, ABS, Normal), // ae + op(lda, ABL, Normal), // af + op(bcs, REL, Branch), // b0 + op(lda, INY, Normal), // b1 + op(lda, INZ, Normal), // b2 + op(lda, INS, Normal), // b3 + op(ldy, ZPX, Normal), // b4 + op(lda, ZPX, Normal), // b5 + op(ldx, ZPY, Normal), // b6 + op(lda, INLY, Normal), // b7 + op(clv, IMP, Normal), // b8 + op(lda, ABY, Normal), // b9 + op(tsx, IMP, Normal), // ba + op(tyx, IMP, Normal), // bb + op(ldy, ABX, Normal), // bc + op(lda, ABX, Normal), // bd + op(ldx, ABY, Normal), // be + op(lda, ABLX, Normal), // bf + op(cpy, IMMX, Normal), // c0 + op(cmp, INX, Normal), // c1 + op(rep, IMM, Normal), // c2 + op(cmp, ZPS, Normal), // c3 + op(cpy, ZP, Normal), // c4 + op(cmp, ZP, Normal), // c5 + op(dec, ZP, Normal), // c6 + op(cmp, INL, Normal), // c7 + op(iny, IMP, Normal), // c8 + op(cmp, IMMM, Normal), // c9 + op(dex, IMP, Normal), // ca + op(wai, IMP, Normal), // cb + op(cpy, ABS, Normal), // cc + op(cmp, ABS, Normal), // cd + op(dec, ABS, Normal), // ce + op(cmp, ABL, Normal), // cf + op(bne, REL, Branch), // d0 + op(cmp, INY, Normal), // d1 + op(cmp, INZ, Normal), // d2 + op(cmp, INS, Normal), // d3 + op(pei, ZP, Normal), // d4 + op(cmp, ZPX, Normal), // d5 + op(DEC, ZPX, Normal), // d6 + op(cmp, INLY, Normal), // d7 + op(cld, IMP, Normal), // d8 + op(cmp, ABY, Normal), // d9 + op(phx, IMP, Normal), // da + op(stp, IMP, Return), // db + op(jmp, IND, Jump), // dc + op(cmp, ABX, Normal), // dd + op(dec, ABX, Normal), // de + op(cmp, ABLX, Normal), // df + op(cpx, IMMX, Normal), // e0 + op(sbc, INX, Normal), // e1 + op(sep, IMM, Normal), // e2 + op(sbc, ZPS, Normal), // e3 + op(cpx, ZP, Normal), // e4 + op(sbc, ZP, Normal), // e5 + op(inc, ZP, Normal), // e6 + op(sbc, INL, Normal), // e7 + op(inx, IMP, Normal), // e8 + op(sbc, IMMM, Normal), // e9 + op(nop, IMP, Normal), // ea + op(xba, IMP, Normal), // eb + op(cpx, ABS, Normal), // ec + op(sbc, ABS, Normal), // ed + op(inc, ABS, Normal), // ee + op(sbc, ABL, Normal), // ef + op(beq, REL, Branch), // f0 + op(sbc, INY, Normal), // f1 + op(sbc, INZ, Normal), // f2 + op(sbc, INS, Normal), // f3 + op(pea, IMMS, Normal), // f4 + op(sbc, ZPX, Normal), // f5 + op(inc, ZPX, Normal), // f6 + op(sbc, INLY, Normal), // f7 + op(sed, IMP, Normal), // f8 + op(sbc, ABY, Normal), // f9 + op(plx, IMP, Normal), // fa + op(xce, IMP, Normal), // fb + op(jsr, AIX, Call), // fc + op(sbc, ABX, Normal), // fd + op(inc, ABX, Normal), // fe + op(sbc, ABLX, Normal), // ff +}; + +#undef op + +struct AddressSize { + Addressing mode; + int length; +}; + +static const AddressSize addressSizes[] = { + {IMP, 1}, + {IMM, 2}, + {IMMM, 3}, + {IMMX, 3}, + {IMMS, 3}, + {ABS, 3}, + {ABL, 4}, + {ABX, 3}, + {ABY, 3}, + {ABLX, 4}, + {AIX, 3}, + {ZP, 2}, + {ZPX, 2}, + {ZPY, 2}, + {ZPS, 2}, + {IND, 3}, + {INZ, 2}, + {INL, 2}, + {INX, 2}, + {INY, 2}, + {INLY, 2}, + {INS, 2}, + {REL, 2}, + {RELL, 3}, + {BANK, 3}, + {DB, 1}, + {DW, 2}, + {DD, 4}, +}; + +#define numAddressSizes (sizeof(addressSizes) / sizeof(addressSizes[0])) diff --git a/src/disasm.cc b/src/disasm.cc index 68f497b..abf8ebe 100644 --- a/src/disasm.cc +++ b/src/disasm.cc @@ -1,10 +1,20 @@ /** @copyright 2020 Sean Kasun */ #include "disasm.h" +#include "65816.h" #include #include +#include -Disassembler::Disassembler(std::shared_ptr prints) : fingerprints(prints) { } +static std::map sizes; + +Disassembler::Disassembler(std::shared_ptr prints, + std::map symbols) + : symbols(symbols), fingerprints(prints) { + for (int i = 0; i < numAddressSizes; i++) { + sizes[addressSizes[i].mode] = addressSizes[i].length; + } + } bool Disassembler::disassemble(std::vector segments, std::vector entries) { @@ -29,7 +39,7 @@ bool Disassembler::disassemble(std::vector segments, std::cerr << "Failed to open '" << fname << "' for writing" << std::endl; return false; } - f << "Section $" << std::ios::hex << segment.segnum << " " + f << "Section $" << hex(segment.segnum, Value) << " " << segment.name << std::endl; if (!decode(segment.mapped, segment.mapped + segment.length)) { std::cerr << "Disassembly failed" << std::endl; @@ -62,9 +72,9 @@ bool Disassembler::trace(const Entry &start) { int8_t len = 0; auto fstart = ptr->tell(); do { - node = node->map.value(ptr->r8(), nullptr); + node = node->map[ptr->r8()]; len++; - if (node != nullptr && !node->name.isEmpty()) { + if (node != nullptr && !node->name.empty()) { if (inst == nullptr) { inst = std::make_shared(); inst->type = Special; @@ -86,7 +96,7 @@ bool Disassembler::trace(const Entry &start) { if (i) { inst->name += ", "; } - inst->name += hex2(ptr->r8()); + inst->name += hex(ptr->r8(), Value); } inst->name += "}"; inst->length += numDB; @@ -97,18 +107,20 @@ bool Disassembler::trace(const Entry &start) { } map[addr] = inst; if (inst->type == Jump || inst->type == Branch || inst->type == Call) { - auto target = target(inst, resolver); - if (target > 0 && !labels.contains(target)) { - workList.push({state.flags, target}); - labels.insert(target, target); + if (inst->operType == Opr::Imm || inst->operType == Opr::Abs) { + if (valid(inst->oper) && labels.find(inst->oper) == labels.end()) { + workList.push({state.flags, inst->oper}); + labels.insert(std::pair(inst->oper, + inst->oper)); + } } } if (inst->type == Jump || inst->type == Branch || inst->type == Return) { - branches.insert(state.org, addr); + branches.insert(std::pair(state.org, addr)); } if (inst->type == Invalid) { - branches.insert(addr, addr); + branches.insert(std::pair(addr, addr)); } } while (inst->type != Return && inst->type != Jump && inst->type != Invalid); @@ -116,6 +128,66 @@ bool Disassembler::trace(const Entry &start) { return true; } +bool Disassembler::basicBlocks() { + // always starts at a label + auto address = labels.lower_bound(0)->first; + auto block = getBlock(address); + auto done = false; + while (!done) { + auto label = labels.upper_bound(address); + auto branch = branches.upper_bound(address); + if (label != labels.end() && (branch == branches.end() || + label->second < branch->second)) { + // label was earliest + address = label->second; + block->length = address - block->address; + auto next = getBlock(address); + next->preds.append(block); + block->succs.append(next); + block = next; + } else if (branch != branches.end() && (label == labels.end() || + branch->second <= label->second)) { + // branch was earliest (or equal) + auto b = map[branch->second]; + block->branchLen = b->length; + block->length = branch->first - block->address; + if (b->type != Return && b->type != Invalid) { + // branch has a destination + if (b->operType == Opr::Imm || b->operType == Opr::Abs) { + if (valid(b->oper)) { + auto next = getBlock(b->oper); + next->preds.append(block); + block->succs.append(next); + } + } + } + if (b->type == Jump || b->type == Return || b->type == Invalid) { + // branch doesn't continue + auto next = labels.upper_bound(branch->second); + if (next == labels.end()) { + done = true; + } else { + address = next->second; + block = getBlock(address); + } + } else { + // branch continues + auto next = getBlock(branch->first); + next->preds.append(block); + block->succs.append(next); + block = next; + address = block->address; + } + } else { + // out of labels and branches, we screwed up + block->length = map.lastKey() + map.last()->length - block->address; + done = true; + } + } + std::sort(blocks.begin(), blocks.end(), compareBlocks); + return true; +} + Handle Disassembler::getAddress(uint32_t address) { for (auto &s : segments) { if (address >= s.mapped && address < s.mapped + s.length) { @@ -125,3 +197,245 @@ Handle Disassembler::getAddress(uint32_t address) { } return nullptr; } + +bool Disassembler::valid(uint32_t address) { + for (auto &s : segments) { + if (address >= s.mapped && address < s.mapped + s.length) { + return true; + } + } + return false; +} + +std::shared_ptr Disassembler::decodeInst(Handle f, Entry *entry) { + auto inst = std::make_shared(); + auto opcode = f->r8(); + inst->name = opcodes[opcode].inst; + inst->type = opcodes[opcode].type; + auto mode = opcodes[opcode].addressing; + inst->length = sizes[mode]; + if (mode == IMMM && (entry->flags & (IsEmu | IsM8))) { + inst->length--; + } + if (mode == IMMX && (entry->flags & (IsEmu | IsX8))) { + inst->length--; + } + entry->org += inst->length; + uint32_t addr = entry->org; + entry->flags &= IsFlags; // clear changed flags + uint32_t oldFlags = entry->flags; + switch (mode) { + case IMP: + inst->operType = Opr::None; + break; + case IMM: + inst->oper = f->r8(); + inst->operType = Opr::Imm; + if (opcode == 0xe2) { + entry->flags |= inst->oper & IsFlags; + } else if (opcode == 0xc2) { + entry->flags &= ~inst->oper; + } + if ((entry->flags ^ oldFlags) & IsX8) { + entry->flags |= IsX8Changed; + } + if ((entry->flags ^ oldFlags) & IsM8) { + entry->flags |= IsM8Changed; + } + break; + case IMMM: + if (entry->flags & (IsEmu | IsM8)) { + inst->oper = f->r8(); + } else { + inst->oper = f->r16(); + } + inst->operType = Opr::Imm; + break; + case IMMX: + if (entry->flags & (IsEmu | IsX8)) { + inst->oper = f->r8(); + } else { + inst->oper = f->r16(); + } + inst->operType = Opr::Imm; + break; + case IMMS: + inst->oper = f->r16(); + inst->operType = Opr::Imm; + break; + case ABS: + inst->oper = f->r16(); + if (inst->type == InsType::Jump || inst->type == InsType::Call) { + inst->oper |= entry->org & 0xff0000; // K + inst->operType = Opr::Abs; + } else { + inst->operType = Opr::AbsB; + } + break; + case ABL: + inst->oper = f->r24(); + inst->operType = Opr::Abs; + break; + case ABX: + inst->oper = f->r16(); + if (inst->type == InsType::Jump || inst->type == InsType::Call) { + inst->oper |= entry->org & 0xff0000; // K + inst->operType = Opr::AbsX; + } else { + inst->operType = Opr::AbsXB; + } + break; + case ABY: + inst->oper = f->r16(); + if (inst->type == InsType::Jump || inst->type == InsType::Call) { + inst->oper |= entry->org & 0xff0000; // K + inst->operType = Opr::AbsY; + } else { + inst->operType = Opr::AbsYB; + } + break; + case ABLX: + inst->oper = f->r24(); + inst->operType = Opr::AbsX; + break; + case AIX: + inst->oper = f->r16(); + if (inst->type == InsType::Jump || inst->type == InsType::Call) { + inst->oper |= entry->org & 0xff0000; // K + inst->operType = Opr::IndX; + } else { + inst->operType = Opr::IndXB; + } + break; + case ZP: + inst->oper = f->r8(); + inst->operType = Opr::AbsD; + break; + case ZPX: + inst->oper = f->r8(); + inst->operType = Opr::AbsXD; + break; + case ZPY: + inst->oper = f->r8(); + inst->operType = Opr::AbsYD; + break; + case ZPS: + inst->oper = f->r8(); + inst->operType = Opr::AbsS; + break; + case IND: + inst->oper = f->r16(); + if (inst->type == InsType::Jump || inst->type == InsType::Call) { + inst->oper |= entry->org & 0xff0000; // K + inst->operType = Opr::Ind; + } else { + inst->operType = Opr::IndB; + } + break; + case INZ: + inst->oper = f->r8(); + inst->operType = Opr::IndD; + break; + case INL: + inst->oper = f->r8(); + inst->operType = Opr::IndL; + break; + case INX: + inst->oper = f->r8(); + inst->operType = Opr::IndX; + break; + case INY: + inst->oper = f->r8(); + inst->operType = Opr::IndY; + break; + case INLY: + inst->oper = f->r8(); + inst->operType = Opr::IndLY; + break; + case INS: + inst->oper = f->r8(); + inst->operType = Opr::IndS; + break; + case REL: + inst->oper = addr + static_cast(f->r8()); + inst->operType = Opr::Abs; + break; + case RELL: + inst->oper = addr + static_cast(f->r16()); + inst->operType = Opr::Abs; + break; + case BANK: + inst->oper = f->r16(); + inst->operType = Opr::Bank; + break; + case DB: + inst->oper = opcode; + inst->operType = Opr::Abs; + break; + case DW: + inst->oper = opcode | (f->r8() << 8); + inst->operType = Opr::Abs; + break; + case DD: + inst->oper = opcode | (f->r24() << 8); + inst->operType = Opr::Abs; + break; + } + if (opcode == 0x18) { + if (f->r8() == 0xfb) { // clc xce + entry->flags &= 0xffffff ^ IsEmu; + } + f->skip(-1); + } + if (opcode == 0x38) { + if (f->r8() == 0xfb) { // sec xce + entry->flags |= IsEmu; + } + f->skip(-1); + } + if ((entry->flags ^ oldFlags) & IsEmu) { + entry->flags |= IsEmuChanged; + } + inst->flags = entry->flags; + return inst; +} + +std::string Disassembler::hex(uint32_t val, HexType type) { + std::string ret; + int width = 0; + if (type == HexType::Address) { + ret = symbols[val]; + } + if (ret.empty()) { + if ((val & ~0xff) == ~0xff) { + ret += "$-"; + val = ~val + 1; + width = 2; + } else if ((val & ~0xff) == 0) { + ret += "$"; + width = 2; + } else if ((val & ~0xffff) == ~0xffff) { + ret += "$-"; + val = ~val + 1; + width = 4; + } else if ((val & ~0xffff) == 0) { + ret += "$"; + width = 4; + } else if (val & 0x80000000) { + ret += "$-"; + width = 8; + } else { + ret += "$"; + width = 8; + } + for (int i = 0; i < width; i++) { + uint8_t ch = val >> (width - (i + 1)) * 4; + if (ch < 10) { + ret += static_cast(ch + '0'); + } else { + ret += static_cast(ch - 10 + 'a'); + } + } + } + return ret; +} diff --git a/src/disasm.h b/src/disasm.h index 13aa243..e28e287 100644 --- a/src/disasm.h +++ b/src/disasm.h @@ -26,23 +26,44 @@ enum InsType : uint16_t { Invalid = 0xff, }; +enum HexType { + Value = 0x01, + Address = 0x02, +}; + +enum class Opr { + None = 0, Imm, Abs, AbsB, AbsD, AbsX, AbsXB, AbsXD, AbsY, AbsYB, AbsYD, AbsS, + Ind, IndB, IndD, IndX, IndXB, IndY, IndL, IndLY, IndS, Bank, +}; + struct Inst { std::string name; InsType type; uint16_t length; + Opr operType; + uint32_t oper; + uint32_t flags; }; class Disassembler { public: - Disassembler(std::shared_ptr prints); - bool disassemble(std::vector segments, std::vector entries); + Disassembler(std::shared_ptr prints, + std::map symbols); + bool disassemble(std::vector segments, + std::vector entries); private: - bool trace(const Entry &start); + bool trace(const struct Entry &start); + bool basicBlocks(); + std::shared_ptr decodeInst(Handle f, Entry *entry); Handle getAddress(uint32_t address); + bool valid(uint32_t address); + std::string hex(uint32_t value, HexType type); + std::map symbols; std::map labels; std::map branches; - std::vector segments; + std::vector segments; std::shared_ptr fingerprints; + std::map> map; }; diff --git a/src/main.cc b/src/main.cc index 31b5bd5..f8425ac 100644 --- a/src/main.cc +++ b/src/main.cc @@ -130,27 +130,33 @@ int main(int argc, char **argv) { auto prints = std::make_shared(); for (auto s : api.symbols) { - if (s->kind == symbol::isFunction) { - auto f = std::static_pointer_cast(s); + if (s.second->kind == symbol::isFunction) { + auto f = std::static_pointer_cast(s.second); if (f->signature.size() >= 2) { if (f->signature[0] >= 0) { // tool // ldx tool, jsl e1/0000 - std::vector sig = { 0xa2, f->signature[0], f->signature[1], + std::vector sig = { 0xa2, 0x00, 0x00, 0x22, 0x00, 0x00, 0xe1 }; + sig[1] = f->signature[0]; + sig[2] = f->signature[1]; prints->add(sig, f->name); } else if (f->signature[0] == -1) { // p16/gsos // jsl e1/00a8 - std::vector sig = { 0x22, 0xa8, 0x00, 0xe1, - f->signature[2] & 0xff, f->signature[2] >> 8 }; + std::vector sig = { 0x22, 0xa8, 0x00, 0xe1, 0x00, 0x00 }; + sig[4] = f->signature[2] & 0xff; + sig[5] = f->signature[2] >> 8; prints->add(sig, f->name, f->signature[1] & 0xff); } else if (f->signature[0] == -2) { // p8 // jsr bf00 - std::vector sig = { 0x20, 0x00, 0xbf, f->signature[2] }; + std::vector sig = { 0x20, 0x00, 0xbf, 0x00 }; + sig[3] = f->signature[2]; prints->add(sig, f->name, f->signature[1] & 0xff); } else if (f->signature[0] == -3) { // smartport // jsr c50d - std::vector sig5 = { 0x20, 0x0d, 0xc5, f->signature[2] }; - std::vector sig7 = { 0x20, 0x0d, 0xc7, f->signature[2] }; + std::vector sig5 = { 0x20, 0x0d, 0xc5, 0x00 }; + std::vector sig7 = { 0x20, 0x0d, 0xc7, 0x00 }; + sig5[3] = f->signature[2]; + sig7[3] = f->signature[2]; prints->add(sig5, f->name, f->signature[1]); prints->add(sig7, f->name, f->signature[1]); } @@ -158,6 +164,6 @@ int main(int argc, char **argv) { } } - Disassembler d(prints); + Disassembler d(prints, map.getSymbols()); d.disassemble(segments, map.getEntries()); } diff --git a/src/map.h b/src/map.h index 5aa2c23..442a453 100644 --- a/src/map.h +++ b/src/map.h @@ -34,6 +34,7 @@ class Map { Map(const char *filename); bool needsEntry(); std::vector getEntries(); + std::map getSymbols(); void addEntry(uint32_t entry, uint32_t flags); uint32_t org;