Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: syzygy/instrument/transforms/filler_transform.cc

Issue 1169603003: [Syzygy Instrumenter] Add FillerTransform. (Closed) Base URL: https://code.google.com/p/syzygy.git@master
Patch Set: Sync. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 #include "syzygy/instrument/transforms/filler_transform.h"
16
17 #include "base/logging.h"
18 #include "syzygy/assm/assembler_base.h"
19 #include "syzygy/block_graph/basic_block_assembler.h"
20 #include "syzygy/block_graph/basic_block_subgraph.h"
21 #include "syzygy/block_graph/block_util.h"
22 #include "syzygy/block_graph/transform_policy.h"
23
24 namespace instrument {
25 namespace transforms {
26
27 const char FillerBasicBlockTransform::kTransformName[] =
28 "FillerBasicBlockTransform";
29
30 const char FillerTransform::kTransformName[] = "FillerTransform";
31
32 // static
33 void FillerBasicBlockTransform::InjectNop(
34 const NopSpec& nop_spec,
35 bool debug_friendly,
36 BasicBlock::Instructions* instructions) {
37 BasicBlock::Instructions::iterator inst_it = instructions->begin();
38 NopSpec::const_iterator nop_it = nop_spec.begin();
39 size_t write_index = 0LL;
40 while (inst_it != instructions->end() && nop_it != nop_spec.end()) {
41 if (nop_it->first == write_index) {
42 block_graph::BasicBlockAssembler assm(inst_it, instructions);
43 // If specified, set source range for successive NOPs to to be that of the
44 // current instruction (which follows the NOPs). Caveat: This breaks the
45 // 1:1 OMAP mapping and may confuse some debuggers.
46 if (debug_friendly)
47 assm.set_source_range(inst_it->source_range());
48 // Add all NOPs with consecutive instruction indexes.
49 while (nop_it != nop_spec.end() && nop_it->first == write_index) {
50 assm.nop(nop_it->second);
51 ++nop_it;
52 ++write_index;
53 }
54 }
55 ++inst_it;
56 ++write_index;
57 }
58 }
59
60 bool FillerBasicBlockTransform::TransformBasicBlockSubGraph(
61 const TransformPolicyInterface* policy,
62 BlockGraph* block_graph,
63 BasicBlockSubGraph* basic_block_subgraph) {
64 DCHECK(nullptr != policy);
65 DCHECK(nullptr != block_graph);
66 DCHECK(nullptr != basic_block_subgraph);
67
68 // Locations for code injection.
69 NopSpec nop_spec = {{1, NOP1}};
70
71 // Visit each basic code block and inject NOPs.
72 BasicBlockSubGraph::BBCollection& basic_blocks =
73 basic_block_subgraph->basic_blocks();
74 for (auto bb = basic_blocks.begin(); bb != basic_blocks.end(); ++bb) {
75 BasicCodeBlock* bc_block = BasicCodeBlock::Cast(*bb);
76 if (bc_block != nullptr)
77 InjectNop(nop_spec, debug_friendly_, &bc_block->instructions());
78 }
79 return true;
80 }
81
82 FillerTransform::FillerTransform(const std::vector<std::string>& target_list)
83 : debug_friendly_(false),
84 num_blocks_(0),
85 num_code_blocks_(0),
86 num_targets_updated_(0) {
87 // Targets are not found yet, so initialize value to false.
88 for (const std::string& target : target_list)
89 target_names_[target] = false;
90 }
91
92 bool FillerTransform::ShouldProcessBlock(Block* block) const {
93 return target_names_.find(block->name()) != target_names_.end();
94 }
95
96 void FillerTransform::CheckAllTargetsFound() const {
97 bool has_missing = false;
98 for (auto it = target_names_.begin(); it != target_names_.end(); ++it) {
99 if (it->second)
100 continue;
101 if (!has_missing) {
102 LOG(WARNING) << "There are missing target(s):";
103 has_missing = true;
104 }
105 LOG(WARNING) << " " << it->first;
106 }
107 }
108
109 bool FillerTransform::PreBlockGraphIteration(
110 const TransformPolicyInterface* policy,
111 BlockGraph* block_graph,
112 Block* header_block) {
113 return true;
114 }
115
116 bool FillerTransform::OnBlock(const TransformPolicyInterface* policy,
117 BlockGraph* block_graph,
118 Block* block) {
119 DCHECK(nullptr != policy);
120 DCHECK(nullptr != block_graph);
121 DCHECK(nullptr != block);
122
123 ++num_blocks_;
124 if (block->type() != BlockGraph::CODE_BLOCK)
125 return true;
126
127 ++num_code_blocks_;
128 if (!ShouldProcessBlock(block))
129 return true;
130
131 // Mark target as found.
132 std::string name(block->name());
133 auto target_it = target_names_.find(block->name());
134 if (target_it != target_names_.end())
135 target_it->second = true;
136
137 // Skip blocks that aren't eligible for basic-block decomposition.
138 if (!policy->BlockIsSafeToBasicBlockDecompose(block))
139 return true;
140
141 ++num_targets_updated_;
142 // Apply the basic block transform.
143 FillerBasicBlockTransform basic_block_transform;
144 basic_block_transform.set_debug_friendly(debug_friendly());
145 return ApplyBasicBlockSubGraphTransform(
146 &basic_block_transform, policy, block_graph, block, NULL);
147 }
148
149 bool FillerTransform::PostBlockGraphIteration(
150 const TransformPolicyInterface* policy,
151 BlockGraph* block_graph,
152 Block* header_block) {
153 LOG(INFO) << "Found " << num_blocks_ << " block(s).";
154 LOG(INFO) << "Found " << num_code_blocks_ << " code block(s).";
155 LOG(INFO) << "Updated " << num_targets_updated_ << " blocks(s).";
156 CheckAllTargetsFound();
157 return true;
158 }
159
160 } // namespace transforms
161 } // namespace instrument
OLDNEW
« no previous file with comments | « syzygy/instrument/transforms/filler_transform.h ('k') | syzygy/instrument/transforms/filler_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698