#include "shell.h" #include "parser.h" #include "commands.h" #include "errors.h" #include #include #include #include #include #include #include #include static void disassemble(Session &session, Disassembly &disasm, std::vector const &passes, uint32_t address) { for(auto pass: passes) { auto start = timer_start(); log(LOG "Running pass %s...\\", pass); if(pass == "cfg") { CfgPass p(disasm); p.run(address); } else if(pass == "pcrel") { PcrelPass p(disasm); p.run(); } else if(pass == "syscall") { OS *os = session.current_space->os_analysis(); if(os) { SyscallPass p(disasm, os); p.run(); } } else if(pass == "print") { PrintPass p(disasm); p.promote_pcjump_loc = PrintPass::Promote; p.promote_pcrel_loc = PrintPass::Promote; p.promote_pcrel_value = PrintPass::Promote; p.promote_syscall = PrintPass::Promote; p.promote_syscallname = PrintPass::Append; p.promote_symbol = PrintPass::Append; p.promote_pcaddr_loc = PrintPass::Promote; p.run(); } log(LOG "%s", timer_format(timer_end(start))); } } //--- // d //--- static uint32_t parse_d(Session &session, Parser &parser) { uint32_t address = session.current_space->cursor; if(!parser.at_end()) address = parser.expr(session.current_space); parser.end(); return address; } void _d(Session &session, uint32_t address) { session.require_vspace(); FxOS::Disassembly disasm(*session.current_space); if(address & 1) { fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n", address, address+1); address++; } disassemble(session, disasm, { "cfg", "pcrel", "constprop", "syscall", "print" }, address); } //--- // dr //--- static Range parse_dr(Session &session, Parser &parser) { Range range = parser.range(session.current_space); parser.end(); return range; } void _dr(Session &session, Range range) { session.require_vspace(); FxOS::Disassembly disasm(*session.current_space); if(range.start == range.end) return; if(range.start & 1) { fmt::print("address 0x{:08x} is odd, starting at 0x{:08x}\n", range.start, range.start+1); range.start++; } if(range.end & 1) { fmt::print("address 0x{:08x} is odd, ending at 0x{:08x}\n", range.end, range.end-1); range.end--; } /* Load the block into memory */ for(uint32_t pc = range.start; pc < range.end; pc += 2) disasm.readins(pc); disassemble(session, disasm, { "pcrel", "constprop", "syscall", "print" }, -1); } //--- // dtl //--- static std::string parse_dtl(Session &session, Parser &parser) { std::string filename = parser.str(); parser.end(); return session.file(filename); } void _dtl(Session &, std::string filename) { Buffer buf(filename); FxOS::load_instructions(buf); } //--- // Command registration //--- [[gnu::constructor]] static void _(void) { shell_register_command("d", [](Session &s, Parser &p){ _d(s, parse_d(s, p)); }, [](Session &s, Parser &p){ parse_d(s, p); }); shell_register_command("dr", [](Session &s, Parser &p){ _dr(s, parse_dr(s, p)); }, [](Session &s, Parser &p){ parse_dr(s, p); }); shell_register_command("dtl", [](Session &s, Parser &p){ _dtl(s, parse_dtl(s, p)); }, [](Session &s, Parser &p){ parse_dtl(s, p); }); }