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 : // The PECoffRelinker class serves as the base class of both PERelinker and
16 : // CoffRelinker for common implementation routines.
17 :
18 : #ifndef SYZYGY_PE_PE_COFF_RELINKER_H_
19 : #define SYZYGY_PE_PE_COFF_RELINKER_H_
20 :
21 : #include <vector>
22 :
23 : #include "base/files/file_path.h"
24 : #include "syzygy/block_graph/transform_policy.h"
25 : #include "syzygy/pe/image_layout.h"
26 : #include "syzygy/pe/relinker.h"
27 :
28 : namespace pe {
29 :
30 : // Base class for full file-to-file transformations of PE or COFF files;
31 : // PERelinker and CoffRelinker extend this class. It provides implementation
32 : // for common book-keeping routines for transforms and orderers.
33 : class PECoffRelinker : public RelinkerInterface {
34 : public:
35 : typedef block_graph::BlockGraph BlockGraph;
36 : typedef block_graph::BlockGraphOrdererInterface Orderer;
37 : typedef block_graph::BlockGraphTransformInterface Transform;
38 : typedef block_graph::OrderedBlockGraph OrderedBlockGraph;
39 : typedef block_graph::TransformPolicyInterface TransformPolicyInterface;
40 :
41 : // Change the path to the main input file. By default, it is empty.
42 : //
43 : // @param input_path the new input path.
44 E : void set_input_path(const base::FilePath& input_path) {
45 E : input_path_ = input_path;
46 E : }
47 :
48 : // Change the path to the main output file. By default, it is empty.
49 : //
50 : // @param output_path the new output path.
51 E : void set_output_path(const base::FilePath& output_path) {
52 E : output_path_ = output_path;
53 E : }
54 :
55 : // Specify whether to allow output files to be overwritten. By default, it
56 : // is false. If @p allow_overwrite is true, input and output files may
57 : // overlap.
58 : //
59 : // @param allow_overwrite whether the output files may be overwritten.
60 E : void set_allow_overwrite(bool allow_overwrite) {
61 E : allow_overwrite_ = allow_overwrite;
62 E : }
63 :
64 : // @returns the path to the main input file.
65 E : const base::FilePath& input_path() const { return input_path_; }
66 :
67 : // @returns the path to the main output file.
68 E : const base::FilePath& output_path() const { return output_path_; }
69 :
70 : // @returns whether output files may be overwritten.
71 E : bool allow_overwrite() const { return allow_overwrite_; }
72 :
73 : // @see RelinkerInterface::AppendTransform()
74 : virtual bool AppendTransform(Transform* transform) override;
75 :
76 : // @see RelinkerInterface::AppendTransforms()
77 : virtual bool AppendTransforms(
78 : const std::vector<Transform*>& transforms) override;
79 :
80 : // @see RelinkerInterface::AppendOrderer()
81 : virtual bool AppendOrderer(Orderer* orderer) override;
82 :
83 : // @see RelinkerInterface::AppendOrderers()
84 : virtual bool AppendOrderers(const std::vector<Orderer*>& orderers) override;
85 :
86 : // The following accessors provide access to properties not initialized by
87 : // this class; they should be valid after the relinker has been
88 : // initialized in some fashion specific to the child class.
89 : // @{
90 : // After initialization, retrieve the original unmodified image layout.
91 : //
92 : // @returns the original image layout.
93 E : const ImageLayout& input_image_layout() const {
94 E : DCHECK(inited_);
95 E : return input_image_layout_;
96 E : }
97 :
98 : // After initialization, retrieve the block graph being processed; the
99 : // returned block graph will reflect changes made by passes.
100 : //
101 : // @returns the block graph.
102 E : const BlockGraph& block_graph() const {
103 E : DCHECK(inited_);
104 E : return block_graph_;
105 E : }
106 :
107 : // After initialization, retrieve the headers block being processed; the
108 : // returned block will reflect changes made by passes.
109 : //
110 : // @returns the headers block.
111 E : const BlockGraph::Block* headers_block() const {
112 E : DCHECK(inited_);
113 E : return headers_block_;
114 E : }
115 : // @}
116 :
117 : protected:
118 : // Construct a default PECoffRelinker. Initialize properties to default
119 : // values.
120 : // @param transform_policy The policy that dictates how to apply transforms.
121 : explicit PECoffRelinker(const TransformPolicyInterface* transform_policy);
122 :
123 : // Apply user-supplied transforms to the block graph
124 : // @returns true on success, or false on failure.
125 : bool ApplyUserTransforms();
126 :
127 : // Apply user-supplied orderers to the specified ordered block graph, or
128 : // the default original orderer if none has been added.
129 : // @param ordered_graph the ordered block graph to order or reorder.
130 : // @returns true on success, or false on failure.
131 : bool ApplyUserOrderers(OrderedBlockGraph* ordered_graph);
132 :
133 : // The policy that dictates how to apply transforms.
134 : const TransformPolicyInterface* transform_policy_;
135 :
136 : // The path to the main input file.
137 : base::FilePath input_path_;
138 :
139 : // The path to the main input file.
140 : base::FilePath output_path_;
141 :
142 : // Whether we may overwrite output files.
143 : bool allow_overwrite_;
144 :
145 : // Transforms to be applied, in order.
146 : std::vector<Transform*> transforms_;
147 :
148 : // Orderers to be applied, in order.
149 : std::vector<Orderer*> orderers_;
150 :
151 : // Whether the relinker has been initialized.
152 : bool inited_;
153 :
154 : // These refer to the original image, and don't change after init.
155 : ImageLayout input_image_layout_;
156 :
157 : // The block graph being processed. May be altered by user-supplied
158 : // passes.
159 : BlockGraph block_graph_;
160 :
161 : // The headers block of block_graph_.
162 : BlockGraph::Block* headers_block_;
163 :
164 : private:
165 : DISALLOW_COPY_AND_ASSIGN(PECoffRelinker);
166 : };
167 :
168 : } // namespace pe
169 :
170 : #endif // SYZYGY_PE_PE_COFF_RELINKER_H_
|