fxos/include/fxos/passes/cfg.h

61 lines
2.5 KiB
C++

//---------------------------------------------------------------------------//
// 1100101 |_ mov #0, r4 __ //
// 11 |_ <0xb380 %5c4> / _|_ _____ ___ //
// 0110 |_ 3.50 -> 3.60 | _\ \ / _ (_-< //
// |_ base# + offset |_| /_\_\___/__/ //
//---------------------------------------------------------------------------//
// fxos/passes/cfg: Control Flow Graph construction
//
// This pass explores functions by loading every instruction's potential
// successor into the diassembly store. It also sets the [jmptarget] field of
// the Instructions as it goes, allowing other passes to traverse the (somewhat
// implicit) CFG.
//
// This is the main exploration pass; other passes do not typically load new
// instructions from the underlying disassembly. Straightforward passes such as
// [print] iterate on instructions loaded by this pass.
//
// The main problem that this pass has to deal with is delay slots. These are
// pretty tricky to deal with; for instance, in
//
// bra pc+120
// mov #1, r4
//
// the CPU will run [mov #1, r4] while performing the branch to pc+120 in order
// to fill an otherwise-unfillable pipeline cycle. This is annoying for all
// kinds of reasons, and fxos handles this by acting as if the mov itself had
// pc+120 as an uncondition successor.
//
// This could be tricky for the abstract interpreter because the jump target
// has to be computed using the state at the jump instruction, not the one at
// the delay slot. Luckily all delayed jumps are no-ops in termsof state, so
// the confusion has no effect.
//
// Note that jumping into a delay slot will activate the jump in fxos, which is
// not the actual behavior of the processor. I don't believe any compiler does
// this kind of things (most are not inherently designed for delay slots
// anyway). If such an instance is found, fxos will throw an exception and give
// up to make sure no analysis pass returns invalid results.
//
// Take-home message: delay slots are a pain to analyze, so we get rid of them
// as soon as possible and proceed with normal semantics.
//---
#ifndef FXOS_PASSES_CFG_H
#define FXOS_PASSES_CFG_H
#include <fxos/disassembly.h>
namespace FxOS {
class CfgPass: public DisassemblyPass
{
public:
CfgPass(Disassembly &disasm);
bool analyze(uint32_t pc, Instruction &inst) override;
};
} /* namespace FxOS */
#endif /* FXOS_PASSES_CFG_H */