diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/Manifest b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/Manifest
index e69bf3b0ad..9adaa7a4b2 100644
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/Manifest
+++ b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/Manifest
@@ -1,8 +1,5 @@
DIST dejavu-sans-ttf-2.37.zip 417746 BLAKE2B c8904f3cd5a49370a7dc10e456684c88aeae998a99090bf4d0a5baa4f36cc8fb8f70586cf6d610a5ffeee97261d28c80f55bbe9dcfc3ed796d5c2d60e79adb58 SHA512 ede5899daa1984c5aa8cacb1c850eb53f189dddef3d9bb78bf9774d8976b7c0d6eb0bcf86237cd7d11f5b36cf5b5058d42cd94d3bd76f2bd0931c7ceb1271fae
-DIST grub-2.06-backports-r2.tar.xz 40416 BLAKE2B d9b4a8274a24aa35023eef7450bc4311045d0872250b1d11b1714b9daa32f7862fe1444b5b86db8b885a9f7b3af2459a5b2f87f0beaf4326a982fd96ec51d602 SHA512 99cf40b3d3d10cf6ba928ccc571c3a8baab217f650267fa7de4ba4ce807a895ff9414156647cc4dcb34bfbe48747a0c486bf60fee1c188a2dc89f26c2db3840f
+DIST grub-2.06-backports-r3.tar.xz 47612 BLAKE2B 235610e826c7a76d05872fb51e74564fb3861590f95377d5dcb9a5a4b0f5037d0b71c9f334bfe0bbe399f65036088d808f7af8e43090007ab7394002d05f7b4a SHA512 561f031dca2cdc13fc1b3f3cfdbdccd7decd67ef18ddcc588327f141b026eadcda5d64d729929859cad54959b3855ff86c1f62e3ff1d8ae5f6f5ac5761fa6ba4
DIST grub-2.06.tar.xz 6581924 BLAKE2B 2a40b9b03d7bb3b9e7b1309ab274d686f01b3c42e7035ebc6e5a0e59a59c3b7362ba518341664b314cb0dbc8222bb10ea05ce09f08ce9d58a293207cb909e417 SHA512 4f11c648f3078567e53fc0c74d5026fdc6da4be27d188975e79d9a4df817ade0fe5ad2ddd694238a07edc45adfa02943d83c57767dd51548102b375e529e8efe
DIST grub-2.06.tar.xz.sig 566 BLAKE2B 2ff18fb40d9cce36cac110ba9996f88236dbaa261d19e777a6d23a0e9754a9fc8bc45a01896f4838c88bb44edff0172a97611202cb3ffd5653a3cbdfc102ae16 SHA512 797683dafade76b5981bd02f079d7dcecb36f5d07eca652181fd69f3df821931f84cc0d8771bfb80506ef41fbd96edfb202b6698af1fec3c8228dd320a05fa84
-DIST grub-2.12~rc1.tar.xz 6589460 BLAKE2B edfad62a01970026ca4ad088056da6225ef1319a08e8a95418b24cc8102be7fe45bb1412797aab13f8c1f4f690cf2fa9e5b4725f6769013ce76aa81c43952557 SHA512 6f1fbce004b6dccf58e203bf6a6eeb771bac5ecc54b503265e56a97e9adce0221677bb3e64328144ec921f327a099f0345e7a9952be41cd8808f7635cded52cb
-DIST grub-2.12~rc1.tar.xz.sig 566 BLAKE2B 4b0563623498d06f512d29d9a84a4f8386e7d5adf257d0f2ea8f3301e5112b7ad669741d78519dfa35d16e7f1695b0c74740d679f07e41774ecc8910c3f6bc5c SHA512 b8b3c818679b50810e2d9e597a01c34b05fbc1218a88bdf35aaec798ce29b376c7aa696c50233d416306a480f6ee602dfcbe7eaf481c503f3c203a7b8e8db7a2
DIST unifont-12.1.02.pcf.gz 1335424 BLAKE2B 97080312468e3f3c8aa6f49cef08f5622641e8c9c035f3ede1e09d8d98de4e78d3b23c8aba2e8070eb46cbebd2d55e8568e467d7f15f35aa8fc8db792b7e5f14 SHA512 b280b2db7cf5f480b0668c331130dede2c0cc87d5e02e44566b77787113d0f6604d0105522858288f2ac6b8e77df7a2d9878725013a6c778dc5bfb183156e2f0
-DIST unifont-15.0.06.pcf.gz 1358322 BLAKE2B 81811e3de390ca35d1a2dc1f1dee73464e97f44907ba522c218ba9c5e39ca3c9d767552780a257a97c156eb623c17786d9c0d2b67786d61df5ca33a1e10db7ca SHA512 0a28a406629c604f5cbf51f501528239a7ed50d19f93ea505bc5bdc72639e4b926b03f4b8782a5733041f7cdb4aebb9948ac7cfd5a8ad9a0fe309944e595517b
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/README.md b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/README.md
deleted file mode 100644
index c41786a2bc..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/README.md
+++ /dev/null
@@ -1,460 +0,0 @@
-Flatcar uses a patched version of the GRUB, which implements the functionality to
-read the [Flatcar Container Linux partition table](https://www.flatcar.org/docs/latest/reference/developer-guides/sdk-disk-partitions/#partition-table)
-
-## History
-
-CoreOS Container Linux maintained a fork of the [grub](https://github.com/coreos/grub) and then was referenced
-in the coreos-overlay. Any changes were made through [PRs](https://github.com/coreos/grub/pulls?q=is%3Apr+is%3Aclosed) to the grub repository.
-
-When Flatcar was born, a `grub` repo under the flatcar-linux org was created
-and referenced in the Flatcar's coreos-overlay. Except for a few, now many changes
-where brought into the system.
-
-The repo was maintained at 2.02 version. During the 2.06 migration, the philosophy
-to use a separate repo was scraped, and a single patch file was created. The patch
-files migrated only the essential commits, and dropped all the other commits, which
-were either half-baked, or redundant at the point of migration. The two patches are applied
-on top of the grub sources, and emerge is done.
-
-Given below are the list of commits that were referenced to create the two patches.
-
-## Summary of the patches
-
-The patch starts with adding a new implementation of reading the GPT instead
-of using the traditional module. It provides essential functionality to interact
-with GPT structures on disk, and checking/validating data integrity & GPT specification.
-
-The commits goes on to add the following modules gptprio, gptrepair, and search
-commands by label and partition.
-
-The `gptprio` command which provides a mechanism to prioritize and select the
-next bootable partition based on the GPT attributes and results in flexible
-partition booting. The `gptrepair` command implements the repair functions for
-GPT information on a specified device. Few other functions include searching
-devices by partition label or partition UUID.
-
-## Commits
-
-Below are the commits that are picked to create the two patches for the grub. One is
-descriptive, and other is comprehensive.
-
-
- (click to expand) The descriptive log for all the commits picked
-
-```
-commit f69a9e0fdcf63ac33906e2753e14152bab2fcd05
-Author: Michael Marineau
-Date: Sun Sep 28 21:26:21 2014 -0700
-
- gpt: start new GPT module
-
- This module is a new implementation for reading GUID Partition Tables
- which is much stricter than the existing part_gpt module and exports GPT
- data directly instead of the generic grub_partition structure. It will
- be the basis for modules that need to read/write/update GPT data.
-
- The current code does nothing more than read and verify the table.
-
-commit c26743a145c918958b862d580c4261735d1c1a6e
-Author: Michael Marineau
-Date: Sat Oct 18 15:39:13 2014 -0700
-
- gpt: rename misnamed header location fields
-
- The header location fields refer to 'this header' and 'alternate header'
- respectively, not 'primary header' and 'backup header'. The previous
- field names are backwards for the backup header.
-
-commit 94f04a532d2b0e2b81e47a92488ebb1613bda1a0
-Author: Michael Marineau
-Date: Sat Oct 18 16:46:17 2014 -0700
-
- gpt: record size of of the entries table
-
- The size of the entries table will be needed later when writing it back
- to disk. Restructure the entries reading code to flow a little better.
-
-commit 3d066264ac13198e45dc151b863a9aac4c095225
-Author: Michael Marineau
-Date: Sat Oct 18 18:18:17 2014 -0700
-
- gpt: consolidate crc32 computation code
-
- The gcrypt API is overly verbose, wrap it up in a helper function to
- keep this rather common operation easy to use.
-
-commit dab6fac705bdad7e6ec130b24085189bcb15a5c9
-Author: Michael Marineau
-Date: Sat Oct 18 18:21:07 2014 -0700
-
- gpt: add new repair function to sync up primary and backup tables.
-
-commit 5e1829d4141343617b5e13e84298d118eac15bdf
-Author: Michael Marineau
-Date: Sun Oct 19 14:21:29 2014 -0700
-
- gpt: add write function and gptrepair command
-
- The first hint of something practical, a command that can restore any of
- the GPT structures from the alternate location. New test case must run
- under QEMU because the loopback device used by the other unit tests does
- not support writing.
-
-commit 2cd009dffe98c19672394608661767e4c3c84764
-Author: Michael Marineau
-Date: Thu Oct 30 20:55:21 2014 -0700
-
- gpt: add a new generic GUID type
-
- In order to do anything with partition GUIDs they need to be stored in a
- proper structure like the partition type GUIDs. Additionally add an
- initializer macro to simplify defining both GUID types.
-
-commit 508b02fc8a1fe58413ec8938ed1a7b149b5855fe
-Author: Michael Marineau
-Date: Mon Nov 3 17:14:37 2014 -0800
-
- gpt: new gptprio.next command for selecting priority based partitions
-
- Basic usage would look something like this:
-
- gptprio.next -d usr_dev -u usr_uuid
- linuxefi ($usr_dev)/boot/vmlinuz mount.usr=PARTUUID=$usr_uuid
-
- After booting the system should set the 'successful' bit on the
- partition that was used.
-
-commit f8f6f790aa7448a35c2e3aae2d1a35d9d323a1b2
-Author: Michael Marineau
-Date: Sat Nov 15 13:27:13 2014 -0800
-
- gpt: split out checksum recomputation
-
- For basic data modifications the full repair function is overkill.
-
-commit d9bdbc10485a5c6f610569077631294683da4e34
-Author: Michael Marineau
-Date: Thu Nov 27 12:55:53 2014 -0800
-
- gpt: move gpt guid printing function to common library
-
-commit ffb13159f1e88d8c66954c3dfbeb027f943b3b1d
-Author: Michael Marineau
-Date: Thu Nov 27 14:54:27 2014 -0800
-
- gpt: switch partition names to a 16 bit type
-
- In UEFI/GPT strings are UTF-16 so use a uint16 to make dealing with the
- string practical.
-
-commit febf4666fbabc3ab4eaab32f4972b45b5c64c06d
-Author: Michael Marineau
-Date: Thu Nov 27 15:49:57 2014 -0800
-
- tests: add some partitions to the gpt unit test data
-
-commit 67475f53e0ac4a844f793296ba2e4af707d5b20e
-Author: Michael Marineau
-Date: Thu Nov 27 16:34:21 2014 -0800
-
- gpt: add search by partition label and uuid commands
-
- Builds on the existing filesystem search code. Only for GPT right now.
-
-commit d1270a2ba31cc3dd747d410a907f272ff03a6d68
-Author: Michael Marineau
-Date: Fri Jul 31 15:03:11 2015 -0700
-
- gpt: clean up little-endian crc32 computation
-
- - Remove problematic cast from *uint8_t to *uint32_t (alignment issue).
- - Remove dynamic allocation and associated error handling paths.
- - Match parameter ordering to existing grub_crypto_hash function.
-
-commit bacbed2c07f4b4e21c70310814a75fa9a1c3a155
-Author: Alex Crawford
-Date: Mon Aug 31 15:23:39 2015 -0700
-
- gpt: minor cleanup
-
-commit 1545295ad49d2aff2b75c6c0e7db58214351768e
-Author: Alex Crawford
-Date: Mon Aug 31 15:15:48 2015 -0700
-
- gpt: add search by disk uuid command
-
-commit 6d4ea47541db4e0a1eab81de8843a491973e6b40
-Author: Michael Marineau
-Date: Mon Jul 25 14:59:29 2016 -0700
-
- gpt: do not use disk sizes GRUB will reject as invalid later on
-
- GRUB assumes that no disk is ever larger than 1EiB and rejects
- reads/writes to such locations. Unfortunately this is not conveyed in
- the usual way with the special GRUB_DISK_SIZE_UNKNOWN value.
-
-commit 99959fa2fb8bfafadc1fa5aec773a8d605a1df4e
-Author: Michael Marineau
-Date: Wed Aug 10 18:26:03 2016 -0700
-
- gpt: add verbose debug logging
-
-commit f6b89ec3156a549999a13b3d15e9a67b4a9bf824
-Author: Michael Marineau
-Date: Wed Aug 10 18:26:03 2016 -0700
-
- gpt: improve validation of GPT headers
-
- Adds basic validation of all the disk locations in the headers, reducing
- the chance of corrupting weird locations on disk.
-
-commit fa18d3a292bdcd61012d549c61e25d557481a05e
-Author: Michael Marineau
-Date: Thu Aug 11 15:02:21 2016 -0700
-
- gpt: refuse to write to sector 0
-
-commit b1ef48849c8dc12756793567520dfd3654539a27
-Author: Michael Marineau
-Date: Sat Aug 20 17:42:12 2016 -0700
-
- gpt: properly detect and repair invalid tables
-
- GPT_BOTH_VALID is 4 bits so simple a boolean check is not sufficient.
- This broken condition allowed gptprio to trust bogus disk locations in
- headers that were marked invalid causing arbitrary disk corruption.
-
-commit 9af98c2bfd31a73b899268e67f01bca785681d52
-Author: Michael Marineau
-Date: Mon Aug 22 16:44:30 2016 -0700
-
- gptrepair_test: fix typo in cleanup trap
-
-commit d457364d1d811ad262519cf6dde3d098caf7c778
-Author: Michael Marineau
-Date: Mon Aug 22 16:45:10 2016 -0700
-
- gptprio_test: check GPT is repaired when appropriate
-
-commit 3a3e45823dd677b428ceb40d8963676aff63f8d2
-Author: Michael Marineau
-Date: Mon Aug 22 18:30:56 2016 -0700
-
- fix checking alternate_lba
-
-commit 72b178950d313d567dfdf11f403199370d81a9f3
-Author: Michael Marineau
-Date: Wed Aug 24 16:14:20 2016 -0700
-
- gpt: fix partition table indexing and validation
-
- Portions of the code attempted to handle the fact that GPT entries on
- disk may be larger than the currently defined struct while others
- assumed the data could be indexed by the struct size directly. This
- never came up because no utility uses a size larger than 128 bytes but
- for the sake of safety we need to do this by the spec.
-
-commit 1d358a2061f40ad89567754f4787d0c76001d48a
-Author: Michael Marineau
-Date: Tue Aug 23 13:09:14 2016 -0700
-
- gpt: prefer disk size from header over firmware
-
- The firmware and the OS may disagree on the disk configuration and size.
- Although such a setup should be avoided users are unlikely to know about
- the problem, assuming everything behaves like the OS. Tolerate this as
- best we can and trust the reported on-disk location over the firmware
- when looking for the backup GPT. If the location is inaccessible report
- the error as best we can and move on.
-
-commit 2ed905dc03c757c92064486b380f59166cc704e8
-Author: Vito Caputo
-Date: Thu Aug 25 17:21:18 2016 -0700
-
- gpt: add helper for picking a valid header
-
- Eliminate some repetition in primary vs. backup header acquisition.
-
-commit 4af1d7a8b7d0cefa41a1ea4df050b161ea6cdf50
-Author: Michael Marineau
-Date: Tue Sep 20 13:06:05 2016 -0700
-
- gptrepair: fix status checking
-
- None of these status bit checks were correct. Fix and simplify.
-
-commit a794435ae9f5b1a2e0281d36b10545c6e643fd8d
-Author: Michael Marineau
-Date: Tue Sep 20 12:43:01 2016 -0700
-
- gpt: use inline functions for checking status bits
-
- This should prevent bugs like 6078f836 and 4268f3da.
-
-commit 38cc185319b74d7d33ad380fe4d519fb0b0c85a6
-Author: Michael Marineau
-Date: Tue Sep 20 13:40:11 2016 -0700
-
- gpt: allow repair function to noop
-
- Simplifies usage a little.
-
-commit 2aeadda52929bb47089ef99c2bad0f928eadeffa
-Author: Michael Marineau
-Date: Wed Sep 21 13:22:06 2016 -0700
-
- gpt: do not use an enum for status bit values
-
-commit 34652e500d64dc747ca17091b4490f9adf93ff82
-Author: Michael Marineau
-Date: Wed Sep 21 13:44:11 2016 -0700
-
- gpt: check header and entries status bits together
-
- Use the new status function which checks *_HEADER_VALID and
- *_ENTRIES_VALID bits together. It doesn't make sense for the header and
- entries bits to mismatch so don't allow for it.
-
-commit 753dd9201306e8cd7092a1231ceb194524397b04
-Author: Michael Marineau
-Date: Wed Sep 21 13:52:52 2016 -0700
-
- gpt: be more careful about relocating backup header
-
- The header was being relocated without checking the new location is
- actually safe. If the BIOS thinks the disk is smaller than the OS then
- repair may relocate the header into allocated space, failing the final
- validation check. So only move it if the disk has grown.
-
- Additionally, if the backup is valid then we can assume its current
- location is good enough and leave it as-is.
-
-commit f1f618740d1379000b04130a632f4d53bc2392b8
-Author: Michael Marineau
-Date: Wed Sep 21 14:33:48 2016 -0700
-
- gpt: selectively update fields during repair
-
- Just a little cleanup/refactor to skip touching data we don't need to.
-
-commit 285368e3753b1dbd631c1f5a4a127b7321a6941f
-Author: Michael Marineau
-Date: Wed Sep 21 14:55:19 2016 -0700
-
- gpt: always revalidate when recomputing checksums
-
- This ensures all code modifying GPT data include the same sanity check
- that repair does. If revalidation fails the status flags are left in the
- appropriate state.
-
-commit f19f5cc49dc00752f6b267c2d580a25c31697afb
-Author: Michael Marineau
-Date: Wed Sep 21 15:01:09 2016 -0700
-
- gpt: include backup-in-sync check in revalidation
-
-commit 7b25acebc343895adf942975bba5a52ef3408437
-Author: Michael Marineau
-Date: Wed Sep 21 15:29:55 2016 -0700
-
- gpt: read entries table at the same time as the header
-
- I personally think this reads easier. Also has the side effect of
- directly comparing the primary and backup tables instead of presuming
- they are equal if the crc32 matches.
-
-commit edd01f055a8a8f922491ba7077bf26fcaf015516
-Author: Michael Marineau
-Date: Wed Sep 21 16:02:53 2016 -0700
-
- gpt: report all revalidation errors
-
- Before returning an error that the primary or backup GPT is invalid push
- the existing error onto the stack so the user will be told what is bad.
-
-commit 176fe49cf03ffdd72b8bd174a149032c3867ddde
-Author: Michael Marineau
-Date: Thu Sep 22 10:00:27 2016 -0700
-
- gpt: rename and update documentation for grub_gpt_update
-
- The function now does more than just recompute checksums so give it a
- more general name to reflect that.
-
-commit eb28d32081be2d224874c430345e7ef97bfbba07
-Author: Michael Marineau
-Date: Thu Sep 22 11:18:42 2016 -0700
-
- gpt: write backup GPT first, skip if inaccessible.
-
- Writing the primary GPT before the backup may lead to a confusing
- situation: booting a freshly updated system could consistently fail and
- next boot will fall back to the old system if writing the primary works
- but writing the backup fails. If the backup is written first and fails
- the primary is left in the old state so the next boot will re-try and
- possibly fail in the exact same way. Making that repeatable should make
- it easier for users to identify the error.
-
- Additionally if the firmware and OS disagree on the disk size, making
- the backup inaccessible to GRUB, then just skip writing the backup.
- When this happens the automatic call to `coreos-setgoodroot` after boot
- will take care of repairing the backup.
-
-commit 03b547c21ec3475980a54b71e909034ed5ed5254
-Author: Matthew Garrett
-Date: Thu May 28 11:15:30 2015 -0700
-
- Add verity hash passthrough
-
- Read the verity hash from the kernel binary and pass it to the running
- system via the kernel command line
-```
-
-
-
- (click to expand) Comprehensive log of the commits
-
-```
-f69a9e0fd gpt: start new GPT module
-c26743a14 gpt: rename misnamed header location fields
-94f04a532 gpt: record size of of the entries table
-3d066264a gpt: consolidate crc32 computation code
-dab6fac70 gpt: add new repair function to sync up primary and backup tables.
-5e1829d41 gpt: add write function and gptrepair command
-2cd009dff gpt: add a new generic GUID type
-508b02fc8 gpt: new gptprio.next command for selecting priority based partitions
-f8f6f790a gpt: split out checksum recomputation
-d9bdbc104 gpt: move gpt guid printing function to common library
-ffb13159f gpt: switch partition names to a 16 bit type
-febf4666f tests: add some partitions to the gpt unit test data
-67475f53e gpt: add search by partition label and uuid commands
-d1270a2ba gpt: clean up little-endian crc32 computation
-bacbed2c0 gpt: minor cleanup
-1545295ad gpt: add search by disk uuid command
-6d4ea4754 gpt: do not use disk sizes GRUB will reject as invalid later on
-99959fa2f gpt: add verbose debug logging
-f6b89ec31 gpt: improve validation of GPT headers
-fa18d3a29 gpt: refuse to write to sector 0
-b1ef48849 gpt: properly detect and repair invalid tables
-9af98c2bf gptrepair_test: fix typo in cleanup trap
-d457364d1 gptprio_test: check GPT is repaired when appropriate
-3a3e45823 fix checking alternate_lba
-72b178950 gpt: fix partition table indexing and validation
-1d358a206 gpt: prefer disk size from header over firmware
-2ed905dc0 gpt: add helper for picking a valid header
-4af1d7a8b gptrepair: fix status checking
-a794435ae gpt: use inline functions for checking status bits
-38cc18531 gpt: allow repair function to noop
-2aeadda52 gpt: do not use an enum for status bit values
-34652e500 gpt: check header and entries status bits together
-753dd9201 gpt: be more careful about relocating backup header
-f1f618740 gpt: selectively update fields during repair
-285368e37 gpt: always revalidate when recomputing checksums
-f19f5cc49 gpt: include backup-in-sync check in revalidation
-7b25acebc gpt: read entries table at the same time as the header
-edd01f055 gpt: report all revalidation errors
-176fe49cf gpt: rename and update documentation for grub_gpt_update
-eb28d3208 gpt: write backup GPT first, skip if inaccessible.
-03b547c21 Add verity hash passthrough
-```
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-gpt-partition-scheme.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-gpt-partition-scheme.patch
deleted file mode 100644
index cef57e856a..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-gpt-partition-scheme.patch
+++ /dev/null
@@ -1,2792 +0,0 @@
-From 026cab86883e256607f6df30375bfda4468ae71e Mon Sep 17 00:00:00 2001
-From: Sayan Chowdhury
-Date: Thu, 24 Aug 2023 00:00:00 +0530
-Subject: [PATCH] gpt: Add patch to implement the custom GPT module
-
-This module is a new implementation for reading GUID Partition Tables
-which is much stricter than the existing part_gpt module and exports GPT
-data directly instead of the generic grub_partition structure. It will
-be the basis for modules that need to read/write/update GPT data.
-
-This patch also includes the supporting functions like gptprio,
-gptrepair, search commands.
-
-The patch is prepared using the coreos/grub PRs, picking the only
-required ones, and dropping the others. The README.md file in the
-coreos-overlay/sys-boot/grub/ contains more contexual information
-along with the commits used to create the patch.
-
-Authored-by: Michael Marineau
-Signed-off-by: Sayan Chowdhury
----
- Makefile.util.def | 30 +
- grub-core/Makefile.core.def | 25 +
- grub-core/commands/gptprio.c | 223 +++++++
- grub-core/commands/gptrepair.c | 110 ++++
- grub-core/commands/search.c | 49 ++
- grub-core/commands/search_part_label.c | 5 +
- grub-core/commands/search_part_uuid.c | 5 +
- grub-core/commands/search_wrap.c | 12 +
- grub-core/lib/gpt.c | 757 +++++++++++++++++++++++
- include/grub/gpt_partition.h | 211 ++++++-
- include/grub/search.h | 4 +
- tests/gpt_unit_test.c | 807 +++++++++++++++++++++++++
- tests/gptprio_test.in | 207 +++++++
- tests/gptrepair_test.in | 102 ++++
- 14 files changed, 2530 insertions(+), 17 deletions(-)
- create mode 100644 grub-core/commands/gptprio.c
- create mode 100644 grub-core/commands/gptrepair.c
- create mode 100644 grub-core/commands/search_part_label.c
- create mode 100644 grub-core/commands/search_part_uuid.c
- create mode 100644 grub-core/lib/gpt.c
- create mode 100644 tests/gpt_unit_test.c
- create mode 100644 tests/gptprio_test.in
- create mode 100644 tests/gptrepair_test.in
-
-diff --git a/Makefile.util.def b/Makefile.util.def
-index f8b356cc1..07df521ec 100644
---- a/Makefile.util.def
-+++ b/Makefile.util.def
-@@ -1211,6 +1211,18 @@ script = {
- common = tests/syslinux_test.in;
- };
-
-+script = {
-+ testcase;
-+ name = gptrepair_test;
-+ common = tests/gptrepair_test.in;
-+};
-+
-+script = {
-+ testcase;
-+ name = gptprio_test;
-+ common = tests/gptprio_test.in;
-+};
-+
- program = {
- testcase;
- name = example_unit_test;
-@@ -1288,6 +1300,24 @@ program = {
- ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
- };
-
-+program = {
-+ testcase;
-+ name = gpt_unit_test;
-+ common = tests/gpt_unit_test.c;
-+ common = tests/lib/unit_test.c;
-+ common = grub-core/commands/search_part_label.c;
-+ common = grub-core/commands/search_part_uuid.c;
-+ common = grub-core/disk/host.c;
-+ common = grub-core/kern/emu/hostfs.c;
-+ common = grub-core/lib/gpt.c;
-+ common = grub-core/tests/lib/test.c;
-+ ldadd = libgrubmods.a;
-+ ldadd = libgrubgcry.a;
-+ ldadd = libgrubkern.a;
-+ ldadd = grub-core/gnulib/libgnu.a;
-+ ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
-+};
-+
- program = {
- name = grub-menulst2cfg;
- mansection = 1;
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index 8022e1c0a..e9baa2144 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -897,6 +897,21 @@ module = {
- common = commands/gptsync.c;
- };
-
-+module = {
-+ name = gptrepair;
-+ common = commands/gptrepair.c;
-+};
-+
-+module = {
-+ name = gptprio;
-+ common = commands/gptprio.c;
-+};
-+
-+module = {
-+ name = gpt;
-+ common = lib/gpt.c;
-+};
-+
- module = {
- name = halt;
- nopc = commands/halt.c;
-@@ -1073,6 +1088,16 @@ module = {
- common = commands/search_label.c;
- };
-
-+module = {
-+ name = search_part_uuid;
-+ common = commands/search_part_uuid.c;
-+};
-+
-+module = {
-+ name = search_part_label;
-+ common = commands/search_part_label.c;
-+};
-+
- module = {
- name = setpci;
- common = commands/setpci.c;
-diff --git a/grub-core/commands/gptprio.c b/grub-core/commands/gptprio.c
-new file mode 100644
-index 000000000..4a24fa62d
---- /dev/null
-+++ b/grub-core/commands/gptprio.c
-@@ -0,0 +1,223 @@
-+/* gptprio.c - manage priority based partition selection. */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2009 Free Software Foundation, Inc.
-+ * Copyright (C) 2014 CoreOS, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+GRUB_MOD_LICENSE ("GPLv3+");
-+
-+static const struct grub_arg_option options_next[] = {
-+ {"set-device", 'd', 0,
-+ N_("Set a variable to the name of selected partition."),
-+ N_("VARNAME"), ARG_TYPE_STRING},
-+ {"set-uuid", 'u', 0,
-+ N_("Set a variable to the GPT UUID of selected partition."),
-+ N_("VARNAME"), ARG_TYPE_STRING},
-+ {0, 0, 0, 0, 0, 0}
-+};
-+
-+enum options_next
-+{
-+ NEXT_SET_DEVICE,
-+ NEXT_SET_UUID,
-+};
-+
-+static unsigned int
-+grub_gptprio_priority (struct grub_gpt_partentry *entry)
-+{
-+ return (unsigned int) grub_gpt_entry_attribute
-+ (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY, 4);
-+}
-+
-+static unsigned int
-+grub_gptprio_tries_left (struct grub_gpt_partentry *entry)
-+{
-+ return (unsigned int) grub_gpt_entry_attribute
-+ (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
-+}
-+
-+static void
-+grub_gptprio_set_tries_left (struct grub_gpt_partentry *entry,
-+ unsigned int tries_left)
-+{
-+ grub_gpt_entry_set_attribute
-+ (entry, tries_left, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
-+}
-+
-+static unsigned int
-+grub_gptprio_successful (struct grub_gpt_partentry *entry)
-+{
-+ return (unsigned int) grub_gpt_entry_attribute
-+ (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL, 1);
-+}
-+
-+static grub_err_t
-+grub_find_next (const char *disk_name,
-+ const grub_gpt_part_type_t *part_type,
-+ char **part_name, char **part_guid)
-+{
-+ struct grub_gpt_partentry *part, *part_found = NULL;
-+ grub_device_t dev = NULL;
-+ grub_gpt_t gpt = NULL;
-+ grub_uint32_t i, part_index;
-+
-+ dev = grub_device_open (disk_name);
-+ if (!dev)
-+ goto done;
-+
-+ gpt = grub_gpt_read (dev->disk);
-+ if (!gpt)
-+ goto done;
-+
-+ if (grub_gpt_repair (dev->disk, gpt))
-+ goto done;
-+
-+ for (i = 0; (part = grub_gpt_get_partentry (gpt, i)) != NULL; i++)
-+ {
-+ if (grub_memcmp (part_type, &part->type, sizeof (*part_type)) == 0)
-+ {
-+ unsigned int priority, tries_left, successful, old_priority = 0;
-+
-+ priority = grub_gptprio_priority (part);
-+ tries_left = grub_gptprio_tries_left (part);
-+ successful = grub_gptprio_successful (part);
-+
-+ if (part_found)
-+ old_priority = grub_gptprio_priority (part_found);
-+
-+ if ((tries_left || successful) && priority > old_priority)
-+ {
-+ part_index = i;
-+ part_found = part;
-+ }
-+ }
-+ }
-+
-+ if (!part_found)
-+ {
-+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such partition"));
-+ goto done;
-+ }
-+
-+ if (grub_gptprio_tries_left (part_found))
-+ {
-+ unsigned int tries_left = grub_gptprio_tries_left (part_found);
-+
-+ grub_gptprio_set_tries_left (part_found, tries_left - 1);
-+
-+ if (grub_gpt_update (gpt))
-+ goto done;
-+
-+ if (grub_gpt_write (dev->disk, gpt))
-+ goto done;
-+ }
-+
-+ *part_name = grub_xasprintf ("%s,gpt%u", disk_name, part_index + 1);
-+ if (!*part_name)
-+ goto done;
-+
-+ *part_guid = grub_gpt_guid_to_str (&part_found->guid);
-+ if (!*part_guid)
-+ goto done;
-+
-+ grub_errno = GRUB_ERR_NONE;
-+
-+done:
-+ grub_gpt_free (gpt);
-+
-+ if (dev)
-+ grub_device_close (dev);
-+
-+ return grub_errno;
-+}
-+
-+
-+
-+static grub_err_t
-+grub_cmd_next (grub_extcmd_context_t ctxt, int argc, char **args)
-+{
-+ struct grub_arg_list *state = ctxt->state;
-+ char *p, *root = NULL, *part_name = NULL, *part_guid = NULL;
-+
-+ /* TODO: Add a uuid parser and a command line flag for providing type. */
-+ grub_gpt_part_type_t part_type = GRUB_GPT_PARTITION_TYPE_USR_X86_64;
-+
-+ if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set)
-+ {
-+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("-d and -u are required"));
-+ goto done;
-+ }
-+
-+ if (argc == 0)
-+ root = grub_strdup (grub_env_get ("root"));
-+ else if (argc == 1)
-+ root = grub_strdup (args[0]);
-+ else
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
-+ goto done;
-+ }
-+
-+ if (!root)
-+ goto done;
-+
-+ /* To make using $root practical strip off the partition name. */
-+ p = grub_strchr (root, ',');
-+ if (p)
-+ *p = '\0';
-+
-+ if (grub_find_next (root, &part_type, &part_name, &part_guid))
-+ goto done;
-+
-+ if (grub_env_set (state[NEXT_SET_DEVICE].arg, part_name))
-+ goto done;
-+
-+ if (grub_env_set (state[NEXT_SET_UUID].arg, part_guid))
-+ goto done;
-+
-+ grub_errno = GRUB_ERR_NONE;
-+
-+done:
-+ grub_free (root);
-+ grub_free (part_name);
-+ grub_free (part_guid);
-+
-+ return grub_errno;
-+}
-+
-+static grub_extcmd_t cmd_next;
-+
-+GRUB_MOD_INIT(gptprio)
-+{
-+ cmd_next = grub_register_extcmd ("gptprio.next", grub_cmd_next, 0,
-+ N_("-d VARNAME -u VARNAME [DEVICE]"),
-+ N_("Select next partition to boot."),
-+ options_next);
-+}
-+
-+GRUB_MOD_FINI(gptprio)
-+{
-+ grub_unregister_extcmd (cmd_next);
-+}
-diff --git a/grub-core/commands/gptrepair.c b/grub-core/commands/gptrepair.c
-new file mode 100644
-index 000000000..c17c7346c
---- /dev/null
-+++ b/grub-core/commands/gptrepair.c
-@@ -0,0 +1,110 @@
-+/* gptrepair.c - verify and restore GPT info from alternate location. */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2009 Free Software Foundation, Inc.
-+ * Copyright (C) 2014 CoreOS, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+GRUB_MOD_LICENSE ("GPLv3+");
-+
-+static char *
-+trim_dev_name (char *name)
-+{
-+ grub_size_t len = grub_strlen (name);
-+ if (len && name[0] == '(' && name[len - 1] == ')')
-+ {
-+ name[len - 1] = '\0';
-+ name = name + 1;
-+ }
-+ return name;
-+}
-+
-+static grub_err_t
-+grub_cmd_gptrepair (grub_command_t cmd __attribute__ ((unused)),
-+ int argc, char **args)
-+{
-+ grub_device_t dev = NULL;
-+ grub_gpt_t gpt = NULL;
-+ char *dev_name;
-+
-+ if (argc != 1 || !grub_strlen(args[0]))
-+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-+
-+ dev_name = trim_dev_name (args[0]);
-+ dev = grub_device_open (dev_name);
-+ if (!dev)
-+ goto done;
-+
-+ if (!dev->disk)
-+ {
-+ grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
-+ goto done;
-+ }
-+
-+ gpt = grub_gpt_read (dev->disk);
-+ if (!gpt)
-+ goto done;
-+
-+ if (grub_gpt_both_valid (gpt))
-+ {
-+ grub_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name);
-+ goto done;
-+ }
-+
-+ if (!grub_gpt_primary_valid (gpt))
-+ grub_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name);
-+
-+ if (!grub_gpt_backup_valid (gpt))
-+ grub_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name);
-+
-+ if (grub_gpt_repair (dev->disk, gpt))
-+ goto done;
-+
-+ if (grub_gpt_write (dev->disk, gpt))
-+ goto done;
-+
-+ grub_printf_ (N_("Repaired GPT on %s\n"), dev_name);
-+
-+done:
-+ if (gpt)
-+ grub_gpt_free (gpt);
-+
-+ if (dev)
-+ grub_device_close (dev);
-+
-+ return grub_errno;
-+}
-+
-+static grub_command_t cmd;
-+
-+GRUB_MOD_INIT(gptrepair)
-+{
-+ cmd = grub_register_command ("gptrepair", grub_cmd_gptrepair,
-+ N_("DEVICE"),
-+ N_("Verify and repair GPT on drive DEVICE."));
-+}
-+
-+GRUB_MOD_FINI(gptrepair)
-+{
-+ grub_unregister_command (cmd);
-+}
-diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
-index ed090b3af..4ad72c5b4 100644
---- a/grub-core/commands/search.c
-+++ b/grub-core/commands/search.c
-@@ -30,6 +30,9 @@
- #include
- #include
- #include
-+#if defined(DO_SEARCH_PART_UUID) || defined(DO_SEARCH_PART_LABEL)
-+#include
-+#endif
-
- GRUB_MOD_LICENSE ("GPLv3+");
-
-@@ -90,6 +93,44 @@ iterate_device (const char *name, void *data)
- }
- grub_free (buf);
- }
-+#elif defined(DO_SEARCH_PART_UUID)
-+ {
-+ grub_device_t dev;
-+ char *quid;
-+
-+ dev = grub_device_open (name);
-+ if (dev)
-+ {
-+ if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
-+ {
-+ if (grub_strcasecmp (quid, ctx->key) == 0)
-+ found = 1;
-+
-+ grub_free (quid);
-+ }
-+
-+ grub_device_close (dev);
-+ }
-+ }
-+#elif defined(DO_SEARCH_PART_LABEL)
-+ {
-+ grub_device_t dev;
-+ char *quid;
-+
-+ dev = grub_device_open (name);
-+ if (dev)
-+ {
-+ if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
-+ {
-+ if (grub_strcmp (quid, ctx->key) == 0)
-+ found = 1;
-+
-+ grub_free (quid);
-+ }
-+
-+ grub_device_close (dev);
-+ }
-+ }
- #else
- {
- /* SEARCH_FS_UUID or SEARCH_LABEL */
-@@ -313,6 +354,10 @@ static grub_command_t cmd;
-
- #ifdef DO_SEARCH_FILE
- GRUB_MOD_INIT(search_fs_file)
-+#elif defined(DO_SEARCH_PART_UUID)
-+GRUB_MOD_INIT(search_part_uuid)
-+#elif defined(DO_SEARCH_PART_LABEL)
-+GRUB_MOD_INIT(search_part_label)
- #elif defined (DO_SEARCH_FS_UUID)
- GRUB_MOD_INIT(search_fs_uuid)
- #else
-@@ -327,6 +372,10 @@ GRUB_MOD_INIT(search_label)
-
- #ifdef DO_SEARCH_FILE
- GRUB_MOD_FINI(search_fs_file)
-+#elif defined(DO_SEARCH_PART_UUID)
-+GRUB_MOD_FINI(search_part_uuid)
-+#elif defined(DO_SEARCH_PART_LABEL)
-+GRUB_MOD_FINI(search_part_label)
- #elif defined (DO_SEARCH_FS_UUID)
- GRUB_MOD_FINI(search_fs_uuid)
- #else
-diff --git a/grub-core/commands/search_part_label.c b/grub-core/commands/search_part_label.c
-new file mode 100644
-index 000000000..ca906cbd9
---- /dev/null
-+++ b/grub-core/commands/search_part_label.c
-@@ -0,0 +1,5 @@
-+#define DO_SEARCH_PART_LABEL 1
-+#define FUNC_NAME grub_search_part_label
-+#define COMMAND_NAME "search.part_label"
-+#define HELP_MESSAGE N_("Search devices by partition label. If VARIABLE is specified, the first device found is set to a variable.")
-+#include "search.c"
-diff --git a/grub-core/commands/search_part_uuid.c b/grub-core/commands/search_part_uuid.c
-new file mode 100644
-index 000000000..2d1d3d0d7
---- /dev/null
-+++ b/grub-core/commands/search_part_uuid.c
-@@ -0,0 +1,5 @@
-+#define DO_SEARCH_PART_UUID 1
-+#define FUNC_NAME grub_search_part_uuid
-+#define COMMAND_NAME "search.part_uuid"
-+#define HELP_MESSAGE N_("Search devices by partition UUID. If VARIABLE is specified, the first device found is set to a variable.")
-+#include "search.c"
-diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
-index 47fc8eb99..d357454a9 100644
---- a/grub-core/commands/search_wrap.c
-+++ b/grub-core/commands/search_wrap.c
-@@ -36,6 +36,10 @@ static const struct grub_arg_option options[] =
- 0, 0},
- {"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
- 0, 0},
-+ {"part-label", 'L', 0, N_("Search devices by a partition label."),
-+ 0, 0},
-+ {"part-uuid", 'U', 0, N_("Search devices by a partition UUID."),
-+ 0, 0},
- {"set", 's', GRUB_ARG_OPTION_OPTIONAL,
- N_("Set a variable to the first device found."), N_("VARNAME"),
- ARG_TYPE_STRING},
-@@ -71,6 +75,8 @@ enum options
- SEARCH_FILE,
- SEARCH_LABEL,
- SEARCH_FS_UUID,
-+ SEARCH_PART_LABEL,
-+ SEARCH_PART_UUID,
- SEARCH_SET,
- SEARCH_NO_FLOPPY,
- SEARCH_HINT,
-@@ -186,6 +192,12 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
- else if (state[SEARCH_FS_UUID].set)
- grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
- hints, nhints);
-+ else if (state[SEARCH_PART_LABEL].set)
-+ grub_search_part_label (id, var, state[SEARCH_NO_FLOPPY].set,
-+ hints, nhints);
-+ else if (state[SEARCH_PART_UUID].set)
-+ grub_search_part_uuid (id, var, state[SEARCH_NO_FLOPPY].set,
-+ hints, nhints);
- else if (state[SEARCH_FILE].set)
- grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set,
- hints, nhints);
-diff --git a/grub-core/lib/gpt.c b/grub-core/lib/gpt.c
-new file mode 100644
-index 000000000..098fa65c4
---- /dev/null
-+++ b/grub-core/lib/gpt.c
-@@ -0,0 +1,757 @@
-+/* gpt.c - Read/Verify/Write GUID Partition Tables (GPT). */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc.
-+ * Copyright (C) 2014 CoreOS, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+GRUB_MOD_LICENSE ("GPLv3+");
-+
-+static grub_uint8_t grub_gpt_magic[] = GRUB_GPT_HEADER_MAGIC;
-+
-+static grub_err_t
-+grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
-+ struct grub_gpt_header *header,
-+ void **ret_entries,
-+ grub_size_t *ret_entries_size);
-+
-+char *
-+grub_gpt_guid_to_str (grub_gpt_guid_t *guid)
-+{
-+ return grub_xasprintf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-+ grub_le_to_cpu32 (guid->data1),
-+ grub_le_to_cpu16 (guid->data2),
-+ grub_le_to_cpu16 (guid->data3),
-+ guid->data4[0], guid->data4[1],
-+ guid->data4[2], guid->data4[3],
-+ guid->data4[4], guid->data4[5],
-+ guid->data4[6], guid->data4[7]);
-+}
-+
-+static grub_err_t
-+grub_gpt_device_partentry (grub_device_t device,
-+ struct grub_gpt_partentry *entry)
-+{
-+ grub_disk_t disk = device->disk;
-+ grub_partition_t p;
-+ grub_err_t err;
-+
-+ if (!disk || !disk->partition)
-+ return grub_error (GRUB_ERR_BUG, "not a partition");
-+
-+ if (grub_strcmp (disk->partition->partmap->name, "gpt"))
-+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a GPT partition");
-+
-+ p = disk->partition;
-+ disk->partition = p->parent;
-+ err = grub_disk_read (disk, p->offset, p->index, sizeof (*entry), entry);
-+ disk->partition = p;
-+
-+ return err;
-+}
-+
-+grub_err_t
-+grub_gpt_part_label (grub_device_t device, char **label)
-+{
-+ struct grub_gpt_partentry entry;
-+ const grub_size_t name_len = ARRAY_SIZE (entry.name);
-+ const grub_size_t label_len = name_len * GRUB_MAX_UTF8_PER_UTF16 + 1;
-+ grub_size_t i;
-+ grub_uint8_t *end;
-+
-+ if (grub_gpt_device_partentry (device, &entry))
-+ return grub_errno;
-+
-+ *label = grub_malloc (label_len);
-+ if (!*label)
-+ return grub_errno;
-+
-+ for (i = 0; i < name_len; i++)
-+ entry.name[i] = grub_le_to_cpu16 (entry.name[i]);
-+
-+ end = grub_utf16_to_utf8 ((grub_uint8_t *) *label, entry.name, name_len);
-+ *end = '\0';
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+grub_err_t
-+grub_gpt_part_uuid (grub_device_t device, char **uuid)
-+{
-+ struct grub_gpt_partentry entry;
-+
-+ if (grub_gpt_device_partentry (device, &entry))
-+ return grub_errno;
-+
-+ *uuid = grub_gpt_guid_to_str (&entry.guid);
-+ if (!*uuid)
-+ return grub_errno;
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static struct grub_gpt_header *
-+grub_gpt_get_header (grub_gpt_t gpt)
-+{
-+ if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID)
-+ return &gpt->primary;
-+ else if (gpt->status & GRUB_GPT_BACKUP_HEADER_VALID)
-+ return &gpt->backup;
-+
-+ grub_error (GRUB_ERR_BUG, "No valid GPT header");
-+ return NULL;
-+}
-+
-+static grub_uint64_t
-+grub_gpt_size_to_sectors (grub_gpt_t gpt, grub_size_t size)
-+{
-+ unsigned int sector_size;
-+ grub_uint64_t sectors;
-+
-+ sector_size = 1U << gpt->log_sector_size;
-+ sectors = size / sector_size;
-+ if (size % sector_size)
-+ sectors++;
-+
-+ return sectors;
-+}
-+
-+/* Copied from grub-core/kern/disk_common.c grub_disk_adjust_range so we can
-+ * avoid attempting to use disk->total_sectors when GRUB won't let us.
-+ * TODO: Why is disk->total_sectors not set to GRUB_DISK_SIZE_UNKNOWN? */
-+static int
-+grub_gpt_disk_size_valid (grub_disk_t disk)
-+{
-+ grub_disk_addr_t total_sectors;
-+
-+ /* Transform total_sectors to number of 512B blocks. */
-+ total_sectors = disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS);
-+
-+ /* Some drivers have problems with disks above reasonable.
-+ Treat unknown as 1EiB disk. While on it, clamp the size to 1EiB.
-+ Just one condition is enough since GRUB_DISK_UNKNOWN_SIZE << ls is always
-+ above 9EiB.
-+ */
-+ if (total_sectors > (1ULL << 51))
-+ return 0;
-+
-+ return 1;
-+}
-+
-+static void
-+grub_gpt_lecrc32 (grub_uint32_t *crc, const void *data, grub_size_t len)
-+{
-+ grub_uint32_t crc32_val;
-+
-+ grub_crypto_hash (GRUB_MD_CRC32, &crc32_val, data, len);
-+
-+ /* GRUB_MD_CRC32 always uses big endian, gpt is always little. */
-+ *crc = grub_swap_bytes32 (crc32_val);
-+}
-+
-+static void
-+grub_gpt_header_lecrc32 (grub_uint32_t *crc, struct grub_gpt_header *header)
-+{
-+ grub_uint32_t old, new;
-+
-+ /* crc32 must be computed with the field cleared. */
-+ old = header->crc32;
-+ header->crc32 = 0;
-+ grub_gpt_lecrc32 (&new, header, sizeof (*header));
-+ header->crc32 = old;
-+
-+ *crc = new;
-+}
-+
-+/* Make sure the MBR is a protective MBR and not a normal MBR. */
-+grub_err_t
-+grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr)
-+{
-+ unsigned int i;
-+
-+ if (mbr->signature !=
-+ grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE))
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid MBR signature");
-+
-+ for (i = 0; i < sizeof (mbr->entries); i++)
-+ if (mbr->entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK)
-+ return GRUB_ERR_NONE;
-+
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid protective MBR");
-+}
-+
-+static grub_uint64_t
-+grub_gpt_entries_size (struct grub_gpt_header *gpt)
-+{
-+ return (grub_uint64_t) grub_le_to_cpu32 (gpt->maxpart) *
-+ (grub_uint64_t) grub_le_to_cpu32 (gpt->partentry_size);
-+}
-+
-+static grub_uint64_t
-+grub_gpt_entries_sectors (struct grub_gpt_header *gpt,
-+ unsigned int log_sector_size)
-+{
-+ grub_uint64_t sector_bytes, entries_bytes;
-+
-+ sector_bytes = 1ULL << log_sector_size;
-+ entries_bytes = grub_gpt_entries_size (gpt);
-+ return grub_divmod64(entries_bytes + sector_bytes - 1, sector_bytes, NULL);
-+}
-+
-+static int
-+is_pow2 (grub_uint32_t n)
-+{
-+ return (n & (n - 1)) == 0;
-+}
-+
-+grub_err_t
-+grub_gpt_header_check (struct grub_gpt_header *gpt,
-+ unsigned int log_sector_size)
-+{
-+ grub_uint32_t crc = 0, size;
-+ grub_uint64_t start, end;
-+
-+ if (grub_memcmp (gpt->magic, grub_gpt_magic, sizeof (grub_gpt_magic)) != 0)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT signature");
-+
-+ if (gpt->version != GRUB_GPT_HEADER_VERSION)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "unknown GPT version");
-+
-+ grub_gpt_header_lecrc32 (&crc, gpt);
-+ if (gpt->crc32 != crc)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT header crc32");
-+
-+ /* The header size "must be greater than or equal to 92 and must be less
-+ * than or equal to the logical block size." */
-+ size = grub_le_to_cpu32 (gpt->headersize);
-+ if (size < 92U || size > (1U << log_sector_size))
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT header size");
-+
-+ /* The partition entry size must be "a value of 128*(2^n) where n is an
-+ * integer greater than or equal to zero (e.g., 128, 256, 512, etc.)." */
-+ size = grub_le_to_cpu32 (gpt->partentry_size);
-+ if (size < 128U || size % 128U || !is_pow2 (size / 128U))
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry size");
-+
-+ /* The minimum entries table size is specified in terms of bytes,
-+ * regardless of how large the individual entry size is. */
-+ if (grub_gpt_entries_size (gpt) < GRUB_GPT_DEFAULT_ENTRIES_SIZE)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry table size");
-+
-+ /* And of course there better be some space for partitions! */
-+ start = grub_le_to_cpu64 (gpt->start);
-+ end = grub_le_to_cpu64 (gpt->end);
-+ if (start > end)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid usable sectors");
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static int
-+grub_gpt_headers_equal (grub_gpt_t gpt)
-+{
-+ /* Assume headers passed grub_gpt_header_check so skip magic and version.
-+ * Individual fields must be checked instead of just using memcmp because
-+ * crc32, header, alternate, and partitions will all normally differ. */
-+
-+ if (gpt->primary.headersize != gpt->backup.headersize ||
-+ gpt->primary.header_lba != gpt->backup.alternate_lba ||
-+ gpt->primary.alternate_lba != gpt->backup.header_lba ||
-+ gpt->primary.start != gpt->backup.start ||
-+ gpt->primary.end != gpt->backup.end ||
-+ gpt->primary.maxpart != gpt->backup.maxpart ||
-+ gpt->primary.partentry_size != gpt->backup.partentry_size ||
-+ gpt->primary.partentry_crc32 != gpt->backup.partentry_crc32)
-+ return 0;
-+
-+ return grub_memcmp(&gpt->primary.guid, &gpt->backup.guid,
-+ sizeof(grub_gpt_guid_t)) == 0;
-+}
-+
-+static grub_err_t
-+grub_gpt_check_primary (grub_gpt_t gpt)
-+{
-+ grub_uint64_t backup, primary, entries, entries_len, start, end;
-+
-+ primary = grub_le_to_cpu64 (gpt->primary.header_lba);
-+ backup = grub_le_to_cpu64 (gpt->primary.alternate_lba);
-+ entries = grub_le_to_cpu64 (gpt->primary.partitions);
-+ entries_len = grub_gpt_entries_sectors(&gpt->primary, gpt->log_sector_size);
-+ start = grub_le_to_cpu64 (gpt->primary.start);
-+ end = grub_le_to_cpu64 (gpt->primary.end);
-+
-+ grub_dprintf ("gpt", "Primary GPT layout:\n"
-+ "primary header = 0x%llx backup header = 0x%llx\n"
-+ "entries location = 0x%llx length = 0x%llx\n"
-+ "first usable = 0x%llx last usable = 0x%llx\n",
-+ (unsigned long long) primary,
-+ (unsigned long long) backup,
-+ (unsigned long long) entries,
-+ (unsigned long long) entries_len,
-+ (unsigned long long) start,
-+ (unsigned long long) end);
-+
-+ if (grub_gpt_header_check (&gpt->primary, gpt->log_sector_size))
-+ return grub_errno;
-+ if (primary != 1)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid primary GPT LBA");
-+ if (entries <= 1 || entries+entries_len > start)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid entries location");
-+ if (backup <= end)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA");
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_gpt_check_backup (grub_gpt_t gpt)
-+{
-+ grub_uint64_t backup, primary, entries, entries_len, start, end;
-+
-+ backup = grub_le_to_cpu64 (gpt->backup.header_lba);
-+ primary = grub_le_to_cpu64 (gpt->backup.alternate_lba);
-+ entries = grub_le_to_cpu64 (gpt->backup.partitions);
-+ entries_len = grub_gpt_entries_sectors(&gpt->backup, gpt->log_sector_size);
-+ start = grub_le_to_cpu64 (gpt->backup.start);
-+ end = grub_le_to_cpu64 (gpt->backup.end);
-+
-+ grub_dprintf ("gpt", "Backup GPT layout:\n"
-+ "primary header = 0x%llx backup header = 0x%llx\n"
-+ "entries location = 0x%llx length = 0x%llx\n"
-+ "first usable = 0x%llx last usable = 0x%llx\n",
-+ (unsigned long long) primary,
-+ (unsigned long long) backup,
-+ (unsigned long long) entries,
-+ (unsigned long long) entries_len,
-+ (unsigned long long) start,
-+ (unsigned long long) end);
-+
-+ if (grub_gpt_header_check (&gpt->backup, gpt->log_sector_size))
-+ return grub_errno;
-+ if (primary != 1)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid primary GPT LBA");
-+ if (entries <= end || entries+entries_len > backup)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid entries location");
-+ if (backup <= end)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA");
-+
-+ /* If both primary and backup are valid but differ prefer the primary. */
-+ if ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) &&
-+ !grub_gpt_headers_equal (gpt))
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "backup GPT out of sync");
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_gpt_read_primary (grub_disk_t disk, grub_gpt_t gpt)
-+{
-+ grub_disk_addr_t addr;
-+
-+ /* TODO: The gpt partmap module searches for the primary header instead
-+ * of relying on the disk's sector size. For now trust the disk driver
-+ * but eventually this code should match the existing behavior. */
-+ gpt->log_sector_size = disk->log_sector_size;
-+
-+ grub_dprintf ("gpt", "reading primary GPT from sector 0x1\n");
-+
-+ addr = grub_gpt_sector_to_addr (gpt, 1);
-+ if (grub_disk_read (disk, addr, 0, sizeof (gpt->primary), &gpt->primary))
-+ return grub_errno;
-+
-+ if (grub_gpt_check_primary (gpt))
-+ return grub_errno;
-+
-+ gpt->status |= GRUB_GPT_PRIMARY_HEADER_VALID;
-+
-+ if (grub_gpt_read_entries (disk, gpt, &gpt->primary,
-+ &gpt->entries, &gpt->entries_size))
-+ return grub_errno;
-+
-+ gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID;
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_gpt_read_backup (grub_disk_t disk, grub_gpt_t gpt)
-+{
-+ void *entries = NULL;
-+ grub_size_t entries_size;
-+ grub_uint64_t sector;
-+ grub_disk_addr_t addr;
-+
-+ /* Assumes gpt->log_sector_size == disk->log_sector_size */
-+ if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID)
-+ {
-+ sector = grub_le_to_cpu64 (gpt->primary.alternate_lba);
-+ if (grub_gpt_disk_size_valid (disk) && sector >= disk->total_sectors)
-+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "backup GPT located at 0x%llx, "
-+ "beyond last disk sector at 0x%llx",
-+ (unsigned long long) sector,
-+ (unsigned long long) disk->total_sectors - 1);
-+ }
-+ else if (grub_gpt_disk_size_valid (disk))
-+ sector = disk->total_sectors - 1;
-+ else
-+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
-+ "size of disk unknown, cannot locate backup GPT");
-+
-+ grub_dprintf ("gpt", "reading backup GPT from sector 0x%llx\n",
-+ (unsigned long long) sector);
-+
-+ addr = grub_gpt_sector_to_addr (gpt, sector);
-+ if (grub_disk_read (disk, addr, 0, sizeof (gpt->backup), &gpt->backup))
-+ return grub_errno;
-+
-+ if (grub_gpt_check_backup (gpt))
-+ return grub_errno;
-+
-+ /* Ensure the backup header thinks it is located where we found it. */
-+ if (grub_le_to_cpu64 (gpt->backup.header_lba) != sector)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA");
-+
-+ gpt->status |= GRUB_GPT_BACKUP_HEADER_VALID;
-+
-+ if (grub_gpt_read_entries (disk, gpt, &gpt->backup,
-+ &entries, &entries_size))
-+ return grub_errno;
-+
-+ if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID)
-+ {
-+ if (entries_size != gpt->entries_size ||
-+ grub_memcmp (entries, gpt->entries, entries_size) != 0)
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "backup GPT out of sync");
-+
-+ grub_free (entries);
-+ }
-+ else
-+ {
-+ gpt->entries = entries;
-+ gpt->entries_size = entries_size;
-+ }
-+
-+ gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID;
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt,
-+ struct grub_gpt_header *header,
-+ void **ret_entries,
-+ grub_size_t *ret_entries_size)
-+{
-+ void *entries = NULL;
-+ grub_uint32_t count, size, crc;
-+ grub_uint64_t sector;
-+ grub_disk_addr_t addr;
-+ grub_size_t entries_size;
-+
-+ /* Grub doesn't include calloc, hence the manual overflow check. */
-+ count = grub_le_to_cpu32 (header->maxpart);
-+ size = grub_le_to_cpu32 (header->partentry_size);
-+ entries_size = count *size;
-+ if (size && entries_size / size != count)
-+ {
-+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
-+ goto fail;
-+ }
-+
-+ /* Double check that the header was validated properly. */
-+ if (entries_size < GRUB_GPT_DEFAULT_ENTRIES_SIZE)
-+ return grub_error (GRUB_ERR_BUG, "invalid GPT entries table size");
-+
-+ entries = grub_malloc (entries_size);
-+ if (!entries)
-+ goto fail;
-+
-+ sector = grub_le_to_cpu64 (header->partitions);
-+ grub_dprintf ("gpt", "reading GPT %lu entries from sector 0x%llx\n",
-+ (unsigned long) count,
-+ (unsigned long long) sector);
-+
-+ addr = grub_gpt_sector_to_addr (gpt, sector);
-+ if (grub_disk_read (disk, addr, 0, entries_size, entries))
-+ goto fail;
-+
-+ grub_gpt_lecrc32 (&crc, entries, entries_size);
-+ if (crc != header->partentry_crc32)
-+ {
-+ grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry crc32");
-+ goto fail;
-+ }
-+
-+ *ret_entries = entries;
-+ *ret_entries_size = entries_size;
-+ return GRUB_ERR_NONE;
-+
-+fail:
-+ grub_free (entries);
-+ return grub_errno;
-+}
-+
-+grub_gpt_t
-+grub_gpt_read (grub_disk_t disk)
-+{
-+ grub_gpt_t gpt;
-+
-+ grub_dprintf ("gpt", "reading GPT from %s\n", disk->name);
-+
-+ gpt = grub_zalloc (sizeof (*gpt));
-+ if (!gpt)
-+ goto fail;
-+
-+ if (grub_disk_read (disk, 0, 0, sizeof (gpt->mbr), &gpt->mbr))
-+ goto fail;
-+
-+ /* Check the MBR but errors aren't reported beyond the status bit. */
-+ if (grub_gpt_pmbr_check (&gpt->mbr))
-+ grub_errno = GRUB_ERR_NONE;
-+ else
-+ gpt->status |= GRUB_GPT_PROTECTIVE_MBR;
-+
-+ /* If both the primary and backup fail report the primary's error. */
-+ if (grub_gpt_read_primary (disk, gpt))
-+ {
-+ grub_error_push ();
-+ grub_gpt_read_backup (disk, gpt);
-+ grub_error_pop ();
-+ }
-+ else
-+ grub_gpt_read_backup (disk, gpt);
-+
-+ /* If either succeeded clear any possible error from the other. */
-+ if (grub_gpt_primary_valid (gpt) || grub_gpt_backup_valid (gpt))
-+ grub_errno = GRUB_ERR_NONE;
-+ else
-+ goto fail;
-+
-+ return gpt;
-+
-+fail:
-+ grub_gpt_free (gpt);
-+ return NULL;
-+}
-+
-+struct grub_gpt_partentry *
-+grub_gpt_get_partentry (grub_gpt_t gpt, grub_uint32_t n)
-+{
-+ struct grub_gpt_header *header;
-+ grub_size_t offset;
-+
-+ header = grub_gpt_get_header (gpt);
-+ if (!header)
-+ return NULL;
-+
-+ if (n >= grub_le_to_cpu32 (header->maxpart))
-+ return NULL;
-+
-+ offset = (grub_size_t) grub_le_to_cpu32 (header->partentry_size) * n;
-+ return (struct grub_gpt_partentry *) ((char *) gpt->entries + offset);
-+}
-+
-+grub_err_t
-+grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt)
-+{
-+ /* Skip if there is nothing to do. */
-+ if (grub_gpt_both_valid (gpt))
-+ return GRUB_ERR_NONE;
-+
-+ grub_dprintf ("gpt", "repairing GPT for %s\n", disk->name);
-+
-+ if (disk->log_sector_size != gpt->log_sector_size)
-+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-+ "GPT sector size must match disk sector size");
-+
-+ if (grub_gpt_primary_valid (gpt))
-+ {
-+ grub_uint64_t backup_header;
-+
-+ grub_dprintf ("gpt", "primary GPT is valid\n");
-+
-+ /* Relocate backup to end if disk if the disk has grown. */
-+ backup_header = grub_le_to_cpu64 (gpt->primary.alternate_lba);
-+ if (grub_gpt_disk_size_valid (disk) &&
-+ disk->total_sectors - 1 > backup_header)
-+ {
-+ backup_header = disk->total_sectors - 1;
-+ grub_dprintf ("gpt", "backup GPT header relocated to 0x%llx\n",
-+ (unsigned long long) backup_header);
-+
-+ gpt->primary.alternate_lba = grub_cpu_to_le64 (backup_header);
-+ }
-+
-+ grub_memcpy (&gpt->backup, &gpt->primary, sizeof (gpt->backup));
-+ gpt->backup.header_lba = gpt->primary.alternate_lba;
-+ gpt->backup.alternate_lba = gpt->primary.header_lba;
-+ gpt->backup.partitions = grub_cpu_to_le64 (backup_header -
-+ grub_gpt_size_to_sectors (gpt, gpt->entries_size));
-+ }
-+ else if (grub_gpt_backup_valid (gpt))
-+ {
-+ grub_dprintf ("gpt", "backup GPT is valid\n");
-+
-+ grub_memcpy (&gpt->primary, &gpt->backup, sizeof (gpt->primary));
-+ gpt->primary.header_lba = gpt->backup.alternate_lba;
-+ gpt->primary.alternate_lba = gpt->backup.header_lba;
-+ gpt->primary.partitions = grub_cpu_to_le64_compile_time (2);
-+ }
-+ else
-+ return grub_error (GRUB_ERR_BUG, "No valid GPT");
-+
-+ if (grub_gpt_update (gpt))
-+ return grub_errno;
-+
-+ grub_dprintf ("gpt", "repairing GPT for %s successful\n", disk->name);
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+grub_err_t
-+grub_gpt_update (grub_gpt_t gpt)
-+{
-+ grub_uint32_t crc;
-+
-+ /* Clear status bits, require revalidation of everything. */
-+ gpt->status &= ~(GRUB_GPT_PRIMARY_HEADER_VALID |
-+ GRUB_GPT_PRIMARY_ENTRIES_VALID |
-+ GRUB_GPT_BACKUP_HEADER_VALID |
-+ GRUB_GPT_BACKUP_ENTRIES_VALID);
-+
-+ /* Writing headers larger than our header structure are unsupported. */
-+ gpt->primary.headersize =
-+ grub_cpu_to_le32_compile_time (sizeof (gpt->primary));
-+ gpt->backup.headersize =
-+ grub_cpu_to_le32_compile_time (sizeof (gpt->backup));
-+
-+ grub_gpt_lecrc32 (&crc, gpt->entries, gpt->entries_size);
-+ gpt->primary.partentry_crc32 = crc;
-+ gpt->backup.partentry_crc32 = crc;
-+
-+ grub_gpt_header_lecrc32 (&gpt->primary.crc32, &gpt->primary);
-+ grub_gpt_header_lecrc32 (&gpt->backup.crc32, &gpt->backup);
-+
-+ if (grub_gpt_check_primary (gpt))
-+ {
-+ grub_error_push ();
-+ return grub_error (GRUB_ERR_BUG, "Generated invalid GPT primary header");
-+ }
-+
-+ gpt->status |= (GRUB_GPT_PRIMARY_HEADER_VALID |
-+ GRUB_GPT_PRIMARY_ENTRIES_VALID);
-+
-+ if (grub_gpt_check_backup (gpt))
-+ {
-+ grub_error_push ();
-+ return grub_error (GRUB_ERR_BUG, "Generated invalid GPT backup header");
-+ }
-+
-+ gpt->status |= (GRUB_GPT_BACKUP_HEADER_VALID |
-+ GRUB_GPT_BACKUP_ENTRIES_VALID);
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_gpt_write_table (grub_disk_t disk, grub_gpt_t gpt,
-+ struct grub_gpt_header *header)
-+{
-+ grub_disk_addr_t addr;
-+
-+ if (grub_le_to_cpu32 (header->headersize) != sizeof (*header))
-+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-+ "Header size is %u, must be %u",
-+ grub_le_to_cpu32 (header->headersize),
-+ sizeof (*header));
-+
-+ addr = grub_gpt_sector_to_addr (gpt, grub_le_to_cpu64 (header->header_lba));
-+ if (addr == 0)
-+ return grub_error (GRUB_ERR_BUG,
-+ "Refusing to write GPT header to address 0x0");
-+ if (grub_disk_write (disk, addr, 0, sizeof (*header), header))
-+ return grub_errno;
-+
-+ addr = grub_gpt_sector_to_addr (gpt, grub_le_to_cpu64 (header->partitions));
-+ if (addr < 2)
-+ return grub_error (GRUB_ERR_BUG,
-+ "Refusing to write GPT entries to address 0x%llx",
-+ (unsigned long long) addr);
-+ if (grub_disk_write (disk, addr, 0, gpt->entries_size, gpt->entries))
-+ return grub_errno;
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+grub_err_t
-+grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt)
-+{
-+ grub_uint64_t backup_header;
-+
-+ /* TODO: update/repair protective MBRs too. */
-+
-+ if (!grub_gpt_both_valid (gpt))
-+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
-+
-+ /* Write the backup GPT first so if writing fails the update is aborted
-+ * and the primary is left intact. However if the backup location is
-+ * inaccessible we have to just skip and hope for the best, the backup
-+ * will need to be repaired in the OS. */
-+ backup_header = grub_le_to_cpu64 (gpt->backup.header_lba);
-+ if (grub_gpt_disk_size_valid (disk) &&
-+ backup_header >= disk->total_sectors)
-+ {
-+ grub_printf ("warning: backup GPT located at 0x%llx, "
-+ "beyond last disk sector at 0x%llx\n",
-+ (unsigned long long) backup_header,
-+ (unsigned long long) disk->total_sectors - 1);
-+ grub_printf ("warning: only writing primary GPT, "
-+ "the backup GPT must be repaired from the OS\n");
-+ }
-+ else
-+ {
-+ grub_dprintf ("gpt", "writing backup GPT to %s\n", disk->name);
-+ if (grub_gpt_write_table (disk, gpt, &gpt->backup))
-+ return grub_errno;
-+ }
-+
-+ grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);
-+ if (grub_gpt_write_table (disk, gpt, &gpt->primary))
-+ return grub_errno;
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+void
-+grub_gpt_free (grub_gpt_t gpt)
-+{
-+ if (!gpt)
-+ return;
-+
-+ grub_free (gpt->entries);
-+ grub_free (gpt);
-+}
-diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
-index 7a93f4329..5c4372dce 100644
---- a/include/grub/gpt_partition.h
-+++ b/include/grub/gpt_partition.h
-@@ -21,6 +21,7 @@
-
- #include
- #include
-+#include
-
- struct grub_gpt_part_guid
- {
-@@ -30,25 +31,46 @@ struct grub_gpt_part_guid
- grub_uint8_t data4[8];
- } GRUB_PACKED;
- typedef struct grub_gpt_part_guid grub_gpt_part_guid_t;
-+typedef struct grub_gpt_part_guid grub_gpt_guid_t;
-+typedef struct grub_gpt_part_guid grub_gpt_part_type_t;
-
--#define GRUB_GPT_PARTITION_TYPE_EMPTY \
-- { 0x0, 0x0, 0x0, \
-- { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \
-+/* Format the raw little-endian GUID as a newly allocated string. */
-+char * grub_gpt_guid_to_str (grub_gpt_guid_t *guid);
-+
-+
-+#define GRUB_GPT_GUID_INIT(a, b, c, d1, d2, d3, d4, d5, d6, d7, d8) \
-+ { \
-+ grub_cpu_to_le32_compile_time (a), \
-+ grub_cpu_to_le16_compile_time (b), \
-+ grub_cpu_to_le16_compile_time (c), \
-+ { d1, d2, d3, d4, d5, d6, d7, d8 } \
- }
-
-+#define GRUB_GPT_PARTITION_TYPE_EMPTY \
-+ GRUB_GPT_GUID_INIT (0x0, 0x0, 0x0, \
-+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
-+
-+#define GRUB_GPT_PARTITION_TYPE_EFI_SYSTEM \
-+ GRUB_GPT_GUID_INIT (0xc12a7328, 0xf81f, 0x11d2, \
-+ 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b)
-+
- #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \
-- { grub_cpu_to_le32_compile_time (0x21686148), \
-- grub_cpu_to_le16_compile_time (0x6449), \
-- grub_cpu_to_le16_compile_time (0x6e6f), \
-- { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \
-- }
-+ GRUB_GPT_GUID_INIT (0x21686148, 0x6449, 0x6e6f, \
-+ 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49)
-
- #define GRUB_GPT_PARTITION_TYPE_LDM \
-- { grub_cpu_to_le32_compile_time (0x5808C8AAU),\
-- grub_cpu_to_le16_compile_time (0x7E8F), \
-- grub_cpu_to_le16_compile_time (0x42E0), \
-- { 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 } \
-- }
-+ GRUB_GPT_GUID_INIT (0x5808c8aa, 0x7e8f, 0x42e0, \
-+ 0x85, 0xd2, 0xe1, 0xe9, 0x04, 0x34, 0xcf, 0xb3)
-+
-+#define GRUB_GPT_PARTITION_TYPE_USR_X86_64 \
-+ GRUB_GPT_GUID_INIT (0x5dfbf5f4, 0x2848, 0x4bac, \
-+ 0xaa, 0x5e, 0x0d, 0x9a, 0x20, 0xb7, 0x45, 0xa6)
-+
-+#define GRUB_GPT_HEADER_MAGIC \
-+ { 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 }
-+
-+#define GRUB_GPT_HEADER_VERSION \
-+ grub_cpu_to_le32_compile_time (0x00010000U)
-
- struct grub_gpt_header
- {
-@@ -57,11 +79,11 @@ struct grub_gpt_header
- grub_uint32_t headersize;
- grub_uint32_t crc32;
- grub_uint32_t unused1;
-- grub_uint64_t primary;
-- grub_uint64_t backup;
-+ grub_uint64_t header_lba;
-+ grub_uint64_t alternate_lba;
- grub_uint64_t start;
- grub_uint64_t end;
-- grub_uint8_t guid[16];
-+ grub_gpt_part_guid_t guid;
- grub_uint64_t partitions;
- grub_uint32_t maxpart;
- grub_uint32_t partentry_size;
-@@ -75,13 +97,168 @@ struct grub_gpt_partentry
- grub_uint64_t start;
- grub_uint64_t end;
- grub_uint64_t attrib;
-- char name[72];
-+ grub_uint16_t name[36];
- } GRUB_PACKED;
-
-+enum grub_gpt_part_attr_offset
-+{
-+ /* Standard partition attribute bits defined by UEFI. */
-+ GRUB_GPT_PART_ATTR_OFFSET_REQUIRED = 0,
-+ GRUB_GPT_PART_ATTR_OFFSET_NO_BLOCK_IO_PROTOCOL = 1,
-+ GRUB_GPT_PART_ATTR_OFFSET_LEGACY_BIOS_BOOTABLE = 2,
-+
-+ /* De facto standard attribute bits defined by Microsoft and reused by
-+ * http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec */
-+ GRUB_GPT_PART_ATTR_OFFSET_READ_ONLY = 60,
-+ GRUB_GPT_PART_ATTR_OFFSET_NO_AUTO = 63,
-+
-+ /* Partition attributes for priority based selection,
-+ * Currently only valid for PARTITION_TYPE_USR_X86_64.
-+ * TRIES_LEFT and PRIORITY are 4 bit wide fields. */
-+ GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY = 48,
-+ GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT = 52,
-+ GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL = 56,
-+};
-+
-+/* Helpers for reading/writing partition attributes. */
-+static inline grub_uint64_t
-+grub_gpt_entry_attribute (struct grub_gpt_partentry *entry,
-+ enum grub_gpt_part_attr_offset offset,
-+ unsigned int bits)
-+{
-+ grub_uint64_t attrib = grub_le_to_cpu64 (entry->attrib);
-+
-+ return (attrib >> offset) & ((1ULL << bits) - 1);
-+}
-+
-+static inline void
-+grub_gpt_entry_set_attribute (struct grub_gpt_partentry *entry,
-+ grub_uint64_t value,
-+ enum grub_gpt_part_attr_offset offset,
-+ unsigned int bits)
-+{
-+ grub_uint64_t attrib, mask;
-+
-+ mask = (((1ULL << bits) - 1) << offset);
-+ attrib = grub_le_to_cpu64 (entry->attrib) & ~mask;
-+ attrib |= ((value << offset) & mask);
-+ entry->attrib = grub_cpu_to_le64 (attrib);
-+}
-+
-+/* Basic GPT partmap module. */
- grub_err_t
- grub_gpt_partition_map_iterate (grub_disk_t disk,
- grub_partition_iterate_hook_t hook,
- void *hook_data);
-
-+/* Advanced GPT library. */
-+
-+/* Status bits for the grub_gpt.status field. */
-+#define GRUB_GPT_PROTECTIVE_MBR 0x01
-+#define GRUB_GPT_HYBRID_MBR 0x02
-+#define GRUB_GPT_PRIMARY_HEADER_VALID 0x04
-+#define GRUB_GPT_PRIMARY_ENTRIES_VALID 0x08
-+#define GRUB_GPT_BACKUP_HEADER_VALID 0x10
-+#define GRUB_GPT_BACKUP_ENTRIES_VALID 0x20
-+
-+/* UEFI requires the entries table to be at least 16384 bytes for a
-+ * total of 128 entries given the standard 128 byte entry size. */
-+#define GRUB_GPT_DEFAULT_ENTRIES_SIZE 16384
-+#define GRUB_GPT_DEFAULT_ENTRIES_LENGTH \
-+ (GRUB_GPT_DEFAULT_ENTRIES_SIZE / sizeof (struct grub_gpt_partentry))
-+
-+struct grub_gpt
-+{
-+ /* Bit field indicating which structures on disk are valid. */
-+ unsigned status;
-+
-+ /* Protective or hybrid MBR. */
-+ struct grub_msdos_partition_mbr mbr;
-+
-+ /* Each of the two GPT headers. */
-+ struct grub_gpt_header primary;
-+ struct grub_gpt_header backup;
-+
-+ /* Only need one entries table, on disk both copies are identical.
-+ * The on disk entry size may be larger than our partentry struct so
-+ * the table cannot be indexed directly. */
-+ void *entries;
-+ grub_size_t entries_size;
-+
-+ /* Logarithm of sector size, in case GPT and disk driver disagree. */
-+ unsigned int log_sector_size;
-+};
-+typedef struct grub_gpt *grub_gpt_t;
-+
-+/* Helpers for checking the gpt status field. */
-+static inline int
-+grub_gpt_mbr_valid (grub_gpt_t gpt)
-+{
-+ return ((gpt->status & GRUB_GPT_PROTECTIVE_MBR) ||
-+ (gpt->status & GRUB_GPT_HYBRID_MBR));
-+}
-+
-+static inline int
-+grub_gpt_primary_valid (grub_gpt_t gpt)
-+{
-+ return ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) &&
-+ (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID));
-+}
-+
-+static inline int
-+grub_gpt_backup_valid (grub_gpt_t gpt)
-+{
-+ return ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) &&
-+ (gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID));
-+}
-+
-+static inline int
-+grub_gpt_both_valid (grub_gpt_t gpt)
-+{
-+ return grub_gpt_primary_valid (gpt) && grub_gpt_backup_valid (gpt);
-+}
-+
-+/* Translate GPT sectors to GRUB's 512 byte block addresses. */
-+static inline grub_disk_addr_t
-+grub_gpt_sector_to_addr (grub_gpt_t gpt, grub_uint64_t sector)
-+{
-+ return (sector << (gpt->log_sector_size - GRUB_DISK_SECTOR_BITS));
-+}
-+
-+/* Allocates and fills new grub_gpt structure, free with grub_gpt_free. */
-+grub_gpt_t grub_gpt_read (grub_disk_t disk);
-+
-+/* Helper for indexing into the entries table.
-+ * Returns NULL when the end of the table has been reached. */
-+struct grub_gpt_partentry * grub_gpt_get_partentry (grub_gpt_t gpt,
-+ grub_uint32_t n);
-+
-+/* Sync and update primary and backup headers if either are invalid. */
-+grub_err_t grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt);
-+
-+/* Recompute checksums and revalidate everything, must be called after
-+ * modifying any GPT data. */
-+grub_err_t grub_gpt_update (grub_gpt_t gpt);
-+
-+/* Write headers and entry tables back to disk. */
-+grub_err_t grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt);
-+
-+void grub_gpt_free (grub_gpt_t gpt);
-+
-+grub_err_t grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr);
-+grub_err_t grub_gpt_header_check (struct grub_gpt_header *gpt,
-+ unsigned int log_sector_size);
-+
-+
-+/* Utilities for simple partition data lookups, usage is intended to
-+ * be similar to fs->label and fs->uuid functions. */
-+
-+/* Return the partition label of the device DEVICE in LABEL.
-+ * The label is in a new buffer and should be freed by the caller. */
-+grub_err_t grub_gpt_part_label (grub_device_t device, char **label);
-+
-+/* Return the partition uuid of the device DEVICE in UUID.
-+ * The uuid is in a new buffer and should be freed by the caller. */
-+grub_err_t grub_gpt_part_uuid (grub_device_t device, char **uuid);
-
- #endif /* ! GRUB_GPT_PARTITION_HEADER */
-diff --git a/include/grub/search.h b/include/grub/search.h
-index d80347df3..c2f40abe9 100644
---- a/include/grub/search.h
-+++ b/include/grub/search.h
-@@ -25,5 +25,9 @@ void grub_search_fs_uuid (const char *key, const char *var, int no_floppy,
- char **hints, unsigned nhints);
- void grub_search_label (const char *key, const char *var, int no_floppy,
- char **hints, unsigned nhints);
-+void grub_search_part_uuid (const char *key, const char *var, int no_floppy,
-+ char **hints, unsigned nhints);
-+void grub_search_part_label (const char *key, const char *var, int no_floppy,
-+ char **hints, unsigned nhints);
-
- #endif
-diff --git a/tests/gpt_unit_test.c b/tests/gpt_unit_test.c
-new file mode 100644
-index 000000000..53f686912
---- /dev/null
-+++ b/tests/gpt_unit_test.c
-@@ -0,0 +1,807 @@
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2014 CoreOS, Inc.
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+/* from gnulib */
-+#include
-+
-+/* Confirm that the GPT structures conform to the sizes in the spec:
-+ * The header size "must be greater than or equal to 92 and must be less
-+ * than or equal to the logical block size."
-+ * The partition entry size must be "a value of 128*(2^n) where n is an
-+ * integer greater than or equal to zero (e.g., 128, 256, 512, etc.)." */
-+verify (sizeof (struct grub_gpt_header) == 92);
-+verify (sizeof (struct grub_gpt_partentry) == 128);
-+
-+/* GPT section sizes. */
-+#define HEADER_SIZE (sizeof (struct grub_gpt_header))
-+#define HEADER_PAD (GRUB_DISK_SECTOR_SIZE - HEADER_SIZE)
-+#define ENTRY_SIZE (sizeof (struct grub_gpt_partentry))
-+#define TABLE_ENTRIES 0x80
-+#define TABLE_SIZE (TABLE_ENTRIES * ENTRY_SIZE)
-+#define TABLE_SECTORS (TABLE_SIZE / GRUB_DISK_SECTOR_SIZE)
-+
-+/* Double check that the table size calculation was valid. */
-+verify (TABLE_SECTORS * GRUB_DISK_SECTOR_SIZE == TABLE_SIZE);
-+
-+/* GPT section locations for a 1MiB disk. */
-+#define DISK_SECTORS 0x800
-+#define DISK_SIZE (GRUB_DISK_SECTOR_SIZE * DISK_SECTORS)
-+#define PRIMARY_HEADER_SECTOR 0x1
-+#define PRIMARY_TABLE_SECTOR 0x2
-+#define BACKUP_HEADER_SECTOR (DISK_SECTORS - 0x1)
-+#define BACKUP_TABLE_SECTOR (BACKUP_HEADER_SECTOR - TABLE_SECTORS)
-+
-+#define DATA_START_SECTOR (PRIMARY_TABLE_SECTOR + TABLE_SECTORS)
-+#define DATA_END_SECTOR (BACKUP_TABLE_SECTOR - 0x1)
-+#define DATA_SECTORS (BACKUP_TABLE_SECTOR - DATA_START_SECTOR)
-+#define DATA_SIZE (GRUB_DISK_SECTOR_SIZE * DATA_SECTORS)
-+
-+struct test_disk
-+{
-+ struct grub_msdos_partition_mbr mbr;
-+
-+ struct grub_gpt_header primary_header;
-+ grub_uint8_t primary_header_pad[HEADER_PAD];
-+ struct grub_gpt_partentry primary_entries[TABLE_ENTRIES];
-+
-+ grub_uint8_t data[DATA_SIZE];
-+
-+ struct grub_gpt_partentry backup_entries[TABLE_ENTRIES];
-+ struct grub_gpt_header backup_header;
-+ grub_uint8_t backup_header_pad[HEADER_PAD];
-+} GRUB_PACKED;
-+
-+/* Sanity check that all the above ugly math was correct. */
-+verify (sizeof (struct test_disk) == DISK_SIZE);
-+
-+struct test_data
-+{
-+ int fd;
-+ grub_device_t dev;
-+ struct test_disk *raw;
-+};
-+
-+
-+/* Sample primary GPT header for a 1MB disk. */
-+static const struct grub_gpt_header example_primary = {
-+ .magic = GRUB_GPT_HEADER_MAGIC,
-+ .version = GRUB_GPT_HEADER_VERSION,
-+ .headersize = sizeof (struct grub_gpt_header),
-+ .crc32 = grub_cpu_to_le32_compile_time (0xb985abe0),
-+ .header_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR),
-+ .alternate_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR),
-+ .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR),
-+ .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR),
-+ .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6,
-+ 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac),
-+ .partitions = grub_cpu_to_le64_compile_time (PRIMARY_TABLE_SECTOR),
-+ .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES),
-+ .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE),
-+ .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c),
-+};
-+
-+static const struct grub_gpt_partentry example_entries[TABLE_ENTRIES] = {
-+ {
-+ .type = GRUB_GPT_PARTITION_TYPE_EFI_SYSTEM,
-+ .guid = GRUB_GPT_GUID_INIT (0xa0f1792e, 0xb4ce, 0x4136, 0xbc, 0xf2,
-+ 0x1a, 0xfc, 0x13, 0x3c, 0x28, 0x28),
-+ .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR),
-+ .end = grub_cpu_to_le64_compile_time (0x3f),
-+ .attrib = 0x0,
-+ .name = {
-+ grub_cpu_to_le16_compile_time ('E'),
-+ grub_cpu_to_le16_compile_time ('F'),
-+ grub_cpu_to_le16_compile_time ('I'),
-+ grub_cpu_to_le16_compile_time (' '),
-+ grub_cpu_to_le16_compile_time ('S'),
-+ grub_cpu_to_le16_compile_time ('Y'),
-+ grub_cpu_to_le16_compile_time ('S'),
-+ grub_cpu_to_le16_compile_time ('T'),
-+ grub_cpu_to_le16_compile_time ('E'),
-+ grub_cpu_to_le16_compile_time ('M'),
-+ 0x0,
-+ }
-+ },
-+ {
-+ .type = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT,
-+ .guid = GRUB_GPT_GUID_INIT (0x876c898d, 0x1b40, 0x4727, 0xa1, 0x61,
-+ 0xed, 0xf9, 0xb5, 0x48, 0x66, 0x74),
-+ .start = grub_cpu_to_le64_compile_time (0x40),
-+ .end = grub_cpu_to_le64_compile_time (0x7f),
-+ .attrib = grub_cpu_to_le64_compile_time (
-+ 1ULL << GRUB_GPT_PART_ATTR_OFFSET_LEGACY_BIOS_BOOTABLE),
-+ .name = {
-+ grub_cpu_to_le16_compile_time ('B'),
-+ grub_cpu_to_le16_compile_time ('I'),
-+ grub_cpu_to_le16_compile_time ('O'),
-+ grub_cpu_to_le16_compile_time ('S'),
-+ grub_cpu_to_le16_compile_time (' '),
-+ grub_cpu_to_le16_compile_time ('B'),
-+ grub_cpu_to_le16_compile_time ('O'),
-+ grub_cpu_to_le16_compile_time ('O'),
-+ grub_cpu_to_le16_compile_time ('T'),
-+ 0x0,
-+ }
-+ },
-+};
-+
-+/* And the backup header. */
-+static const struct grub_gpt_header example_backup = {
-+ .magic = GRUB_GPT_HEADER_MAGIC,
-+ .version = GRUB_GPT_HEADER_VERSION,
-+ .headersize = sizeof (struct grub_gpt_header),
-+ .crc32 = grub_cpu_to_le32_compile_time (0x0af785eb),
-+ .header_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR),
-+ .alternate_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR),
-+ .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR),
-+ .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR),
-+ .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6,
-+ 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac),
-+ .partitions = grub_cpu_to_le64_compile_time (BACKUP_TABLE_SECTOR),
-+ .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES),
-+ .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE),
-+ .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c),
-+};
-+
-+/* Sample protective MBR for the same 1MB disk. Note, this matches
-+ * parted and fdisk behavior. The UEFI spec uses different values. */
-+static const struct grub_msdos_partition_mbr example_pmbr = {
-+ .entries = {{.flag = 0x00,
-+ .start_head = 0x00,
-+ .start_sector = 0x01,
-+ .start_cylinder = 0x00,
-+ .type = 0xee,
-+ .end_head = 0xfe,
-+ .end_sector = 0xff,
-+ .end_cylinder = 0xff,
-+ .start = grub_cpu_to_le32_compile_time (0x1),
-+ .length = grub_cpu_to_le32_compile_time (DISK_SECTORS - 0x1),
-+ }},
-+ .signature = grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE),
-+};
-+
-+/* If errors are left in grub's error stack things can get confused. */
-+static void
-+assert_error_stack_empty (void)
-+{
-+ do
-+ {
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "error on stack: %s", grub_errmsg);
-+ }
-+ while (grub_error_pop ());
-+}
-+
-+static grub_err_t
-+execute_command2 (const char *name, const char *arg1, const char *arg2)
-+{
-+ grub_command_t cmd;
-+ grub_err_t err;
-+ char *argv[2];
-+
-+ cmd = grub_command_find (name);
-+ if (!cmd)
-+ grub_fatal ("can't find command %s", name);
-+
-+ argv[0] = strdup (arg1);
-+ argv[1] = strdup (arg2);
-+ err = (cmd->func) (cmd, 2, argv);
-+ free (argv[0]);
-+ free (argv[1]);
-+
-+ return err;
-+}
-+
-+static void
-+sync_disk (struct test_data *data)
-+{
-+ if (msync (data->raw, DISK_SIZE, MS_SYNC | MS_INVALIDATE) < 0)
-+ grub_fatal ("Syncing disk failed: %s", strerror (errno));
-+
-+ grub_disk_cache_invalidate_all ();
-+}
-+
-+static void
-+reset_disk (struct test_data *data)
-+{
-+ memset (data->raw, 0, DISK_SIZE);
-+
-+ /* Initialize image with valid example tables. */
-+ memcpy (&data->raw->mbr, &example_pmbr, sizeof (data->raw->mbr));
-+ memcpy (&data->raw->primary_header, &example_primary,
-+ sizeof (data->raw->primary_header));
-+ memcpy (&data->raw->primary_entries, &example_entries,
-+ sizeof (data->raw->primary_entries));
-+ memcpy (&data->raw->backup_entries, &example_entries,
-+ sizeof (data->raw->backup_entries));
-+ memcpy (&data->raw->backup_header, &example_backup,
-+ sizeof (data->raw->backup_header));
-+
-+ sync_disk (data);
-+}
-+
-+static void
-+open_disk (struct test_data *data)
-+{
-+ const char *loop = "loop0";
-+ char template[] = "/tmp/grub_gpt_test.XXXXXX";
-+ char host[sizeof ("(host)") + sizeof (template)];
-+
-+ data->fd = mkstemp (template);
-+ if (data->fd < 0)
-+ grub_fatal ("Creating %s failed: %s", template, strerror (errno));
-+
-+ if (ftruncate (data->fd, DISK_SIZE) < 0)
-+ {
-+ int err = errno;
-+ unlink (template);
-+ grub_fatal ("Resizing %s failed: %s", template, strerror (err));
-+ }
-+
-+ data->raw = mmap (NULL, DISK_SIZE, PROT_READ | PROT_WRITE,
-+ MAP_SHARED, data->fd, 0);
-+ if (data->raw == MAP_FAILED)
-+ {
-+ int err = errno;
-+ unlink (template);
-+ grub_fatal ("Maping %s failed: %s", template, strerror (err));
-+ }
-+
-+ snprintf (host, sizeof (host), "(host)%s", template);
-+ if (execute_command2 ("loopback", loop, host) != GRUB_ERR_NONE)
-+ {
-+ unlink (template);
-+ grub_fatal ("loopback %s %s failed: %s", loop, host, grub_errmsg);
-+ }
-+
-+ if (unlink (template) < 0)
-+ grub_fatal ("Unlinking %s failed: %s", template, strerror (errno));
-+
-+ reset_disk (data);
-+
-+ data->dev = grub_device_open (loop);
-+ if (!data->dev)
-+ grub_fatal ("Opening %s failed: %s", loop, grub_errmsg);
-+}
-+
-+static void
-+close_disk (struct test_data *data)
-+{
-+ char *loop;
-+
-+ assert_error_stack_empty ();
-+
-+ if (munmap (data->raw, DISK_SIZE) || close (data->fd))
-+ grub_fatal ("Closing disk image failed: %s", strerror (errno));
-+
-+ loop = strdup (data->dev->disk->name);
-+ grub_test_assert (grub_device_close (data->dev) == GRUB_ERR_NONE,
-+ "Closing disk device failed: %s", grub_errmsg);
-+
-+ grub_test_assert (execute_command2 ("loopback", "-d", loop) ==
-+ GRUB_ERR_NONE, "loopback -d %s failed: %s", loop,
-+ grub_errmsg);
-+
-+ free (loop);
-+}
-+
-+static grub_gpt_t
-+read_disk (struct test_data *data)
-+{
-+ grub_gpt_t gpt;
-+
-+ gpt = grub_gpt_read (data->dev->disk);
-+ if (gpt == NULL)
-+ grub_fatal ("grub_gpt_read failed: %s", grub_errmsg);
-+
-+ return gpt;
-+}
-+
-+static void
-+pmbr_test (void)
-+{
-+ struct grub_msdos_partition_mbr mbr;
-+
-+ memset (&mbr, 0, sizeof (mbr));
-+
-+ /* Empty is invalid. */
-+ grub_gpt_pmbr_check (&mbr);
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ /* A table without a protective partition is invalid. */
-+ mbr.signature = grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE);
-+ grub_gpt_pmbr_check (&mbr);
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ /* A table with a protective type is ok. */
-+ memcpy (&mbr, &example_pmbr, sizeof (mbr));
-+ grub_gpt_pmbr_check (&mbr);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+}
-+
-+static void
-+header_test (void)
-+{
-+ struct grub_gpt_header primary, backup;
-+
-+ /* Example headers should be valid. */
-+ memcpy (&primary, &example_primary, sizeof (primary));
-+ grub_gpt_header_check (&primary, GRUB_DISK_SECTOR_BITS);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ memcpy (&backup, &example_backup, sizeof (backup));
-+ grub_gpt_header_check (&backup, GRUB_DISK_SECTOR_BITS);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ /* Twiddle the GUID to invalidate the CRC. */
-+ primary.guid.data1 = 0;
-+ grub_gpt_header_check (&primary, GRUB_DISK_SECTOR_BITS);
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ backup.guid.data1 = 0;
-+ grub_gpt_header_check (&backup, GRUB_DISK_SECTOR_BITS);
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+}
-+
-+static void
-+read_valid_test (void)
-+{
-+ struct test_data data;
-+ grub_gpt_t gpt;
-+
-+ open_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert (gpt->status == (GRUB_GPT_PROTECTIVE_MBR |
-+ GRUB_GPT_PRIMARY_HEADER_VALID |
-+ GRUB_GPT_PRIMARY_ENTRIES_VALID |
-+ GRUB_GPT_BACKUP_HEADER_VALID |
-+ GRUB_GPT_BACKUP_ENTRIES_VALID),
-+ "unexpected status: 0x%02x", gpt->status);
-+ grub_gpt_free (gpt);
-+ close_disk (&data);
-+}
-+
-+static void
-+read_invalid_entries_test (void)
-+{
-+ struct test_data data;
-+ grub_gpt_t gpt;
-+
-+ open_disk (&data);
-+
-+ /* Corrupt the first entry in both tables. */
-+ memset (&data.raw->primary_entries[0], 0x55,
-+ sizeof (data.raw->primary_entries[0]));
-+ memset (&data.raw->backup_entries[0], 0x55,
-+ sizeof (data.raw->backup_entries[0]));
-+ sync_disk (&data);
-+
-+ gpt = grub_gpt_read (data.dev->disk);
-+ grub_test_assert (gpt == NULL, "no error reported for corrupt entries");
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ close_disk (&data);
-+}
-+
-+static void
-+read_fallback_test (void)
-+{
-+ struct test_data data;
-+ grub_gpt_t gpt;
-+
-+ open_disk (&data);
-+
-+ /* Corrupt the primary header. */
-+ memset (&data.raw->primary_header.guid, 0x55,
-+ sizeof (data.raw->primary_header.guid));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) == 0,
-+ "unreported corrupt primary header");
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ /* Corrupt the backup header. */
-+ memset (&data.raw->backup_header.guid, 0x55,
-+ sizeof (data.raw->backup_header.guid));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) == 0,
-+ "unreported corrupt backup header");
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ /* Corrupt the primary entry table. */
-+ memset (&data.raw->primary_entries[0], 0x55,
-+ sizeof (data.raw->primary_entries[0]));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert ((gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID) == 0,
-+ "unreported corrupt primary entries table");
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ /* Corrupt the backup entry table. */
-+ memset (&data.raw->backup_entries[0], 0x55,
-+ sizeof (data.raw->backup_entries[0]));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID) == 0,
-+ "unreported corrupt backup entries table");
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ /* If primary is corrupt and disk size is unknown fallback fails. */
-+ memset (&data.raw->primary_header.guid, 0x55,
-+ sizeof (data.raw->primary_header.guid));
-+ sync_disk (&data);
-+ data.dev->disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
-+ gpt = grub_gpt_read (data.dev->disk);
-+ grub_test_assert (gpt == NULL, "no error reported");
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ close_disk (&data);
-+}
-+
-+static void
-+repair_test (void)
-+{
-+ struct test_data data;
-+ grub_gpt_t gpt;
-+
-+ open_disk (&data);
-+
-+ /* Erase/Repair primary. */
-+ memset (&data.raw->primary_header, 0, sizeof (data.raw->primary_header));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_gpt_repair (data.dev->disk, gpt);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "repair failed: %s", grub_errmsg);
-+ if (memcmp (&gpt->primary, &example_primary, sizeof (gpt->primary)))
-+ {
-+ printf ("Invalid restored primary header:\n");
-+ hexdump (16, (char*)&gpt->primary, sizeof (gpt->primary));
-+ printf ("Expected primary header:\n");
-+ hexdump (16, (char*)&example_primary, sizeof (example_primary));
-+ grub_test_assert (0, "repair did not restore primary header");
-+ }
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ /* Erase/Repair backup. */
-+ memset (&data.raw->backup_header, 0, sizeof (data.raw->backup_header));
-+ sync_disk (&data);
-+ gpt = read_disk (&data);
-+ grub_gpt_repair (data.dev->disk, gpt);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "repair failed: %s", grub_errmsg);
-+ if (memcmp (&gpt->backup, &example_backup, sizeof (gpt->backup)))
-+ {
-+ printf ("Invalid restored backup header:\n");
-+ hexdump (16, (char*)&gpt->backup, sizeof (gpt->backup));
-+ printf ("Expected backup header:\n");
-+ hexdump (16, (char*)&example_backup, sizeof (example_backup));
-+ grub_test_assert (0, "repair did not restore backup header");
-+ }
-+ grub_gpt_free (gpt);
-+ reset_disk (&data);
-+
-+ close_disk (&data);
-+}
-+
-+/* Finding/reading/writing the backup GPT may be difficult if the OS and
-+ * BIOS report different sizes for the same disk. We need to gracefully
-+ * recognize this and avoid causing trouble for the OS. */
-+static void
-+weird_disk_size_test (void)
-+{
-+ struct test_data data;
-+ grub_gpt_t gpt;
-+
-+ open_disk (&data);
-+
-+ /* Chop off 65536 bytes (128 512B sectors) which may happen when the
-+ * BIOS thinks you are using a software RAID system that reserves that
-+ * area for metadata when in fact you are not and using the bare disk. */
-+ grub_test_assert(data.dev->disk->total_sectors == DISK_SECTORS,
-+ "unexpected disk size: 0x%llx",
-+ (unsigned long long) data.dev->disk->total_sectors);
-+ data.dev->disk->total_sectors -= 128;
-+
-+ gpt = read_disk (&data);
-+ assert_error_stack_empty ();
-+ /* Reading the alternate_lba should have been blocked and reading
-+ * the (new) end of disk should have found no useful data. */
-+ grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) == 0,
-+ "unreported missing backup header");
-+
-+ /* We should be able to reconstruct the backup header and the location
-+ * of the backup should remain unchanged, trusting the GPT data over
-+ * what the BIOS is telling us. Further changes are left to the OS. */
-+ grub_gpt_repair (data.dev->disk, gpt);
-+ grub_test_assert (grub_errno == GRUB_ERR_NONE,
-+ "repair failed: %s", grub_errmsg);
-+ grub_test_assert (memcmp (&gpt->primary, &example_primary,
-+ sizeof (gpt->primary)) == 0,
-+ "repair corrupted primary header");
-+
-+ grub_gpt_free (gpt);
-+ close_disk (&data);
-+}
-+
-+static void
-+iterate_partitions_test (void)
-+{
-+ struct test_data data;
-+ struct grub_gpt_partentry *p;
-+ grub_gpt_t gpt;
-+ grub_uint32_t n;
-+
-+ open_disk (&data);
-+ gpt = read_disk (&data);
-+
-+ for (n = 0; (p = grub_gpt_get_partentry (gpt, n)) != NULL; n++)
-+ grub_test_assert (memcmp (p, &example_entries[n], sizeof (*p)) == 0,
-+ "unexpected partition %d data", n);
-+
-+ grub_test_assert (n == TABLE_ENTRIES, "unexpected partition limit: %d", n);
-+
-+ grub_gpt_free (gpt);
-+ close_disk (&data);
-+}
-+
-+static void
-+large_partitions_test (void)
-+{
-+ struct test_data data;
-+ struct grub_gpt_partentry *p;
-+ grub_gpt_t gpt;
-+ grub_uint32_t n;
-+
-+ open_disk (&data);
-+
-+ /* Double the entry size, cut the number of entries in half. */
-+ data.raw->primary_header.maxpart =
-+ data.raw->backup_header.maxpart =
-+ grub_cpu_to_le32_compile_time (TABLE_ENTRIES/2);
-+ data.raw->primary_header.partentry_size =
-+ data.raw->backup_header.partentry_size =
-+ grub_cpu_to_le32_compile_time (ENTRY_SIZE*2);
-+ data.raw->primary_header.partentry_crc32 =
-+ data.raw->backup_header.partentry_crc32 =
-+ grub_cpu_to_le32_compile_time (0xf2c45af8);
-+ data.raw->primary_header.crc32 = grub_cpu_to_le32_compile_time (0xde00cc8f);
-+ data.raw->backup_header.crc32 = grub_cpu_to_le32_compile_time (0x6d72e284);
-+
-+ memset (&data.raw->primary_entries, 0,
-+ sizeof (data.raw->primary_entries));
-+ for (n = 0; n < TABLE_ENTRIES/2; n++)
-+ memcpy (&data.raw->primary_entries[n*2], &example_entries[n],
-+ sizeof (data.raw->primary_entries[0]));
-+ memcpy (&data.raw->backup_entries, &data.raw->primary_entries,
-+ sizeof (data.raw->backup_entries));
-+
-+ sync_disk(&data);
-+ gpt = read_disk (&data);
-+
-+ for (n = 0; (p = grub_gpt_get_partentry (gpt, n)) != NULL; n++)
-+ grub_test_assert (memcmp (p, &example_entries[n], sizeof (*p)) == 0,
-+ "unexpected partition %d data", n);
-+
-+ grub_test_assert (n == TABLE_ENTRIES/2, "unexpected partition limit: %d", n);
-+
-+ grub_gpt_free (gpt);
-+
-+ /* Editing memory beyond the entry structure should still change the crc. */
-+ data.raw->primary_entries[1].attrib = 0xff;
-+
-+ sync_disk(&data);
-+ gpt = read_disk (&data);
-+ grub_test_assert (gpt->status == (GRUB_GPT_PROTECTIVE_MBR |
-+ GRUB_GPT_PRIMARY_HEADER_VALID |
-+ GRUB_GPT_BACKUP_HEADER_VALID |
-+ GRUB_GPT_BACKUP_ENTRIES_VALID),
-+ "unexpected status: 0x%02x", gpt->status);
-+ grub_gpt_free (gpt);
-+
-+ close_disk (&data);
-+}
-+
-+static void
-+invalid_partsize_test (void)
-+{
-+ struct grub_gpt_header header = {
-+ .magic = GRUB_GPT_HEADER_MAGIC,
-+ .version = GRUB_GPT_HEADER_VERSION,
-+ .headersize = sizeof (struct grub_gpt_header),
-+ .crc32 = grub_cpu_to_le32_compile_time (0x1ff2a054),
-+ .header_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR),
-+ .alternate_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR),
-+ .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR),
-+ .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR),
-+ .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6,
-+ 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac),
-+ .partitions = grub_cpu_to_le64_compile_time (PRIMARY_TABLE_SECTOR),
-+ .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES),
-+ /* Triple the entry size, which is not valid. */
-+ .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE*3),
-+ .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c),
-+ };
-+
-+ grub_gpt_header_check(&header, GRUB_DISK_SECTOR_BITS);
-+ grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_test_assert (strcmp(grub_errmsg, "invalid GPT entry size") == 0,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+}
-+
-+static void
-+search_part_label_test (void)
-+{
-+ struct test_data data;
-+ const char *test_result;
-+ char *expected_result;
-+
-+ open_disk (&data);
-+
-+ expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name);
-+ grub_env_unset ("test_result");
-+ grub_search_part_label ("EFI SYSTEM", "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
-+ "wrong device: %s (%s)", test_result, expected_result);
-+ grub_free (expected_result);
-+
-+ expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name);
-+ grub_env_unset ("test_result");
-+ grub_search_part_label ("BIOS BOOT", "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
-+ "wrong device: %s (%s)", test_result, expected_result);
-+ grub_free (expected_result);
-+
-+ grub_env_unset ("test_result");
-+ grub_search_part_label ("bogus name", "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result == NULL,
-+ "unexpected device: %s", test_result);
-+ grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ close_disk (&data);
-+}
-+
-+static void
-+search_part_uuid_test (void)
-+{
-+ struct test_data data;
-+ const char gpt1_uuid[] = "A0F1792E-B4CE-4136-BCF2-1AFC133C2828";
-+ const char gpt2_uuid[] = "876c898d-1b40-4727-a161-edf9b5486674";
-+ const char bogus_uuid[] = "1534c928-c50e-4866-9daf-6a9fd7918a76";
-+ const char *test_result;
-+ char *expected_result;
-+
-+ open_disk (&data);
-+
-+ expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name);
-+ grub_env_unset ("test_result");
-+ grub_search_part_uuid (gpt1_uuid, "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
-+ "wrong device: %s (%s)", test_result, expected_result);
-+ grub_free (expected_result);
-+
-+ expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name);
-+ grub_env_unset ("test_result");
-+ grub_search_part_uuid (gpt2_uuid, "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
-+ "wrong device: %s (%s)", test_result, expected_result);
-+ grub_free (expected_result);
-+
-+ grub_env_unset ("test_result");
-+ grub_search_part_uuid (bogus_uuid, "test_result", 0, NULL, 0);
-+ test_result = grub_env_get ("test_result");
-+ grub_test_assert (test_result == NULL,
-+ "unexpected device: %s", test_result);
-+ grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND,
-+ "unexpected error: %s", grub_errmsg);
-+ grub_errno = GRUB_ERR_NONE;
-+
-+ close_disk (&data);
-+}
-+
-+void
-+grub_unit_test_init (void)
-+{
-+ grub_init_all ();
-+ grub_hostfs_init ();
-+ grub_host_init ();
-+ grub_test_register ("gpt_pmbr_test", pmbr_test);
-+ grub_test_register ("gpt_header_test", header_test);
-+ grub_test_register ("gpt_read_valid_test", read_valid_test);
-+ grub_test_register ("gpt_read_invalid_test", read_invalid_entries_test);
-+ grub_test_register ("gpt_read_fallback_test", read_fallback_test);
-+ grub_test_register ("gpt_repair_test", repair_test);
-+ grub_test_register ("gpt_iterate_partitions_test", iterate_partitions_test);
-+ grub_test_register ("gpt_large_partitions_test", large_partitions_test);
-+ grub_test_register ("gpt_invalid_partsize_test", invalid_partsize_test);
-+ grub_test_register ("gpt_weird_disk_size_test", weird_disk_size_test);
-+ grub_test_register ("gpt_search_part_label_test", search_part_label_test);
-+ grub_test_register ("gpt_search_uuid_test", search_part_uuid_test);
-+}
-+
-+void
-+grub_unit_test_fini (void)
-+{
-+ grub_test_unregister ("gpt_pmbr_test");
-+ grub_test_unregister ("gpt_header_test");
-+ grub_test_unregister ("gpt_read_valid_test");
-+ grub_test_unregister ("gpt_read_invalid_test");
-+ grub_test_unregister ("gpt_read_fallback_test");
-+ grub_test_unregister ("gpt_repair_test");
-+ grub_test_unregister ("gpt_iterate_partitions_test");
-+ grub_test_unregister ("gpt_large_partitions_test");
-+ grub_test_unregister ("gpt_invalid_partsize_test");
-+ grub_test_unregister ("gpt_weird_disk_size_test");
-+ grub_test_unregister ("gpt_search_part_label_test");
-+ grub_test_unregister ("gpt_search_part_uuid_test");
-+ grub_fini_all ();
-+}
-diff --git a/tests/gptprio_test.in b/tests/gptprio_test.in
-new file mode 100644
-index 000000000..c5cf0f3b7
---- /dev/null
-+++ b/tests/gptprio_test.in
-@@ -0,0 +1,207 @@
-+#! /bin/bash
-+set -e
-+
-+# Copyright (C) 2010 Free Software Foundation, Inc.
-+# Copyright (C) 2014 CoreOS, Inc.
-+#
-+# GRUB is free software: you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation, either version 3 of the License, or
-+# (at your option) any later version.
-+#
-+# GRUB is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with GRUB. If not, see .
-+
-+sgdisk=sgdisk
-+grubshell=@builddir@/grub-shell
-+
-+if ! which "${sgdisk}" >/dev/null 2>&1; then
-+ echo "sgdisk not installed; cannot test gptprio."
-+ exit 77
-+fi
-+
-+. "@builddir@/grub-core/modinfo.sh"
-+
-+case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
-+ mips-qemu_mips | mipsel-qemu_mips | i386-qemu | i386-multiboot | i386-coreboot | mipsel-loongson)
-+ disk=ata0
-+ ;;
-+ powerpc-ieee1275)
-+ disk=ieee1275//pci@80000000/mac-io@4/ata-3@20000/disk@0
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ sparc64-ieee1275)
-+ disk=ieee1275//pci@1fe\,0/pci-ata@5/ide0@500/disk@0
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ i386-ieee1275)
-+ disk=ieee1275/d
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ mips-arc)
-+ # FIXME: ARC firmware has bugs which prevent it from accessing hard disk w/o dvh disklabel.
-+ exit 0 ;;
-+ mipsel-arc)
-+ disk=arc/scsi0/disk0/rdisk0
-+ ;;
-+ *)
-+ disk=hd0
-+ ;;
-+esac
-+img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-+trap "rm -f '${img1}'" EXIT
-+
-+prio_type="5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6"
-+declare -a prio_uuid
-+prio_uuid[2]="9b003904-d006-4ab3-97f1-73f547b7af1a"
-+prio_uuid[3]="1aa5a658-5b02-414d-9b71-f7e6c151f0cd"
-+prio_uuid[4]="8aa0240d-98af-42b0-b32a-ccbe0572d62b"
-+
-+create_disk_image () {
-+ size=$1
-+ rm -f "${img1}"
-+ dd if=/dev/zero of="${img1}" bs=512 count=1 seek=$((size - 1)) status=none
-+ ${sgdisk} \
-+ -n 1:0:+1 -c 1:ESP -t 1:ef00 \
-+ -n 2:0:+1 -c 2:A -t 2:"${prio_type}" -u 2:"${prio_uuid[2]}" \
-+ -n 3:0:+1 -c 3:B -t 3:"${prio_type}" -u 3:"${prio_uuid[3]}" \
-+ -n 4:0:+1 -c 4:C -t 4:"${prio_type}" -u 4:"${prio_uuid[4]}" \
-+ "${img1}" >/dev/null
-+}
-+
-+wipe_disk_area () {
-+ sector=$1
-+ size=$2
-+ dd if=/dev/zero of="${img1}" bs=512 count=${size} seek=${sector} conv=notrunc status=none
-+}
-+
-+is_zero () {
-+ sector=$1
-+ size=$2
-+ cmp -s -i $((sector * 512)) -n $((size * 512)) /dev/zero "${img1}"
-+}
-+
-+check_is_zero () {
-+ sector=$1
-+ size=$2
-+ if ! is_zero "$@"; then
-+ echo "$size sector(s) starting at $sector should be all zero"
-+ exit 1
-+ fi
-+}
-+
-+check_not_zero () {
-+ sector=$1
-+ size=$2
-+ if is_zero "$@"; then
-+ echo "$size sector(s) starting at $sector should not be all zero"
-+ exit 1
-+ fi
-+}
-+
-+fmt_prio () {
-+ priority=$(( ( $1 & 15 ) << 48 ))
-+ tries=$(( ( $2 & 15 ) << 52 ))
-+ success=$(( ( $3 & 1 ) << 56 ))
-+ printf %016x $(( priority | tries | success ))
-+}
-+
-+set_prio () {
-+ part="$1"
-+ attr=$(fmt_prio $2 $3 $4)
-+ ${sgdisk} -A "${part}:=:${attr}" "${img1}" >/dev/null
-+}
-+
-+check_prio () {
-+ part="$1"
-+ expect=$(fmt_prio $2 $3 $4)
-+ result=$(LANG=C ${sgdisk} -i "${part}" "${img1}" 2>&1 \
-+ | awk '/^Attribute flags: / {print $3}')
-+ if [[ "${expect}" != "${result}" ]]; then
-+ echo "Partition ${part} has attributes ${result:-??}, not ${expect}"
-+ exit 1
-+ fi
-+}
-+
-+run_next() {
-+ "${grubshell}" --disk="${img1}" --modules=gptprio <.
-+
-+parted=parted
-+grubshell=@builddir@/grub-shell
-+
-+. "@builddir@/grub-core/modinfo.sh"
-+
-+case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
-+ mips-qemu_mips | mipsel-qemu_mips | i386-qemu | i386-multiboot | i386-coreboot | mipsel-loongson)
-+ disk=ata0
-+ ;;
-+ powerpc-ieee1275)
-+ disk=ieee1275//pci@80000000/mac-io@4/ata-3@20000/disk@0
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ sparc64-ieee1275)
-+ disk=ieee1275//pci@1fe\,0/pci-ata@5/ide0@500/disk@0
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ i386-ieee1275)
-+ disk=ieee1275/d
-+ # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label.
-+ exit 0
-+ ;;
-+ mips-arc)
-+ # FIXME: ARC firmware has bugs which prevent it from accessing hard disk w/o dvh disklabel.
-+ exit 0 ;;
-+ mipsel-arc)
-+ disk=arc/scsi0/disk0/rdisk0
-+ ;;
-+ *)
-+ disk=hd0
-+ ;;
-+esac
-+img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-+img2="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
-+trap "rm -f '${img1}' '${img2}'" EXIT
-+
-+create_disk_image () {
-+ size=$1
-+ rm -f "${img1}"
-+ dd if=/dev/zero of="${img1}" bs=512 count=1 seek=$((size - 1)) status=none
-+ ${parted} -a none -s "${img1}" mklabel gpt
-+ cp "${img1}" "${img2}"
-+}
-+
-+wipe_disk_area () {
-+ sector=$1
-+ size=$2
-+ dd if=/dev/zero of="${img2}" bs=512 count=${size} seek=${sector} conv=notrunc status=none
-+}
-+
-+do_repair () {
-+ output="`echo "gptrepair ($disk)" | "${grubshell}" --disk="${img2}"`"
-+ if echo "${output}" | grep ^error; then
-+ return 1
-+ fi
-+ if echo "${output}" | grep -v GPT; then
-+ echo "Unexpected output ${output}"
-+ return 1
-+ fi
-+ echo "${output}"
-+}
-+
-+echo "Nothing to repair:"
-+create_disk_image 100
-+do_repair
-+cmp "${img1}" "${img2}"
-+echo
-+
-+echo "Repair primary (MBR left intact)"
-+create_disk_image 100
-+wipe_disk_area 1 1
-+do_repair
-+cmp "${img1}" "${img2}"
-+echo
-+
-+echo "Repair backup"
-+create_disk_image 100
-+wipe_disk_area 99 1
-+do_repair
-+cmp "${img1}" "${img2}"
-+echo
---
-2.34.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-verity-hash.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-verity-hash.patch
deleted file mode 100644
index ed892d90dd..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-add-verity-hash.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From 14d4760aacb8896f99422c06d100e5231e09e797 Mon Sep 17 00:00:00 2001
-From: Sayan Chowdhury
-Date: Thu, 24 Aug 2023 00:00:00 +0530
-Subject: Add verity hash passthrough
-
-Read the verity hash from the kernel binary and pass it to the running
-system via the kernel command line
-
-The patch is prepared using the coreos/grub PRs, picking the only
-required ones, and dropping the others. The README.md file in the
-coreos-overlay/sys-boot/grub/ contains more contexual information
-along with the commits used to create the patch.
-
-Authored-by: Matthew Garrett
-Signed-off-by: Sayan Chowdhury
----
- grub-core/loader/arm64/linux.c | 6 +++-
- grub-core/loader/i386/linux.c | 3 ++
- include/grub/verity-hash.h | 51 ++++++++++++++++++++++++++++++++++
- 3 files changed, 59 insertions(+), 1 deletion(-)
- create mode 100644 include/grub/verity-hash.h
-
-diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
-index ef3e9f944..17bed4e15 100644
---- a/grub-core/loader/arm64/linux.c
-+++ b/grub-core/loader/arm64/linux.c
-@@ -34,6 +34,8 @@
- #include
- #include
-
-+#include
-+
- GRUB_MOD_LICENSE ("GPLv3+");
-
- static grub_dl_t my_mod;
-@@ -333,7 +335,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
-
-- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
-+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE)
-+ + VERITY_CMDLINE_LENGTH;
- linux_args = grub_malloc (cmdline_size);
- if (!linux_args)
- {
-@@ -350,6 +353,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
-
- if (grub_errno == GRUB_ERR_NONE)
- {
-+ grub_pass_verity_hash (kernel_addr, linux_args, cmdline_size);
- grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
- loaded = 1;
- }
-diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
-index 9f74a96b1..1c76ac5bf 100644
---- a/grub-core/loader/i386/linux.c
-+++ b/grub-core/loader/i386/linux.c
-@@ -38,6 +38,8 @@
- #include
- #include
-
-+#include
-+
- GRUB_MOD_LICENSE ("GPLv3+");
-
- #ifdef GRUB_MACHINE_PCBIOS
-@@ -1006,6 +1008,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
- goto fail;
- }
-
-+ grub_pass_verity_hash(&lh, linux_cmdline, maximal_cmdline_size);
- len = prot_file_size;
- if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
-diff --git a/include/grub/verity-hash.h b/include/grub/verity-hash.h
-new file mode 100644
-index 000000000..448d9aff0
---- /dev/null
-+++ b/include/grub/verity-hash.h
-@@ -0,0 +1,51 @@
-+/* CoreOS verity hash */
-+
-+#define VERITY_ARG " verity.usrhash="
-+#define VERITY_ARG_LENGTH (sizeof (VERITY_ARG) - 1)
-+#define VERITY_HASH_LENGTH 64
-+#define VERITY_CMDLINE_LENGTH ((VERITY_ARG_LENGTH)+(VERITY_HASH_LENGTH))
-+
-+#if defined(__aarch64__)
-+# define VERITY_HASH_OFFSET 512
-+#elif defined(__i386__) || defined(__amd64__)
-+# define VERITY_HASH_OFFSET 0x40
-+#else
-+# error Unsupported arch
-+#endif
-+
-+
-+/**
-+ * grub_pass_verity_hash - Reads the CoreOS verity hash value from a well known
-+ * kernel image offset and adds a kernel command line argument for it.
-+ *
-+ * @pImage: Kernel image buffer.
-+ * @cmdline: Kernel command line buffer.
-+ * @cmdline_max_len: Kernel command line buffer length.
-+ */
-+
-+static inline void grub_pass_verity_hash(const void *pImage,
-+ char *cmdline,
-+ grub_size_t cmdline_max_len)
-+{
-+ const char *buf = pImage;
-+ grub_size_t cmdline_len;
-+ int i;
-+
-+ for (i=VERITY_HASH_OFFSET; i '9') // Not a number
-+ if (buf[i] < 'a' || buf[i] > 'f') // Not a hex letter
-+ return;
-+ }
-+
-+ cmdline_len = grub_strlen(cmdline);
-+ if (cmdline_len + VERITY_CMDLINE_LENGTH > cmdline_max_len)
-+ return;
-+
-+ grub_memcpy (cmdline + cmdline_len, VERITY_ARG, VERITY_ARG_LENGTH);
-+ cmdline_len += VERITY_ARG_LENGTH;
-+ grub_memcpy (cmdline + cmdline_len, buf + VERITY_HASH_OFFSET,
-+ VERITY_HASH_LENGTH);
-+ cmdline_len += VERITY_HASH_LENGTH;
-+ cmdline[cmdline_len] = '\0';
-+}
---
-2.34.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-fs-ext2-ignore-checksum-seed.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-fs-ext2-ignore-checksum-seed.patch
deleted file mode 100644
index 9024b479a8..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-fs-ext2-ignore-checksum-seed.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-https://bugs.gentoo.org/894200
-https://git.savannah.gnu.org/cgit/grub.git/patch/?id=7fd5feff97c4b1f446f8fcf6d37aca0c64e7c763
-
-From 7fd5feff97c4b1f446f8fcf6d37aca0c64e7c763 Mon Sep 17 00:00:00 2001
-From: Javier Martinez Canillas
-Date: Fri, 11 Jun 2021 21:36:16 +0200
-Subject: fs/ext2: Ignore checksum seed incompat feature
-
-This incompat feature is used to denote that the filesystem stored its
-metadata checksum seed in the superblock. This is used to allow tune2fs
-changing the UUID on a mounted metdata_csum filesystem without having
-to rewrite all the disk metadata. However, the GRUB doesn't use the
-metadata checksum at all. So, it can just ignore this feature if it
-is enabled. This is consistent with the GRUB filesystem code in general
-which just does a best effort to access the filesystem's data.
-
-The checksum seed incompat feature has to be removed from the ignore
-list if the support for metadata checksum verification is added to the
-GRUB ext2 driver later.
-
-Suggested-by: Eric Sandeen
-Suggested-by: Lukas Czerner
-Signed-off-by: Javier Martinez Canillas
-Reviewed-by: Lukas Czerner
-Reviewed-by: Daniel Kiper
----
- grub-core/fs/ext2.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
-index e7dd78e..4953a15 100644
---- a/grub-core/fs/ext2.c
-+++ b/grub-core/fs/ext2.c
-@@ -103,6 +103,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
- #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
- #define EXT4_FEATURE_INCOMPAT_MMP 0x0100
- #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
-+#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000
- #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
-
- /* The set of back-incompatible features this driver DOES support. Add (OR)
-@@ -123,10 +124,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
- * mmp: Not really back-incompatible - was added as such to
- * avoid multiple read-write mounts. Safe to ignore for this
- * RO driver.
-+ * checksum seed: Not really back-incompatible - was added to allow tools
-+ * such as tune2fs to change the UUID on a mounted metadata
-+ * checksummed filesystem. Safe to ignore for now since the
-+ * driver doesn't support checksum verification. However, it
-+ * has to be removed from this list if the support is added later.
- */
- #define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \
-- | EXT4_FEATURE_INCOMPAT_MMP)
--
-+ | EXT4_FEATURE_INCOMPAT_MMP \
-+ | EXT4_FEATURE_INCOMPAT_CSUM_SEED)
-
- #define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U
-
---
-cgit v1.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-gentpl.py-Remove-.interp-section-from-.img-files.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-gentpl.py-Remove-.interp-section-from-.img-files.patch
deleted file mode 100644
index 8d543d4ea9..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-gentpl.py-Remove-.interp-section-from-.img-files.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 28ad1f9b95799afc94fa178ec935e297da94cced Mon Sep 17 00:00:00 2001
-From: Nicholas Vinson
-Date: Fri, 13 Jan 2023 02:56:35 -0500
-Subject: [PATCH] gentpl.py: Remove .interp section from .img files.
-
-Whn building .img files, a .interp section from the .image files will
-sometimes be copied into the .img file. This additional section pushes
-the .img file beyond the 512-byte limit and causes grub-install to fail
-to run for i386-pc platforms.
-
-Signed-off-by: Nicholas Vinson
----
- gentpl.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gentpl.py b/gentpl.py
-index c86550d4f..823a8b5f8 100644
---- a/gentpl.py
-+++ b/gentpl.py
-@@ -766,7 +766,7 @@ def image(defn, platform):
- if test x$(TARGET_APPLE_LINKER) = x1; then \
- $(MACHO2IMG) $< $@; \
- else \
-- $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx $< $@; \
-+ $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx -R .interp $< $@; \
- fi
- """)
-
---
-2.39.0
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-grub-mkconfig-restore-umask.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-grub-mkconfig-restore-umask.patch
deleted file mode 100644
index e2a6414ef0..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-grub-mkconfig-restore-umask.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0adec29674561034771c13e446069b41ef41e4d4 Mon Sep 17 00:00:00 2001
-From: Michael Chang
-Date: Fri, 3 Dec 2021 16:13:28 +0800
-Subject: grub-mkconfig: Restore umask for the grub.cfg
-
-The commit ab2e53c8a (grub-mkconfig: Honor a symlink when generating
-configuration by grub-mkconfig) has inadvertently discarded umask for
-creating grub.cfg in the process of running grub-mkconfig. The resulting
-wrong permission (0644) would allow unprivileged users to read GRUB
-configuration file content. This presents a low confidentiality risk
-as grub.cfg may contain non-secured plain-text passwords.
-
-This patch restores the missing umask and sets the creation file mode
-to 0600 preventing unprivileged access.
-
-Fixes: CVE-2021-3981
-
-Signed-off-by: Michael Chang
-Reviewed-by: Daniel Kiper
----
- util/grub-mkconfig.in | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
-index c3ea761..62335d0 100644
---- a/util/grub-mkconfig.in
-+++ b/util/grub-mkconfig.in
-@@ -301,7 +301,10 @@ and /etc/grub.d/* files or please file a bug report with
- exit 1
- else
- # none of the children aborted with error, install the new grub.cfg
-+ oldumask=$(umask)
-+ umask 077
- cat ${grub_cfg}.new > ${grub_cfg}
-+ umask $oldumask
- rm -f ${grub_cfg}.new
- fi
- fi
---
-cgit v1.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-locale.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-locale.patch
deleted file mode 100644
index 14706cbca3..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-locale.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 5983c2c6adf1c1bbb3ecd751253d1e898bdfd8a3 Mon Sep 17 00:00:00 2001
-From: Michael Chang
-Date: Tue, 26 Oct 2021 15:11:00 +0800
-Subject: templates: Filter out POSIX locale for translation
-
-The POSIX locale is default or native operating system's locale
-identical to the C locale, so no translation to human speaking languages
-are provided. For this reason we should filter out LANG=POSIX as well as
-LANG=C upon generating grub.cfg to avoid looking up for it's gettext's
-message catalogs that will consequently result in an unpleasant message:
-
- error: file `/boot/grub/locale/POSIX.gmo' not found
-
-Signed-off-by: Michael Chang
-Reviewed-by: Daniel Kiper
----
- util/grub.d/00_header.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
-index 93a9023..f74c2a4 100644
---- a/util/grub.d/00_header.in
-+++ b/util/grub.d/00_header.in
-@@ -191,7 +191,7 @@ EOF
- EOF
-
- # Gettext variables and module
--if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then
-+if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "xPOSIX" ] && [ "x${LANG}" != "x" ]; then
- cat << EOF
- set locale_dir=\$prefix/locale
- set lang=${grub_lang}
---
-cgit v1.1
-
-From f42266a8a2a4215e4ffe419b8092bdf9ced33e8e Mon Sep 17 00:00:00 2001
-From: Christian Hesse
-Date: Mon, 19 Sep 2022 15:31:28 +0200
-Subject: templates: Filter C.UTF-8 locale for translation
-
-In addition to C locale there is also C.UTF-8 locale now. Filter that as
-well, by using ${grub_lang}, which contains a stripped value.
-This fixes the following message and resulting boot failure:
-
- error: file `/boot/grub/locale/C.gmo' not found.
-
-Signed-off-by: Christian Hesse
-Reviewed-by: Daniel Kiper
----
- util/grub.d/00_header.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
-index f74c2a4..6a316a5 100644
---- a/util/grub.d/00_header.in
-+++ b/util/grub.d/00_header.in
-@@ -191,7 +191,7 @@ EOF
- EOF
-
- # Gettext variables and module
--if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "xPOSIX" ] && [ "x${LANG}" != "x" ]; then
-+if [ "x${grub_lang}" != "xC" ] && [ "x${LANG}" != "xPOSIX" ] && [ "x${LANG}" != "x" ]; then
- cat << EOF
- set locale_dir=\$prefix/locale
- set lang=${grub_lang}
---
-cgit v1.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-riscv.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-riscv.patch
deleted file mode 100644
index 83c5437570..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.06-riscv.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-https://bugs.gentoo.org/905785
-
-From 049efdd72eb7baa7b2bf8884391ee7fe650da5a0 Mon Sep 17 00:00:00 2001
-From: Heinrich Schuchardt
-Date: Sat, 29 Jan 2022 13:36:55 +0100
-Subject: RISC-V: Adjust -march flags for binutils 2.38
-
-As of version 2.38 binutils defaults to ISA specification version
-2019-12-13. This version of the specification has has separated the
-the csr read/write (csrr*/csrw*) instructions and the fence.i from
-the I extension and put them into separate Zicsr and Zifencei
-extensions.
-
-This implies that we have to adjust the -march flag passed to the
-compiler accordingly.
-
-Signed-off-by: Heinrich Schuchardt
-Reviewed-by: Daniel Kiper
----
- configure.ac | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/configure.ac b/configure.ac
-index 4f649ed..5c01af0 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -870,11 +870,19 @@ if test x"$platform" != xemu ; then
- CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
- [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], [])
-+ # ISA spec version 20191213 factored out extensions Zicsr and Zifencei
-+ CFLAGS="$TARGET_CFLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Werror"
-+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-+ [grub_cv_target_cc_soft_float="-march=rv32imac_zicsr_zifencei -mabi=ilp32"], [])
- fi
- if test "x$target_cpu" = xriscv64; then
- CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
- [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], [])
-+ # ISA spec version 20191213 factored out extensions Zicsr and Zifencei
-+ CFLAGS="$TARGET_CFLAGS -march=rv64imac_zicsr_zifencei -mabi=lp64 -Werror"
-+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
-+ [grub_cv_target_cc_soft_float="-march=rv64imac_zicsr_zifencei -mabi=lp64"], [])
- fi
- if test "x$target_cpu" = xia64; then
- CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror"
---
-cgit v1.1
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.12_rc1-util-grub.d-25_bli.in-fix-shebang-on-unmerged-usr.patch b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.12_rc1-util-grub.d-25_bli.in-fix-shebang-on-unmerged-usr.patch
deleted file mode 100644
index 6c5096d35e..0000000000
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/files/grub-2.12_rc1-util-grub.d-25_bli.in-fix-shebang-on-unmerged-usr.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From f827aac60d760a026db642b9d5c1ecbf587cfefc Mon Sep 17 00:00:00 2001
-From: Oskari Pirhonen
-Date: Mon, 10 Jul 2023 23:55:43 -0500
-Subject: [PATCH] util/grub.d/25_bli.in: fix shebang on unmerged-usr
-
-On an unmerged-usr system, grub-mkconfig errors out with the following
-error due to /usr/bin/sh not existing:
-
-/usr/sbin/grub-mkconfig: /etc/grub.d/25_bli: /usr/bin/sh: bad interpreter: No such file or directory
-
-Use a /bin/sh shebang to fix the error as well as match the other
-existing files.
-
-Signed-off-by: Oskari Pirhonen
----
- util/grub.d/25_bli.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/util/grub.d/25_bli.in b/util/grub.d/25_bli.in
-index 6e4538716..26e27a019 100644
---- a/util/grub.d/25_bli.in
-+++ b/util/grub.d/25_bli.in
-@@ -1,4 +1,4 @@
--#!/usr/bin/sh
-+#! /bin/sh
- set -e
-
- # grub-mkconfig helper script.
---
-2.41.0
-
diff --git a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r7.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r9.ebuild
similarity index 93%
rename from sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r7.ebuild
rename to sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r9.ebuild
index df7a8afb62..f372a2ec6a 100644
--- a/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r7.ebuild
+++ b/sdk_container/src/third_party/coreos-overlay/sys-boot/grub/grub-2.06-r9.ebuild
@@ -54,26 +54,19 @@ if [[ ${PV} != 9999 ]]; then
"
S=${WORKDIR}/${P%_*}
fi
- KEYWORDS="amd64 arm arm64 ~ia64 ppc ppc64 ~riscv sparc x86"
+ KEYWORDS="amd64 ~arm ~arm64 ~ia64 ~ppc ~ppc64 ~riscv ~sparc x86"
else
inherit git-r3
EGIT_REPO_URI="https://git.savannah.gnu.org/git/grub.git"
fi
-SRC_URI+=" https://dev.gentoo.org/~floppym/dist/${P}-backports-r2.tar.xz"
+SRC_URI+=" https://dev.gentoo.org/~floppym/dist/${P}-backports-r3.tar.xz"
PATCHES=(
"${WORKDIR}/${P}-backports"
"${FILESDIR}"/gfxpayload.patch
"${FILESDIR}"/grub-2.02_beta2-KERNEL_GLOBS.patch
"${FILESDIR}"/grub-2.06-test-words.patch
- "${FILESDIR}"/grub-2.06-grub-mkconfig-restore-umask.patch
- "${FILESDIR}"/grub-2.06-gentpl.py-Remove-.interp-section-from-.img-files.patch
- "${FILESDIR}"/grub-2.06-fs-ext2-ignore-checksum-seed.patch
- "${FILESDIR}"/grub-2.06-riscv.patch
- "${FILESDIR}"/grub-2.06-locale.patch
- "${FILESDIR}"/grub-2.06-add-verity-hash.patch
- "${FILESDIR}"/grub-2.06-add-gpt-partition-scheme.patch
)
DEJAVU=dejavu-sans-ttf-2.37
@@ -91,9 +84,6 @@ IUSE="device-mapper doc efiemu +fonts mount nls sdl test +themes truetype libzfs
GRUB_ALL_PLATFORMS=( coreboot efi-32 efi-64 emu ieee1275 loongson multiboot
qemu qemu-mips pc uboot xen xen-32 xen-pvh )
-
-# Flatcar: Add arm64 to the list of platforms
-GRUB_ALL_PLATFORMS+=( arm64 )
IUSE+=" ${GRUB_ALL_PLATFORMS[@]/#/grub_platforms_}"
REQUIRED_USE="
@@ -109,7 +99,6 @@ BDEPEND="
sys-devel/bison
sys-apps/help2man
sys-apps/texinfo
- grub_platforms_arm64? ( cross-aarch64-cros-linux-gnu/gcc )
fonts? (
media-libs/freetype:2
virtual/pkgconfig
@@ -216,7 +205,6 @@ grub_configure() {
efi*) platform=efi ;;
xen-pvh) platform=xen_pvh ;;
xen*) platform=xen ;;
- arm64*) platform=efi ;;
guessed) ;;
*) platform=${MULTIBUILD_VARIANT} ;;
esac