1 : // Copyright 2013 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/pe/pe_coff_relinker.h"
16 :
17 : #include "syzygy/block_graph/orderers/original_orderer.h"
18 :
19 : namespace pe {
20 : namespace {
21 :
22 : typedef block_graph::BlockGraphTransformInterface Transform;
23 : typedef block_graph::BlockGraphOrdererInterface Orderer;
24 :
25 : using block_graph::ApplyBlockGraphTransform;
26 : using block_graph::BlockGraph;
27 : using block_graph::OrderedBlockGraph;
28 : using block_graph::TransformPolicyInterface;
29 : using core::RelativeAddress;
30 :
31 : } // namespace
32 :
33 : PECoffRelinker::PECoffRelinker(const TransformPolicyInterface* transform_policy)
34 : : transform_policy_(transform_policy),
35 : allow_overwrite_(false),
36 : inited_(false),
37 : input_image_layout_(&block_graph_),
38 E : headers_block_(NULL) {
39 E : DCHECK(transform_policy != NULL);
40 E : }
41 :
42 E : bool PECoffRelinker::AppendTransform(Transform* transform) {
43 E : DCHECK(transform != NULL);
44 E : transforms_.push_back(transform);
45 E : return true;
46 E : }
47 :
48 : bool PECoffRelinker::AppendTransforms(
49 E : const std::vector<Transform*>& transforms) {
50 E : transforms_.insert(transforms_.end(), transforms.begin(), transforms.end());
51 E : return true;
52 E : }
53 :
54 E : bool PECoffRelinker::AppendOrderer(Orderer* orderer) {
55 E : DCHECK(orderer != NULL);
56 E : orderers_.push_back(orderer);
57 E : return true;
58 E : }
59 :
60 E : bool PECoffRelinker::AppendOrderers(const std::vector<Orderer*>& orderers) {
61 E : orderers_.insert(orderers_.end(), orderers.begin(), orderers.end());
62 E : return true;
63 E : }
64 :
65 E : bool PECoffRelinker::ApplyUserTransforms() {
66 E : LOG(INFO) << "Transforming block graph.";
67 : if (!block_graph::ApplyBlockGraphTransforms(
68 E : transforms_, transform_policy_, &block_graph_, headers_block_)) {
69 E : return false;
70 : }
71 E : return true;
72 E : }
73 :
74 E : bool PECoffRelinker::ApplyUserOrderers(OrderedBlockGraph* ordered_graph) {
75 E : LOG(INFO) << "Ordering block graph.";
76 :
77 E : if (orderers_.empty()) {
78 : // Default orderer.
79 E : LOG(INFO) << "No orderers specified, applying default orderer.";
80 E : block_graph::orderers::OriginalOrderer default_orderer;
81 E : if (!default_orderer.OrderBlockGraph(ordered_graph, headers_block_)) {
82 i : LOG(ERROR) << "Orderer failed: " << default_orderer.name() << ".";
83 i : return false;
84 : }
85 E : } else {
86 : // Supplied orderers.
87 : if (!block_graph::ApplyBlockGraphOrderers(
88 E : orderers_, ordered_graph, headers_block_)) {
89 E : return false;
90 : }
91 : }
92 :
93 E : return true;
94 E : }
95 :
96 : } // namespace pe
|