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

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: Add test for debug_friendly; cleanups. 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 auto source_range = inst_it->source_range();
chrisha 2015/06/10 18:07:27 What is this needed for?
huangs 2015/06/11 14:54:15 Removed.
49 }
50 // Add all NOPs with consecutive instruction indexes.
51 while (nop_it != nop_spec.end() && nop_it->first == write_index) {
52 assm.nop(nop_it->second);
53 ++nop_it;
54 ++write_index;
55 }
56 }
57 ++inst_it;
58 ++write_index;
59 }
60 }
61
62 bool FillerBasicBlockTransform::TransformBasicBlockSubGraph(
63 const TransformPolicyInterface* policy,
64 BlockGraph* block_graph,
65 BasicBlockSubGraph* basic_block_subgraph) {
66 DCHECK(nullptr != policy);
67 DCHECK(nullptr != block_graph);
68 DCHECK(nullptr != basic_block_subgraph);
69
70 // Locations for code injection.
71 NopSpec nop_spec = {{1, NOP1}};
chrisha 2015/06/10 18:07:27 Is this going to be sufficient? Do we maybe want t
huangs 2015/06/11 14:54:15 We want to start small; will do randomness later.
72
73 fprintf(stderr, "TransformBasicBlockSubGraph: %s\n",
74 debug_friendly_ ? "true" : "false");
chrisha 2015/06/10 18:07:27 Debugging code?
huangs 2015/06/11 14:54:15 Removed.
75
76 // Visit each basic code block and inject NOPs.
77 BasicBlockSubGraph::BBCollection& basic_blocks =
78 basic_block_subgraph->basic_blocks();
79 for (auto bb = basic_blocks.begin(); bb != basic_blocks.end(); ++bb) {
80 BasicCodeBlock* bc_block = BasicCodeBlock::Cast(*bb);
81 if (bc_block != nullptr)
82 InjectNop(nop_spec, debug_friendly_, &bc_block->instructions());
83 }
84 return true;
85 }
86
87 FillerTransform::FillerTransform(const std::vector<std::string>& target_list)
88 : debug_friendly_(false),
89 num_blocks_(0),
90 num_code_blocks_(0),
91 num_targets_updated_(0) {
92 // Targets are not found yet, so initialize value to false.
93 for (const std::string& target : target_list)
94 target_names_[target] = false;
95 }
96
97 bool FillerTransform::ShouldProcessBlock(Block* block) const {
98 return target_names_.find(block->name()) != target_names_.end();
99 }
100
101 void FillerTransform::CheckAllTargetFound() const {
102 bool has_missing = false;
103 for (auto it = target_names_.begin(); it != target_names_.end(); ++it) {
104 if (it->second)
105 continue;
106 if (!has_missing) {
107 LOG(WARNING) << "There are missing target(s):";
108 has_missing = true;
109 }
110 LOG(WARNING) << " " << it->first;
111 }
112 }
113
114 bool FillerTransform::PreBlockGraphIteration(
115 const TransformPolicyInterface* policy,
116 BlockGraph* block_graph,
117 Block* header_block) {
118 return true;
119 }
120
121 bool FillerTransform::OnBlock(const TransformPolicyInterface* policy,
122 BlockGraph* block_graph,
123 Block* block) {
124 DCHECK(nullptr != policy);
125 DCHECK(nullptr != block_graph);
126 DCHECK(nullptr != block);
127
128 ++num_blocks_;
129 if (block->type() != BlockGraph::CODE_BLOCK)
130 return true;
131
132 ++num_code_blocks_;
133 if (!ShouldProcessBlock(block))
134 return true;
135
136 // Mark target as found.
137 std::string name(block->name());
138 auto target_it = target_names_.find(block->name());
139 if (target_it != target_names_.end())
140 target_it->second = true;
141
142 // Skip blocks that aren't eligible for basic-block decomposition.
143 if (!policy->BlockIsSafeToBasicBlockDecompose(block))
144 return true;
145
146 ++num_targets_updated_;
147 // Apply the basic block transform.
148 FillerBasicBlockTransform basic_block_transform;
149 basic_block_transform.set_debug_friendly(debug_friendly());
150 return ApplyBasicBlockSubGraphTransform(
151 &basic_block_transform, policy, block_graph, block, NULL);
152 }
153
154 bool FillerTransform::PostBlockGraphIteration(
155 const TransformPolicyInterface* policy,
156 BlockGraph* block_graph,
157 Block* header_block) {
158 LOG(INFO) << "Found " << num_blocks_ << " block(s).";
159 LOG(INFO) << "Found " << num_code_blocks_ << " code block(s).";
160 LOG(INFO) << "Updated " << num_targets_updated_ << " blocks(s).";
161 CheckAllTargetFound();
162 return true;
163 }
164
165 } // namespace transforms
166 } // namespace instrument
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698