//--- // fxos.disassembly: Disassembler //--- #ifndef LIBFXOS_DISASSEMBLY_H #define LIBFXOS_DISASSEMBLY_H #include #include #include #include #include #include namespace FxOS { /* Register an instruction. @inst Instruction with [opcode] set to the binary pattern Typically this is called by loader functions from data tables describing instructions with parameters, not manually. See . */ void register_instruction(Instruction ins); /* An argument for a concrete instruction. */ struct ConcreteInstructionArg { ConcreteInstructionArg(); //--- // Data set by the abstract interpretation passes //--- /* Location in CPU or memory, if that can be determined */ std::optional loc; /* Alternatively, data type, which can sometimes be determined uniquely even if the location is not constant */ std::optional type; //--- // Data set by the syscall and regs passes //--- /* If the value is a syscall address, the syscall's id */ int syscall_id; /* If the value is a peripheral register, its address */ uint32_t reg_address; }; /* A loaded and annotated instruction. */ struct ConcreteInstruction { ConcreteInstruction(Instruction &inst); ConcreteInstruction(ConcreteInstruction const &other) = default; /* What instruction it is */ Instruction &inst; /* Argument information (contains data set by several passes) */ ConcreteInstructionArg args[2]; //--- // Data set by the pcrel pass //--- /* Jump targets, used for jump instructions only. The first jmp is for unconditional jumps; jmpt and jmpf are for conditional jumps. In many situations the jump is forced on a general instruction by a preceding branch due to the delay slot mechanism. */ union { uint32_t jmp, jmpt; }; uint32_t jmpf; //--- // Data set by the cfg pass //--- /* Whether this instruction is a basic block leader */ bool leader; }; /* Short aliases */ using CI = ConcreteInstruction; using CIArg = ConcreteInstructionArg; /* Disassembly interface that automatically loads code from a target */ class Disassembly { public: Disassembly(Target &target); /* Get the storage to any concrete instruction. The instruction will be loaded and initialized if it had not been read before. */ ConcreteInstruction &readins(uint32_t pc); private: /* Underlying target */ Target &m_target; /* Loaded instructions by address */ std::map m_instructions; }; } /* namespace FxOS */ #endif /* LIBFXOS_DISASSEMBLY_H */