1 : // Copyright 2013 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 : // Implementation of the branch instrumentation transform.
16 : #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_BRANCH_HOOK_TRANSFORM_H_
17 : #define SYZYGY_INSTRUMENT_TRANSFORMS_BRANCH_HOOK_TRANSFORM_H_
18 :
19 : #include <string>
20 : #include <vector>
21 :
22 : #include "base/strings/string_piece.h"
23 : #include "syzygy/block_graph/basic_block_assembler.h"
24 : #include "syzygy/block_graph/iterate.h"
25 : #include "syzygy/block_graph/transforms/iterative_transform.h"
26 : #include "syzygy/block_graph/transforms/named_transform.h"
27 : #include "syzygy/instrument/transforms/add_indexed_frequency_data_transform.h"
28 :
29 : namespace instrument {
30 : namespace transforms {
31 :
32 : // An iterative block transformation that augments the binary with imports for
33 : // basic-block entry/exit-hook function and, for each code basic-block, insert a
34 : // call to the hook functions taking a unique basic-block ID. The hook functions
35 : // are responsible for being non-disruptive to the calling environment.
36 : // I.e., they must preserve all volatile registers, any registers they use, and
37 : // the processor flags.
38 : class BranchHookTransform
39 : : public block_graph::transforms::IterativeTransformImpl<
40 : BranchHookTransform>,
41 : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
42 : BranchHookTransform> {
43 : public:
44 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
45 : typedef block_graph::BlockGraph BlockGraph;
46 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
47 : typedef core::RelativeAddress RelativeAddress;
48 : typedef core::AddressRange<RelativeAddress, size_t> RelativeAddressRange;
49 : typedef std::vector<RelativeAddressRange> RelativeAddressRangeVector;
50 :
51 : // Initialize a new BranchHookTransform instance using the default module and
52 : // function names.
53 : BranchHookTransform();
54 :
55 : // @returns the RVAs and sizes in the original image of the instrumented basic
56 : // blocks. They are in the order in which they were encountered during
57 : // instrumentation, such that the index of the BB in the vector serves as
58 : // its unique ID.
59 E : const RelativeAddressRangeVector& bb_ranges() const { return bb_ranges_; }
60 :
61 : // Overrides the default instrument dll name used by this transform.
62 E : void set_instrument_dll_name(const base::StringPiece& value) {
63 E : DCHECK(!value.empty());
64 E : instrument_dll_name_.assign(value.begin(), value.end());
65 E : }
66 :
67 : // @name Accessors and mutators.
68 : // @{
69 : bool buffering() const { return buffering_; }
70 E : void set_buffering(bool buffering) { buffering_ = buffering; }
71 E : void set_fs_slot(uint32 slot) { fs_slot_ = slot; }
72 : // @}
73 :
74 : protected:
75 : friend NamedBlockGraphTransformImpl<BranchHookTransform>;
76 : friend IterativeTransformImpl<BranchHookTransform>;
77 : friend NamedBasicBlockSubGraphTransformImpl<BranchHookTransform>;
78 :
79 : // @name IterativeTransformImpl implementation.
80 : // @{
81 : bool PreBlockGraphIteration(const TransformPolicyInterface* policy,
82 : BlockGraph* block_graph,
83 : BlockGraph::Block* header_block);
84 : bool OnBlock(const TransformPolicyInterface* policy,
85 : BlockGraph* block_graph,
86 : BlockGraph::Block* block);
87 : bool PostBlockGraphIteration(const TransformPolicyInterface* policy,
88 : BlockGraph* block_graph,
89 : BlockGraph::Block* header_block);
90 : // @}
91 :
92 : // @name BasicBlockSubGraphTransformInterface implementation.
93 : // @{
94 : virtual bool TransformBasicBlockSubGraph(
95 : const TransformPolicyInterface* policy,
96 : BlockGraph* block_graph,
97 : BasicBlockSubGraph* basic_block_subgraph) override;
98 : // @}
99 :
100 : // Adds the basic-block frequency data referenced by the coverage agent.
101 : AddIndexedFrequencyDataTransform add_frequency_data_;
102 :
103 : // Stores the RVAs in the original image for each instrumented basic block.
104 : RelativeAddressRangeVector bb_ranges_;
105 :
106 : // The entry hook to which function entry events are directed.
107 : BlockGraph::Reference function_enter_hook_ref_;
108 :
109 : // The entry hook to which basic-block entry events are directed.
110 : BlockGraph::Reference enter_hook_ref_;
111 :
112 : // The entry hook to which basic-block exit events are directed.
113 : BlockGraph::Reference exit_hook_ref_;
114 :
115 : // The section where the entry-point thunks were placed. This will only be
116 : // non-NULL after a successful application of the transform. This value is
117 : // retained for unit-testing purposes.
118 : BlockGraph::Section* thunk_section_;
119 :
120 : // The instrumentation dll used by this transform.
121 : std::string instrument_dll_name_;
122 :
123 : // The name of this transform.
124 : static const char kTransformName[];
125 :
126 : // Flag indicating if event buffering is activated.
127 : bool buffering_;
128 :
129 : // If not zero, use a FS slot to keep thread local storage instead of the
130 : // standard API.
131 : uint32 fs_slot_;
132 :
133 : private:
134 : DISALLOW_COPY_AND_ASSIGN(BranchHookTransform);
135 : };
136 :
137 : } // namespace transforms
138 : } // namespace instrument
139 :
140 : #endif // SYZYGY_INSTRUMENT_TRANSFORMS_BRANCH_HOOK_TRANSFORM_H_
|