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 : // Implementation of the SyzyAsan instrumentation transform.
16 :
17 : #ifndef SYZYGY_INSTRUMENT_TRANSFORMS_ASAN_TRANSFORM_H_
18 : #define SYZYGY_INSTRUMENT_TRANSFORMS_ASAN_TRANSFORM_H_
19 :
20 : #include <map>
21 : #include <set>
22 : #include <string>
23 : #include <utility>
24 :
25 : #include "base/string_piece.h"
26 : #include "syzygy/block_graph/filterable.h"
27 : #include "syzygy/block_graph/iterate.h"
28 : #include "syzygy/block_graph/transforms/iterative_transform.h"
29 : #include "syzygy/block_graph/transforms/named_transform.h"
30 :
31 : namespace instrument {
32 : namespace transforms {
33 :
34 : // This class implements the transformation applied to each basic block.
35 : class AsanBasicBlockTransform
36 : : public block_graph::transforms::NamedBasicBlockSubGraphTransformImpl<
37 : AsanBasicBlockTransform>,
38 : public block_graph::Filterable {
39 : public:
40 : // Represent the different kind of access to the memory.
41 : enum MemoryAccessMode {
42 : kNoAccess,
43 : kReadAccess,
44 : kWriteAccess,
45 : kInstrAccess,
46 : kRepzAccess,
47 : kRepnzAccess,
48 : };
49 :
50 : // Contains memory access information.
51 : struct MemoryAccessInfo {
52 : MemoryAccessMode mode;
53 : uint8_t size;
54 : uint16_t opcode;
55 : };
56 :
57 : typedef block_graph::BlockGraph BlockGraph;
58 : typedef block_graph::BasicBlockSubGraph BasicBlockSubGraph;
59 : typedef MemoryAccessInfo AsanHookMapEntryKey;
60 : // Map of hooks to asan check access functions.
61 : typedef std::map<AsanHookMapEntryKey, BlockGraph::Reference> AsanHookMap;
62 : typedef std::map<MemoryAccessMode, BlockGraph::Reference> AsanDefaultHookMap;
63 :
64 : // Constructor.
65 : // @param hooks_read_access a reference to the read access check import entry.
66 : // @param hooks_write_access a reference to the write access check import
67 : // entry.
68 : explicit AsanBasicBlockTransform(AsanHookMap* check_access_hooks) :
69 E : check_access_hooks_(check_access_hooks) {
70 E : DCHECK(check_access_hooks != NULL);
71 E : }
72 :
73 : // The transform name.
74 : static const char kTransformName[];
75 :
76 : protected:
77 : // @name BasicBlockSubGraphTransformInterface method.
78 : virtual bool TransformBasicBlockSubGraph(BlockGraph* block_graph,
79 : BasicBlockSubGraph* basic_block_subgraph) OVERRIDE;
80 :
81 : // Instruments the memory accesses in a basic block.
82 : // @param basic_block The basic block to be instrumented.
83 : // @returns true on success, false otherwise.
84 : bool InstrumentBasicBlock(block_graph::BasicCodeBlock* basic_block);
85 :
86 : private:
87 : // The references to the Asan access check import entries.
88 : AsanHookMap* check_access_hooks_;
89 :
90 : DISALLOW_COPY_AND_ASSIGN(AsanBasicBlockTransform);
91 : };
92 :
93 : class AsanTransform
94 : : public block_graph::transforms::IterativeTransformImpl<AsanTransform>,
95 : public block_graph::Filterable {
96 : public:
97 : typedef block_graph::BlockGraph BlockGraph;
98 : typedef AsanBasicBlockTransform::MemoryAccessInfo MemoryAccessInfo;
99 : typedef AsanBasicBlockTransform::MemoryAccessMode MemoryAccessMode;
100 :
101 : // Initialize a new AsanTransform instance.
102 : AsanTransform();
103 :
104 : // @name IterativeTransformImpl implementation.
105 : // @{
106 : bool PreBlockGraphIteration(BlockGraph* block_graph,
107 : BlockGraph::Block* header_block);
108 : bool OnBlock(BlockGraph* block_graph, BlockGraph::Block* block);
109 : bool PostBlockGraphIteration(BlockGraph* block_graph,
110 : BlockGraph::Block* header_block);
111 : // @}
112 :
113 : // @name Accessors.
114 : // @{
115 E : void set_instrument_dll_name(const base::StringPiece& instrument_dll_name) {
116 E : instrument_dll_name.CopyToString(&asan_dll_name_);
117 E : }
118 E : const char* instrument_dll_name() const {
119 E : return asan_dll_name_.c_str();
120 E : }
121 : // @}
122 :
123 : // The name of the DLL that is imported by default.
124 : static const char kSyzyAsanDll[];
125 :
126 : // The transform name.
127 : static const char kTransformName[];
128 :
129 : // The hooks stub name.
130 : static const char kAsanHookStubName[];
131 :
132 : protected:
133 : // Name of the asan_rtl DLL we import. Defaults to "asan_rtl.dll".
134 : std::string asan_dll_name_;
135 :
136 : // References to the different asan check access import entries. Valid after
137 : // successful PreBlockGraphIteration.
138 : AsanBasicBlockTransform::AsanHookMap check_access_hooks_ref_;
139 :
140 : DISALLOW_COPY_AND_ASSIGN(AsanTransform);
141 : };
142 :
143 : bool operator<(const AsanBasicBlockTransform::MemoryAccessInfo& left,
144 : const AsanBasicBlockTransform::MemoryAccessInfo& right);
145 :
146 : } // namespace transforms
147 : } // namespace instrument
148 :
149 : #endif // SYZYGY_INSTRUMENT_TRANSFORMS_ASAN_TRANSFORM_H_
|