basic blocks

This commit is contained in:
Sean 2020-02-19 20:23:23 -07:00
parent 54b1b4b8ce
commit c7837da33e
5 changed files with 683 additions and 24 deletions

317
src/65816.h Normal file
View File

@ -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]))

View File

@ -1,10 +1,20 @@
/** @copyright 2020 Sean Kasun */
#include "disasm.h"
#include "65816.h"
#include <fstream>
#include <iostream>
#include <stack>
Disassembler::Disassembler(std::shared_ptr<Fingerprints> prints) : fingerprints(prints) { }
static std::map<Addressing, int> sizes;
Disassembler::Disassembler(std::shared_ptr<Fingerprints> prints,
std::map<uint32_t, std::string> symbols)
: symbols(symbols), fingerprints(prints) {
for (int i = 0; i < numAddressSizes; i++) {
sizes[addressSizes[i].mode] = addressSizes[i].length;
}
}
bool Disassembler::disassemble(std::vector<Segment> segments,
std::vector<Entry> entries) {
@ -29,7 +39,7 @@ bool Disassembler::disassemble(std::vector<Segment> 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>();
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<uint32_t, uint32_t>(inst->oper,
inst->oper));
}
}
}
if (inst->type == Jump || inst->type == Branch ||
inst->type == Return) {
branches.insert(state.org, addr);
branches.insert(std::pair<uint32_t, uint32_t>(state.org, addr));
}
if (inst->type == Invalid) {
branches.insert(addr, addr);
branches.insert(std::pair<uint32_t, uint32_t>(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<Inst> Disassembler::decodeInst(Handle f, Entry *entry) {
auto inst = std::make_shared<Inst>();
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<int8_t>(f->r8());
inst->operType = Opr::Abs;
break;
case RELL:
inst->oper = addr + static_cast<int16_t>(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<char>(ch + '0');
} else {
ret += static_cast<char>(ch - 10 + 'a');
}
}
}
return ret;
}

View File

@ -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<Fingerprints> prints);
bool disassemble(std::vector<Segment> segments, std::vector<Entry> entries);
Disassembler(std::shared_ptr<Fingerprints> prints,
std::map<uint32_t, std::string> symbols);
bool disassemble(std::vector<struct Segment> segments,
std::vector<struct Entry> entries);
private:
bool trace(const Entry &start);
bool trace(const struct Entry &start);
bool basicBlocks();
std::shared_ptr<Inst> 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<uint32_t, std::string> symbols;
std::map<uint32_t, uint32_t> labels;
std::map<uint32_t, uint32_t> branches;
std::vector<Segment> segments;
std::vector<struct Segment> segments;
std::shared_ptr<Fingerprints> fingerprints;
std::map<uint32_t, std::shared_ptr<Inst>> map;
};

View File

@ -130,27 +130,33 @@ int main(int argc, char **argv) {
auto prints = std::make_shared<Fingerprints>();
for (auto s : api.symbols) {
if (s->kind == symbol::isFunction) {
auto f = std::static_pointer_cast<symbol::Function>(s);
if (s.second->kind == symbol::isFunction) {
auto f = std::static_pointer_cast<symbol::Function>(s.second);
if (f->signature.size() >= 2) {
if (f->signature[0] >= 0) { // tool
// ldx tool, jsl e1/0000
std::vector<uint8_t> sig = { 0xa2, f->signature[0], f->signature[1],
std::vector<uint8_t> 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<uint8_t> sig = { 0x22, 0xa8, 0x00, 0xe1,
f->signature[2] & 0xff, f->signature[2] >> 8 };
std::vector<uint8_t> 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<uint8_t> sig = { 0x20, 0x00, 0xbf, f->signature[2] };
std::vector<uint8_t> 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<uint8_t> sig5 = { 0x20, 0x0d, 0xc5, f->signature[2] };
std::vector<uint8_t> sig7 = { 0x20, 0x0d, 0xc7, f->signature[2] };
std::vector<uint8_t> sig5 = { 0x20, 0x0d, 0xc5, 0x00 };
std::vector<uint8_t> 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());
}

View File

@ -34,6 +34,7 @@ class Map {
Map(const char *filename);
bool needsEntry();
std::vector<Entry> getEntries();
std::map<uint32_t, std::string> getSymbols();
void addEntry(uint32_t entry, uint32_t flags);
uint32_t org;