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 "base/files/file_util.h"
18 : #include "gmock/gmock.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/block_graph/unittest_util.h"
21 : #include "syzygy/common/defs.h"
22 : #include "syzygy/core/unittest_util.h"
23 : #include "syzygy/pe/unittest_util.h"
24 :
25 : namespace pe {
26 : namespace {
27 :
28 : using block_graph::BlockGraph;
29 : using block_graph::BlockGraphOrdererInterface;
30 : using block_graph::BlockGraphTransformInterface;
31 : using block_graph::ImageLayoutTransformInterface;
32 : using block_graph::OrderedBlockGraph;
33 : using block_graph::TransformPolicyInterface;
34 :
35 : class TestPECoffRelinker : public PECoffRelinker {
36 : public:
37 E : explicit TestPECoffRelinker(const TransformPolicyInterface* transform_policy)
38 E : : PECoffRelinker(transform_policy) {
39 E : }
40 :
41 : using PECoffRelinker::transforms_;
42 : using PECoffRelinker::orderers_;
43 : using PECoffRelinker::layout_transforms_;
44 :
45 i : virtual ImageFormat image_format() const override {
46 i : return BlockGraph::PE_IMAGE;
47 i : }
48 :
49 i : virtual bool Init() override { return true; }
50 i : virtual bool Relink() override { return true; }
51 : };
52 :
53 : class MockTransform : public BlockGraphTransformInterface {
54 : public:
55 i : const char* name() const { return "MockTransform"; }
56 i : MOCK_METHOD3(TransformBlockGraph,
57 : bool(const TransformPolicyInterface*,
58 : BlockGraph*,
59 i : BlockGraph::Block*));
60 : };
61 :
62 : class MockOrderer : public BlockGraphOrdererInterface {
63 : public:
64 i : const char* name() const { return "MockOrderer"; }
65 i : MOCK_METHOD2(OrderBlockGraph, bool(OrderedBlockGraph*, BlockGraph::Block*));
66 : };
67 :
68 : class MockLayoutTransform : public ImageLayoutTransformInterface {
69 : public:
70 i : const char* name() const { return "MockLayoutTransform"; }
71 i : MOCK_METHOD3(TransformImageLayout,
72 : bool(const TransformPolicyInterface*,
73 : const ImageLayout*,
74 i : const OrderedBlockGraph*));
75 : };
76 :
77 :
78 : } // namespace
79 :
80 E : TEST(PECoffRelinkerTest, Properties) {
81 E : testing::DummyTransformPolicy policy;
82 E : TestPECoffRelinker relinker(&policy);
83 E : base::FilePath dummy_path(L"foo");
84 :
85 E : EXPECT_EQ(base::FilePath(), relinker.input_path());
86 E : relinker.set_input_path(dummy_path);
87 E : EXPECT_EQ(dummy_path, relinker.input_path());
88 :
89 E : EXPECT_EQ(base::FilePath(), relinker.output_path());
90 E : relinker.set_output_path(dummy_path);
91 E : EXPECT_EQ(dummy_path, relinker.output_path());
92 :
93 E : EXPECT_FALSE(relinker.allow_overwrite());
94 E : relinker.set_allow_overwrite(true);
95 E : EXPECT_TRUE(relinker.allow_overwrite());
96 E : relinker.set_allow_overwrite(false);
97 E : EXPECT_FALSE(relinker.allow_overwrite());
98 E : }
99 :
100 E : TEST(PECoffRelinkerTest, AppendTransforms) {
101 E : testing::DummyTransformPolicy policy;
102 E : TestPECoffRelinker relinker(&policy);
103 :
104 E : MockTransform transform1, transform2;
105 E : std::vector<BlockGraphTransformInterface*> transforms;
106 E : transforms.push_back(&transform2);
107 :
108 E : relinker.AppendTransform(&transform1);
109 E : relinker.AppendTransforms(transforms);
110 :
111 E : std::vector<BlockGraphTransformInterface*> expected;
112 E : expected.push_back(&transform1);
113 E : expected.push_back(&transform2);
114 :
115 E : EXPECT_EQ(expected, relinker.transforms_);
116 E : }
117 :
118 E : TEST(PECoffRelinkerTest, AppendOrderers) {
119 E : testing::DummyTransformPolicy policy;
120 E : TestPECoffRelinker relinker(&policy);
121 :
122 E : MockOrderer orderer1, orderer2;
123 E : std::vector<BlockGraphOrdererInterface*> orderers;
124 E : orderers.push_back(&orderer2);
125 :
126 E : relinker.AppendOrderer(&orderer1);
127 E : relinker.AppendOrderers(orderers);
128 :
129 E : std::vector<BlockGraphOrdererInterface*> expected;
130 E : expected.push_back(&orderer1);
131 E : expected.push_back(&orderer2);
132 :
133 E : EXPECT_EQ(expected, relinker.orderers_);
134 E : }
135 :
136 E : TEST(PECoffRelinkerTest, AppendLayoutTransforms) {
137 E : testing::DummyTransformPolicy policy;
138 E : TestPECoffRelinker relinker(&policy);
139 :
140 E : MockLayoutTransform transform1, transform2;
141 E : std::vector<ImageLayoutTransformInterface*> transforms;
142 E : transforms.push_back(&transform2);
143 :
144 E : relinker.AppendLayoutTransform(&transform1);
145 E : relinker.AppendLayoutTransforms(transforms);
146 :
147 E : std::vector<ImageLayoutTransformInterface*> expected;
148 E : expected.push_back(&transform1);
149 E : expected.push_back(&transform2);
150 :
151 E : EXPECT_EQ(expected, relinker.layout_transforms_);
152 E : }
153 :
154 : } // namespace pe
|