OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "courgette/label_manager.h" | 5 #include "courgette/label_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <iterator> | 10 #include <iterator> |
11 #include <map> | 11 #include <map> |
12 #include <set> | 12 #include <set> |
13 #include <string> | 13 #include <string> |
14 #include <utility> | 14 #include <utility> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/macros.h" | 18 #include "base/macros.h" |
| 19 #include "courgette/image_utils.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
20 | 21 |
21 namespace courgette { | 22 namespace courgette { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 // Test version of RvaVisitor: Just wrap std::vector<RVA>. | 26 class TestLabelManager : public LabelManager { |
26 class TestRvaVisitor : public LabelManagerImpl::RvaVisitor { | |
27 public: | 27 public: |
28 explicit TestRvaVisitor(std::vector<RVA>::const_iterator rva_begin, | 28 void SetLabels(const LabelVector& labels) { |
29 std::vector<RVA>::const_iterator rva_end) | 29 labels_ = labels; |
30 : rva_it_(rva_begin), rva_end_(rva_end) {} | 30 }; |
31 | |
32 ~TestRvaVisitor() override {} | |
33 | |
34 size_t Remaining() const override { return std::distance(rva_it_, rva_end_); } | |
35 | |
36 RVA Get() const override { return *rva_it_; } | |
37 | |
38 void Next() override { ++rva_it_; } | |
39 | |
40 private: | |
41 std::vector<RVA>::const_iterator rva_it_; | |
42 std::vector<RVA>::const_iterator rva_end_; | |
43 }; | 31 }; |
44 | 32 |
45 void CheckLabelManagerContent(LabelManager* label_manager, | 33 void CheckLabelManagerContent(LabelManager* label_manager, |
46 const std::map<RVA, int32_t>& expected) { | 34 const std::map<RVA, int32_t>& expected) { |
47 EXPECT_EQ(expected.size(), label_manager->Size()); | 35 EXPECT_EQ(expected.size(), label_manager->Labels().size()); |
48 for (const auto& rva_and_count : expected) { | 36 for (const auto& rva_and_count : expected) { |
49 Label* label = label_manager->Find(rva_and_count.first); | 37 Label* label = label_manager->Find(rva_and_count.first); |
50 EXPECT_TRUE(label != nullptr); | 38 EXPECT_TRUE(label != nullptr); |
51 EXPECT_EQ(rva_and_count.first, label->rva_); | 39 EXPECT_EQ(rva_and_count.first, label->rva_); |
52 EXPECT_EQ(rva_and_count.second, label->count_); | 40 EXPECT_EQ(rva_and_count.second, label->count_); |
53 } | 41 } |
54 } | 42 } |
55 | 43 |
56 // Instantiates a LabelVector with |n| instances. The |rva_| fields are assigned | 44 // Instantiates a LabelVector with |n| instances. The |rva_| fields are assigned |
57 // 0, ..., |n| - 1. The other fields are uninitialized. | 45 // 0, ..., |n| - 1. The other fields are uninitialized. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 else if (label.index_ >= 0 && label.index_ <= 'Z' - 'A') | 92 else if (label.index_ >= 0 && label.index_ <= 'Z' - 'A') |
105 encoded += static_cast<char>(label.index_ + 'A'); | 93 encoded += static_cast<char>(label.index_ + 'A'); |
106 else | 94 else |
107 NOTREACHED(); | 95 NOTREACHED(); |
108 } | 96 } |
109 return encoded; | 97 return encoded; |
110 } | 98 } |
111 | 99 |
112 } // namespace | 100 } // namespace |
113 | 101 |
114 TEST(LabelManagerTest, GetIndexBound_LabelVector) { | 102 TEST(LabelManagerTest, GetLabelIndexBound) { |
115 LabelVector labels0; | 103 LabelVector labels0; |
116 EXPECT_EQ(0, LabelManager::GetIndexBound(labels0)); | 104 EXPECT_EQ(0, LabelManager::GetLabelIndexBound(labels0)); |
117 | 105 |
118 LabelVector labels1_uninit = CreateLabelVectorBasic(1); | 106 LabelVector labels1_uninit = CreateLabelVectorBasic(1); |
119 ASSERT_EQ(1U, labels1_uninit.size()); | 107 ASSERT_EQ(1U, labels1_uninit.size()); |
120 EXPECT_EQ(0, LabelManager::GetIndexBound(labels1_uninit)); | 108 EXPECT_EQ(0, LabelManager::GetLabelIndexBound(labels1_uninit)); |
121 | 109 |
122 LabelVector labels1_init = CreateLabelVectorBasic(1); | 110 LabelVector labels1_init = CreateLabelVectorBasic(1); |
123 ASSERT_EQ(1U, labels1_init.size()); | 111 ASSERT_EQ(1U, labels1_init.size()); |
124 labels1_init[0].index_ = 99; | 112 labels1_init[0].index_ = 99; |
125 EXPECT_EQ(100, LabelManager::GetIndexBound(labels1_init)); | 113 EXPECT_EQ(100, LabelManager::GetLabelIndexBound(labels1_init)); |
126 | 114 |
127 LabelVector labels6_mixed = CreateLabelVectorBasic(6); | 115 LabelVector labels6_mixed = CreateLabelVectorBasic(6); |
128 ASSERT_EQ(6U, labels6_mixed.size()); | 116 ASSERT_EQ(6U, labels6_mixed.size()); |
129 labels6_mixed[1].index_ = 5; | 117 labels6_mixed[1].index_ = 5; |
130 labels6_mixed[2].index_ = 2; | 118 labels6_mixed[2].index_ = 2; |
131 labels6_mixed[4].index_ = 15; | 119 labels6_mixed[4].index_ = 15; |
132 labels6_mixed[5].index_ = 7; | 120 labels6_mixed[5].index_ = 7; |
133 EXPECT_EQ(16, LabelManager::GetIndexBound(labels6_mixed)); | 121 EXPECT_EQ(16, LabelManager::GetLabelIndexBound(labels6_mixed)); |
134 } | |
135 | |
136 TEST(LabelManagerTest, GetIndexBound_RVAToLabel) { | |
137 RVAToLabel labels_map0; | |
138 EXPECT_EQ(0, LabelManager::GetIndexBound(labels_map0)); | |
139 | |
140 RVAToLabel labels1_map_init; | |
141 Label label1(static_cast<RVA>(0), 99, 1); | |
142 labels1_map_init[label1.rva_] = &label1; | |
143 EXPECT_EQ(100, LabelManager::GetIndexBound(labels1_map_init)); | |
144 | |
145 RVAToLabel labels_map6_mixed; | |
146 Label labels6[] = { | |
147 Label(static_cast<RVA>(1), 5, 1), | |
148 Label(static_cast<RVA>(2), 2, 1), | |
149 Label(static_cast<RVA>(4), 15, 1), | |
150 Label(static_cast<RVA>(5), 7, 1) | |
151 }; | |
152 for (Label& label : labels6) | |
153 labels_map6_mixed[label.rva_] = &label; | |
154 EXPECT_EQ(16, LabelManager::GetIndexBound(labels_map6_mixed)); | |
155 } | 122 } |
156 | 123 |
157 TEST(LabelManagerTest, Basic) { | 124 TEST(LabelManagerTest, Basic) { |
158 static const RVA kTestTargetsRaw[] = { | 125 static const RVA kTestTargetsRaw[] = { |
159 0x04000010, | 126 0x04000010, |
160 0x04000030, | 127 0x04000030, |
161 0x04000020, | 128 0x04000020, |
162 0x04000010, // Redundant. | 129 0x04000010, // Redundant. |
163 0xFEEDF00D, | 130 0xFEEDF00D, |
164 0x04000030, // Redundant. | 131 0x04000030, // Redundant. |
165 0xFEEDF00D, // Redundant. | 132 0xFEEDF00D, // Redundant. |
166 0x00000110, | 133 0x00000110, |
167 0x04000010, // Redundant. | 134 0x04000010, // Redundant. |
168 0xABCD1234 | 135 0xABCD1234 |
169 }; | 136 }; |
170 std::vector<RVA> test_targets(std::begin(kTestTargetsRaw), | 137 std::vector<RVA> test_targets(std::begin(kTestTargetsRaw), |
171 std::end(kTestTargetsRaw)); | 138 std::end(kTestTargetsRaw)); |
172 TestRvaVisitor visitor(test_targets.begin(), test_targets.end()); | 139 TrivialRvaVisitor visitor(test_targets); |
173 | 140 |
174 // Preallocate targets, then populate. | 141 // Preallocate targets, then populate. |
175 LabelManagerImpl label_manager; | 142 TestLabelManager label_manager; |
176 label_manager.Read(&visitor); | 143 label_manager.Read(&visitor); |
177 | 144 |
178 static const std::pair<RVA, int32_t> kExpected1Raw[] = { | 145 static const std::pair<RVA, int32_t> kExpected1Raw[] = { |
179 {0x00000110, 1}, {0x04000010, 3}, {0x04000020, 1}, | 146 {0x00000110, 1}, {0x04000010, 3}, {0x04000020, 1}, |
180 {0x04000030, 2}, {0xABCD1234, 1}, {0xFEEDF00D, 2}}; | 147 {0x04000030, 2}, {0xABCD1234, 1}, {0xFEEDF00D, 2}}; |
181 std::map<RVA, int32_t> expected1(std::begin(kExpected1Raw), | 148 std::map<RVA, int32_t> expected1(std::begin(kExpected1Raw), |
182 std::end(kExpected1Raw)); | 149 std::end(kExpected1Raw)); |
183 | 150 |
184 CheckLabelManagerContent(&label_manager, expected1); | 151 CheckLabelManagerContent(&label_manager, expected1); |
185 | 152 |
(...skipping 12 matching lines...) Expand all Loading... |
198 std::map<RVA, int32_t> expected2(std::begin(kExpected2Raw), | 165 std::map<RVA, int32_t> expected2(std::begin(kExpected2Raw), |
199 std::end(kExpected2Raw)); | 166 std::end(kExpected2Raw)); |
200 CheckLabelManagerContent(&label_manager, expected2); | 167 CheckLabelManagerContent(&label_manager, expected2); |
201 } | 168 } |
202 | 169 |
203 TEST(LabelManagerTest, Single) { | 170 TEST(LabelManagerTest, Single) { |
204 const RVA kRva = 12U; | 171 const RVA kRva = 12U; |
205 for (int dup = 1; dup < 8; ++dup) { | 172 for (int dup = 1; dup < 8; ++dup) { |
206 // Test data: |dup| copies of kRva. | 173 // Test data: |dup| copies of kRva. |
207 std::vector<RVA> test_targets(dup, kRva); | 174 std::vector<RVA> test_targets(dup, kRva); |
208 TestRvaVisitor visitor(test_targets.begin(), test_targets.end()); | 175 TrivialRvaVisitor visitor(test_targets); |
209 LabelManagerImpl label_manager; | 176 TestLabelManager label_manager; |
210 label_manager.Read(&visitor); | 177 label_manager.Read(&visitor); |
211 EXPECT_EQ(1U, label_manager.Size()); // Deduped to 1 Label. | 178 EXPECT_EQ(1U, label_manager.Labels().size()); // Deduped to 1 Label. |
212 | 179 |
213 Label* label = label_manager.Find(kRva); | 180 Label* label = label_manager.Find(kRva); |
214 EXPECT_NE(nullptr, label); | 181 EXPECT_NE(nullptr, label); |
215 EXPECT_EQ(kRva, label->rva_); | 182 EXPECT_EQ(kRva, label->rva_); |
216 EXPECT_EQ(dup, label->count_); | 183 EXPECT_EQ(dup, label->count_); |
217 | 184 |
218 for (RVA rva = 0U; rva < 16U; ++rva) { | 185 for (RVA rva = 0U; rva < 16U; ++rva) { |
219 if (rva != kRva) | 186 if (rva != kRva) |
220 EXPECT_EQ(nullptr, label_manager.Find(rva)); | 187 EXPECT_EQ(nullptr, label_manager.Find(rva)); |
221 } | 188 } |
222 } | 189 } |
223 } | 190 } |
224 | 191 |
225 TEST(LabelManagerTest, Empty) { | 192 TEST(LabelManagerTest, Empty) { |
226 std::vector<RVA> empty_test_targets; | 193 std::vector<RVA> empty_test_targets; |
227 TestRvaVisitor visitor(empty_test_targets.begin(), empty_test_targets.end()); | 194 TrivialRvaVisitor visitor(empty_test_targets); |
228 LabelManagerImpl label_manager; | 195 TestLabelManager label_manager; |
229 label_manager.Read(&visitor); | 196 label_manager.Read(&visitor); |
230 EXPECT_EQ(0U, label_manager.Size()); | 197 EXPECT_EQ(0U, label_manager.Labels().size()); |
231 for (RVA rva = 0U; rva < 16U; ++rva) | 198 for (RVA rva = 0U; rva < 16U; ++rva) |
232 EXPECT_EQ(nullptr, label_manager.Find(rva)); | 199 EXPECT_EQ(nullptr, label_manager.Find(rva)); |
233 } | 200 } |
234 | 201 |
235 TEST(LabelManagerTest, EmptyAssign) { | 202 TEST(LabelManagerTest, EmptyAssign) { |
236 LabelManagerImpl label_manager_empty; | 203 TestLabelManager label_manager_empty; |
237 label_manager_empty.DefaultAssignIndexes(); | 204 label_manager_empty.DefaultAssignIndexes(); |
238 label_manager_empty.UnassignIndexes(); | 205 label_manager_empty.UnassignIndexes(); |
239 label_manager_empty.AssignRemainingIndexes(); | 206 label_manager_empty.AssignRemainingIndexes(); |
240 } | 207 } |
241 | 208 |
242 TEST(LabelManagerTest, TrivialAssign) { | 209 TEST(LabelManagerTest, TrivialAssign) { |
243 for (size_t size = 0; size < 20; ++size) { | 210 for (size_t size = 0; size < 20; ++size) { |
244 LabelManagerImpl label_manager; | 211 TestLabelManager label_manager; |
245 label_manager.SetLabels(CreateLabelVectorBasic(size)); | 212 label_manager.SetLabels(CreateLabelVectorBasic(size)); |
246 | 213 |
247 // Sanity check. | 214 // Sanity check. |
248 for (size_t i = 0; i < size; ++i) | 215 for (size_t i = 0; i < size; ++i) |
249 EXPECT_EQ(Label::kNoIndex, label_manager.Labels()[i].index_); | 216 EXPECT_EQ(Label::kNoIndex, label_manager.Labels()[i].index_); |
250 | 217 |
251 // Default assign. | 218 // Default assign. |
252 label_manager.DefaultAssignIndexes(); | 219 label_manager.DefaultAssignIndexes(); |
253 for (size_t i = 0; i < size; ++i) | 220 for (size_t i = 0; i < size; ++i) |
254 EXPECT_EQ(static_cast<int>(i), label_manager.Labels()[i].index_); | 221 EXPECT_EQ(static_cast<int>(i), label_manager.Labels()[i].index_); |
255 | 222 |
256 // Heuristic assign, but since everything's assigned, so no change. | 223 // Heuristic assign, but since everything's assigned, so no change. |
257 label_manager.AssignRemainingIndexes(); | 224 label_manager.AssignRemainingIndexes(); |
258 for (size_t i = 0; i < size; ++i) | 225 for (size_t i = 0; i < size; ++i) |
259 EXPECT_EQ(static_cast<int>(i), label_manager.Labels()[i].index_); | 226 EXPECT_EQ(static_cast<int>(i), label_manager.Labels()[i].index_); |
260 | 227 |
261 // Unassign. | 228 // Unassign. |
262 label_manager.UnassignIndexes(); | 229 label_manager.UnassignIndexes(); |
263 for (size_t i = 0; i < size; ++i) | 230 for (size_t i = 0; i < size; ++i) |
264 EXPECT_EQ(Label::kNoIndex, label_manager.Labels()[i].index_); | 231 EXPECT_EQ(Label::kNoIndex, label_manager.Labels()[i].index_); |
265 } | 232 } |
266 } | 233 } |
267 | 234 |
268 // Tests SimpleIndexAssigner fill strategies independently. | 235 // Tests SimpleIndexAssigner fill strategies independently. |
269 TEST(LabelManagerTest, SimpleIndexAssigner) { | 236 TEST(LabelManagerTest, SimpleIndexAssigner) { |
270 using SimpleIndexAssigner = LabelManagerImpl::SimpleIndexAssigner; | 237 using SimpleIndexAssigner = LabelManager::SimpleIndexAssigner; |
271 // See CreateLabelVectorWithIndexes() explanation on how we encode LabelVector | 238 // See CreateLabelVectorWithIndexes() explanation on how we encode LabelVector |
272 // |index_| values as a string. | 239 // |index_| values as a string. |
273 const struct TestCase { | 240 const struct TestCase { |
274 const char* input; | 241 const char* input; |
275 const char* expect_forward; | 242 const char* expect_forward; |
276 const char* expect_backward; | 243 const char* expect_backward; |
277 const char* expect_in; | 244 const char* expect_in; |
278 } kTestCases[] = { | 245 } kTestCases[] = { |
279 {"", "", "", ""}, | 246 {"", "", "", ""}, |
280 {".", "A", "A", "A"}, | 247 {".", "A", "A", "A"}, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 {"DA.....", "DABCEFG"}, // Forward: "BC"; backward: "EFG". | 344 {"DA.....", "DABCEFG"}, // Forward: "BC"; backward: "EFG". |
378 // Backward fill and infill. | 345 // Backward fill and infill. |
379 {"G....DA", "GEFBCDA"}, // Backward: "BC"; in: "EF". | 346 {"G....DA", "GEFBCDA"}, // Backward: "BC"; in: "EF". |
380 {"..ZBA..", "XYZBACD"}, // Backward: "XY"; in: "CD". | 347 {"..ZBA..", "XYZBACD"}, // Backward: "XY"; in: "CD". |
381 // All. | 348 // All. |
382 {".....ZED.", "ABCXYZEDF"}, // Forward: "ABC"; backward: "XY"; in: "F". | 349 {".....ZED.", "ABCXYZEDF"}, // Forward: "ABC"; backward: "XY"; in: "F". |
383 {".....GD.", "ABCHFGDE"}, // Forward: "ABC", "E"; backward: "F"; in: "H". | 350 {".....GD.", "ABCHFGDE"}, // Forward: "ABC", "E"; backward: "F"; in: "H". |
384 {"..FE..GD..", "ABFECHGDIJ"}, // Forward: "AB"; backward: "IJ"; in: "CH". | 351 {"..FE..GD..", "ABFECHGDIJ"}, // Forward: "AB"; backward: "IJ"; in: "CH". |
385 }; | 352 }; |
386 for (const auto& test_case : kTestCases) { | 353 for (const auto& test_case : kTestCases) { |
387 LabelManagerImpl label_manager; | 354 TestLabelManager label_manager; |
388 label_manager.SetLabels(CreateLabelVectorWithIndexes(test_case.input)); | 355 label_manager.SetLabels(CreateLabelVectorWithIndexes(test_case.input)); |
389 | 356 |
390 label_manager.AssignRemainingIndexes(); | 357 label_manager.AssignRemainingIndexes(); |
391 std::string result = EncodeLabelIndexes(label_manager.Labels()); | 358 std::string result = EncodeLabelIndexes(label_manager.Labels()); |
392 EXPECT_EQ(test_case.expect, result); | 359 EXPECT_EQ(test_case.expect, result); |
393 } | 360 } |
394 } | 361 } |
395 | 362 |
396 } // namespace courgette | 363 } // namespace courgette |
OLD | NEW |