105 lines
2.5 KiB
C++
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 */
|