cgpt: Separate out certain GPT manipluation functions

For kernel NAND support, some vboot/cgptlib functionality is
needed from depthcharge. This patch moves certain function
declarations to a new header in firmware/include and puts
their definitions in a common place.

TEST=make runalltests passes and packages build
BRANCH=none
BUG=chromium:403432

Change-Id: Idd42b1f9f531651d78bb4afb80ca90c24aae93d9
Reviewed-on: https://chromium-review.googlesource.com/224996
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Daniel Ehrenberg <dehrenberg@chromium.org>
Tested-by: Daniel Ehrenberg <dehrenberg@chromium.org>
diff --git a/Makefile b/Makefile
index a778870..c344b08 100644
--- a/Makefile
+++ b/Makefile
@@ -271,6 +271,7 @@
 	firmware/lib/cgptlib/cgptlib_internal.c \
 	firmware/lib/cgptlib/crc32.c \
 	firmware/lib/cgptlib/mtdlib.c \
+	firmware/lib/gpt_misc.c \
 	firmware/lib/utility_string.c \
 	firmware/lib/vboot_api_kernel.c \
 	firmware/lib/vboot_audio.c \
diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h
new file mode 100644
index 0000000..4d91bd8
--- /dev/null
+++ b/firmware/include/gpt_misc.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VBOOT_REFERENCE_CGPT_MISC_H_
+#define VBOOT_REFERENCE_CGPT_MISC_H_
+
+#include "vboot_api.h"
+
+enum {
+	GPT_SUCCESS = 0,
+	GPT_ERROR_NO_VALID_KERNEL,
+	GPT_ERROR_INVALID_HEADERS,
+	GPT_ERROR_INVALID_ENTRIES,
+	GPT_ERROR_INVALID_SECTOR_SIZE,
+	GPT_ERROR_INVALID_SECTOR_NUMBER,
+	GPT_ERROR_INVALID_UPDATE_TYPE,
+	GPT_ERROR_CRC_CORRUPTED,
+	GPT_ERROR_OUT_OF_REGION,
+	GPT_ERROR_START_LBA_OVERLAP,
+	GPT_ERROR_END_LBA_OVERLAP,
+	GPT_ERROR_DUP_GUID,
+	GPT_ERROR_INVALID_FLASH_GEOMETRY,
+	GPT_ERROR_NO_SUCH_ENTRY,
+	/* Number of errors */
+	GPT_ERROR_COUNT
+};
+
+/* Bit masks for GptData.modified field. */
+#define GPT_MODIFIED_HEADER1 0x01
+#define GPT_MODIFIED_HEADER2 0x02
+#define GPT_MODIFIED_ENTRIES1 0x04
+#define GPT_MODIFIED_ENTRIES2 0x08
+
+/*
+ * Size of GptData.primary_entries and secondary_entries: 128 bytes/entry * 128
+ * entries.
+ */
+#define TOTAL_ENTRIES_SIZE 16384
+
+/*
+ * The 'update_type' of GptUpdateKernelEntry().  We expose TRY and BAD only
+ * because those are what verified boot needs.  For more precise control on GPT
+ * attribute bits, please refer to gpt_internal.h.
+ */
+enum {
+	/*
+	 * System will be trying to boot the currently selected kernel
+	 * partition.  Update its try count if necessary.
+	 */
+	GPT_UPDATE_ENTRY_TRY = 1,
+	/*
+	 * The currently selected kernel partition failed validation.  Mark
+	 * entry as invalid.
+	 */
+	GPT_UPDATE_ENTRY_BAD = 2,
+};
+
+typedef struct {
+	/* Fill in the following fields before calling GptInit() */
+	/* GPT primary header, from sector 1 of disk (size: 512 bytes) */
+	uint8_t *primary_header;
+	/* GPT secondary header, from last sector of disk (size: 512 bytes) */
+	uint8_t *secondary_header;
+	/* Primary GPT table, follows primary header (size: 16 KB) */
+	uint8_t *primary_entries;
+	/* Secondary GPT table, precedes secondary header (size: 16 KB) */
+	uint8_t *secondary_entries;
+	/* Size of a LBA sector, in bytes */
+	uint32_t sector_bytes;
+	/* Size of drive in LBA sectors, in sectors */
+	uint64_t drive_sectors;
+
+	/* Outputs */
+	/* Which inputs have been modified?  GPT_MODIFIED_* */
+	uint8_t modified;
+	/*
+	 * The current chromeos kernel index in partition table.  -1 means not
+	 * found on drive. Note that GPT partition numbers are traditionally
+	 * 1-based, but we're using a zero-based index here.
+	 */
+	int current_kernel;
+
+	/* Internal variables */
+	uint32_t valid_headers, valid_entries;
+	int current_priority;
+} GptData;
+
+/**
+ * Initializes the GPT data structure's internal state.
+ *
+ * The following fields must be filled before calling this function:
+ *
+ *   primary_header
+ *   secondary_header
+ *   primary_entries
+ *   secondary_entries
+ *   sector_bytes
+ *   drive_sectors
+ *
+ * On return the modified field may be set, if the GPT data has been modified
+ * and should be written to disk.
+ *
+ * Returns GPT_SUCCESS if successful, non-zero if error:
+ *   GPT_ERROR_INVALID_HEADERS, both partition table headers are invalid, enters
+ *                              recovery mode,
+ *   GPT_ERROR_INVALID_ENTRIES, both partition table entries are invalid, enters
+ *                              recovery mode,
+ *   GPT_ERROR_INVALID_SECTOR_SIZE, size of a sector is not supported,
+ *   GPT_ERROR_INVALID_SECTOR_NUMBER, number of sectors in drive is invalid (too
+ *                                    small) */
+int GptInit(GptData *gpt);
+
+/**
+ * Allocate and read GPT data from the drive.  The sector_bytes and
+ * drive_sectors fields should be filled on input.  The primary and secondary
+ * header and entries are filled on output.
+ *
+ * Returns 0 if successful, 1 if error.
+ */
+int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata);
+
+/**
+ * Write any changes for the GPT data back to the drive, then free the buffers.
+ */
+int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata);
+
+#endif  /* VBOOT_REFERENCE_CGPT_MISC_H_ */
diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c
index 38ca7d9..9fdf9e2 100644
--- a/firmware/lib/cgptlib/cgptlib_internal.c
+++ b/firmware/lib/cgptlib/cgptlib_internal.c
@@ -9,6 +9,7 @@
 #include "cgptlib_internal.h"
 #include "crc32.h"
 #include "gpt.h"
+#include "gpt_misc.h"
 #include "utility.h"
 
 
diff --git a/firmware/lib/cgptlib/include/cgptlib.h b/firmware/lib/cgptlib/include/cgptlib.h
index ef32978..968ec63 100644
--- a/firmware/lib/cgptlib/include/cgptlib.h
+++ b/firmware/lib/cgptlib/include/cgptlib.h
@@ -7,110 +7,7 @@
 #define VBOOT_REFERENCE_CGPTLIB_H_
 
 #include "sysincludes.h"
-
-enum {
-	GPT_SUCCESS = 0,
-	GPT_ERROR_NO_VALID_KERNEL,
-	GPT_ERROR_INVALID_HEADERS,
-	GPT_ERROR_INVALID_ENTRIES,
-	GPT_ERROR_INVALID_SECTOR_SIZE,
-	GPT_ERROR_INVALID_SECTOR_NUMBER,
-	GPT_ERROR_INVALID_UPDATE_TYPE,
-	GPT_ERROR_CRC_CORRUPTED,
-	GPT_ERROR_OUT_OF_REGION,
-	GPT_ERROR_START_LBA_OVERLAP,
-	GPT_ERROR_END_LBA_OVERLAP,
-	GPT_ERROR_DUP_GUID,
-	GPT_ERROR_INVALID_FLASH_GEOMETRY,
-	GPT_ERROR_NO_SUCH_ENTRY,
-	/* Number of errors */
-	GPT_ERROR_COUNT
-};
-
-/* Bit masks for GptData.modified field. */
-#define GPT_MODIFIED_HEADER1 0x01
-#define GPT_MODIFIED_HEADER2 0x02
-#define GPT_MODIFIED_ENTRIES1 0x04
-#define GPT_MODIFIED_ENTRIES2 0x08
-
-/*
- * Size of GptData.primary_entries and secondary_entries: 128 bytes/entry * 128
- * entries.
- */
-#define TOTAL_ENTRIES_SIZE 16384
-
-/*
- * The 'update_type' of GptUpdateKernelEntry().  We expose TRY and BAD only
- * because those are what verified boot needs.  For more precise control on GPT
- * attribute bits, please refer to gpt_internal.h.
- */
-enum {
-	/*
-	 * System will be trying to boot the currently selected kernel
-	 * partition.  Update its try count if necessary.
-	 */
-	GPT_UPDATE_ENTRY_TRY = 1,
-	/*
-	 * The currently selected kernel partition failed validation.  Mark
-	 * entry as invalid.
-	 */
-	GPT_UPDATE_ENTRY_BAD = 2,
-};
-
-typedef struct {
-	/* Fill in the following fields before calling GptInit() */
-	/* GPT primary header, from sector 1 of disk (size: 512 bytes) */
-	uint8_t *primary_header;
-	/* GPT secondary header, from last sector of disk (size: 512 bytes) */
-	uint8_t *secondary_header;
-	/* Primary GPT table, follows primary header (size: 16 KB) */
-	uint8_t *primary_entries;
-	/* Secondary GPT table, precedes secondary header (size: 16 KB) */
-	uint8_t *secondary_entries;
-	/* Size of a LBA sector, in bytes */
-	uint32_t sector_bytes;
-	/* Size of drive in LBA sectors, in sectors */
-	uint64_t drive_sectors;
-
-	/* Outputs */
-	/* Which inputs have been modified?  GPT_MODIFIED_* */
-	uint8_t modified;
-	/*
-	 * The current chromeos kernel index in partition table.  -1 means not
-	 * found on drive. Note that GPT partition numbers are traditionally
-	 * 1-based, but we're using a zero-based index here.
-	 */
-	int current_kernel;
-
-	/* Internal variables */
-	uint32_t valid_headers, valid_entries;
-	int current_priority;
-} GptData;
-
-/**
- * Initializes the GPT data structure's internal state.
- *
- * The following fields must be filled before calling this function:
- *
- *   primary_header
- *   secondary_header
- *   primary_entries
- *   secondary_entries
- *   sector_bytes
- *   drive_sectors
- *
- * On return the modified field may be set, if the GPT data has been modified
- * and should be written to disk.
- *
- * Returns GPT_SUCCESS if successful, non-zero if error:
- *   GPT_ERROR_INVALID_HEADERS, both partition table headers are invalid, enters
- *                              recovery mode,
- *   GPT_ERROR_INVALID_ENTRIES, both partition table entries are invalid, enters
- *                              recovery mode,
- *   GPT_ERROR_INVALID_SECTOR_SIZE, size of a sector is not supported,
- *   GPT_ERROR_INVALID_SECTOR_NUMBER, number of sectors in drive is invalid (too
- *                                    small) */
-int GptInit(GptData *gpt);
+#include "gpt_misc.h"
 
 /**
  * Provides the location of the next kernel partition, in order of decreasing
diff --git a/firmware/lib/gpt_misc.c b/firmware/lib/gpt_misc.c
new file mode 100644
index 0000000..d00d6b2
--- /dev/null
+++ b/firmware/lib/gpt_misc.c
@@ -0,0 +1,181 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "sysincludes.h"
+
+#include "cgptlib.h"
+#include "cgptlib_internal.h"
+#include "crc32.h"
+#include "gpt.h"
+#include "utility.h"
+#include "vboot_api.h"
+
+
+/**
+ * Allocate and read GPT data from the drive.
+ *
+ * The sector_bytes and drive_sectors fields should be filled on input.  The
+ * primary and secondary header and entries are filled on output.
+ *
+ * Returns 0 if successful, 1 if error.
+ */
+int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
+{
+	uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
+	int primary_valid = 0, secondary_valid = 0;
+
+	/* No data to be written yet */
+	gptdata->modified = 0;
+
+	/* Allocate all buffers */
+	gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes);
+	gptdata->secondary_header =
+		(uint8_t *)VbExMalloc(gptdata->sector_bytes);
+	gptdata->primary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE);
+	gptdata->secondary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE);
+
+	if (gptdata->primary_header == NULL ||
+	    gptdata->secondary_header == NULL ||
+	    gptdata->primary_entries == NULL ||
+	    gptdata->secondary_entries == NULL)
+		return 1;
+
+	/* Read primary header from the drive, skipping the protective MBR */
+	if (0 != VbExDiskRead(disk_handle, 1, 1, gptdata->primary_header))
+		return 1;
+
+	/* Only read primary GPT if the primary header is valid */
+	GptHeader* primary_header = (GptHeader*)gptdata->primary_header;
+	if (0 == CheckHeader(primary_header, 0, gptdata->drive_sectors)) {
+		primary_valid = 1;
+		if (0 != VbExDiskRead(disk_handle,
+				      primary_header->entries_lba,
+				      entries_sectors,
+				      gptdata->primary_entries))
+			return 1;
+	} else {
+		VBDEBUG(("Primary GPT header invalid!\n"));
+	}
+
+	/* Read secondary header from the end of the drive */
+	if (0 != VbExDiskRead(disk_handle, gptdata->drive_sectors - 1, 1,
+			      gptdata->secondary_header))
+		return 1;
+
+	/* Only read secondary GPT if the secondary header is valid */
+	GptHeader* secondary_header = (GptHeader*)gptdata->secondary_header;
+	if (0 == CheckHeader(secondary_header, 1, gptdata->drive_sectors)) {
+		secondary_valid = 1;
+		if (0 != VbExDiskRead(disk_handle,
+				      secondary_header->entries_lba,
+				      entries_sectors,
+				      gptdata->secondary_entries))
+			return 1;
+	} else {
+		VBDEBUG(("Secondary GPT header invalid!\n"));
+	}
+
+	/* Return 0 if least one GPT header was valid */
+	return (primary_valid || secondary_valid) ? 0 : 1;
+}
+
+/**
+ * Write any changes for the GPT data back to the drive, then free the buffers.
+ *
+ * Returns 0 if successful, 1 if error.
+ */
+int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
+{
+	int legacy = 0;
+	uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
+	int ret = 1;
+
+	/*
+	 * TODO(namnguyen): Preserve padding between primary GPT header and
+	 * its entries.
+	 */
+	uint64_t entries_lba = GPT_PMBR_SECTORS + GPT_HEADER_SECTORS;
+	if (gptdata->primary_header) {
+		GptHeader *h = (GptHeader *)(gptdata->primary_header);
+		entries_lba = h->entries_lba;
+
+		/*
+		 * Avoid even looking at this data if we don't need to. We
+		 * may in fact not have read it from disk if the read failed,
+		 * and this avoids a valgrind complaint.
+		 */
+		if (gptdata->modified) {
+			legacy = !Memcmp(h->signature, GPT_HEADER_SIGNATURE2,
+					GPT_HEADER_SIGNATURE_SIZE);
+		}
+		if (gptdata->modified & GPT_MODIFIED_HEADER1) {
+			if (legacy) {
+				VBDEBUG(("Not updating GPT header 1: "
+					 "legacy mode is enabled.\n"));
+			} else {
+				VBDEBUG(("Updating GPT header 1\n"));
+				if (0 != VbExDiskWrite(disk_handle, 1, 1,
+						       gptdata->primary_header))
+					goto fail;
+			}
+		}
+	}
+
+	if (gptdata->primary_entries) {
+		if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
+			if (legacy) {
+				VBDEBUG(("Not updating GPT entries 1: "
+					 "legacy mode is enabled.\n"));
+			} else {
+				VBDEBUG(("Updating GPT entries 1\n"));
+				if (0 != VbExDiskWrite(disk_handle, entries_lba,
+						entries_sectors,
+						gptdata->primary_entries))
+					goto fail;
+			}
+		}
+	}
+
+	entries_lba = (gptdata->drive_sectors - entries_sectors -
+		GPT_HEADER_SECTORS);
+	if (gptdata->secondary_header) {
+		GptHeader *h = (GptHeader *)(gptdata->secondary_header);
+		entries_lba = h->entries_lba;
+		if (gptdata->modified & GPT_MODIFIED_HEADER2) {
+			VBDEBUG(("Updating GPT entries 2\n"));
+			if (0 != VbExDiskWrite(disk_handle,
+					       gptdata->drive_sectors - 1, 1,
+					       gptdata->secondary_header))
+				goto fail;
+		}
+	}
+
+	if (gptdata->secondary_entries) {
+		if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
+			VBDEBUG(("Updating GPT header 2\n"));
+			if (0 != VbExDiskWrite(disk_handle,
+				entries_lba, entries_sectors,
+				gptdata->secondary_entries))
+				goto fail;
+		}
+	}
+
+	ret = 0;
+
+fail:
+	/* Avoid leaking memory on disk write failure */
+	if (gptdata->primary_header)
+		VbExFree(gptdata->primary_header);
+	if (gptdata->primary_entries)
+		VbExFree(gptdata->primary_entries);
+	if (gptdata->secondary_entries)
+		VbExFree(gptdata->secondary_entries);
+	if (gptdata->secondary_header)
+		VbExFree(gptdata->secondary_header);
+
+	/* Success */
+	return ret;
+}
+
diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h
index 2c0f2ce..2f1be5b 100644
--- a/firmware/lib/include/vboot_kernel.h
+++ b/firmware/lib/include/vboot_kernel.h
@@ -10,25 +10,12 @@
 #define VBOOT_REFERENCE_VBOOT_KERNEL_H_
 
 #include "cgptlib.h"
+#include "gpt_misc.h"
 #include "load_firmware_fw.h"
 #include "load_kernel_fw.h"
 #include "vboot_api.h"
 
 /**
- * Allocate and read GPT data from the drive.  The sector_bytes and
- * drive_sectors fields should be filled on input.  The primary and secondary
- * header and entries are filled on output.
- *
- * Returns 0 if successful, 1 if error.
- */
-int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata);
-
-/**
- * Write any changes for the GPT data back to the drive, then free the buffers.
- */
-int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata);
-
-/**
  * Accessors for unit tests only.
  */
 VbNvContext *VbApiKernelGetVnc(void);
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index a66b886..b2cb817 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -13,6 +13,7 @@
 #include "region.h"
 #include "gbb_access.h"
 #include "gbb_header.h"
+#include "gpt_misc.h"
 #include "load_kernel_fw.h"
 #include "utility.h"
 #include "vboot_api.h"
@@ -28,172 +29,6 @@
 	kBootDev = 2        /* Developer boot - self-signed kernel ok */
 } BootMode;
 
-/**
- * Allocate and read GPT data from the drive.
- *
- * The sector_bytes and drive_sectors fields should be filled on input.  The
- * primary and secondary header and entries are filled on output.
- *
- * Returns 0 if successful, 1 if error.
- */
-int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
-{
-	uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
-	int primary_valid = 0, secondary_valid = 0;
-
-	/* No data to be written yet */
-	gptdata->modified = 0;
-
-	/* Allocate all buffers */
-	gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes);
-	gptdata->secondary_header =
-		(uint8_t *)VbExMalloc(gptdata->sector_bytes);
-	gptdata->primary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE);
-	gptdata->secondary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE);
-
-	if (gptdata->primary_header == NULL ||
-	    gptdata->secondary_header == NULL ||
-	    gptdata->primary_entries == NULL ||
-	    gptdata->secondary_entries == NULL)
-		return 1;
-
-	/* Read primary header from the drive, skipping the protective MBR */
-	if (0 != VbExDiskRead(disk_handle, 1, 1, gptdata->primary_header))
-		return 1;
-
-	/* Only read primary GPT if the primary header is valid */
-	GptHeader* primary_header = (GptHeader*)gptdata->primary_header;
-	if (0 == CheckHeader(primary_header, 0, gptdata->drive_sectors)) {
-		primary_valid = 1;
-		if (0 != VbExDiskRead(disk_handle,
-				      primary_header->entries_lba,
-				      entries_sectors,
-				      gptdata->primary_entries))
-			return 1;
-	} else {
-		VBDEBUG(("Primary GPT header invalid!\n"));
-	}
-
-	/* Read secondary header from the end of the drive */
-	if (0 != VbExDiskRead(disk_handle, gptdata->drive_sectors - 1, 1,
-			      gptdata->secondary_header))
-		return 1;
-
-	/* Only read secondary GPT if the secondary header is valid */
-	GptHeader* secondary_header = (GptHeader*)gptdata->secondary_header;
-	if (0 == CheckHeader(secondary_header, 1, gptdata->drive_sectors)) {
-		secondary_valid = 1;
-		if (0 != VbExDiskRead(disk_handle,
-				      secondary_header->entries_lba,
-				      entries_sectors,
-				      gptdata->secondary_entries))
-			return 1;
-	} else {
-		VBDEBUG(("Secondary GPT header invalid!\n"));
-	}
-
-	/* Return 0 if least one GPT header was valid */
-	return (primary_valid || secondary_valid) ? 0 : 1;
-}
-
-/**
- * Write any changes for the GPT data back to the drive, then free the buffers.
- *
- * Returns 0 if successful, 1 if error.
- */
-int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata)
-{
-	int legacy = 0;
-	uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes;
-	int ret = 1;
-
-	/*
-	 * TODO(namnguyen): Preserve padding between primary GPT header and
-	 * its entries.
-	 */
-	uint64_t entries_lba = GPT_PMBR_SECTORS + GPT_HEADER_SECTORS;
-	if (gptdata->primary_header) {
-		GptHeader *h = (GptHeader *)(gptdata->primary_header);
-		entries_lba = h->entries_lba;
-
-		/*
-		 * Avoid even looking at this data if we don't need to. We
-		 * may in fact not have read it from disk if the read failed,
-		 * and this avoids a valgrind complaint.
-		 */
-		if (gptdata->modified) {
-			legacy = !Memcmp(h->signature, GPT_HEADER_SIGNATURE2,
-					GPT_HEADER_SIGNATURE_SIZE);
-		}
-		if (gptdata->modified & GPT_MODIFIED_HEADER1) {
-			if (legacy) {
-				VBDEBUG(("Not updating GPT header 1: "
-					 "legacy mode is enabled.\n"));
-			} else {
-				VBDEBUG(("Updating GPT header 1\n"));
-				if (0 != VbExDiskWrite(disk_handle, 1, 1,
-						       gptdata->primary_header))
-					goto fail;
-			}
-		}
-	}
-
-	if (gptdata->primary_entries) {
-		if (gptdata->modified & GPT_MODIFIED_ENTRIES1) {
-			if (legacy) {
-				VBDEBUG(("Not updating GPT entries 1: "
-					 "legacy mode is enabled.\n"));
-			} else {
-				VBDEBUG(("Updating GPT entries 1\n"));
-				if (0 != VbExDiskWrite(disk_handle, entries_lba,
-						entries_sectors,
-						gptdata->primary_entries))
-					goto fail;
-			}
-		}
-	}
-
-	entries_lba = (gptdata->drive_sectors - entries_sectors -
-		GPT_HEADER_SECTORS);
-	if (gptdata->secondary_header) {
-		GptHeader *h = (GptHeader *)(gptdata->secondary_header);
-		entries_lba = h->entries_lba;
-		if (gptdata->modified & GPT_MODIFIED_HEADER2) {
-			VBDEBUG(("Updating GPT entries 2\n"));
-			if (0 != VbExDiskWrite(disk_handle,
-					       gptdata->drive_sectors - 1, 1,
-					       gptdata->secondary_header))
-				goto fail;
-		}
-	}
-
-	if (gptdata->secondary_entries) {
-		if (gptdata->modified & GPT_MODIFIED_ENTRIES2) {
-			VBDEBUG(("Updating GPT header 2\n"));
-			if (0 != VbExDiskWrite(disk_handle,
-				entries_lba, entries_sectors,
-				gptdata->secondary_entries))
-				goto fail;
-		}
-	}
-
-	ret = 0;
-
-fail:
-	/* Avoid leaking memory on disk write failure */
-	if (gptdata->primary_header)
-		VbExFree(gptdata->primary_header);
-	if (gptdata->primary_entries)
-		VbExFree(gptdata->primary_entries);
-	if (gptdata->secondary_entries)
-		VbExFree(gptdata->secondary_entries);
-	if (gptdata->secondary_header)
-		VbExFree(gptdata->secondary_header);
-
-	/* Success */
-	return ret;
-}
-
 VbError_t LoadKernel(LoadKernelParams *params, VbCommonParams *cparams)
 {
 	VbSharedDataHeader *shared =