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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: syzygy/instrument/transforms/filler_transform.cc
diff --git a/syzygy/instrument/transforms/filler_transform.cc b/syzygy/instrument/transforms/filler_transform.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6ab32411a4d9bb996dc5e3e215c747425b896717
--- /dev/null
+++ b/syzygy/instrument/transforms/filler_transform.cc
@@ -0,0 +1,161 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "syzygy/instrument/transforms/filler_transform.h"
+
+#include "base/logging.h"
+#include "syzygy/assm/assembler_base.h"
+#include "syzygy/block_graph/basic_block_assembler.h"
+#include "syzygy/block_graph/basic_block_subgraph.h"
+#include "syzygy/block_graph/block_util.h"
+#include "syzygy/block_graph/transform_policy.h"
+
+namespace instrument {
+namespace transforms {
+
+const char FillerBasicBlockTransform::kTransformName[] =
+ "FillerBasicBlockTransform";
+
+const char FillerTransform::kTransformName[] = "FillerTransform";
+
+// static
+void FillerBasicBlockTransform::InjectNop(
+ const NopSpec& nop_spec,
+ bool debug_friendly,
+ BasicBlock::Instructions* instructions) {
+ BasicBlock::Instructions::iterator inst_it = instructions->begin();
+ NopSpec::const_iterator nop_it = nop_spec.begin();
+ size_t write_index = 0LL;
+ while (inst_it != instructions->end() && nop_it != nop_spec.end()) {
+ if (nop_it->first == write_index) {
+ block_graph::BasicBlockAssembler assm(inst_it, instructions);
+ // If specified, set source range for successive NOPs to to be that of the
+ // current instruction (which follows the NOPs). Caveat: This breaks the
+ // 1:1 OMAP mapping and may confuse some debuggers.
+ if (debug_friendly)
+ assm.set_source_range(inst_it->source_range());
+ // Add all NOPs with consecutive instruction indexes.
+ while (nop_it != nop_spec.end() && nop_it->first == write_index) {
+ assm.nop(nop_it->second);
+ ++nop_it;
+ ++write_index;
+ }
+ }
+ ++inst_it;
+ ++write_index;
+ }
+}
+
+bool FillerBasicBlockTransform::TransformBasicBlockSubGraph(
+ const TransformPolicyInterface* policy,
+ BlockGraph* block_graph,
+ BasicBlockSubGraph* basic_block_subgraph) {
+ DCHECK(nullptr != policy);
+ DCHECK(nullptr != block_graph);
+ DCHECK(nullptr != basic_block_subgraph);
+
+ // Locations for code injection.
+ NopSpec nop_spec = {{1, NOP1}};
+
+ // Visit each basic code block and inject NOPs.
+ BasicBlockSubGraph::BBCollection& basic_blocks =
+ basic_block_subgraph->basic_blocks();
+ for (auto bb = basic_blocks.begin(); bb != basic_blocks.end(); ++bb) {
+ BasicCodeBlock* bc_block = BasicCodeBlock::Cast(*bb);
+ if (bc_block != nullptr)
+ InjectNop(nop_spec, debug_friendly_, &bc_block->instructions());
+ }
+ return true;
+}
+
+FillerTransform::FillerTransform(const std::vector<std::string>& target_list)
+ : debug_friendly_(false),
+ num_blocks_(0),
+ num_code_blocks_(0),
+ num_targets_updated_(0) {
+ // Targets are not found yet, so initialize value to false.
+ for (const std::string& target : target_list)
+ target_names_[target] = false;
+}
+
+bool FillerTransform::ShouldProcessBlock(Block* block) const {
+ return target_names_.find(block->name()) != target_names_.end();
+}
+
+void FillerTransform::CheckAllTargetsFound() const {
+ bool has_missing = false;
+ for (auto it = target_names_.begin(); it != target_names_.end(); ++it) {
+ if (it->second)
+ continue;
+ if (!has_missing) {
+ LOG(WARNING) << "There are missing target(s):";
+ has_missing = true;
+ }
+ LOG(WARNING) << " " << it->first;
+ }
+}
+
+bool FillerTransform::PreBlockGraphIteration(
+ const TransformPolicyInterface* policy,
+ BlockGraph* block_graph,
+ Block* header_block) {
+ return true;
+}
+
+bool FillerTransform::OnBlock(const TransformPolicyInterface* policy,
+ BlockGraph* block_graph,
+ Block* block) {
+ DCHECK(nullptr != policy);
+ DCHECK(nullptr != block_graph);
+ DCHECK(nullptr != block);
+
+ ++num_blocks_;
+ if (block->type() != BlockGraph::CODE_BLOCK)
+ return true;
+
+ ++num_code_blocks_;
+ if (!ShouldProcessBlock(block))
+ return true;
+
+ // Mark target as found.
+ std::string name(block->name());
+ auto target_it = target_names_.find(block->name());
+ if (target_it != target_names_.end())
+ target_it->second = true;
+
+ // Skip blocks that aren't eligible for basic-block decomposition.
+ if (!policy->BlockIsSafeToBasicBlockDecompose(block))
+ return true;
+
+ ++num_targets_updated_;
+ // Apply the basic block transform.
+ FillerBasicBlockTransform basic_block_transform;
+ basic_block_transform.set_debug_friendly(debug_friendly());
+ return ApplyBasicBlockSubGraphTransform(
+ &basic_block_transform, policy, block_graph, block, NULL);
+}
+
+bool FillerTransform::PostBlockGraphIteration(
+ const TransformPolicyInterface* policy,
+ BlockGraph* block_graph,
+ Block* header_block) {
+ LOG(INFO) << "Found " << num_blocks_ << " block(s).";
+ LOG(INFO) << "Found " << num_code_blocks_ << " code block(s).";
+ LOG(INFO) << "Updated " << num_targets_updated_ << " blocks(s).";
+ CheckAllTargetsFound();
+ return true;
+}
+
+} // namespace transforms
+} // namespace instrument
« 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