1 : // Copyright 2011 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/reorder/dead_code_finder.h"
16 :
17 : namespace reorder {
18 :
19 : DeadCodeFinder::DeadCodeFinder()
20 E : : Reorderer::OrderGenerator("Dead Code Finder") {
21 E : }
22 :
23 E : DeadCodeFinder::~DeadCodeFinder() {
24 E : }
25 :
26 : bool DeadCodeFinder::OnCodeBlockEntry(const Block* block,
27 : RelativeAddress /*address*/,
28 : uint32 /*process_id*/,
29 : uint32 /*thread_id*/,
30 E : const UniqueTime& /*time*/) {
31 E : visited_blocks_.insert(block);
32 E : return true;
33 E : }
34 :
35 E : bool DeadCodeFinder::IsDead(const Block* block) const {
36 : // We don't consider gap blocks as interesting for the purposes of dead code
37 : // identification. We don't have good names for these blocks, so they end up
38 : // just being noise (not easily actionable) for the consumer of the dead code
39 : // finder's output.
40 : return ((block->attributes() & BlockGraph::GAP_BLOCK) == 0)
41 E : && (visited_blocks_.find(block) == visited_blocks_.end());
42 E : }
43 :
44 : bool DeadCodeFinder::CalculateReordering(const PEFile& pe_file,
45 : const ImageLayout& image,
46 : bool reorder_code,
47 : bool reorder_data,
48 E : Order* order) {
49 E : DCHECK(order != NULL);
50 :
51 E : order->comment = "Unvisited blocks per section";
52 E : order->sections.clear();
53 E : order->sections.resize(image.sections.size());
54 E : for (size_t i = 0; i < image.sections.size(); ++i) {
55 E : const ImageLayout::SectionInfo& section = image.sections[i];
56 E : order->sections[i].id = i;
57 E : order->sections[i].name = section.name;
58 E : order->sections[i].characteristics = section.characteristics;
59 E : if ((section.characteristics & IMAGE_SCN_CNT_CODE) == 0)
60 E : continue;
61 :
62 : // Prepare to iterate over all block in the section.
63 E : BlockGraph::AddressSpace::Range section_range(section.addr, section.size);
64 : AddressSpace::RangeMapConstIterPair section_blocks(
65 : image.blocks.GetIntersectingBlocks(
66 E : section_range.start(), section_range.size()));
67 :
68 : // Gather up all unvisited blocks within the section in the "order".
69 E : AddressSpace::RangeMapConstIter& section_it = section_blocks.first;
70 E : const AddressSpace::RangeMapConstIter& section_end = section_blocks.second;
71 E : Order::BlockSpecVector& block_vector = order->sections[i].blocks;
72 E : for (; section_it != section_end; ++section_it) {
73 E : const BlockGraph::Block* block = section_it->second;
74 E : if (IsDead(block)) {
75 E : block_vector.push_back(Order::BlockSpec(block));
76 : }
77 E : }
78 E : }
79 :
80 E : return true;
81 E : }
82 :
83 : } // namespace reorder
|