| 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 |