Coverage for /Syzygy/block_graph/basic_block.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%98980.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Provides the Basic-Block Graph representation and APIs.
  16    :  //
  17    :  // See http://en.wikipedia.org/wiki/Basic_block for a brief discussion of
  18    :  // basic blocks, their uses, and related terminology.
  19    :  //
  20    :  // TODO(rogerm): Unify the representation and idioms for attributes of
  21    :  //     block, basic-blocks, and labels. Blocks and labels are similar but
  22    :  //     not the same, and basic-blocks just has "is_padding" as a boolean.
  23    :  
  24    :  #ifndef SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_H_
  25    :  #define SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_H_
  26    :  
  27    :  #include "base/string_piece.h"
  28    :  #include "syzygy/block_graph/block_graph.h"
  29    :  #include "syzygy/common/align.h"
  30    :  #include "syzygy/core/assembler.h"
  31    :  #include "syzygy/core/disassembler_util.h"
  32    :  
  33    :  #include "distorm.h"  // NOLINT
  34    :  
  35    :  namespace block_graph {
  36    :  
  37    :  // Forward declarations.
  38    :  class BasicBlock;
  39    :  class BasicCodeBlock;
  40    :  class BasicDataBlock;
  41    :  class Instruction;
  42    :  class Successor;
  43    :  
  44    :  // Represents a reference from one basic-block to another basic-block or to
  45    :  // another code- or data-block altogether.
  46    :  class BasicBlockReference {
  47    :   public:
  48    :    typedef BlockGraph::ReferenceType ReferenceType;
  49    :    typedef BlockGraph::Block Block;
  50    :    typedef BlockGraph::Offset Offset;
  51    :    typedef BlockGraph::Size Size;
  52    :  
  53    :    enum ReferredType {
  54    :      REFERRED_TYPE_UNKNOWN,
  55    :      REFERRED_TYPE_BLOCK,
  56    :      REFERRED_TYPE_BASIC_BLOCK,
  57    :  
  58    :      // This enum value should always be last.
  59    :      MAX_REFERRED_TYPE,
  60    :    };
  61    :  
  62    :    // Default constructor; needed for storage in stl containers.
  63    :    BasicBlockReference();
  64    :  
  65    :    // Create a reference to a block.
  66    :    //
  67    :    // @param type type of reference.
  68    :    // @param size size of reference.
  69    :    // @param block the referenced block.
  70    :    // @param offset offset of reference into @p block.
  71    :    // @param base base of the reference within @p block.
  72    :    BasicBlockReference(ReferenceType type,
  73    :                        Size size,
  74    :                        Block* block,
  75    :                        Offset offset,
  76    :                        Offset base);
  77    :  
  78    :    // Create a reference to a basic-block.
  79    :    //
  80    :    // @param type type of reference.
  81    :    // @param size size of reference.
  82    :    // @param basic_block the referenced basic block.
  83    :    BasicBlockReference(ReferenceType type,
  84    :                        Size size,
  85    :                        BasicBlock* basic_block);
  86    :  
  87    :    // Creates a reference to the same destination as @p ref, but with
  88    :    // a potentially new type and size.
  89    :    //
  90    :    // @param type type of reference.
  91    :    // @param size size of reference.
  92    :    // @param basic_block the destination for the new reference.
  93    :    BasicBlockReference(ReferenceType type,
  94    :                        Size size,
  95    :                        const BasicBlockReference& ref);
  96    :  
  97    :    // Copy constructor.
  98    :    BasicBlockReference(const BasicBlockReference& other);
  99    :  
 100    :    // Accessors.
 101    :    // @{
 102    :  
 103    :    // Retrieves the type of block (macro or basic) that it referenced.
 104  E :    ReferredType referred_type() const { return referred_type_; }
 105    :  
 106    :    // Retrieves the type reference (absolute or relative) for this reference.
 107  E :    ReferenceType reference_type() const { return reference_type_; }
 108    :  
 109    :    // Retrieves the size of the reference.
 110  E :    Size size() const { return size_; }
 111    :  
 112    :    // Retrieves the referenced block or NULL if this reference does not
 113    :    // refer to a block.
 114  E :    Block* block() const {
 115  E :      return referred_type_ == REFERRED_TYPE_BLOCK ? referred_block_ : NULL;
 116  E :    }
 117    :  
 118    :    // Retrieves the referenced basic-block or NULL if this reference does not
 119    :    // refer to a basic block.
 120  E :    BasicBlock* basic_block() const {
 121    :      return referred_type_ == REFERRED_TYPE_BASIC_BLOCK ?
 122  E :          referred_basic_block_ : NULL;
 123  E :    }
 124    :  
 125    :    // Retrieves the offset into the referenced macro- or basic-block.
 126  E :    Offset offset() const { return offset_; }
 127    :  
 128    :    // Retrieves the base offset to which this reference refers.
 129  E :    Offset base() const { return base_; }
 130    :    // @}
 131    :  
 132    :    // Compare this BasicBlockReferences with another for equality.
 133  E :    bool operator==(const BasicBlockReference& other) const {
 134    :      return (referred_type_ == other.referred_type_ &&
 135    :              reference_type_ == other.reference_type_ &&
 136    :              size_ == other.size_ &&
 137    :              referred_block_ == other.referred_block_ &&
 138  E :              offset_ == other.offset_);
 139  E :    }
 140    :  
 141    :    // Test if this reference has been initialized to refer to something.
 142  E :    bool IsValid() const {
 143  E :      return size_ != 0 && referred_block_ != NULL;
 144  E :    }
 145    :  
 146    :   protected:
 147    :    // Denotes whether this reference is to a block or basic block.
 148    :    ReferredType referred_type_;
 149    :  
 150    :    // The type of this reference.
 151    :    ReferenceType reference_type_;
 152    :  
 153    :    // The size of this reference.
 154    :    // Absolute references are always pointer wide, but PC-relative
 155    :    // references can be 1, 2 or 4 bytes wide, which affects their range.
 156    :    Size size_;
 157    :  
 158    :    // The block or basic-block that is referenced.
 159    :    union {
 160    :      Block* referred_block_;
 161    :      BasicBlock* referred_basic_block_;
 162    :    };
 163    :  
 164    :    // The offset into the referenced block or basic-block. This may or may not
 165    :    // end up referring into the target block's byte range.
 166    :    Offset offset_;
 167    :  
 168    :    // The base of the reference, as an offset into the referenced block or
 169    :    // basic-block. This must be a location strictly within the target block's
 170    :    // byte range.
 171    :    Offset base_;
 172    :  };
 173    :  
 174    :  // This class keeps track of a reference from an external block to a basic
 175    :  // block. Instances of this only make sense in the context of a given basic
 176    :  // block breakdown.
 177    :  class BasicBlockReferrer {
 178    :   public:
 179    :    typedef BlockGraph::Block Block;
 180    :    typedef BlockGraph::Offset Offset;
 181    :  
 182    :    // Create an empty (invalid) BasicBlockReferrer.
 183    :    BasicBlockReferrer();
 184    :  
 185    :    // Create a BasicBlockReferrer which tracks that an external block makes
 186    :    // reference to this basic block.
 187    :    // @param block The block which refers to this basic block.
 188    :    // @param offset The offset in the block at which the reference occurs.
 189    :    BasicBlockReferrer(const Block* block, Offset offset);
 190    :  
 191    :    // Create a copy of the @p other BasicBlockReferrer.
 192    :    // @param other A basic block referrer record to be copy constructed.
 193    :    BasicBlockReferrer(const BasicBlockReferrer& other);
 194    :  
 195    :    // Returns the block which refers to this basic block, or NULL.
 196  E :    const Block* block() const {
 197  E :      return referrer_;
 198  E :    }
 199    :  
 200    :    // Returns the offset in the referrer at which the reference to
 201    :    // the basic block occurs.
 202  E :    Offset offset() const { return offset_; }
 203    :  
 204    :    // Returns whether or not this is a valid basic block referrer object.
 205    :    bool IsValid() const;
 206    :  
 207    :    // Equality comparator.
 208  E :    bool operator==(const BasicBlockReferrer& other) const {
 209  E :      return referrer_ == other.referrer_ && offset_ == other.offset_;
 210  E :    }
 211    :  
 212    :    // Less-than comparator. Useful for putting BasicBlockReferrers into
 213    :    // ordered containers.
 214    :    struct CompareAsLess {
 215    :      bool operator()(const BasicBlockReferrer& lhs,
 216  E :                      const BasicBlockReferrer& rhs) const {
 217    :        return lhs.referrer_ < rhs.referrer_ ||
 218  E :           (lhs.referrer_ == rhs.referrer_ && lhs.offset_ < rhs.offset_);
 219  E :      }
 220    :    };
 221    :  
 222    :   protected:
 223    :    // The referring block.
 224    :    const Block* referrer_;
 225    :  
 226    :    // The source offset in the block where the reference occurs.
 227    :    Offset offset_;
 228    :  };
 229    :  
 230    :  // Represents an instruction in a basic-block.
 231    :  class Instruction {
 232    :   public:
 233    :    typedef BlockGraph::Size Size;
 234    :    typedef BlockGraph::Offset Offset;
 235    :    typedef BlockGraph::Block::SourceRange SourceRange;
 236    :    typedef _DInst Representation;
 237    :    typedef std::map<Offset, BasicBlockReference> BasicBlockReferenceMap;
 238    :  
 239    :    // The maximum size (in bytes) of an x86 instruction, per specs.
 240    :    static const size_t kMaxSize = core::AssemblerImpl::kMaxInstructionLength;
 241    :  
 242    :    // A default constructed Instruction will be a single byte NOP.
 243    :    Instruction();
 244    :  
 245    :    // Copy constructor.
 246    :    Instruction(const Instruction& other);
 247    :  
 248    :    // Factory to construct an initialized an Instruction instance from a buffer.
 249    :    // @param buf the data comprising the instruction.
 250    :    // @param len the maximum length (in bytes) of @p buf to consume
 251    :    // @returns true on success, false otherwise.
 252    :    static bool FromBuffer(const uint8* buf, size_t len, Instruction* inst);
 253    :  
 254    :    // Accessors.
 255    :    // @{
 256  E :    const Representation& representation() const { return representation_; }
 257  E :    Representation& representation() { return representation_; }
 258  E :    const BasicBlockReferenceMap& references() const { return references_; }
 259  E :    BasicBlockReferenceMap& references() { return references_; }
 260    :  
 261  E :    SourceRange source_range() const { return source_range_; }
 262  E :    void set_source_range(const SourceRange& source_range) {
 263  E :      source_range_ = source_range;
 264  E :    }
 265  E :    const BlockGraph::Label& label() const { return label_; }
 266  E :    void set_label(const BlockGraph::Label& label) { label_ = label; }
 267  E :    bool has_label() const { return label_.IsValid(); }
 268    :  
 269  E :    uint16 opcode() const { return representation_.opcode; }
 270  E :    Size size() const { return representation_.size; }
 271  E :    const uint8* data() const { return data_; }
 272    :    /// @}
 273    :  
 274    :    // @name Deprecated accessors.
 275    :    // @{
 276    :    Offset offset() const { return offset_; }
 277    :    void set_offset(Offset offset) { offset_ = offset; }
 278    :    // @}
 279    :  
 280    :    // @name Helper functions.
 281    :    // @{
 282  E :    bool IsNop() const { return core::IsNop(representation_); }
 283  E :    bool IsCall() const { return core::IsCall(representation_); }
 284  E :    bool IsReturn() const { return core::IsReturn(representation_); }
 285  E :    bool IsSystemCall() const { return core::IsSystemCall(representation_); }
 286  E :    bool IsConditionalBranch() const {
 287  E :        return core::IsConditionalBranch(representation_);
 288  E :    }
 289    :    bool IsUnconditionalBranch() const {
 290    :        return core::IsUnconditionalBranch(representation_);
 291    :    }
 292  E :    bool IsBranch() const { return core::IsBranch(representation_); }
 293  E :    bool HasPcRelativeOperand(int operand_index) const {
 294  E :      return core::HasPcRelativeOperand(representation_, operand_index);
 295  E :    }
 296  E :    bool IsControlFlow() const { return core::IsControlFlow(representation_); }
 297  E :    bool IsImplicitControlFlow() const {
 298  E :      return core::IsImplicitControlFlow(representation_);
 299  E :    }
 300  E :    bool IsInterrupt() const { return core::IsInterrupt(representation_); }
 301    :    bool IsDebugInterrupt() const {
 302    :      return core::IsDebugInterrupt(representation_);
 303    :    }
 304    :    bool CallsNonReturningFunction() const;
 305    :    // @}
 306    :  
 307    :    // Returns the mnemonic name for this instruction.
 308    :    const char* GetName() const;
 309    :  
 310    :    // Dump a text representation of this instruction.
 311    :    // @param buf receives the text representation.
 312    :    // @returns true if this instruction was successfully dumped, false otherwise.
 313    :    bool ToString(std::string* buf) const;
 314    :  
 315    :    // Returns the maximum size required to serialize this instruction.
 316    :    Size GetMaxSize() const { return representation_.size; }
 317    :  
 318    :    // Add a reference @p ref to this instruction at @p offset. If the reference
 319    :    // is to a basic block, also update that basic blocks referrer set.
 320    :    bool SetReference(Offset offset, const BasicBlockReference& ref);
 321    :  
 322    :    // Finds the reference, if any, for @p operand_index of this instruction.
 323    :    // @param operand_index the desired operand, in the range 0-3.
 324    :    // @param reference on success returns the reference.
 325    :    // @returns true iff @p operand_index exists and has a reference.
 326    :    bool FindOperandReference(size_t operand_index,
 327    :                              BasicBlockReference* reference) const;
 328    :  
 329    :    // Helper function to invert a conditional branching opcode.
 330    :    static bool InvertConditionalBranchOpcode(uint16* opcode);
 331    :  
 332    :    // Returns true if the given PC-relative or indirect-memory call instruction
 333    :    // is to a non-returning function. The block (and offset into it) being
 334    :    // directly referenced by the call need to be provided explicitly.
 335    :    static bool IsCallToNonReturningFunction(const Representation& inst,
 336    :                                             const BlockGraph::Block* target,
 337    :                                             Offset offset);
 338    :  
 339    :   protected:
 340    :    // Construct an instruction from its parsed representation and underlying
 341    :    // memory buffer.
 342    :    Instruction(const _DInst& repr, const uint8* data);
 343    :  
 344    :    // The internal representation of this instruction.
 345    :    Representation representation_;
 346    :  
 347    :    // Captures the references (if any) that this instruction makes to another
 348    :    // basic block or macro block.
 349    :    BasicBlockReferenceMap references_;
 350    :  
 351    :    // The label, if any, associated with this instruction.
 352    :    BlockGraph::Label label_;
 353    :  
 354    :    // The source range, if any, associated with this instruction.
 355    :    SourceRange source_range_;
 356    :  
 357    :    // The data associated with this instruction.
 358    :    uint8 data_[kMaxSize];
 359    :  
 360    :    // Deprecated.
 361    :    Offset offset_;
 362    :  };
 363    :  
 364    :  // This class represents a control flow transfer to a basic block, which
 365    :  // includes both the target basic block as well as the condition on which
 366    :  // control flows to that basic block.
 367    :  class Successor {
 368    :   public:
 369    :    typedef core::AbsoluteAddress AbsoluteAddress;
 370    :    typedef BlockGraph::Offset Offset;
 371    :    typedef BlockGraph::Size Size;
 372    :    typedef BlockGraph::Block::SourceRange SourceRange;
 373    :    typedef std::map<Offset, BasicBlockReference> BasicBlockReferenceMap;
 374    :  
 375    :    // The op-code of an binary instruction.
 376    :    typedef uint16 OpCode;
 377    :  
 378    :    // The set of logical branching flow a successor may embody.
 379    :    enum Condition {
 380    :      // Sentinel value denoting an invalid branch condition.
 381    :      kInvalidCondition = -1,
 382    :  
 383    :      // These correspond to the conditional branch instructions.
 384    :      // @{
 385    :      kConditionAbove = core::kAbove,  // JA and JNBE.
 386    :      kConditionAboveOrEqual = core::kAboveEqual,  // JAE, JNB and JNC.
 387    :      kConditionBelow = core::kBelow,  // JB, JNAE and JC.
 388    :      kConditionBelowOrEqual = core::kBelowEqual,  // JBE and JNA.
 389    :      kConditionEqual = core::kEqual,  // JE and JZ.
 390    :      kConditionGreater =  core::kGreater,  // JG and JNLE.
 391    :      kConditionGreaterOrEqual = core::kGreaterEqual,  // JGE and JNL.
 392    :      kConditionLess = core::kLess,  // JL and JNGE.
 393    :      kConditionLessOrEqual = core::kLessEqual,  // JLE and JNG.
 394    :      kConditionNotEqual = core::kNotEqual,  // JNZ, JNE.
 395    :      kConditionNotOverflow = core::kNoOverflow,  // JNO.
 396    :      kConditionNotParity = core::kParityOdd,  // JNP and JPO.
 397    :      kConditionNotSigned = core::kNotSign,  // JNS.
 398    :      kConditionOverflow = core::kOverflow,  // JO.
 399    :      kConditionParity = core::kParityEven,  // JP and JPE.
 400    :      kConditionSigned = core::kSign,  // JS.
 401    :  
 402    :      // Definitions for the bounding values for the conditional branches.
 403    :      // Note: that the maximum must be defined here to let all subsequent
 404    :      //     enum values be properly incremented.
 405    :      kMinConditionalBranch = core::kMinConditionCode,
 406    :      kMaxConditionalBranch = core::kMaxConditionCode,
 407    :  
 408    :      // Unconditional control flow instructions.
 409    :      // @{
 410    :      kConditionTrue,  // JMP.
 411    :      // @}
 412    :  
 413    :      // Sentinels for the largest successor condition values.
 414    :      kMaxCondition,
 415    :    };
 416    :  
 417    :    // Constructors.
 418    :    // @{
 419    :  
 420    :    // Creates a dangling successor.
 421    :    //
 422    :    // This needs to exist so that successors can be stored in STL containers.
 423    :    Successor();
 424    :  
 425    :    // Creates a successor that resolves to a known block or basic block.
 426    :    //
 427    :    // @param condition the branching condition for this successor.
 428    :    // @param target the basic block to which this successor refers.
 429    :    // @param offset the offset in the original block at which the instruction(s)
 430    :    //     for this successor are located.
 431    :    // @param size the length (in bytes) that the instructions for this successor
 432    :    //     occupies in the original block.
 433    :    Successor(Condition condition,
 434    :              const BasicBlockReference& target,
 435    :              Size instruction_size);
 436    :  
 437    :    // Copy-constructor.
 438    :    Successor(const Successor& other);
 439    :    // @}
 440    :  
 441    :    // Accessors.
 442    :    // @{
 443    :    // The type of branch represented by this successor.
 444  E :    Condition condition() const { return condition_; }
 445    :  
 446  E :    BasicBlockReference reference() const { return reference_; }
 447  E :    void set_reference(const BasicBlockReference& reference) {
 448  E :      reference_ = reference;
 449  E :    };
 450    :  
 451  E :    SourceRange source_range() const { return source_range_; }
 452  E :    void set_source_range(const SourceRange& source_range) {
 453  E :      source_range_ = source_range;
 454  E :    }
 455  E :    Size instruction_size() const { return instruction_size_; }
 456  E :    const BlockGraph::Label& label() const { return label_; }
 457  E :    void set_label(const BlockGraph::Label& label) { label_ = label; }
 458  E :    bool has_label() const { return label_.IsValid(); }
 459    :    // @}
 460    :  
 461    :    // Set the target reference @p ref for this successor. If @p ref refers
 462    :    // to a basic block, also update that basic block's referrer set.
 463    :    bool SetReference(const BasicBlockReference& ref);
 464    :  
 465    :    // Get the branch type that corresponds to the given @p op_code.
 466    :    // @returns kInvalidCondition if @p op_code isn't a recognized branch
 467    :    //     instruction.
 468    :    static Condition OpCodeToCondition(OpCode op_code);
 469    :  
 470    :    // Get the condition that represents the inversion of the given @p condition.
 471    :    //
 472    :    // @p condition the condition to invert.
 473    :    // @returns kInvalidCondition if @p condition is not invertible.
 474    :    static Condition InvertCondition(Condition condition);
 475    :  
 476    :    // Returns a textual description of this successor.
 477    :    std::string ToString() const;
 478    :  
 479    :   protected:
 480    :    // The type of branch represented by this successor.
 481    :    Condition condition_;
 482    :  
 483    :    // The destination for this successor.
 484    :    BasicBlockReference reference_;
 485    :  
 486    :    // The label, if any, associated with this successor.
 487    :    BlockGraph::Label label_;
 488    :  
 489    :    // The source range, if any, associated with this successor.
 490    :    SourceRange source_range_;
 491    :  
 492    :    // The size of the instruction this successor is derived from,
 493    :    // or zero if it's synthesized or added post-decomposition.
 494    :    Size instruction_size_;
 495    :  };
 496    :  
 497    :  // An indivisible portion of code or data within a code block.
 498    :  //
 499    :  // See http://en.wikipedia.org/wiki/Basic_block for a general description of
 500    :  // the properties. This has been augmented with the ability to also represent
 501    :  // blocks of data that are tightly coupled with the code (jump and case tables
 502    :  // for example).
 503    :  class BasicBlock {
 504    :   public:
 505    :    enum BasicBlockType {
 506    :      BASIC_CODE_BLOCK,
 507    :      BASIC_DATA_BLOCK,
 508    :  
 509    :      // This must be last.
 510    :      BASIC_BLOCK_TYPE_MAX
 511    :    };
 512    :  
 513    :    typedef BlockGraph::BlockId BlockId;
 514    :    typedef std::list<Instruction> Instructions;
 515    :    typedef BlockGraph::Size Size;
 516    :    typedef std::list<Successor> Successors;
 517    :    typedef BlockGraph::Offset Offset;
 518    :  
 519    :    // The collection of references this basic block makes to other basic
 520    :    // blocks, keyed by the references offset relative to the start of this
 521    :    // basic block.
 522    :    typedef Instruction::BasicBlockReferenceMap BasicBlockReferenceMap;
 523    :  
 524    :    // The set of the blocks that have a reference to this basic block.
 525    :    // This is keyed on block and source offset (not destination offset),
 526    :    // to allow us to easily locate and remove the back-references on change or
 527    :    // deletion.
 528    :    typedef std::set<BasicBlockReferrer, BasicBlockReferrer::CompareAsLess>
 529    :        BasicBlockReferrerSet;
 530    :  
 531    :    // This offset is used to denote that an instruction, successor, or
 532    :    // basic block has been synthesized and has no corresponding image in
 533    :    // the original block.
 534    :    static const Offset kNoOffset;
 535    :  
 536    :    // Virtual destructor to allow subclassing.
 537    :    virtual ~BasicBlock();
 538    :  
 539    :    // Return a textual label for a basic block type.
 540    :    static const char* BasicBlockTypeToString(BasicBlockType type);
 541    :  
 542    :    // Accessors.
 543    :    // @{
 544  E :    BasicBlockType type() const { return type_; }
 545  E :    const std::string& name() const { return name_; }
 546  E :    bool is_padding() const { return is_padding_; }
 547    :  
 548  E :    size_t alignment() const { return alignment_; }
 549  E :    void set_alignment(size_t alignment) {
 550  E :      DCHECK_LE(1u, alignment_);
 551  E :      DCHECK(common::IsPowerOfTwo(alignment));
 552  E :      alignment_ = alignment;
 553  E :    }
 554    :  
 555  E :    Offset offset() const { return offset_; }
 556  E :    void set_offset(Offset offset) { offset_ = offset; }
 557    :  
 558  E :    const BasicBlockReferrerSet& referrers() const { return referrers_; }
 559  E :    BasicBlockReferrerSet& referrers() { return referrers_; }
 560    :    // @}
 561    :  
 562    :    // Returns true iff this basic block is a valid block (i.e., it
 563    :    // is a BASIC_DATA_BLOCK the contains data XOR a BASIC_CODE_BLOCK that
 564    :    // contains instructions and/or successors.
 565    :    virtual bool IsValid() const = 0;
 566    :  
 567    :    // Mark this basic block as padding/unreachable. This transformation is uni-
 568    :    // directional; the block should be considered immutable once this is called.
 569    :    void MarkAsPadding();
 570    :  
 571    :   protected:
 572    :    // Initialize a basic block.
 573    :    // @param name A textual identifier for this basic block.
 574    :    // @param type The disposition (code, data, padding) of this basic block.
 575    :    BasicBlock(const base::StringPiece& name,
 576    :               BasicBlockType type);
 577    :  
 578    :    // The type of this basic block.
 579    :    BasicBlockType type_;
 580    :  
 581    :    // The name of this basic block.
 582    :    std::string name_;
 583    :  
 584    :    // The alignment of this basic block.
 585    :    size_t alignment_;
 586    :  
 587    :    // The offset of this basic block in the original block. Set to the offset
 588    :    // of the first byte the basic block originated from during decomposition.
 589    :    // Useful as a stable, unique identifier for basic blocks in a decomposition.
 590    :    Offset offset_;
 591    :  
 592    :    // The set of basic blocks references (from other basic blocks in same
 593    :    // original block) to this basic block.
 594    :    BasicBlockReferrerSet referrers_;
 595    :  
 596    :    // The label associated with this basic block.
 597    :    BlockGraph::Label label_;
 598    :  
 599    :    // Tracks whether or not this basic block is unreachable padding.
 600    :    bool is_padding_;
 601    :  
 602    :   private:
 603    :    DISALLOW_COPY_AND_ASSIGN(BasicBlock);
 604    :  };
 605    :  
 606    :  class BasicCodeBlock : public BasicBlock {
 607    :   public:
 608    :    // Initialize a basic code block.
 609    :    // @param name A textual identifier for this basic block.
 610    :    explicit BasicCodeBlock(const base::StringPiece& name);
 611    :  
 612    :    // Down-cast from basic block to basic code block.
 613    :    static BasicCodeBlock* Cast(BasicBlock* basic_block);
 614    :    static const BasicCodeBlock* Cast(const BasicBlock* basic_block);
 615    :  
 616    :    // Accessors.
 617    :    // @{
 618  E :    const Instructions& instructions() const { return instructions_; }
 619  E :    Instructions& instructions() { return instructions_; }
 620  E :    const Successors& successors() const { return successors_; }
 621  E :    Successors& successors() { return successors_; }
 622    :    // @}
 623    :  
 624    :    // Returns true iff this basic block is a valid code block - i.e., it
 625    :    // contains at least one instruction and/or 0-2 successors.
 626    :    virtual bool IsValid() const OVERRIDE;
 627    :  
 628    :    // Return the number of bytes required to store the instructions
 629    :    // this basic block contains, exclusive successors.
 630    :    Size GetInstructionSize() const;
 631    :  
 632    :   private:
 633    :    // The set of non-branching instructions comprising this basic-block.
 634    :    // Any branching at the end of the basic-block is represented using the
 635    :    // successors_ member.
 636    :    Instructions instructions_;
 637    :  
 638    :    // The set of (logical) successors to this basic block. There can only be
 639    :    // 0, 1 or 2 successors in this list.
 640    :    // If there is a single successor, it must be unconditional.
 641    :    // If there are two successors, they must have complementary conditions.
 642    :    Successors successors_;
 643    :  
 644    :   private:
 645    :    DISALLOW_COPY_AND_ASSIGN(BasicCodeBlock);
 646    :  };
 647    :  
 648    :  class BasicDataBlock : public BasicBlock {
 649    :   public:
 650    :    typedef BlockGraph::Block::SourceRange SourceRange;
 651    :  
 652    :    // Initialize a basic data or padding block.
 653    :    // @param name A textual identifier for this basic block.
 654    :    // @param type The disposition (data or padding) of this basic block.
 655    :    // @param data The block's data, must be non-NULL.
 656    :    // @param size The size of @p data, must be greater than zero.
 657    :    // @note The block does not take ownership of @p data, and @p data must have
 658    :    //     a lifetime greater than the block.
 659    :    BasicDataBlock(const base::StringPiece& name,
 660    :                   const uint8* data,
 661    :                   Size size);
 662    :  
 663    :    // Down-cast from basic block to basic data block.
 664    :    static BasicDataBlock* Cast(BasicBlock* basic_block);
 665    :    static const BasicDataBlock* Cast(const BasicBlock* basic_block);
 666    :  
 667    :    // Accessors.
 668    :    // @{
 669  E :    Size size() const { return size_; }
 670  E :    const uint8* data() const { return data_; }
 671    :  
 672  E :    const BasicBlockReferenceMap& references() const { return references_; }
 673  E :    BasicBlockReferenceMap& references() { return references_; }
 674    :  
 675  E :    SourceRange source_range() const { return source_range_; }
 676  E :    void set_source_range(const SourceRange& source_range) {
 677  E :      source_range_ = source_range;
 678  E :    }
 679    :  
 680  E :    const BlockGraph::Label& label() const { return label_; }
 681  E :    void set_label(const BlockGraph::Label& label) { label_ = label; }
 682  E :    bool has_label() const { return label_.IsValid(); }
 683    :    // @}
 684    :  
 685    :    // Add a reference @p ref to this basic block at @p offset.
 686    :    bool SetReference(Offset offset, const BasicBlockReference& ref);
 687    :  
 688    :    // Returns true iff this basic block is a valid block i.e., it contains data.
 689    :    virtual bool IsValid() const OVERRIDE;
 690    :  
 691    :   private:
 692    :    // The number of bytes of data in the original block that corresponds with
 693    :    // this basic block.
 694    :    Size size_;
 695    :  
 696    :    // The data in the original block that corresponds with this basic block
 697    :    // will be referenced here.
 698    :    const uint8* data_;
 699    :  
 700    :    // The source range, if any, associated with this data block.
 701    :    SourceRange source_range_;
 702    :  
 703    :    // The map of references (if any) that this block makes to other basic blocks
 704    :    // from the original block.
 705    :    BasicBlockReferenceMap references_;
 706    :  
 707    :   private:
 708    :    DISALLOW_COPY_AND_ASSIGN(BasicDataBlock);
 709    :  };
 710    :  
 711    :  }  // namespace block_graph
 712    :  
 713    :  #endif  // SYZYGY_BLOCK_GRAPH_BASIC_BLOCK_H_

Coverage information generated Thu Jul 04 09:34:53 2013.