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 : // Declares a block-graph transform to be used by the code coverage
16 : // instrumenter. This transform does 4 things:
17 : //
18 : // (1) Injects an import for the run-time code coverage library.
19 : // (2) Grabs an entry hook and wires it up the run-time library.
20 : // (3) Adds a read/write data section containing code coverage information.
21 : // (4) Instruments each basic block to gather basic block visit information.
22 :
23 : #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_COVERAGE_TRANSFORM_H_
24 : #define SYZYGY_INSTRUMENT_TRANSFORMS_COVERAGE_TRANSFORM_H_
25 :
26 : #include <vector>
27 :
28 : #include "syzygy/block_graph/transforms/iterative_transform.h"
29 : #include "syzygy/core/address_space.h"
30 : #include "syzygy/instrument/transforms/add_indexed_frequency_data_transform.h"
31 : #include "syzygy/instrument/transforms/entry_thunk_transform.h"
32 :
33 : namespace instrument {
34 : namespace transforms {
35 :
36 : class CoverageInstrumentationTransform
37 : : public block_graph::transforms::IterativeTransformImpl<
38 : CoverageInstrumentationTransform>,
39 : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
40 : CoverageInstrumentationTransform> {
41 : public:
42 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
43 : typedef block_graph::BlockGraph BlockGraph;
44 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
45 : typedef core::RelativeAddress RelativeAddress;
46 : typedef core::AddressRange<RelativeAddress, size_t> RelativeAddressRange;
47 : typedef std::vector<RelativeAddressRange> RelativeAddressRangeVector;
48 :
49 : // Constructor.
50 : CoverageInstrumentationTransform();
51 :
52 : // The name of this transform.
53 : static const char kTransformName[];
54 :
55 : // BasicBlockSubGraphTransform implementation.
56 : virtual bool TransformBasicBlockSubGraph(
57 : const TransformPolicyInterface* policy,
58 : BlockGraph* block_graph,
59 : BasicBlockSubGraph* basic_block_subgraph) OVERRIDE;
60 :
61 : // @name Accessors.
62 : // @{
63 :
64 : // @returns the RVAs and sizes in the original image of the instrumented basic
65 : // blocks. They are in the order in which they were encountered during
66 : // instrumentation, such that the index of the BB in the vector serves
67 : // as its unique ID.
68 E : const RelativeAddressRangeVector& bb_ranges() const { return bb_ranges_; }
69 :
70 : // @}
71 :
72 : // @name Pass-throughs to EntryThunkTransform.
73 : // @{
74 : bool src_ranges_for_thunks() const {
75 : return entry_thunk_tx_.src_ranges_for_thunks();
76 : }
77 E : void set_src_ranges_for_thunks(bool value) {
78 E : entry_thunk_tx_.set_src_ranges_for_thunks(value);
79 E : }
80 E : void set_instrument_dll_name(const base::StringPiece& instrument_dll_name) {
81 E : entry_thunk_tx_.set_instrument_dll_name(instrument_dll_name);
82 E : }
83 : const char* instrument_dll_name() const {
84 : return entry_thunk_tx_.instrument_dll_name();
85 : }
86 : // @}
87 :
88 : // @name Pass-throughs for AddIndexedFrequencyDataTransform.
89 : // @{
90 E : BlockGraph::Block* frequency_data_block() {
91 E : return add_bb_freq_data_tx_.frequency_data_block();
92 E : }
93 E : BlockGraph::Block* frequency_data_buffer_block() {
94 E : return add_bb_freq_data_tx_.frequency_data_buffer_block();
95 E : }
96 : // @}
97 :
98 : protected:
99 : friend block_graph::transforms::IterativeTransformImpl<
100 : CoverageInstrumentationTransform>;
101 :
102 : // @name IterativeTransformImpl implementation.
103 : // @{
104 : // Called prior to iterating over the blocks. This creates the coverage
105 : // data block, populating coverage_data_block_ and
106 : // basic_block_seen_array_ref_.
107 : bool PreBlockGraphIteration(const TransformPolicyInterface* policy,
108 : BlockGraph* block_graph,
109 : BlockGraph::Block* header_block);
110 : // Called after iterating over the blocks. Increments basic_block_count_ as
111 : // code blocks are processed.
112 : bool OnBlock(const TransformPolicyInterface* policy,
113 : BlockGraph* block_graph,
114 : BlockGraph::Block* block);
115 : // Called after iterating over the blocks. Sets the basic-block count member
116 : // of coverage_data_block_.
117 : bool PostBlockGraphIteration(const TransformPolicyInterface* policy,
118 : BlockGraph* block_graph,
119 : BlockGraph::Block* header_block);
120 : // @}
121 :
122 : // Adds the basic-block frequency data referenced by the coverage agent.
123 : AddIndexedFrequencyDataTransform add_bb_freq_data_tx_;
124 : // The entry hook transform used by the coverage agent.
125 : EntryThunkTransform entry_thunk_tx_;
126 :
127 : // Stores the RVAs in the original image for each instrumented basic block.
128 : RelativeAddressRangeVector bb_ranges_;
129 :
130 : DISALLOW_COPY_AND_ASSIGN(CoverageInstrumentationTransform);
131 : };
132 :
133 : } // namespace transforms
134 : } // namespace instrument
135 :
136 : #endif // SYZYGY_INSTRUMENT_TRANSFORMS_COVERAGE_TRANSFORM_H_
|