fxos/include/fxos/disassembly.h

105 lines
2.5 KiB
C++

//---
// fxos.disassembly: Disassembler
//---
#ifndef LIBFXOS_DISASSEMBLY_H
#define LIBFXOS_DISASSEMBLY_H
#include <fxos/lang.h>
#include <fxos/target.h>
#include <fxos/semantics.h>
#include <vector>
#include <optional>
#include <map>
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 <fxos/load.h>. */
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<Location> loc;
/* Alternatively, data type, which can sometimes be determined uniquely
even if the location is not constant */
std::optional<DataType> 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<uint32_t, ConcreteInstruction> m_instructions;
};
} /* namespace FxOS */
#endif /* LIBFXOS_DISASSEMBLY_H */