2019-12-28 17:18:13 +01:00
|
|
|
//---
|
|
|
|
// fxos.passes.print: Print disassembly
|
|
|
|
//---
|
|
|
|
|
2020-02-12 07:53:00 +01:00
|
|
|
#include <fxos/disasm-passes/print.h>
|
2019-12-28 17:18:13 +01:00
|
|
|
#include <fxos/disassembly.h>
|
|
|
|
|
|
|
|
namespace FxOS {
|
|
|
|
|
|
|
|
PrintPass::PrintPass(Disassembly &disasm):
|
|
|
|
DisassemblyPass(disasm)
|
|
|
|
{
|
2020-02-12 07:53:00 +01:00
|
|
|
/* Default parameter set */
|
|
|
|
hide_resolved_pcjump = false;
|
|
|
|
hide_resolved_pcrel = false;
|
|
|
|
hide_movpc_address = Hide_MovPC_Never;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PrintPass::run(void)
|
|
|
|
{
|
|
|
|
for(auto &pair: m_disasm.instructions())
|
|
|
|
{
|
|
|
|
analyze(pair.first, pair.second);
|
|
|
|
}
|
2019-12-28 17:18:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void PrintPass::analyze(uint32_t pc, ConcreteInstruction &ci)
|
|
|
|
{
|
2020-02-12 07:53:00 +01:00
|
|
|
Instruction const &i = ci.inst;
|
|
|
|
|
|
|
|
/* Mnemonic */
|
|
|
|
|
|
|
|
static std::map<int, std::string> suffixes = {
|
|
|
|
{ 1, ".b" }, { 2, ".w" }, { 4, ".l" } };
|
|
|
|
|
|
|
|
std::string mnemonic = i.mnemonic + suffixes[i.opsize];
|
|
|
|
if(i.args.size())
|
|
|
|
mnemonic += std::string(8 - mnemonic.size(), ' ');
|
|
|
|
|
|
|
|
printf(" %08x: %04x %s", pc, ci.inst.opcode, mnemonic.c_str());
|
|
|
|
|
|
|
|
/* Arguments */
|
|
|
|
|
|
|
|
for(size_t n = 0; n < i.args.size(); n++)
|
|
|
|
{
|
|
|
|
auto &a = i.args[n];
|
|
|
|
Location &l = ci.args[n].location;
|
2020-02-12 16:33:08 +01:00
|
|
|
std::optional<DataValue> v = ci.args[n].value;
|
2020-02-12 07:53:00 +01:00
|
|
|
|
|
|
|
if(n) printf(", ");
|
|
|
|
|
2020-02-12 16:33:08 +01:00
|
|
|
if(a.kind == Argument::PcJump)
|
2020-02-12 07:53:00 +01:00
|
|
|
{
|
2020-02-12 16:33:08 +01:00
|
|
|
if(!l || !hide_resolved_pcjump)
|
|
|
|
printf("%s", a.str().c_str());
|
|
|
|
if(l)
|
|
|
|
printf("<%s>", l.str().c_str());
|
2020-02-12 07:53:00 +01:00
|
|
|
}
|
2020-02-12 16:33:08 +01:00
|
|
|
else if(a.kind == Argument::PcRel)
|
2020-02-12 07:53:00 +01:00
|
|
|
{
|
2020-02-12 16:33:08 +01:00
|
|
|
pcrel(pc, a, l, v);
|
2020-02-12 07:53:00 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("%s", a.str().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\n");
|
2019-12-28 17:18:13 +01:00
|
|
|
}
|
|
|
|
|
2020-02-12 16:33:08 +01:00
|
|
|
void PrintPass::pcrel(uint32_t pc, Argument const &a, Location const &l,
|
|
|
|
std::optional<DataValue> v)
|
|
|
|
{
|
|
|
|
if(!l || !hide_resolved_pcrel)
|
|
|
|
{
|
|
|
|
printf("%s", a.str().c_str());
|
|
|
|
}
|
|
|
|
if(!l || !RelConstDomain().is_constant(l)) return;
|
|
|
|
|
|
|
|
auto reg_code = MemoryRegion::region_for(pc);
|
|
|
|
auto reg_data = MemoryRegion::region_for(l.uval);
|
|
|
|
|
|
|
|
bool hma = hide_movpc_address;
|
|
|
|
bool same_region = (reg_code && reg_code == reg_data);
|
|
|
|
|
|
|
|
if(!v || hma == Hide_MovPC_Never ||
|
|
|
|
(hma == Hide_MovPC_Region && !same_region))
|
|
|
|
{
|
|
|
|
printf("<%s>", l.str().c_str());
|
|
|
|
if(v)
|
|
|
|
printf("(%s)", v->str().c_str());
|
|
|
|
}
|
|
|
|
else if(v)
|
|
|
|
{
|
|
|
|
printf("%s", v->str().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-12-28 17:18:13 +01:00
|
|
|
} /* namespace FxOS */
|