| OLD | NEW |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS 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 | 5 |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 | 7 |
| 8 #include "cgptlib.h" | 8 #include "cgptlib.h" |
| 9 #include "cgptlib_internal.h" | 9 #include "cgptlib_internal.h" |
| 10 #include "cgptlib_test.h" | 10 #include "cgptlib_test.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 #define DEFAULT_SECTOR_SIZE 512 | 39 #define DEFAULT_SECTOR_SIZE 512 |
| 40 #define MAX_SECTOR_SIZE 4096 | 40 #define MAX_SECTOR_SIZE 4096 |
| 41 #define DEFAULT_DRIVE_SECTORS 467 | 41 #define DEFAULT_DRIVE_SECTORS 467 |
| 42 #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ | 42 #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ |
| 43 | 43 |
| 44 static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; | 44 static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; |
| 45 static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; | 45 static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; |
| 46 static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; | 46 static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; |
| 47 | 47 |
| 48 /* Copy a random-for-this-program-only Guid into the dest. The num parameter |
| 49 * completely determines the Guid. |
| 50 */ |
| 51 static void SetGuid(void *dest, uint32_t num) { |
| 52 Guid g = {{{num,0xd450,0x44bc,0xa6,0x93,{0xb8,0xac,0x75,0x5f,0xcd,0x48}}}}; |
| 53 Memcpy(dest, &g, sizeof(Guid)); |
| 54 } |
| 48 | 55 |
| 49 /* Given a GptData pointer, first re-calculate entries CRC32 value, | 56 /* Given a GptData pointer, first re-calculate entries CRC32 value, |
| 50 * then reset header CRC32 value to 0, and calculate header CRC32 value. | 57 * then reset header CRC32 value to 0, and calculate header CRC32 value. |
| 51 * Both primary and secondary are updated. */ | 58 * Both primary and secondary are updated. */ |
| 52 static void RefreshCrc32(GptData* gpt) { | 59 static void RefreshCrc32(GptData* gpt) { |
| 53 GptHeader *header, *header2; | 60 GptHeader *header, *header2; |
| 54 GptEntry *entries, *entries2; | 61 GptEntry *entries, *entries2; |
| 55 | 62 |
| 56 header = (GptHeader*)gpt->primary_header; | 63 header = (GptHeader*)gpt->primary_header; |
| 57 entries = (GptEntry*)gpt->primary_entries; | 64 entries = (GptEntry*)gpt->primary_entries; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 header->size = sizeof(GptHeader); | 147 header->size = sizeof(GptHeader); |
| 141 header->reserved_zero = 0; | 148 header->reserved_zero = 0; |
| 142 header->my_lba = 1; | 149 header->my_lba = 1; |
| 143 header->alternate_lba = DEFAULT_DRIVE_SECTORS - 1; | 150 header->alternate_lba = DEFAULT_DRIVE_SECTORS - 1; |
| 144 header->first_usable_lba = 34; | 151 header->first_usable_lba = 34; |
| 145 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ | 152 header->last_usable_lba = DEFAULT_DRIVE_SECTORS - 1 - 32 - 1; /* 433 */ |
| 146 header->entries_lba = 2; | 153 header->entries_lba = 2; |
| 147 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ | 154 header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ |
| 148 header->size_of_entry = 128; /* bytes */ | 155 header->size_of_entry = 128; /* bytes */ |
| 149 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); | 156 Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); |
| 157 SetGuid(&entries[0].unique, 0); |
| 150 entries[0].starting_lba = 34; | 158 entries[0].starting_lba = 34; |
| 151 entries[0].ending_lba = 133; | 159 entries[0].ending_lba = 133; |
| 152 Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); | 160 Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); |
| 161 SetGuid(&entries[1].unique, 1); |
| 153 entries[1].starting_lba = 134; | 162 entries[1].starting_lba = 134; |
| 154 entries[1].ending_lba = 232; | 163 entries[1].ending_lba = 232; |
| 155 Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); | 164 Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); |
| 165 SetGuid(&entries[2].unique, 2); |
| 156 entries[2].starting_lba = 234; | 166 entries[2].starting_lba = 234; |
| 157 entries[2].ending_lba = 331; | 167 entries[2].ending_lba = 331; |
| 158 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); | 168 Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); |
| 169 SetGuid(&entries[3].unique, 3); |
| 159 entries[3].starting_lba = 334; | 170 entries[3].starting_lba = 334; |
| 160 entries[3].ending_lba = 430; | 171 entries[3].ending_lba = 430; |
| 161 | 172 |
| 162 /* build secondary */ | 173 /* build secondary */ |
| 163 header2 = (GptHeader*)gpt->secondary_header; | 174 header2 = (GptHeader*)gpt->secondary_header; |
| 164 entries2 = (GptEntry*)gpt->secondary_entries; | 175 entries2 = (GptEntry*)gpt->secondary_entries; |
| 165 Memcpy(header2, header, sizeof(GptHeader)); | 176 Memcpy(header2, header, sizeof(GptHeader)); |
| 166 Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE); | 177 Memcpy(entries2, entries, PARTITION_ENTRIES_SIZE); |
| 167 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ | 178 header2->my_lba = DEFAULT_DRIVE_SECTORS - 1; /* 466 */ |
| 168 header2->alternate_lba = 1; | 179 header2->alternate_lba = 1; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 | 667 |
| 657 for (i = 0; i < ARRAY_SIZE(cases); ++i) { | 668 for (i = 0; i < ARRAY_SIZE(cases); ++i) { |
| 658 BuildTestGptData(gpt); | 669 BuildTestGptData(gpt); |
| 659 ZeroEntries(gpt); | 670 ZeroEntries(gpt); |
| 660 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { | 671 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { |
| 661 if (!cases[i].entries[j].starting_lba) | 672 if (!cases[i].entries[j].starting_lba) |
| 662 break; | 673 break; |
| 663 | 674 |
| 664 if (cases[i].entries[j].active) | 675 if (cases[i].entries[j].active) |
| 665 Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); | 676 Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); |
| 677 SetGuid(&e[j].unique, j); |
| 666 e[j].starting_lba = cases[i].entries[j].starting_lba; | 678 e[j].starting_lba = cases[i].entries[j].starting_lba; |
| 667 e[j].ending_lba = cases[i].entries[j].ending_lba; | 679 e[j].ending_lba = cases[i].entries[j].ending_lba; |
| 668 } | 680 } |
| 669 RefreshCrc32(gpt); | 681 RefreshCrc32(gpt); |
| 670 | 682 |
| 671 EXPECT(cases[i].overlapped == CheckEntries(e, h)); | 683 EXPECT(cases[i].overlapped == CheckEntries(e, h)); |
| 672 } | 684 } |
| 673 return TEST_OK; | 685 return TEST_OK; |
| 674 } | 686 } |
| 675 | 687 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 gpt->secondary_entries[0]++; | 782 gpt->secondary_entries[0]++; |
| 771 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 783 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 772 EXPECT(MASK_BOTH == gpt->valid_headers); | 784 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 773 EXPECT(MASK_PRIMARY == gpt->valid_entries); | 785 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
| 774 GptRepair(gpt); | 786 GptRepair(gpt); |
| 775 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 787 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 776 EXPECT(MASK_BOTH == gpt->valid_headers); | 788 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 777 EXPECT(MASK_BOTH == gpt->valid_entries); | 789 EXPECT(MASK_BOTH == gpt->valid_entries); |
| 778 EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); | 790 EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); |
| 779 | 791 |
| 792 /* Modify both header and entries */ |
| 793 BuildTestGptData(gpt); |
| 794 gpt->primary_header[0]++; |
| 795 gpt->primary_entries[0]++; |
| 796 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 797 EXPECT(MASK_SECONDARY == gpt->valid_headers); |
| 798 EXPECT(MASK_SECONDARY == gpt->valid_entries); |
| 799 GptRepair(gpt); |
| 800 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 801 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 802 EXPECT(MASK_BOTH == gpt->valid_entries); |
| 803 EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified); |
| 804 |
| 805 BuildTestGptData(gpt); |
| 806 gpt->secondary_header[0]++; |
| 807 gpt->secondary_entries[0]++; |
| 808 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 809 EXPECT(MASK_PRIMARY == gpt->valid_headers); |
| 810 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
| 811 GptRepair(gpt); |
| 812 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 813 EXPECT(MASK_BOTH == gpt->valid_headers); |
| 814 EXPECT(MASK_BOTH == gpt->valid_entries); |
| 815 EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified); |
| 816 |
| 780 /* Test cross-correction (h1+e2, h2+e1) */ | 817 /* Test cross-correction (h1+e2, h2+e1) */ |
| 781 BuildTestGptData(gpt); | 818 BuildTestGptData(gpt); |
| 782 gpt->primary_header[0]++; | 819 gpt->primary_header[0]++; |
| 783 gpt->secondary_entries[0]++; | 820 gpt->secondary_entries[0]++; |
| 784 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 821 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 785 EXPECT(MASK_SECONDARY == gpt->valid_headers); | 822 EXPECT(MASK_SECONDARY == gpt->valid_headers); |
| 786 EXPECT(MASK_PRIMARY == gpt->valid_entries); | 823 EXPECT(MASK_PRIMARY == gpt->valid_entries); |
| 787 GptRepair(gpt); | 824 GptRepair(gpt); |
| 788 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); | 825 EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); |
| 789 EXPECT(MASK_BOTH == gpt->valid_headers); | 826 EXPECT(MASK_BOTH == gpt->valid_headers); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 GptData* gpt = GetEmptyGptData(); | 1122 GptData* gpt = GetEmptyGptData(); |
| 1086 | 1123 |
| 1087 BuildTestGptData(gpt); | 1124 BuildTestGptData(gpt); |
| 1088 gpt->current_kernel = 0; /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ | 1125 gpt->current_kernel = 0; /* anything, but not CGPT_KERNEL_ENTRY_NOT_FOUND */ |
| 1089 EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == | 1126 EXPECT(GPT_ERROR_INVALID_UPDATE_TYPE == |
| 1090 GptUpdateKernelEntry(gpt, 99)); /* any invalid update_type value */ | 1127 GptUpdateKernelEntry(gpt, 99)); /* any invalid update_type value */ |
| 1091 | 1128 |
| 1092 return TEST_OK; | 1129 return TEST_OK; |
| 1093 } | 1130 } |
| 1094 | 1131 |
| 1132 |
| 1133 /* Tests duplicate UniqueGuids can be detected. */ |
| 1134 static int DuplicateUniqueGuidTest() { |
| 1135 GptData* gpt = GetEmptyGptData(); |
| 1136 GptHeader* h = (GptHeader*)gpt->primary_header; |
| 1137 GptEntry* e = (GptEntry*)gpt->primary_entries; |
| 1138 int i, j; |
| 1139 |
| 1140 struct { |
| 1141 int duplicate; |
| 1142 struct { |
| 1143 uint64_t starting_lba; |
| 1144 uint64_t ending_lba; |
| 1145 uint32_t type_guid; |
| 1146 uint32_t unique_guid; |
| 1147 } entries[16]; /* enough for testing. */ |
| 1148 } cases[] = { |
| 1149 {0, {{100, 109, 1, 1}, |
| 1150 {110, 119, 2, 2}, |
| 1151 {120, 129, 3, 3}, |
| 1152 {130, 139, 4, 4}, |
| 1153 }}, |
| 1154 {0, {{100, 109, 1, 1}, |
| 1155 {110, 119, 1, 2}, |
| 1156 {120, 129, 2, 3}, |
| 1157 {130, 139, 2, 4}, |
| 1158 }}, |
| 1159 {1, {{100, 109, 1, 1}, |
| 1160 {110, 119, 2, 2}, |
| 1161 {120, 129, 3, 1}, |
| 1162 {130, 139, 4, 4}, |
| 1163 }}, |
| 1164 {1, {{100, 109, 1, 1}, |
| 1165 {110, 119, 1, 2}, |
| 1166 {120, 129, 2, 3}, |
| 1167 {130, 139, 2, 2}, |
| 1168 }}, |
| 1169 }; |
| 1170 |
| 1171 for (i = 0; i < ARRAY_SIZE(cases); ++i) { |
| 1172 BuildTestGptData(gpt); |
| 1173 ZeroEntries(gpt); |
| 1174 for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { |
| 1175 if (!cases[i].entries[j].starting_lba) |
| 1176 break; |
| 1177 |
| 1178 e[j].starting_lba = cases[i].entries[j].starting_lba; |
| 1179 e[j].ending_lba = cases[i].entries[j].ending_lba; |
| 1180 SetGuid(&e[j].type, cases[i].entries[j].type_guid); |
| 1181 SetGuid(&e[j].unique, cases[i].entries[j].unique_guid); |
| 1182 } |
| 1183 RefreshCrc32(gpt); |
| 1184 |
| 1185 EXPECT(cases[i].duplicate == CheckEntries(e, h)); |
| 1186 } |
| 1187 return TEST_OK; |
| 1188 } |
| 1189 |
| 1190 |
| 1191 |
| 1095 /* disable MSVC warnings on unused arguments */ | 1192 /* disable MSVC warnings on unused arguments */ |
| 1096 __pragma(warning (disable: 4100)) | 1193 __pragma(warning (disable: 4100)) |
| 1097 | 1194 |
| 1098 int main(int argc, char *argv[]) { | 1195 int main(int argc, char *argv[]) { |
| 1099 int i; | 1196 int i; |
| 1100 int error_count = 0; | 1197 int error_count = 0; |
| 1101 struct { | 1198 struct { |
| 1102 char *name; | 1199 char *name; |
| 1103 test_func fp; | 1200 test_func fp; |
| 1104 int retval; | 1201 int retval; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1121 { TEST_CASE(OverlappedPartitionTest), }, | 1218 { TEST_CASE(OverlappedPartitionTest), }, |
| 1122 { TEST_CASE(SanityCheckTest), }, | 1219 { TEST_CASE(SanityCheckTest), }, |
| 1123 { TEST_CASE(NoValidKernelEntryTest), }, | 1220 { TEST_CASE(NoValidKernelEntryTest), }, |
| 1124 { TEST_CASE(EntryAttributeGetSetTest), }, | 1221 { TEST_CASE(EntryAttributeGetSetTest), }, |
| 1125 { TEST_CASE(EntryTypeTest), }, | 1222 { TEST_CASE(EntryTypeTest), }, |
| 1126 { TEST_CASE(GetNextNormalTest), }, | 1223 { TEST_CASE(GetNextNormalTest), }, |
| 1127 { TEST_CASE(GetNextPrioTest), }, | 1224 { TEST_CASE(GetNextPrioTest), }, |
| 1128 { TEST_CASE(GetNextTriesTest), }, | 1225 { TEST_CASE(GetNextTriesTest), }, |
| 1129 { TEST_CASE(GptUpdateTest), }, | 1226 { TEST_CASE(GptUpdateTest), }, |
| 1130 { TEST_CASE(UpdateInvalidKernelTypeTest), }, | 1227 { TEST_CASE(UpdateInvalidKernelTypeTest), }, |
| 1228 { TEST_CASE(DuplicateUniqueGuidTest), }, |
| 1131 { TEST_CASE(TestCrc32TestVectors), }, | 1229 { TEST_CASE(TestCrc32TestVectors), }, |
| 1132 }; | 1230 }; |
| 1133 | 1231 |
| 1134 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { | 1232 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { |
| 1135 printf("Running %s() ...\n", test_cases[i].name); | 1233 printf("Running %s() ...\n", test_cases[i].name); |
| 1136 test_cases[i].retval = test_cases[i].fp(); | 1234 test_cases[i].retval = test_cases[i].fp(); |
| 1137 if (test_cases[i].retval) { | 1235 if (test_cases[i].retval) { |
| 1138 printf(COL_RED "[ERROR]\n\n" COL_STOP); | 1236 printf(COL_RED "[ERROR]\n\n" COL_STOP); |
| 1139 ++error_count; | 1237 ++error_count; |
| 1140 } else { | 1238 } else { |
| 1141 printf(COL_GREEN "[PASS]\n\n" COL_STOP); | 1239 printf(COL_GREEN "[PASS]\n\n" COL_STOP); |
| 1142 } | 1240 } |
| 1143 } | 1241 } |
| 1144 | 1242 |
| 1145 if (error_count) { | 1243 if (error_count) { |
| 1146 printf("\n--------------------------------------------------\n"); | 1244 printf("\n--------------------------------------------------\n"); |
| 1147 printf(COL_RED "The following %d test cases are failed:\n" COL_STOP, | 1245 printf(COL_RED "The following %d test cases are failed:\n" COL_STOP, |
| 1148 error_count); | 1246 error_count); |
| 1149 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { | 1247 for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i) { |
| 1150 if (test_cases[i].retval) | 1248 if (test_cases[i].retval) |
| 1151 printf(" %s()\n", test_cases[i].name); | 1249 printf(" %s()\n", test_cases[i].name); |
| 1152 } | 1250 } |
| 1153 } | 1251 } |
| 1154 | 1252 |
| 1155 return (error_count) ? 1 : 0; | 1253 return (error_count) ? 1 : 0; |
| 1156 } | 1254 } |
| OLD | NEW |