1 : // Copyright 2012 Google Inc.
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 basic-block entry hook instrumentation transform.
16 :
17 : #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_BASIC_BLOCK_ENTRY_HOOK_TRANSFORM_H_
18 : #define SYZYGY_INSTRUMENT_TRANSFORMS_BASIC_BLOCK_ENTRY_HOOK_TRANSFORM_H_
19 :
20 : #include <string>
21 : #include <vector>
22 :
23 : #include "base/string_piece.h"
24 : #include "syzygy/block_graph/basic_block_assembler.h"
25 : #include "syzygy/block_graph/iterate.h"
26 : #include "syzygy/block_graph/transforms/iterative_transform.h"
27 : #include "syzygy/block_graph/transforms/named_transform.h"
28 :
29 : namespace instrument {
30 : namespace transforms {
31 :
32 : // An iterative block transformation that augments the binary with an import
33 : // for a basic-block entry-hook function and, for each code basic-block,
34 : // prepends a call to the entry-hook function taking a unique basic-block ID.
35 : // The entry-hook function is responsible for being non-disruptive to the
36 : // the calling environment. I.e., it must preserve all volatile registers, any
37 : // registers it uses, and the processor flags.
38 : class BasicBlockEntryHookTransform
39 : : public block_graph::transforms::IterativeTransformImpl<
40 : BasicBlockEntryHookTransform>,
41 : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
42 : BasicBlockEntryHookTransform> {
43 : public:
44 : typedef block_graph::BasicBlock BasicBlock;
45 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
46 : typedef block_graph::BlockGraph BlockGraph;
47 : typedef BlockGraph::Block Block;
48 : typedef BlockGraph::Offset Offset;
49 : typedef BlockGraph::Reference Reference;
50 : typedef std::vector<core::RelativeAddress> RelativeAddressVector;
51 :
52 : // Initialize a new BasicBlockEntryHookTransform instance using the default
53 : // module and function names.
54 : BasicBlockEntryHookTransform();
55 :
56 : // Initialize a new BasicBlockEntryHookTransform instance.
57 : // @param module_name The name of the module containing the basic-block
58 : // entry-hook function.
59 : // @param function_name The name of basic-block entry-hook function.
60 : // @param id_generator The functor that will return a unique id for each
61 : // basic-block in the image under transformation.
62 : BasicBlockEntryHookTransform(const base::StringPiece& module_name,
63 : const base::StringPiece& function_name);
64 :
65 E : const std::string& module_name() const { return module_name_; }
66 E : void set_module_name(const base::StringPiece& value) {
67 E : DCHECK(!value.empty());
68 E : value.CopyToString(&module_name_);
69 E : }
70 :
71 E : const std::string& function_name() const { return function_name_; }
72 E : void set_function_name(const base::StringPiece& value) {
73 E : DCHECK(!value.empty());
74 E : value.CopyToString(&function_name_);
75 E : }
76 :
77 : // Get the entry-hook reference that was used to instrument each basic-block.
78 : // This will only be valid after a successful application of the transform.
79 E : const Reference& bb_entry_hook_ref() const { return bb_entry_hook_ref_; }
80 :
81 : // Gen an id-to-address map for the basic-block entry-hook calls.
82 : // @returns the RVAs in the original image of the instrumented basic blocks.
83 : // They are in the order in which they were encountered during
84 : // instrumentation, such that the index of the BB in the vector serves
85 : // as its unique ID.
86 E : const RelativeAddressVector& bb_addresses() const { return bb_addresses_; }
87 :
88 : // The default module name to which to bind the instrumentation.
89 : static const char kDefaultModuleName[];
90 :
91 : // The default function name to which to bind the instrumentation.
92 : static const char kDefaultFunctionName[];
93 :
94 : protected:
95 : friend NamedBlockGraphTransformImpl<BasicBlockEntryHookTransform>;
96 : friend IterativeTransformImpl<BasicBlockEntryHookTransform>;
97 : friend NamedBasicBlockSubGraphTransformImpl<BasicBlockEntryHookTransform>;
98 :
99 : // @name IterativeTransformImpl implementation.
100 : // @{
101 : bool PreBlockGraphIteration(BlockGraph* block_graph,
102 : BlockGraph::Block* header_block);
103 : bool OnBlock(BlockGraph* block_graph, BlockGraph::Block* block);
104 : // @}
105 :
106 : // @name BasicBlockSubGraphTransformInterface methods.
107 : // @{
108 : virtual bool TransformBasicBlockSubGraph(
109 : BlockGraph* block_graph,
110 : BasicBlockSubGraph* basic_block_subgraph) OVERRIDE;
111 : // @}
112 :
113 : // Name of the instrumentation DLL we import.
114 : std::string module_name_;
115 :
116 : // Name of the hook function (in module_name) to which we insert calls.
117 : std::string function_name_;
118 :
119 : // Stores the RVAs in the original image for each instrumented basic block.
120 : RelativeAddressVector bb_addresses_;
121 :
122 : // The entry hook to which basic-block entry events are directed.
123 : Reference bb_entry_hook_ref_;
124 :
125 : // The name of this transform.
126 : static const char kTransformName[];
127 :
128 : DISALLOW_COPY_AND_ASSIGN(BasicBlockEntryHookTransform);
129 : };
130 :
131 : } // namespace transforms
132 : } // namespace instrument
133 :
134 : #endif // SYZYGY_INSTRUMENT_TRANSFORMS_BASIC_BLOCK_ENTRY_HOOK_TRANSFORM_H_
|