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::BlockGraph BlockGraph;
43 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
44 : typedef core::RelativeAddress RelativeAddress;
45 : typedef core::AddressRange<RelativeAddress, size_t> RelativeAddressRange;
46 : typedef std::vector<RelativeAddressRange> RelativeAddressRangeVector;
47 :
48 : // Constructor.
49 : CoverageInstrumentationTransform();
50 :
51 : // The name of this transform.
52 : static const char kTransformName[];
53 :
54 : // BasicBlockSubGraphTransform implementation.
55 : virtual bool TransformBasicBlockSubGraph(
56 : BlockGraph* block_graph,
57 : BasicBlockSubGraph* basic_block_subgraph) OVERRIDE;
58 :
59 : // @name Accessors.
60 : // @{
61 :
62 : // @returns the RVAs and sizes in the original image of the instrumented basic
63 : // blocks. They are in the order in which they were encountered during
64 : // instrumentation, such that the index of the BB in the vector serves
65 : // as its unique ID.
66 E : const RelativeAddressRangeVector& bb_ranges() const { return bb_ranges_; }
67 :
68 : // @}
69 :
70 : // @name Pass-throughs to EntryThunkTransform.
71 : // @{
72 : bool src_ranges_for_thunks() const {
73 : return entry_thunk_tx_.src_ranges_for_thunks();
74 : }
75 E : void set_src_ranges_for_thunks(bool value) {
76 E : entry_thunk_tx_.set_src_ranges_for_thunks(value);
77 E : }
78 E : void set_instrument_dll_name(const base::StringPiece& instrument_dll_name) {
79 E : entry_thunk_tx_.set_instrument_dll_name(instrument_dll_name);
80 E : }
81 : const char* instrument_dll_name() const {
82 : return entry_thunk_tx_.instrument_dll_name();
83 : }
84 : // @}
85 :
86 : // @name Pass-throughs for AddIndexedFrequencyDataTransform.
87 : // @{
88 E : BlockGraph::Block* frequency_data_block() {
89 E : return add_bb_freq_data_tx_.frequency_data_block();
90 E : }
91 E : BlockGraph::Block* frequency_data_buffer_block() {
92 E : return add_bb_freq_data_tx_.frequency_data_buffer_block();
93 E : }
94 : // @}
95 :
96 : protected:
97 : friend block_graph::transforms::IterativeTransformImpl<
98 : CoverageInstrumentationTransform>;
99 :
100 : // @name IterativeTransformImpl implementation.
101 : // @{
102 : // Called prior to iterating over the blocks. This creates the coverage
103 : // data block, populating coverage_data_block_ and
104 : // basic_block_seen_array_ref_.
105 : bool PreBlockGraphIteration(BlockGraph* block_graph,
106 : BlockGraph::Block* header_block);
107 : // Called after iterating over the blocks. Increments basic_block_count_ as
108 : // code blocks are processed.
109 : bool OnBlock(BlockGraph* block_graph,
110 : BlockGraph::Block* block);
111 : // Called after iterating over the blocks. Sets the basic-block count member
112 : // of coverage_data_block_.
113 : bool PostBlockGraphIteration(BlockGraph* block_graph,
114 : BlockGraph::Block* header_block);
115 : // @}
116 :
117 : // Adds the basic-block frequency data referenced by the coverage agent.
118 : AddIndexedFrequencyDataTransform add_bb_freq_data_tx_;
119 : // The entry hook transform used by the coverage agent.
120 : EntryThunkTransform entry_thunk_tx_;
121 :
122 : // Stores the RVAs in the original image for each instrumented basic block.
123 : RelativeAddressRangeVector bb_ranges_;
124 :
125 : DISALLOW_COPY_AND_ASSIGN(CoverageInstrumentationTransform);
126 : };
127 :
128 : } // namespace transforms
129 : } // namespace instrument
130 :
131 : #endif // SYZYGY_INSTRUMENT_TRANSFORMS_COVERAGE_TRANSFORM_H_
|