//===-- llvm/MC/MCFunction.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the data structures to hold a CFG reconstructed from // machine code. // //===----------------------------------------------------------------------===// #ifndef LLVM_MC_MCFUNCTION_H #define LLVM_MC_MCFUNCTION_H #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCInst.h" #include #include namespace llvm { class MCFunction; class MCModule; class MCTextAtom; /// \brief Basic block containing a sequence of disassembled instructions. /// The basic block is backed by an MCTextAtom, which holds the instructions, /// and the address range it covers. /// Create a basic block using MCFunction::createBlock. class MCBasicBlock { const MCTextAtom *Insts; // MCFunction owns the basic block. MCFunction *Parent; friend class MCFunction; MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent); /// \name Predecessors/Successors, to represent the CFG. /// @{ typedef std::vector BasicBlockListTy; BasicBlockListTy Successors; BasicBlockListTy Predecessors; /// @} public: /// \brief Get the backing MCTextAtom, containing the instruction sequence. const MCTextAtom *getInsts() const { return Insts; } /// \name Get the owning MCFunction. /// @{ const MCFunction *getParent() const { return Parent; } MCFunction *getParent() { return Parent; } /// @} /// MC CFG access: Predecessors/Successors. /// @{ typedef BasicBlockListTy::const_iterator succ_const_iterator; succ_const_iterator succ_begin() const { return Successors.begin(); } succ_const_iterator succ_end() const { return Successors.end(); } typedef BasicBlockListTy::const_iterator pred_const_iterator; pred_const_iterator pred_begin() const { return Predecessors.begin(); } pred_const_iterator pred_end() const { return Predecessors.end(); } void addSuccessor(const MCBasicBlock *MCBB); bool isSuccessor(const MCBasicBlock *MCBB) const; void addPredecessor(const MCBasicBlock *MCBB); bool isPredecessor(const MCBasicBlock *MCBB) const; /// \brief Split block, mirrorring NewAtom = Insts->split(..). /// This moves all successors to \p SplitBB, and /// adds a fallthrough to it. /// \p SplitBB The result of splitting Insts, a basic block directly following /// this basic block. void splitBasicBlock(MCBasicBlock *SplitBB); /// @} }; /// \brief Represents a function in machine code, containing MCBasicBlocks. /// MCFunctions are created by MCModule. class MCFunction { MCFunction (const MCFunction&) LLVM_DELETED_FUNCTION; MCFunction& operator=(const MCFunction&) LLVM_DELETED_FUNCTION; std::string Name; MCModule *ParentModule; typedef std::vector BasicBlockListTy; BasicBlockListTy Blocks; // MCModule owns the function. friend class MCModule; MCFunction(StringRef Name, MCModule *Parent); ~MCFunction(); public: /// \brief Create an MCBasicBlock backed by Insts and add it to this function. /// \param Insts Sequence of straight-line code backing the basic block. /// \returns The newly created basic block. MCBasicBlock &createBlock(const MCTextAtom &Insts); StringRef getName() const { return Name; } /// \name Get the owning MC Module. /// @{ const MCModule *getParent() const { return ParentModule; } MCModule *getParent() { return ParentModule; } /// @} /// \name Access to the function's basic blocks. No ordering is enforced, /// except that the first block is the entry block. /// @{ /// \brief Get the entry point basic block. const MCBasicBlock *getEntryBlock() const { return front(); } MCBasicBlock *getEntryBlock() { return front(); } bool empty() const { return Blocks.empty(); } typedef BasicBlockListTy::const_iterator const_iterator; typedef BasicBlockListTy:: iterator iterator; const_iterator begin() const { return Blocks.begin(); } iterator begin() { return Blocks.begin(); } const_iterator end() const { return Blocks.end(); } iterator end() { return Blocks.end(); } const MCBasicBlock* front() const { return Blocks.front(); } MCBasicBlock* front() { return Blocks.front(); } const MCBasicBlock* back() const { return Blocks.back(); } MCBasicBlock* back() { return Blocks.back(); } /// \brief Find the basic block, if any, that starts at \p StartAddr. const MCBasicBlock *find(uint64_t StartAddr) const; MCBasicBlock *find(uint64_t StartAddr); /// @} }; } #endif