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_
|