diff --git a/gpt-utils/gpt-utils.cpp b/gpt-utils/gpt-utils.cpp
new file mode 100644
index 0000000..73a1968
--- /dev/null
+++ b/gpt-utils/gpt-utils.cpp
@@ -0,0 +1,1546 @@
+/*
+ * Copyright (c) 2013,2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _LARGEFILE64_SOURCE /* enable lseek64() */
+
+/******************************************************************************
+ * INCLUDE SECTION
+ ******************************************************************************/
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <scsi/ufs/ioctl.h>
+#include <scsi/ufs/ufs.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#include <limits.h>
+#include <dirent.h>
+#include <linux/kernel.h>
+#include <asm/byteorder.h>
+#include <map>
+#include <vector>
+#include <string>
+#define LOG_TAG "gpt-utils"
+#include <log/log.h>
+#include <cutils/properties.h>
+#include "gpt-utils.h"
+#include "sparse_crc32.h"
+#include <endian.h>
+
+
+/******************************************************************************
+ * DEFINE SECTION
+ ******************************************************************************/
+#define BLK_DEV_FILE    "/dev/block/mmcblk0"
+/* list the names of the backed-up partitions to be swapped */
+/* extension used for the backup partitions - tzbak, abootbak, etc. */
+#define BAK_PTN_NAME_EXT    "bak"
+#define XBL_PRIMARY         "/dev/block/bootdevice/by-name/xbl"
+#define XBL_BACKUP          "/dev/block/bootdevice/by-name/xblbak"
+#define XBL_AB_PRIMARY      "/dev/block/bootdevice/by-name/xbl_a"
+#define XBL_AB_SECONDARY    "/dev/block/bootdevice/by-name/xbl_b"
+/* GPT defines */
+#define MAX_LUNS                    26
+//Size of the buffer that needs to be passed to the UFS ioctl
+#define UFS_ATTR_DATA_SIZE          32
+//This will allow us to get the root lun path from the path to the partition.
+//i.e: from /dev/block/sdaXXX get /dev/block/sda. The assumption here is that
+//the boot critical luns lie between sda to sdz which is acceptable because
+//only user added external disks,etc would lie beyond that limit which do not
+//contain partitions that interest us here.
+#define PATH_TRUNCATE_LOC (sizeof("/dev/block/sda") - 1)
+
+//From /dev/block/sda get just sda
+#define LUN_NAME_START_LOC (sizeof("/dev/block/") - 1)
+#define BOOT_LUN_A_ID 1
+#define BOOT_LUN_B_ID 2
+/******************************************************************************
+ * MACROS
+ ******************************************************************************/
+
+
+#define GET_4_BYTES(ptr)    ((uint32_t) *((uint8_t *)(ptr)) | \
+        ((uint32_t) *((uint8_t *)(ptr) + 1) << 8) | \
+        ((uint32_t) *((uint8_t *)(ptr) + 2) << 16) | \
+        ((uint32_t) *((uint8_t *)(ptr) + 3) << 24))
+
+#define GET_8_BYTES(ptr)    ((uint64_t) *((uint8_t *)(ptr)) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 1) << 8) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 2) << 16) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 3) << 24) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 4) << 32) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 5) << 40) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 6) << 48) | \
+        ((uint64_t) *((uint8_t *)(ptr) + 7) << 56))
+
+#define PUT_4_BYTES(ptr, y)   *((uint8_t *)(ptr)) = (y) & 0xff; \
+        *((uint8_t *)(ptr) + 1) = ((y) >> 8) & 0xff; \
+        *((uint8_t *)(ptr) + 2) = ((y) >> 16) & 0xff; \
+        *((uint8_t *)(ptr) + 3) = ((y) >> 24) & 0xff;
+
+/******************************************************************************
+ * TYPES
+ ******************************************************************************/
+using namespace std;
+enum gpt_state {
+    GPT_OK = 0,
+    GPT_BAD_SIGNATURE,
+    GPT_BAD_CRC
+};
+//List of LUN's containing boot critical images.
+//Required in the case of UFS devices
+struct update_data {
+     char lun_list[MAX_LUNS][PATH_MAX];
+     uint32_t num_valid_entries;
+};
+
+/******************************************************************************
+ * FUNCTIONS
+ ******************************************************************************/
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Read/Write len bytes from/to block dev
+ *
+ *  \param [in] fd      block dev file descriptor (returned from open)
+ *  \param [in] rw      RW flag: 0 - read, != 0 - write
+ *  \param [in] offset  block dev offset [bytes] - RW start position
+ *  \param [in] buf     Pointer to the buffer containing the data
+ *  \param [in] len     RW size in bytes. Buf must be at least that big
+ *
+ *  \return  0 on success
+ *
+ *  ==========================================================================
+ */
+static int blk_rw(int fd, int rw, int64_t offset, uint8_t *buf, unsigned len)
+{
+    int r;
+
+    if (lseek64(fd, offset, SEEK_SET) < 0) {
+        fprintf(stderr, "block dev lseek64 %" PRId64 " failed: %s\n", offset,
+                strerror(errno));
+        return -1;
+    }
+
+    if (rw)
+        r = write(fd, buf, len);
+    else
+        r = read(fd, buf, len);
+
+    if (r < 0)
+        fprintf(stderr, "block dev %s failed: %s\n", rw ? "write" : "read",
+                strerror(errno));
+    else
+        r = 0;
+
+    return r;
+}
+
+
+
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Search within GPT for partition entry with the given name
+ *  or it's backup twin (name-bak).
+ *
+ *  \param [in] ptn_name        Partition name to seek
+ *  \param [in] pentries_start  Partition entries array start pointer
+ *  \param [in] pentries_end    Partition entries array end pointer
+ *  \param [in] pentry_size     Single partition entry size [bytes]
+ *
+ *  \return  First partition entry pointer that matches the name or NULL
+ *
+ *  ==========================================================================
+ */
+static uint8_t *gpt_pentry_seek(const char *ptn_name,
+                                const uint8_t *pentries_start,
+                                const uint8_t *pentries_end,
+                                uint32_t pentry_size)
+{
+    char *pentry_name;
+    unsigned len = strlen(ptn_name);
+
+    for (pentry_name = (char *) (pentries_start + PARTITION_NAME_OFFSET);
+         pentry_name < (char *) pentries_end; pentry_name += pentry_size) {
+        char name8[MAX_GPT_NAME_SIZE] = {0}; // initialize with null
+        unsigned i;
+
+        /* Partition names in GPT are UTF-16 - ignoring UTF-16 2nd byte */
+        for (i = 0; i < sizeof(name8) / 2; i++)
+            name8[i] = pentry_name[i * 2];
+        if (!strncmp(ptn_name, name8, len))
+            if (name8[len] == 0 || !strcmp(&name8[len], BAK_PTN_NAME_EXT))
+                return (uint8_t *) (pentry_name - PARTITION_NAME_OFFSET);
+    }
+
+    return NULL;
+}
+
+
+
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Swaps boot chain in GPT partition entries array
+ *
+ *  \param [in] pentries_start  Partition entries array start
+ *  \param [in] pentries_end    Partition entries array end
+ *  \param [in] pentry_size     Single partition entry size
+ *
+ *  \return  0 on success, 1 if no backup partitions found
+ *
+ *  ==========================================================================
+ */
+static int gpt_boot_chain_swap(const uint8_t *pentries_start,
+                                const uint8_t *pentries_end,
+                                uint32_t pentry_size)
+{
+    const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST };
+
+    int backup_not_found = 1;
+    unsigned i;
+
+    for (i = 0; i < ARRAY_SIZE(ptn_swap_list); i++) {
+        uint8_t *ptn_entry;
+        uint8_t *ptn_bak_entry;
+        uint8_t ptn_swap[PTN_ENTRY_SIZE];
+        //Skip the xbl partition on UFS devices. That is handled
+        //seperately.
+        if (gpt_utils_is_ufs_device() && !strncmp(ptn_swap_list[i],
+                                PTN_XBL,
+                                strlen(PTN_XBL)))
+            continue;
+
+        ptn_entry = gpt_pentry_seek(ptn_swap_list[i], pentries_start,
+                        pentries_end, pentry_size);
+        if (ptn_entry == NULL)
+            continue;
+
+        ptn_bak_entry = gpt_pentry_seek(ptn_swap_list[i],
+                        ptn_entry + pentry_size, pentries_end, pentry_size);
+        if (ptn_bak_entry == NULL) {
+            fprintf(stderr, "'%s' partition not backup - skip safe update\n",
+                    ptn_swap_list[i]);
+            continue;
+        }
+
+        /* swap primary <-> backup partition entries */
+        memcpy(ptn_swap, ptn_entry, PTN_ENTRY_SIZE);
+        memcpy(ptn_entry, ptn_bak_entry, PTN_ENTRY_SIZE);
+        memcpy(ptn_bak_entry, ptn_swap, PTN_ENTRY_SIZE);
+        backup_not_found = 0;
+    }
+
+    return backup_not_found;
+}
+
+
+
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Sets secondary GPT boot chain
+ *
+ *  \param [in] fd    block dev file descriptor
+ *  \param [in] boot  Boot chain to switch to
+ *
+ *  \return  0 on success
+ *
+ *  ==========================================================================
+ */
+static int gpt2_set_boot_chain(int fd, enum boot_chain boot)
+{
+    int64_t  gpt2_header_offset;
+    uint64_t pentries_start_offset;
+    uint32_t gpt_header_size;
+    uint32_t pentry_size;
+    uint32_t pentries_array_size;
+
+    uint8_t *gpt_header = NULL;
+    uint8_t  *pentries = NULL;
+    uint32_t crc;
+    uint32_t blk_size = 0;
+    int r;
+
+    if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
+            fprintf(stderr, "Failed to get GPT device block size: %s\n",
+                            strerror(errno));
+            r = -1;
+            goto EXIT;
+    }
+    gpt_header = (uint8_t*)malloc(blk_size);
+    if (!gpt_header) {
+            fprintf(stderr, "Failed to allocate memory to hold GPT block\n");
+            r = -1;
+            goto EXIT;
+    }
+    gpt2_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
+    if (gpt2_header_offset < 0) {
+        fprintf(stderr, "Getting secondary GPT header offset failed: %s\n",
+                strerror(errno));
+        r = -1;
+        goto EXIT;
+    }
+
+    /* Read primary GPT header from block dev */
+    r = blk_rw(fd, 0, blk_size, gpt_header, blk_size);
+
+    if (r) {
+            fprintf(stderr, "Failed to read primary GPT header from blk dev\n");
+            goto EXIT;
+    }
+    pentries_start_offset =
+        GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size;
+    pentry_size = GET_4_BYTES(gpt_header + PENTRY_SIZE_OFFSET);
+    pentries_array_size =
+        GET_4_BYTES(gpt_header + PARTITION_COUNT_OFFSET) * pentry_size;
+
+    pentries = (uint8_t *) calloc(1, pentries_array_size);
+    if (pentries == NULL) {
+        fprintf(stderr,
+                    "Failed to alloc memory for GPT partition entries array\n");
+        r = -1;
+        goto EXIT;
+    }
+    /* Read primary GPT partititon entries array from block dev */
+    r = blk_rw(fd, 0, pentries_start_offset, pentries, pentries_array_size);
+    if (r)
+        goto EXIT;
+
+    crc = sparse_crc32(0, pentries, pentries_array_size);
+    if (GET_4_BYTES(gpt_header + PARTITION_CRC_OFFSET) != crc) {
+        fprintf(stderr, "Primary GPT partition entries array CRC invalid\n");
+        r = -1;
+        goto EXIT;
+    }
+
+    /* Read secondary GPT header from block dev */
+    r = blk_rw(fd, 0, gpt2_header_offset, gpt_header, blk_size);
+    if (r)
+        goto EXIT;
+
+    gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
+    pentries_start_offset =
+        GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size;
+
+    if (boot == BACKUP_BOOT) {
+        r = gpt_boot_chain_swap(pentries, pentries + pentries_array_size,
+                                pentry_size);
+        if (r)
+            goto EXIT;
+    }
+
+    crc = sparse_crc32(0, pentries, pentries_array_size);
+    PUT_4_BYTES(gpt_header + PARTITION_CRC_OFFSET, crc);
+
+    /* header CRC is calculated with this field cleared */
+    PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
+    crc = sparse_crc32(0, gpt_header, gpt_header_size);
+    PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc);
+
+    /* Write the modified GPT header back to block dev */
+    r = blk_rw(fd, 1, gpt2_header_offset, gpt_header, blk_size);
+    if (!r)
+        /* Write the modified GPT partititon entries array back to block dev */
+        r = blk_rw(fd, 1, pentries_start_offset, pentries,
+                    pentries_array_size);
+
+EXIT:
+    if(gpt_header)
+            free(gpt_header);
+    if (pentries)
+            free(pentries);
+    return r;
+}
+
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Checks GPT state (header signature and CRC)
+ *
+ *  \param [in] fd      block dev file descriptor
+ *  \param [in] gpt     GPT header to be checked
+ *  \param [out] state  GPT header state
+ *
+ *  \return  0 on success
+ *
+ *  ==========================================================================
+ */
+static int gpt_get_state(int fd, enum gpt_instance gpt, enum gpt_state *state)
+{
+    int64_t gpt_header_offset;
+    uint32_t gpt_header_size;
+    uint8_t  *gpt_header = NULL;
+    uint32_t crc;
+    uint32_t blk_size = 0;
+
+    *state = GPT_OK;
+
+    if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
+            fprintf(stderr, "Failed to get GPT device block size: %s\n",
+                            strerror(errno));
+            goto error;
+    }
+    gpt_header = (uint8_t*)malloc(blk_size);
+    if (!gpt_header) {
+            fprintf(stderr, "gpt_get_state:Failed to alloc memory for header\n");
+            goto error;
+    }
+    if (gpt == PRIMARY_GPT)
+        gpt_header_offset = blk_size;
+    else {
+        gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
+        if (gpt_header_offset < 0) {
+            fprintf(stderr, "gpt_get_state:Seek to end of GPT part fail\n");
+            goto error;
+        }
+    }
+
+    if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) {
+        fprintf(stderr, "gpt_get_state: blk_rw failed\n");
+        goto error;
+    }
+    if (memcmp(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE)))
+        *state = GPT_BAD_SIGNATURE;
+    gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
+
+    crc = GET_4_BYTES(gpt_header + HEADER_CRC_OFFSET);
+    /* header CRC is calculated with this field cleared */
+    PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
+    if (sparse_crc32(0, gpt_header, gpt_header_size) != crc)
+        *state = GPT_BAD_CRC;
+    free(gpt_header);
+    return 0;
+error:
+    if (gpt_header)
+            free(gpt_header);
+    return -1;
+}
+
+
+
+/**
+ *  ==========================================================================
+ *
+ *  \brief  Sets GPT header state (used to corrupt and fix GPT signature)
+ *
+ *  \param [in] fd     block dev file descriptor
+ *  \param [in] gpt    GPT header to be checked
+ *  \param [in] state  GPT header state to set (GPT_OK or GPT_BAD_SIGNATURE)
+ *
+ *  \return  0 on success
+ *
+ *  ==========================================================================
+ */
+static int gpt_set_state(int fd, enum gpt_instance gpt, enum gpt_state state)
+{
+    int64_t gpt_header_offset;
+    uint32_t gpt_header_size;
+    uint8_t  *gpt_header = NULL;
+    uint32_t crc;
+    uint32_t blk_size = 0;
+
+    if (ioctl(fd, BLKSSZGET, &blk_size) != 0) {
+            fprintf(stderr, "Failed to get GPT device block size: %s\n",
+                            strerror(errno));
+            goto error;
+    }
+    gpt_header = (uint8_t*)malloc(blk_size);
+    if (!gpt_header) {
+            fprintf(stderr, "Failed to alloc memory for gpt header\n");
+            goto error;
+    }
+    if (gpt == PRIMARY_GPT)
+        gpt_header_offset = blk_size;
+    else {
+        gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size;
+        if (gpt_header_offset < 0) {
+            fprintf(stderr, "Failed to seek to end of GPT device\n");
+            goto error;
+        }
+    }
+    if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) {
+        fprintf(stderr, "Failed to r/w gpt header\n");
+        goto error;
+    }
+    if (state == GPT_OK)
+        memcpy(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE));
+    else if (state == GPT_BAD_SIGNATURE)
+        *gpt_header = 0;
+    else {
+        fprintf(stderr, "gpt_set_state: Invalid state\n");
+        goto error;
+    }
+
+    gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET);
+
+    /* header CRC is calculated with this field cleared */
+    PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0);
+    crc = sparse_crc32(0, gpt_header, gpt_header_size);
+    PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc);
+
+    if (blk_rw(fd, 1, gpt_header_offset, gpt_header, blk_size)) {
+        fprintf(stderr, "gpt_set_state: blk write failed\n");
+        goto error;
+    }
+    return 0;
+error:
+    if(gpt_header)
+           free(gpt_header);
+    return -1;
+}
+
+int get_scsi_node_from_bootdevice(const char *bootdev_path,
+                char *sg_node_path,
+                size_t buf_size)
+{
+        char sg_dir_path[PATH_MAX] = {0};
+        char real_path[PATH_MAX] = {0};
+        DIR *scsi_dir = NULL;
+        struct dirent *de;
+        int node_found = 0;
+        if (!bootdev_path || !sg_node_path) {
+                fprintf(stderr, "%s : invalid argument\n",
+                                 __func__);
+                goto error;
+        }
+        if (readlink(bootdev_path, real_path, sizeof(real_path) - 1) < 0) {
+                        fprintf(stderr, "failed to resolve link for %s(%s)\n",
+                                        bootdev_path,
+                                        strerror(errno));
+                        goto error;
+        }
+        if(strlen(real_path) < PATH_TRUNCATE_LOC + 1){
+            fprintf(stderr, "Unrecognized path :%s:\n",
+                           real_path);
+            goto error;
+        }
+        //For the safe side in case there are additional partitions on
+        //the XBL lun we truncate the name.
+        real_path[PATH_TRUNCATE_LOC] = '\0';
+        if(strlen(real_path) < LUN_NAME_START_LOC + 1){
+            fprintf(stderr, "Unrecognized truncated path :%s:\n",
+                           real_path);
+            goto error;
+        }
+        //This will give us /dev/block/sdb/device/scsi_generic
+        //which contains a file sgY whose name gives us the path
+        //to /dev/sgY which we return
+        snprintf(sg_dir_path, sizeof(sg_dir_path) - 1,
+                        "/sys/block/%s/device/scsi_generic",
+                        &real_path[LUN_NAME_START_LOC]);
+        scsi_dir = opendir(sg_dir_path);
+        if (!scsi_dir) {
+                fprintf(stderr, "%s : Failed to open %s(%s)\n",
+                                __func__,
+                                sg_dir_path,
+                                strerror(errno));
+                goto error;
+        }
+        while((de = readdir(scsi_dir))) {
+                if (de->d_name[0] == '.')
+                        continue;
+                else if (!strncmp(de->d_name, "sg", 2)) {
+                          snprintf(sg_node_path,
+                                        buf_size -1,
+                                        "/dev/%s",
+                                        de->d_name);
+                          fprintf(stderr, "%s:scsi generic node is :%s:\n",
+                                          __func__,
+                                          sg_node_path);
+                          node_found = 1;
+                          break;
+                }
+        }
+        if(!node_found) {
+                fprintf(stderr,"%s: Unable to locate scsi generic node\n",
+                               __func__);
+                goto error;
+        }
+        closedir(scsi_dir);
+        return 0;
+error:
+        if (scsi_dir)
+                closedir(scsi_dir);
+        return -1;
+}
+
+int set_boot_lun(char *sg_dev, uint8_t boot_lun_id)
+{
+        int fd = -1;
+        int rc;
+        struct ufs_ioctl_query_data *data = NULL;
+        size_t ioctl_data_size = sizeof(struct ufs_ioctl_query_data) + UFS_ATTR_DATA_SIZE;
+
+        data = (struct ufs_ioctl_query_data*)malloc(ioctl_data_size);
+        if (!data) {
+                fprintf(stderr, "%s: Failed to alloc query data struct\n",
+                                __func__);
+                goto error;
+        }
+        memset(data, 0, ioctl_data_size);
+        data->opcode = UPIU_QUERY_OPCODE_WRITE_ATTR;
+        data->idn = QUERY_ATTR_IDN_BOOT_LU_EN;
+        data->buf_size = UFS_ATTR_DATA_SIZE;
+        data->buffer[0] = boot_lun_id;
+        fd = open(sg_dev, O_RDWR);
+        if (fd < 0) {
+                fprintf(stderr, "%s: Failed to open %s(%s)\n",
+                                __func__,
+                                sg_dev,
+                                strerror(errno));
+                goto error;
+        }
+        rc = ioctl(fd, UFS_IOCTL_QUERY, data);
+        if (rc) {
+                fprintf(stderr, "%s: UFS query ioctl failed(%s)\n",
+                                __func__,
+                                strerror(errno));
+                goto error;
+        }
+        close(fd);
+        free(data);
+        return 0;
+error:
+        if (fd >= 0)
+                close(fd);
+        if (data)
+                free(data);
+        return -1;
+}
+
+//Swtich betwieen using either the primary or the backup
+//boot LUN for boot. This is required since UFS boot partitions
+//cannot have a backup GPT which is what we use for failsafe
+//updates of the other 'critical' partitions. This function will
+//not be invoked for emmc targets and on UFS targets is only required
+//to be invoked for XBL.
+//
+//The algorithm to do this is as follows:
+//- Find the real block device(eg: /dev/block/sdb) that corresponds
+//  to the /dev/block/bootdevice/by-name/xbl(bak) symlink
+//
+//- Once we have the block device 'node' name(sdb in the above example)
+//  use this node to to locate the scsi generic device that represents
+//  it by checking the file /sys/block/sdb/device/scsi_generic/sgY
+//
+//- Once we locate sgY we call the query ioctl on /dev/sgy to switch
+//the boot lun to either LUNA or LUNB
+int gpt_utils_set_xbl_boot_partition(enum boot_chain chain)
+{
+        struct stat st;
+        ///sys/block/sdX/device/scsi_generic/
+        char sg_dev_node[PATH_MAX] = {0};
+        uint8_t boot_lun_id = 0;
+        const char *boot_dev = NULL;
+
+        if (chain == BACKUP_BOOT) {
+                boot_lun_id = BOOT_LUN_B_ID;
+                if (!stat(XBL_BACKUP, &st))
+                        boot_dev = XBL_BACKUP;
+                else if (!stat(XBL_AB_SECONDARY, &st))
+                        boot_dev = XBL_AB_SECONDARY;
+                else {
+                        fprintf(stderr, "%s: Failed to locate secondary xbl\n",
+                                        __func__);
+                        goto error;
+                }
+        } else if (chain == NORMAL_BOOT) {
+                boot_lun_id = BOOT_LUN_A_ID;
+                if (!stat(XBL_PRIMARY, &st))
+                        boot_dev = XBL_PRIMARY;
+                else if (!stat(XBL_AB_PRIMARY, &st))
+                        boot_dev = XBL_AB_PRIMARY;
+                else {
+                        fprintf(stderr, "%s: Failed to locate primary xbl\n",
+                                        __func__);
+                        goto error;
+                }
+        } else {
+                fprintf(stderr, "%s: Invalid boot chain id\n", __func__);
+                goto error;
+        }
+        //We need either both xbl and xblbak or both xbl_a and xbl_b to exist at
+        //the same time. If not the current configuration is invalid.
+        if((stat(XBL_PRIMARY, &st) ||
+                                stat(XBL_BACKUP, &st)) &&
+                        (stat(XBL_AB_PRIMARY, &st) ||
+                         stat(XBL_AB_SECONDARY, &st))) {
+                fprintf(stderr, "%s:primary/secondary XBL prt not found(%s)\n",
+                                __func__,
+                                strerror(errno));
+                goto error;
+        }
+        fprintf(stderr, "%s: setting %s lun as boot lun\n",
+                        __func__,
+                        boot_dev);
+        if (get_scsi_node_from_bootdevice(boot_dev,
+                                sg_dev_node,
+                                sizeof(sg_dev_node))) {
+                fprintf(stderr, "%s: Failed to get scsi node path for xblbak\n",
+                                __func__);
+                goto error;
+        }
+        if (set_boot_lun(sg_dev_node, boot_lun_id)) {
+                fprintf(stderr, "%s: Failed to set xblbak as boot partition\n",
+                                __func__);
+                goto error;
+        }
+        return 0;
+error:
+        return -1;
+}
+
+int gpt_utils_is_ufs_device()
+{
+    char bootdevice[PROPERTY_VALUE_MAX] = {0};
+    property_get("ro.boot.bootdevice", bootdevice, "N/A");
+    if (strlen(bootdevice) < strlen(".ufshc") + 1)
+        return 0;
+    return (!strncmp(&bootdevice[strlen(bootdevice) - strlen(".ufshc")],
+                            ".ufshc",
+                            sizeof(".ufshc")));
+}
+//dev_path is the path to the block device that contains the GPT image that
+//needs to be updated. This would be the device which holds one or more critical
+//boot partitions and their backups. In the case of EMMC this function would
+//be invoked only once on /dev/block/mmcblk1 since it holds the GPT image
+//containing all the partitions For UFS devices it could potentially be
+//invoked multiple times, once for each LUN containing critical image(s) and
+//their backups
+int prepare_partitions(enum boot_update_stage stage, const char *dev_path)
+{
+    int r = 0;
+    int fd = -1;
+    int is_ufs = gpt_utils_is_ufs_device();
+    enum gpt_state gpt_prim, gpt_second;
+    enum boot_update_stage internal_stage;
+    struct stat xbl_partition_stat;
+    struct stat ufs_dir_stat;
+
+    if (!dev_path) {
+        fprintf(stderr, "%s: Invalid dev_path\n",
+                        __func__);
+        r = -1;
+        goto EXIT;
+    }
+    fd = open(dev_path, O_RDWR);
+    if (fd < 0) {
+        fprintf(stderr, "%s: Opening '%s' failed: %s\n",
+                        __func__,
+                       BLK_DEV_FILE,
+                       strerror(errno));
+        r = -1;
+        goto EXIT;
+    }
+    r = gpt_get_state(fd, PRIMARY_GPT, &gpt_prim) ||
+        gpt_get_state(fd, SECONDARY_GPT, &gpt_second);
+    if (r) {
+        fprintf(stderr, "%s: Getting GPT headers state failed\n",
+                        __func__);
+        goto EXIT;
+    }
+
+    /* These 2 combinations are unexpected and unacceptable */
+    if (gpt_prim == GPT_BAD_CRC || gpt_second == GPT_BAD_CRC) {
+        fprintf(stderr, "%s: GPT headers CRC corruption detected, aborting\n",
+                        __func__);
+        r = -1;
+        goto EXIT;
+    }
+    if (gpt_prim == GPT_BAD_SIGNATURE && gpt_second == GPT_BAD_SIGNATURE) {
+        fprintf(stderr, "%s: Both GPT headers corrupted, aborting\n",
+                        __func__);
+        r = -1;
+        goto EXIT;
+    }
+
+    /* Check internal update stage according GPT headers' state */
+    if (gpt_prim == GPT_OK && gpt_second == GPT_OK)
+        internal_stage = UPDATE_MAIN;
+    else if (gpt_prim == GPT_BAD_SIGNATURE)
+        internal_stage = UPDATE_BACKUP;
+    else if (gpt_second == GPT_BAD_SIGNATURE)
+        internal_stage = UPDATE_FINALIZE;
+    else {
+        fprintf(stderr, "%s: Abnormal GPTs state: primary (%d), secondary (%d), "
+                "aborting\n", __func__, gpt_prim, gpt_second);
+        r = -1;
+        goto EXIT;
+    }
+
+    /* Stage already set - ready for update, exitting */
+    if ((int) stage == (int) internal_stage - 1)
+        goto EXIT;
+    /* Unexpected stage given */
+    if (stage != internal_stage) {
+        r = -1;
+        goto EXIT;
+    }
+
+    switch (stage) {
+    case UPDATE_MAIN:
+            if (is_ufs) {
+                if(stat(XBL_PRIMARY, &xbl_partition_stat)||
+                                stat(XBL_BACKUP, &xbl_partition_stat)){
+                        //Non fatal error. Just means this target does not
+                        //use XBL but relies on sbl whose update is handled
+                        //by the normal methods.
+                        fprintf(stderr, "%s: xbl part not found(%s).Assuming sbl in use\n",
+                                        __func__,
+                                        strerror(errno));
+                } else {
+                        //Switch the boot lun so that backup boot LUN is used
+                        r = gpt_utils_set_xbl_boot_partition(BACKUP_BOOT);
+                        if(r){
+                                fprintf(stderr, "%s: Failed to set xbl backup partition as boot\n",
+                                                __func__);
+                                goto EXIT;
+                        }
+                }
+        }
+        //Fix up the backup GPT table so that it actually points to
+        //the backup copy of the boot critical images
+        fprintf(stderr, "%s: Preparing for primary partition update\n",
+                        __func__);
+        r = gpt2_set_boot_chain(fd, BACKUP_BOOT);
+        if (r) {
+            if (r < 0)
+                fprintf(stderr,
+                                "%s: Setting secondary GPT to backup boot failed\n",
+                                __func__);
+            /* No backup partitions - do not corrupt GPT, do not flag error */
+            else
+                r = 0;
+            goto EXIT;
+        }
+        //corrupt the primary GPT so that the backup(which now points to
+        //the backup boot partitions is used)
+        r = gpt_set_state(fd, PRIMARY_GPT, GPT_BAD_SIGNATURE);
+        if (r) {
+            fprintf(stderr, "%s: Corrupting primary GPT header failed\n",
+                            __func__);
+            goto EXIT;
+        }
+        break;
+    case UPDATE_BACKUP:
+        if (is_ufs) {
+                if(stat(XBL_PRIMARY, &xbl_partition_stat)||
+                                stat(XBL_BACKUP, &xbl_partition_stat)){
+                        //Non fatal error. Just means this target does not
+                        //use XBL but relies on sbl whose update is handled
+                        //by the normal methods.
+                        fprintf(stderr, "%s: xbl part not found(%s).Assuming sbl in use\n",
+                                        __func__,
+                                        strerror(errno));
+                } else {
+                        //Switch the boot lun so that backup boot LUN is used
+                        r = gpt_utils_set_xbl_boot_partition(NORMAL_BOOT);
+                        if(r) {
+                                fprintf(stderr, "%s: Failed to set xbl backup partition as boot\n",
+                                                __func__);
+                                goto EXIT;
+                        }
+                }
+        }
+        //Fix the primary GPT header so that is used
+        fprintf(stderr, "%s: Preparing for backup partition update\n",
+                        __func__);
+        r = gpt_set_state(fd, PRIMARY_GPT, GPT_OK);
+        if (r) {
+            fprintf(stderr, "%s: Fixing primary GPT header failed\n",
+                             __func__);
+            goto EXIT;
+        }
+        //Corrupt the scondary GPT header
+        r = gpt_set_state(fd, SECONDARY_GPT, GPT_BAD_SIGNATURE);
+        if (r) {
+            fprintf(stderr, "%s: Corrupting secondary GPT header failed\n",
+                            __func__);
+            goto EXIT;
+        }
+        break;
+    case UPDATE_FINALIZE:
+        //Undo the changes we had made in the UPDATE_MAIN stage so that the
+        //primary/backup GPT headers once again point to the same set of
+        //partitions
+        fprintf(stderr, "%s: Finalizing partitions\n",
+                        __func__);
+        r = gpt2_set_boot_chain(fd, NORMAL_BOOT);
+        if (r < 0) {
+            fprintf(stderr, "%s: Setting secondary GPT to normal boot failed\n",
+                            __func__);
+            goto EXIT;
+        }
+
+        r = gpt_set_state(fd, SECONDARY_GPT, GPT_OK);
+        if (r) {
+            fprintf(stderr, "%s: Fixing secondary GPT header failed\n",
+                            __func__);
+            goto EXIT;
+        }
+        break;
+    default:;
+    }
+
+EXIT:
+    if (fd >= 0) {
+       fsync(fd);
+       close(fd);
+    }
+    return r;
+}
+
+int add_lun_to_update_list(char *lun_path, struct update_data *dat)
+{
+        uint32_t i = 0;
+        struct stat st;
+        if (!lun_path || !dat){
+                fprintf(stderr, "%s: Invalid data",
+                                __func__);
+                return -1;
+        }
+        if (stat(lun_path, &st)) {
+                fprintf(stderr, "%s: Unable to access %s. Skipping adding to list",
+                                __func__,
+                                lun_path);
+                return -1;
+        }
+        if (dat->num_valid_entries == 0) {
+                fprintf(stderr, "%s: Copying %s into lun_list[%d]\n",
+                                __func__,
+                                lun_path,
+                                i);
+                strlcpy(dat->lun_list[0], lun_path,
+                                PATH_MAX * sizeof(char));
+                dat->num_valid_entries = 1;
+        } else {
+                for (i = 0; (i < dat->num_valid_entries) &&
+                                (dat->num_valid_entries < MAX_LUNS - 1); i++) {
+                        //Check if the current LUN is not already part
+                        //of the lun list
+                        if (!strncmp(lun_path,dat->lun_list[i],
+                                                strlen(dat->lun_list[i]))) {
+                                //LUN already in list..Return
+                                return 0;
+                        }
+                }
+                fprintf(stderr, "%s: Copying %s into lun_list[%d]\n",
+                                __func__,
+                                lun_path,
+                                dat->num_valid_entries);
+                //Add LUN path lun list
+                strlcpy(dat->lun_list[dat->num_valid_entries], lun_path,
+                                PATH_MAX * sizeof(char));
+                dat->num_valid_entries++;
+        }
+        return 0;
+}
+
+int prepare_boot_update(enum boot_update_stage stage)
+{
+        int r, fd;
+        int is_ufs = gpt_utils_is_ufs_device();
+        struct stat ufs_dir_stat;
+        struct update_data data;
+        int rcode = 0;
+        uint32_t i = 0;
+        int is_error = 0;
+        const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST };
+        //Holds /dev/block/bootdevice/by-name/*bak entry
+        char buf[PATH_MAX] = {0};
+        //Holds the resolved path of the symlink stored in buf
+        char real_path[PATH_MAX] = {0};
+
+        if (!is_ufs) {
+                //emmc device. Just pass in path to mmcblk0
+                return prepare_partitions(stage, BLK_DEV_FILE);
+        } else {
+                //Now we need to find the list of LUNs over
+                //which the boot critical images are spread
+                //and set them up for failsafe updates.To do
+                //this we find out where the symlinks for the
+                //each of the paths under
+                ///dev/block/bootdevice/by-name/PTN_SWAP_LIST
+                //actually point to.
+                fprintf(stderr, "%s: Running on a UFS device\n",
+                                __func__);
+                memset(&data, '\0', sizeof(struct update_data));
+                for (i=0; i < ARRAY_SIZE(ptn_swap_list); i++) {
+                        //XBL on UFS does not follow the convention
+                        //of being loaded based on well known GUID'S.
+                        //We take care of switching the UFS boot LUN
+                        //explicitly later on.
+                        if (!strncmp(ptn_swap_list[i],
+                                                PTN_XBL,
+                                                strlen(PTN_XBL)))
+                                continue;
+                        snprintf(buf, sizeof(buf),
+                                        "%s/%sbak",
+                                        BOOT_DEV_DIR,
+                                        ptn_swap_list[i]);
+                        if (stat(buf, &ufs_dir_stat)) {
+                                continue;
+                        }
+                        if (readlink(buf, real_path, sizeof(real_path) - 1) < 0)
+                        {
+                                fprintf(stderr, "%s: readlink error. Skipping %s",
+                                                __func__,
+                                                strerror(errno));
+                        } else {
+                              if(strlen(real_path) < PATH_TRUNCATE_LOC + 1){
+                                    fprintf(stderr, "Unknown path.Skipping :%s:\n",
+                                                real_path);
+                                } else {
+                                    real_path[PATH_TRUNCATE_LOC] = '\0';
+                                    add_lun_to_update_list(real_path, &data);
+                                }
+                        }
+                        memset(buf, '\0', sizeof(buf));
+                        memset(real_path, '\0', sizeof(real_path));
+                }
+                for (i=0; i < data.num_valid_entries; i++) {
+                        fprintf(stderr, "%s: Preparing %s for update stage %d\n",
+                                        __func__,
+                                        data.lun_list[i],
+                                        stage);
+                        rcode = prepare_partitions(stage, data.lun_list[i]);
+                        if (rcode != 0)
+                        {
+                                fprintf(stderr, "%s: Failed to prepare %s.Continuing..\n",
+                                                __func__,
+                                                data.lun_list[i]);
+                                is_error = 1;
+                        }
+                }
+        }
+        if (is_error)
+                return -1;
+        return 0;
+}
+
+//Given a parttion name(eg: rpm) get the path to the block device that
+//represents the GPT disk the partition resides on. In the case of emmc it
+//would be the default emmc dev(/dev/block/mmcblk0). In the case of UFS we look
+//through the /dev/block/bootdevice/by-name/ tree for partname, and resolve
+//the path to the LUN from there.
+static int get_dev_path_from_partition_name(const char *partname,
+                char *buf,
+                size_t buflen)
+{
+        struct stat st;
+        char path[PATH_MAX] = {0};
+        if (!partname || !buf || buflen < ((PATH_TRUNCATE_LOC) + 1)) {
+                ALOGE("%s: Invalid argument", __func__);
+                goto error;
+        }
+        if (gpt_utils_is_ufs_device()) {
+                //Need to find the lun that holds partition partname
+                snprintf(path, sizeof(path),
+                                "%s/%s",
+                                BOOT_DEV_DIR,
+                                partname);
+                if (stat(path, &st)) {
+                        goto error;
+                }
+                if (readlink(path, buf, buflen) < 0)
+                {
+                        goto error;
+                } else {
+                        buf[PATH_TRUNCATE_LOC] = '\0';
+                }
+        } else {
+                snprintf(buf, buflen, BLK_DEV_FILE);
+        }
+        return 0;
+
+error:
+        return -1;
+}
+
+int gpt_utils_get_partition_map(vector<string>& ptn_list,
+                map<string, vector<string>>& partition_map) {
+        char devpath[PATH_MAX] = {'\0'};
+        map<string, vector<string>>::iterator it;
+        if (ptn_list.size() < 1) {
+                fprintf(stderr, "%s: Invalid ptn list\n", __func__);
+                goto error;
+        }
+        //Go through the passed in list
+        for (uint32_t i = 0; i < ptn_list.size(); i++)
+        {
+                //Key in the map is the path to the device that holds the
+                //partition
+                if (get_dev_path_from_partition_name(ptn_list[i].c_str(),
+                                devpath,
+                                sizeof(devpath))) {
+                        //Not necessarily an error. The partition may just
+                        //not be present.
+                        continue;
+                }
+                string path = devpath;
+                it = partition_map.find(path);
+                if (it != partition_map.end()) {
+                        it->second.push_back(ptn_list[i]);
+                } else {
+                        vector<string> str_vec;
+                        str_vec.push_back( ptn_list[i]);
+                        partition_map.insert(pair<string, vector<string>>
+                                        (path, str_vec));
+                }
+                memset(devpath, '\0', sizeof(devpath));
+        }
+        return 0;
+error:
+        return -1;
+}
+
+//Get the block size of the disk represented by decsriptor fd
+static uint32_t gpt_get_block_size(int fd)
+{
+        uint32_t block_size = 0;
+        if (fd < 0) {
+                ALOGE("%s: invalid descriptor",
+                                __func__);
+                goto error;
+        }
+        if (ioctl(fd, BLKSSZGET, &block_size) != 0) {
+                ALOGE("%s: Failed to get GPT dev block size : %s",
+                                __func__,
+                                strerror(errno));
+                goto error;
+        }
+        return block_size;
+error:
+        return 0;
+}
+
+//Write the GPT header present in the passed in buffer back to the
+//disk represented by fd
+static int gpt_set_header(uint8_t *gpt_header, int fd,
+                enum gpt_instance instance)
+{
+        uint32_t block_size = 0;
+        off64_t gpt_header_offset = 0;
+        if (!gpt_header || fd < 0) {
+                ALOGE("%s: Invalid arguments",
+                                __func__);
+                goto error;
+        }
+        block_size = gpt_get_block_size(fd);
+        if (block_size == 0) {
+                ALOGE("%s: Failed to get block size", __func__);
+                goto error;
+        }
+        if (instance == PRIMARY_GPT)
+                gpt_header_offset = block_size;
+        else
+                gpt_header_offset = lseek64(fd, 0, SEEK_END) - block_size;
+        if (gpt_header_offset <= 0) {
+                ALOGE("%s: Failed to get gpt header offset",__func__);
+                goto error;
+        }
+        if (blk_rw(fd, 1, gpt_header_offset, gpt_header, block_size)) {
+                ALOGE("%s: Failed to write back GPT header", __func__);
+                goto error;
+        }
+        return 0;
+error:
+        return -1;
+}
+
+//Read out the GPT header for the disk that contains the partition partname
+static uint8_t* gpt_get_header(const char *partname, enum gpt_instance instance)
+{
+        uint8_t* hdr = NULL;
+        char devpath[PATH_MAX] = {0};
+        int64_t hdr_offset = 0;
+        uint32_t block_size = 0;
+        int fd = -1;
+        if (!partname) {
+                ALOGE("%s: Invalid partition name", __func__);
+                goto error;
+        }
+        if (get_dev_path_from_partition_name(partname, devpath, sizeof(devpath))
+                        != 0) {
+                ALOGE("%s: Failed to resolve path for %s",
+                                __func__,
+                                partname);
+                goto error;
+        }
+        fd = open(devpath, O_RDWR);
+        if (fd < 0) {
+                ALOGE("%s: Failed to open %s : %s",
+                                __func__,
+                                devpath,
+                                strerror(errno));
+                goto error;
+        }
+        block_size = gpt_get_block_size(fd);
+        if (block_size == 0)
+        {
+                ALOGE("%s: Failed to get gpt block size for %s",
+                                __func__,
+                                partname);
+                goto error;
+        }
+
+        hdr = (uint8_t*)malloc(block_size);
+        if (!hdr) {
+                ALOGE("%s: Failed to allocate memory for gpt header",
+                                __func__);
+        }
+        if (instance == PRIMARY_GPT)
+                hdr_offset = block_size;
+        else {
+                hdr_offset = lseek64(fd, 0, SEEK_END) - block_size;
+        }
+        if (hdr_offset < 0) {
+                ALOGE("%s: Failed to get gpt header offset",
+                                __func__);
+                goto error;
+        }
+        if (blk_rw(fd, 0, hdr_offset, hdr, block_size)) {
+                ALOGE("%s: Failed to read GPT header from device",
+                                __func__);
+                goto error;
+        }
+        close(fd);
+        return hdr;
+error:
+        if (fd >= 0)
+                close(fd);
+        if (hdr)
+                free(hdr);
+        return NULL;
+}
+
+//Returns the partition entry array based on the
+//passed in buffer which contains the gpt header.
+//The fd here is the descriptor for the 'disk' which
+//holds the partition
+static uint8_t* gpt_get_pentry_arr(uint8_t *hdr, int fd)
+{
+        uint64_t pentries_start = 0;
+        uint32_t pentry_size = 0;
+        uint32_t block_size = 0;
+        uint32_t pentries_arr_size = 0;
+        uint8_t *pentry_arr = NULL;
+        int rc = 0;
+        if (!hdr) {
+                ALOGE("%s: Invalid header", __func__);
+                goto error;
+        }
+        if (fd < 0) {
+                ALOGE("%s: Invalid fd", __func__);
+                goto error;
+        }
+        block_size = gpt_get_block_size(fd);
+        if (!block_size) {
+                ALOGE("%s: Failed to get gpt block size for",
+                                __func__);
+                goto error;
+        }
+        pentries_start = GET_8_BYTES(hdr + PENTRIES_OFFSET) * block_size;
+        pentry_size = GET_4_BYTES(hdr + PENTRY_SIZE_OFFSET);
+        pentries_arr_size =
+                GET_4_BYTES(hdr + PARTITION_COUNT_OFFSET) * pentry_size;
+        pentry_arr = (uint8_t*)calloc(1, pentries_arr_size);
+        if (!pentry_arr) {
+                ALOGE("%s: Failed to allocate memory for partition array",
+                                __func__);
+                goto error;
+        }
+        rc = blk_rw(fd, 0,
+                        pentries_start,
+                        pentry_arr,
+                        pentries_arr_size);
+        if (rc) {
+                ALOGE("%s: Failed to read partition entry array",
+                                __func__);
+                goto error;
+        }
+        return pentry_arr;
+error:
+        if (pentry_arr)
+                free(pentry_arr);
+        return NULL;
+}
+
+static int gpt_set_pentry_arr(uint8_t *hdr, int fd, uint8_t* arr)
+{
+        uint32_t block_size = 0;
+        uint64_t pentries_start = 0;
+        uint32_t pentry_size = 0;
+        uint32_t pentries_arr_size = 0;
+        int rc = 0;
+        if (!hdr || fd < 0 || !arr) {
+                ALOGE("%s: Invalid argument", __func__);
+                goto error;
+        }
+        block_size = gpt_get_block_size(fd);
+        if (!block_size) {
+                ALOGE("%s: Failed to get gpt block size for",
+                                __func__);
+                goto error;
+        }
+        pentries_start = GET_8_BYTES(hdr + PENTRIES_OFFSET) * block_size;
+        pentry_size = GET_4_BYTES(hdr + PENTRY_SIZE_OFFSET);
+        pentries_arr_size =
+                GET_4_BYTES(hdr + PARTITION_COUNT_OFFSET) * pentry_size;
+        rc = blk_rw(fd, 1,
+                        pentries_start,
+                        arr,
+                        pentries_arr_size);
+        if (rc) {
+                ALOGE("%s: Failed to read partition entry array",
+                                __func__);
+                goto error;
+        }
+        return 0;
+error:
+        return -1;
+}
+
+
+
+//Allocate a handle used by calls to the "gpt_disk" api's
+struct gpt_disk * gpt_disk_alloc()
+{
+        struct gpt_disk *disk;
+        disk = (struct gpt_disk *)malloc(sizeof(struct gpt_disk));
+        if (!disk) {
+                ALOGE("%s: Failed to allocate memory", __func__);
+                goto end;
+        }
+        memset(disk, 0, sizeof(struct gpt_disk));
+end:
+        return disk;
+}
+
+//Free previously allocated/initialized handle
+void gpt_disk_free(struct gpt_disk *disk)
+{
+        if (!disk)
+                return;
+        if (disk->hdr)
+                free(disk->hdr);
+        if (disk->hdr_bak)
+                free(disk->hdr_bak);
+        if (disk->pentry_arr)
+                free(disk->pentry_arr);
+        if (disk->pentry_arr_bak)
+                free(disk->pentry_arr_bak);
+        free(disk);
+        return;
+}
+
+//fills up the passed in gpt_disk struct with information about the
+//disk represented by path dev. Returns 0 on success and -1 on error.
+int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *dsk)
+{
+        struct gpt_disk *disk = NULL;
+        int fd = -1;
+        uint32_t gpt_header_size = 0;
+
+        if (!dsk || !dev) {
+                ALOGE("%s: Invalid arguments", __func__);
+                goto error;
+        }
+        disk = dsk;
+        disk->hdr = gpt_get_header(dev, PRIMARY_GPT);
+        if (!disk->hdr) {
+                ALOGE("%s: Failed to get primary header", __func__);
+                goto error;
+        }
+        gpt_header_size = GET_4_BYTES(disk->hdr + HEADER_SIZE_OFFSET);
+        disk->hdr_crc = sparse_crc32(0, disk->hdr, gpt_header_size);
+        disk->hdr_bak = gpt_get_header(dev, SECONDARY_GPT);
+        if (!disk->hdr_bak) {
+                ALOGE("%s: Failed to get backup header", __func__);
+                goto error;
+        }
+        disk->hdr_bak_crc = sparse_crc32(0, disk->hdr_bak, gpt_header_size);
+
+        //Descriptor for the block device. We will use this for further
+        //modifications to the partition table
+        if (get_dev_path_from_partition_name(dev,
+                                disk->devpath,
+                                sizeof(disk->devpath)) != 0) {
+                ALOGE("%s: Failed to resolve path for %s",
+                                __func__,
+                                dev);
+                goto error;
+        }
+        fd = open(disk->devpath, O_RDWR);
+        if (fd < 0) {
+                ALOGE("%s: Failed to open %s: %s",
+                                __func__,
+                                disk->devpath,
+                                strerror(errno));
+                goto error;
+        }
+        disk->pentry_arr = gpt_get_pentry_arr(disk->hdr, fd);
+        if (!disk->pentry_arr) {
+                ALOGE("%s: Failed to obtain partition entry array",
+                                __func__);
+                goto error;
+        }
+        disk->pentry_arr_bak = gpt_get_pentry_arr(disk->hdr_bak, fd);
+        if (!disk->pentry_arr_bak) {
+                ALOGE("%s: Failed to obtain backup partition entry array",
+                                __func__);
+                goto error;
+        }
+        disk->pentry_size = GET_4_BYTES(disk->hdr + PENTRY_SIZE_OFFSET);
+        disk->pentry_arr_size =
+                GET_4_BYTES(disk->hdr + PARTITION_COUNT_OFFSET) *
+                disk->pentry_size;
+        disk->pentry_arr_crc = GET_4_BYTES(disk->hdr + PARTITION_CRC_OFFSET);
+        disk->pentry_arr_bak_crc = GET_4_BYTES(disk->hdr_bak +
+                        PARTITION_CRC_OFFSET);
+        disk->block_size = gpt_get_block_size(fd);
+        close(fd);
+        disk->is_initialized = GPT_DISK_INIT_MAGIC;
+        return 0;
+error:
+        if (fd >= 0)
+                close(fd);
+        return -1;
+}
+
+//Get pointer to partition entry from a allocated gpt_disk structure
+uint8_t* gpt_disk_get_pentry(struct gpt_disk *disk,
+                const char *partname,
+                enum gpt_instance instance)
+{
+        uint8_t *ptn_arr = NULL;
+        if (!disk || !partname || disk->is_initialized != GPT_DISK_INIT_MAGIC) {
+                ALOGE("%s: Invalid argument",__func__);
+                goto error;
+        }
+        ptn_arr = (instance == PRIMARY_GPT) ?
+                disk->pentry_arr : disk->pentry_arr_bak;
+        return (gpt_pentry_seek(partname, ptn_arr,
+                        ptn_arr + disk->pentry_arr_size ,
+                        disk->pentry_size));
+error:
+        return NULL;
+}
+
+//Update CRC values for the various components of the gpt_disk
+//structure. This function should be called after any of the fields
+//have been updated before the structure contents are written back to
+//disk.
+int gpt_disk_update_crc(struct gpt_disk *disk)
+{
+        uint32_t gpt_header_size = 0;
+        if (!disk || (disk->is_initialized != GPT_DISK_INIT_MAGIC)) {
+                ALOGE("%s: invalid argument", __func__);
+                goto error;
+        }
+        //Recalculate the CRC of the primary partiton array
+        disk->pentry_arr_crc = sparse_crc32(0,
+                        disk->pentry_arr,
+                        disk->pentry_arr_size);
+        //Recalculate the CRC of the backup partition array
+        disk->pentry_arr_bak_crc = sparse_crc32(0,
+                        disk->pentry_arr_bak,
+                        disk->pentry_arr_size);
+        //Update the partition CRC value in the primary GPT header
+        PUT_4_BYTES(disk->hdr + PARTITION_CRC_OFFSET, disk->pentry_arr_crc);
+        //Update the partition CRC value in the backup GPT header
+        PUT_4_BYTES(disk->hdr_bak + PARTITION_CRC_OFFSET,
+                        disk->pentry_arr_bak_crc);
+        //Update the CRC value of the primary header
+        gpt_header_size = GET_4_BYTES(disk->hdr + HEADER_SIZE_OFFSET);
+        //Header CRC is calculated with its own CRC field set to 0
+        PUT_4_BYTES(disk->hdr + HEADER_CRC_OFFSET, 0);
+        PUT_4_BYTES(disk->hdr_bak + HEADER_CRC_OFFSET, 0);
+        disk->hdr_crc = sparse_crc32(0, disk->hdr, gpt_header_size);
+        disk->hdr_bak_crc = sparse_crc32(0, disk->hdr_bak, gpt_header_size);
+        PUT_4_BYTES(disk->hdr + HEADER_CRC_OFFSET, disk->hdr_crc);
+        PUT_4_BYTES(disk->hdr_bak + HEADER_CRC_OFFSET, disk->hdr_bak_crc);
+        return 0;
+error:
+        return -1;
+}
+
+//Write the contents of struct gpt_disk back to the actual disk
+int gpt_disk_commit(struct gpt_disk *disk)
+{
+        int fd = -1;
+        if (!disk || (disk->is_initialized != GPT_DISK_INIT_MAGIC)){
+                ALOGE("%s: Invalid args", __func__);
+                goto error;
+        }
+        fd = open(disk->devpath, O_RDWR);
+        if (fd < 0) {
+                ALOGE("%s: Failed to open %s: %s",
+                                __func__,
+                                disk->devpath,
+                                strerror(errno));
+                goto error;
+        }
+        //Write the primary header
+        if(gpt_set_header(disk->hdr, fd, PRIMARY_GPT) != 0) {
+                ALOGE("%s: Failed to update primary GPT header",
+                                __func__);
+                goto error;
+        }
+        //Write back the primary partition array
+        if (gpt_set_pentry_arr(disk->hdr, fd, disk->pentry_arr)) {
+                ALOGE("%s: Failed to write primary GPT partition arr",
+                                __func__);
+                goto error;
+        }
+        //Write back the secondary header
+        if(gpt_set_header(disk->hdr_bak, fd, SECONDARY_GPT) != 0) {
+                ALOGE("%s: Failed to update secondary GPT header",
+                                __func__);
+                goto error;
+        }
+        //Write back the secondary partition array
+        if (gpt_set_pentry_arr(disk->hdr_bak, fd, disk->pentry_arr_bak)) {
+                ALOGE("%s: Failed to write secondary GPT partition arr",
+                                __func__);
+                goto error;
+        }
+        close(fd);
+        return 0;
+error:
+        if (fd >= 0)
+                close(fd);
+        return -1;
+}
