//---------------------------------------------------------------------------// // 1100101 |_ mov #0, r4 __ // // 11 |_ <0xb380 %5c4> / _|_ _____ ___ // // 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< // // |_ base# + offset |_| /_\_\___/__/ // //---------------------------------------------------------------------------// // fxos/passes/print: Disassembly printer // // This pass prints the program and adds annotations depending on a number of // customizable boolean parameters. // // Data for an instruction, and arguments in particular, might have a large // number of equivalent representations, depending on how much information was // added during disassembly. // // The main mechanic of this pass is to define *promotions* which allow high- // level information to be added or to replace low-level data. For instance, an // @(disp,pc) argument could promote to a statically-computed address, which // could promote to its known pointed value in the case of a read, which could // itself promote to a symbol or syscall number. // // Each promotion opportunity has 3 possible settings: // - Never: the higher-level information is not shown. // - Append: the higher-level information is shown after the low-level one. // - Promote: the higher-level information replaces the low-level one. // // For example, by default @(disp,pc) is set to Promote to statically-computed // addresses, their values, and syscall numbers, but syscall names are only set // to Append. Therefore, a mov.l @(disp,pc) which loads the address of syscall // %ace on an fx-series model (which is memcp) might show as // // mov.l %ace memcmp, r3 // // where the first element has been promoted twice and the second appended. //--- #ifndef FXOS_PASSES_PRINT_H #define FXOS_PASSES_PRINT_H #include #include namespace FxOS { class OS; class PrintPass: public InstructionPass { public: PrintPass(Disassembly &disasm); bool analyzeInstruction(uint32_t pc, Instruction &inst) override; //--- // Print pass parameters //--- /* Promotion parameters. Default is always to append. */ enum Promotion { /* Never promote */ Never = 1, /* Promote but keep the lower-level information */ Append = 0, /* Promote and hide the lower-level information */ Promote = 2, }; /** In the following, promote_x always means promote *to x* **/ /* In jumps, promote "pc+" to the target address */ int promote_pcjump_loc; /* In a PC-relative mov, promote "@(,pc)" to computed address */ int promote_pcrel_loc; /* In a PC-relative mov, promote address to pointed value */ int promote_pcrel_value; /* Promote an integer to a syscall number */ int promote_syscall; /* Promote a syscall number to a syscall name */ int promote_syscallname; /* Promote an integer to a symbol */ int promote_symbol; /* In a mova, promote "pc+" to the computed address */ int promote_pcaddr_loc; /* TODO: More print pass parameters */ private: /* Symbol tables to look up names */ std::vector> m_symtables; /* Query symbol tables, most recent first */ std::optional symquery(Symbol::Type type, uint32_t value); /* OS for the target, to mark syscalls before instructions */ OS *m_os; /* Last printed address (for ellipses) */ uint32_t m_last_address; /** Internal promotion tree printers **/ void queue(std::string, bool = false); void queue_flush(); std::vector m_messages; void pcjumploc(Argument const &); void pcrelloc(Argument const &); void pcrelval(Argument const &); void syscall(Argument const &); void syscallname(Argument const &); void symbol(Argument const &); void pcaddrloc(Argument const &); }; } /* namespace FxOS */ #endif /* FXOS_PASSES_PRINT_H */