bug-parted
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: fix gcc bug and big-endian issues for GPT


From: Richard Hirst
Subject: PATCH: fix gcc bug and big-endian issues for GPT
Date: Wed, 20 Mar 2002 00:03:34 +0000
User-agent: Mutt/1.3.24i

Hi,
  This patch to parted 1.4 changes disk_gpt.c to keep the structures
representing on-disk data in little-endian format all the time.  Fields
are accessed via PED_LE32_TO_CPU() and friends, and the GUID fields are
swapped to big endian round calls to libuuid functions.  One other
effect of this is that it now write the unique GUIDs witht he right byte
order.  It also treats the GUIDs as raw 16 byte blobs, which avoids
triggering the gcc ((packed)) bug.  In addition, I fixed various printf
strings for 64 bit values by adding '%'.  Some of this patch is based on
patches Matt Domsch has previously posted here.

The patch is large because of all the changes to when struct members are
swapped, but it should be pretty safe because (a) it is only used on
little-endian ATM, so the swapping is a nop, and big-endian was broken
before so it can't be any worse, and (b) I've tested it on a big-endian
platform and could move disks between ia64 and hppa and still read the
table.

Cheers,
  Richard



diff -ur parted-1.4.24.ori/ChangeLog parted-1.4.24-1.le1/ChangeLog
--- parted-1.4.24.ori/ChangeLog Sat Jan 26 18:03:37 2002
+++ parted-1.4.24-1.le1/ChangeLog       Tue Mar 19 16:18:51 2002
@@ -7,6 +7,13 @@
 -----------------------------------------------------------------------------
 1.4.x
 -----------------------------------------------------------------------------
+
+2002-03-19  Richard Hirst  <address@hidden>
+* treat GPT structs as little-endian always, regardless of cpu byte order,
+  now gets unique GUID byte order correct, and works on big-endian
+* treat GUIDs as little-endian blobs except when calling libuuid functions,
+  avoid triggering gcc ((packed)) bug
+
 2002-01-26  Andrew Cluasen  <address@hidden>
 * added new/updated translations: ca, fr, da
 * backported fixes from 1.6.x:
diff -ur parted-1.4.24.ori/include/parted/disk_gpt.h 
parted-1.4.24-1.le1/include/parted/disk_gpt.h
--- parted-1.4.24.ori/include/parted/disk_gpt.h Mon Oct  1 22:06:33 2001
+++ parted-1.4.24-1.le1/include/parted/disk_gpt.h       Tue Mar 19 16:13:47 2002
@@ -42,35 +42,45 @@
 
 typedef uint16_t efi_char16_t; /* UNICODE character */
 
+/* This is a struct so code can do "blah->foo = PARTITION_SYSTEM_GUID;" */
 typedef struct {
-        uint32_t time_low;
-        uint16_t time_mid;
-        uint16_t time_hi_and_version;
-        uint8_t  clock_seq_hi_and_reserved;
-        uint8_t  clock_seq_low;
-        uint8_t  node[6];
-} __attribute__ ((packed)) efi_guid_t;
-
+        uint8_t  guid[16];
+} efi_guid_t;
 
+/* A GUID is treated as a little-endian string, except when calling
+ * libuuid functions, when we swap it.
+ */
+#define EFI_GUID(a,b,c,b0,b1,b2,b3,b4,b5,b6,b7)                (efi_guid_t)    
  \
+{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+         (b) & 0xff, ((b) >> 8) & 0xff,                                  \
+         (c) & 0xff, ((c) >> 8) & 0xff,                                  \
+         (b0), (b1), (b2), (b3), (b4), (b5), (b6), (b7)                  \
+}}
+                     
 #define UNUSED_ENTRY_GUID    \
-    ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, { 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00 }})
+    EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00)
 #define PARTITION_SYSTEM_GUID \
-    ((efi_guid_t) { 0xC12A7328, 0xF81F, 0x11d2, 0xBA, 0x4B, { 0x00, 0xA0, 
0xC9, 0x3E, 0xC9, 0x3B }})
+    EFI_GUID(0xC12A7328, 0xF81F, 0x11d2, 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 
0xC9, 0x3B)
 #define LEGACY_MBR_PARTITION_GUID \
-    ((efi_guid_t) { 0x024DEE41, 0x33E7, 0x11d3, 0x9D, 0x69, { 0x00, 0x08, 
0xC7, 0x81, 0xF3, 0x9F }})
+    EFI_GUID(0x024DEE41, 0x33E7, 0x11d3, 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 
0xF3, 0x9F)
 #define PARTITION_MSFT_RESERVED_GUID \
-    ((efi_guid_t) { 0xE3C9E316, 0x0B5C, 0x4DB8, 0x81, 0x7D, { 0xF9, 0x2D, 
0xF0, 0x02, 0x15, 0xAE }})
+    EFI_GUID(0xE3C9E316, 0x0B5C, 0x4DB8, 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 
0x15, 0xAE)
 #define PARTITION_BASIC_DATA_GUID \
-    ((efi_guid_t) { 0xEBD0A0A2, 0xB9E5, 0x4433, 0x87, 0xC0, { 0x68, 0xB6, 
0xB7, 0x26, 0x99, 0xC7 }})
+    EFI_GUID(0xEBD0A0A2, 0xB9E5, 0x4433, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 
0x99, 0xC7)
 #define PARTITION_RAID_GUID \
-    ((efi_guid_t) { 0xa19d880f, 0x05fc, 0x4d3b, 0xa0, 0x06, { 0x74, 0x3f, 
0x0f, 0x84, 0x91, 0x1e }})
+    EFI_GUID(0xa19d880f, 0x05fc, 0x4d3b, 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 
0x91, 0x1e)
 #define PARTITION_SWAP_GUID \
-    ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, 0x84, 0xe5, { 0x09, 0x33, 
0xc8, 0x4b, 0x4f, 0x4f }})
+    EFI_GUID(0x0657fd6d, 0xa4ab, 0x43c4, 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 
0x4f, 0x4f)
 #define PARTITION_LVM_GUID \
-    ((efi_guid_t) { 0xe6d6d379, 0xf507, 0x44c2, 0xa2, 0x3c, { 0x23, 0x8f, 
0x2a, 0x3d, 0xf9, 0x28 }})
+    EFI_GUID(0xe6d6d379, 0xf507, 0x44c2, 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 
0xf9, 0x28)
 #define PARTITION_RESERVED_GUID \
-    ((efi_guid_t) { 0x8da63339, 0x0007, 0x60c0, 0xc4, 0x36, { 0x08, 0x3a, 
0xc8, 0x23, 0x09, 0x08 }})
+    EFI_GUID(0x8da63339, 0x0007, 0x60c0, 0xc4, 0x36, 0x08, 0x3a, 0xc8, 0x23, 
0x09, 0x08)
+
 
+/* NOTE: The following structure is _always_ in little-endian format,
+ * regardless of local CPU byte-order.  This is to simplify CRC calculations
+ * and checking.
+ */
 typedef struct _GuidPartitionTableHeader_t {
        uint64_t Signature;
        uint32_t Revision;
@@ -89,18 +99,16 @@
        uint8_t Reserved2[GPT_BLOCK_SIZE - 92];
 } __attribute__ ((packed)) GuidPartitionTableHeader_t;
 
-typedef struct _GuidPartitionEntryAttributes_t {
-       uint64_t RequiredToFunction:1;
-       uint64_t Reserved:47;
-        uint64_t GuidSpecific:16;
-} __attribute__ ((packed)) GuidPartitionEntryAttributes_t;
-
+/* NOTE: The following structure is _always_ in little-endian format,
+ * regardless of local CPU byte-order.  This is to simplify CRC calculations
+ * and checking.
+ */
 typedef struct _GuidPartitionEntry_t {
        efi_guid_t PartitionTypeGuid;
        efi_guid_t UniquePartitionGuid;
        uint64_t StartingLBA;
        uint64_t EndingLBA;
-       GuidPartitionEntryAttributes_t Attributes;
+       uint64_t Attributes;
        efi_char16_t PartitionName[72 / sizeof(efi_char16_t)];
 } __attribute__ ((packed)) GuidPartitionEntry_t;
 
diff -ur parted-1.4.24.ori/include/parted/endian.h 
parted-1.4.24-1.le1/include/parted/endian.h
--- parted-1.4.24.ori/include/parted/endian.h   Sat May  5 00:41:07 2001
+++ parted-1.4.24-1.le1/include/parted/endian.h Tue Mar 19 13:45:54 2002
@@ -63,7 +63,7 @@
 #define PED_BE16_TO_CPU(x)     (x)
 #define PED_LE32_TO_CPU(x)     PED_SWAP32(x)
 #define PED_BE32_TO_CPU(x)     (x)
-#define PED_LE64_TO_CPU(x)     PED_SWAP32(x)
+#define PED_LE64_TO_CPU(x)     PED_SWAP64(x)
 #define PED_BE64_TO_CPU(x)     (x)
 
 #else /* !WORDS_BIGENDIAN */
diff -ur parted-1.4.24.ori/libparted/disk_gpt.c 
parted-1.4.24-1.le1/libparted/disk_gpt.c
--- parted-1.4.24.ori/libparted/disk_gpt.c      Sat Oct 20 06:52:42 2001
+++ parted-1.4.24-1.le1/libparted/disk_gpt.c    Tue Mar 19 16:14:13 2002
@@ -121,41 +121,35 @@
 };
 
 
-
-static void
-gpt_le_guid_to_cpu(efi_guid_t *guid)
-{
-       guid->time_low            = PED_LE32_TO_CPU(guid->time_low);
-       guid->time_mid            = PED_LE16_TO_CPU(guid->time_mid);
-       guid->time_hi_and_version = PED_LE16_TO_CPU(guid->time_hi_and_version);
-       /* no need to change clock_seq and node[6].
-          They're already arrays of chars */
-       return;
-}
-
-static void
-gpt_cpu_to_le_guid(efi_guid_t *guid)
-{
-       guid->time_low            = PED_CPU_TO_LE32(guid->time_low);
-       guid->time_mid            = PED_CPU_TO_LE16(guid->time_mid);
-       guid->time_hi_and_version = PED_CPU_TO_LE16(guid->time_hi_and_version);
-       /* no need to change clock_seq and node[6].
-          They're already arrays of chars */
-       return;
-}
-
+/**
+ * swap_uuid_and_efi_guid() - converts between uuid formats
+ * @uuid - uuid_t in either format (converts it to the other)
+ *
+ * There are two different representations for Globally Unique Identifiers
+ * (GUIDs or UUIDs).
+ * 
+ * The RFC specifies a UUID as a string of 16 bytes, essentially
+ * a big-endian array of char.
+ * Intel, in their EFI Specification, references the same RFC, but
+ * then defines a GUID as a structure of little-endian fields.
+ * Coincidentally, both structures have the same format when unparsed.
+ *
+ * When read from disk, EFI GUIDs are in struct of little endian format,
+ * and need to be converted to and from a uuid_t round calls to libuuid
+ * functions.
+ *
+ * Blame Intel.
+ */
 static void
-gpt_le_part_attributes_to_cpu(GuidPartitionEntryAttributes_t *a)
+swap_uuid_and_efi_guid(uuid_t uuid)
 {
-       uint64_t *b = (uint64_t *)a;
-       *b = PED_LE64_TO_CPU(*b);
-}
+       uint8_t t, *p = (uint8_t *)uuid;
 
-static void
-gpt_cpu_to_le_part_attributes(GuidPartitionEntryAttributes_t *a)
-{
-       uint64_t *b = (uint64_t *)a;
-       *b = PED_CPU_TO_LE64(*b);
+       PED_ASSERT(uuid != NULL, return);
+       t = p[0]; p[0] = p[3]; p[3] = t;
+       t = p[1]; p[1] = p[2]; p[2] = t;
+       t = p[4]; p[4] = p[5]; p[5] = t;
+       t = p[6]; p[6] = p[7]; p[7] = t;
 }
 
 
@@ -183,7 +177,7 @@
 {
        int i, found = 0, signature = 0;
        PED_ASSERT(mbr != NULL, return 0);
-       signature = (mbr->Signature == MSDOS_MBR_SIGNATURE);
+       signature = (PED_LE16_TO_CPU(mbr->Signature) == MSDOS_MBR_SIGNATURE);
        for (i=0; signature && i<4; i++) {
                if (mbr->PartitionRecord[i].OSType ==
                    EFI_PMBR_OSTYPE_EFI_GPT) {
@@ -246,34 +240,22 @@
        PED_ASSERT(gpt != NULL, return NULL);
 
        ptes = (GuidPartitionEntry_t *)
-               ped_malloc(gpt->NumberOfPartitionEntries *
-                          gpt->SizeOfPartitionEntry);
+               ped_malloc(PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries) *
+                          PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry));
 
        PED_ASSERT(ptes != NULL, return NULL);
 
-       memset(ptes, 0, gpt->NumberOfPartitionEntries *
-              gpt->SizeOfPartitionEntry);
+       memset(ptes, 0, PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries) *
+              PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry));
 
 
-       if (!ped_device_read(dev, ptes, gpt->PartitionEntryLBA,
-                    gpt->NumberOfPartitionEntries *
-                    gpt->SizeOfPartitionEntry / dev->sector_size)) {
+       if (!ped_device_read(dev, ptes, PED_LE64_TO_CPU(gpt->PartitionEntryLBA),
+                    PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries) *
+                    PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry) / 
dev->sector_size)) {
                ped_free(ptes);
                return NULL;
        }
 
-       /* Fixup endianness */
-       for (i=0; i<gpt->NumberOfPartitionEntries; i++) {
-               gpt_le_guid_to_cpu(&ptes[i].PartitionTypeGuid);
-               gpt_le_guid_to_cpu(&ptes[i].UniquePartitionGuid);
-               ptes[i].StartingLBA = PED_LE64_TO_CPU(ptes[i].StartingLBA);
-               ptes[i].EndingLBA   = PED_LE64_TO_CPU(ptes[i].EndingLBA);
-               gpt_le_part_attributes_to_cpu(&ptes[i].Attributes);
-               for (j=0; j<(72/sizeof(efi_char16_t)); j++) {
-                       ptes[i].PartitionName[j] = 
(efi_char16_t)(PED_LE16_TO_CPU((uint16_t)(ptes[i].PartitionName[j])));
-               }
-       }
-
        return ptes;
 }
 
@@ -296,7 +278,6 @@
                       GuidPartitionTableHeader_t * gpt,
                       GuidPartitionEntry_t *ptes)
 {
-       GuidPartitionEntry_t *new_ptes;
        unsigned long ptes_size;
        int rc;
        unsigned int i, j;
@@ -306,34 +287,17 @@
        PED_ASSERT(dev != NULL, return NULL);
        PED_ASSERT(dev->sector_size != 0, return NULL);
 
-       ptes_size = gpt->NumberOfPartitionEntries *
-               gpt->SizeOfPartitionEntry;
-
-       new_ptes = ped_malloc(ptes_size);
-       if (!new_ptes) return NULL;
-       memcpy(new_ptes, ptes, ptes_size);
-
-       /* Fixup endianness */
-       for (i=0; i<gpt->NumberOfPartitionEntries; i++) {
-               gpt_cpu_to_le_guid(&new_ptes->PartitionTypeGuid);
-               gpt_cpu_to_le_guid(&new_ptes->UniquePartitionGuid);
-               new_ptes[i].StartingLBA = 
PED_CPU_TO_LE64(new_ptes[i].StartingLBA);
-               new_ptes[i].EndingLBA   = 
PED_CPU_TO_LE64(new_ptes[i].EndingLBA);
-               gpt_cpu_to_le_part_attributes(&new_ptes[i].Attributes);
-
-               for (j=0; j<(72/sizeof(efi_char16_t)); j++) {
-                       new_ptes[i].PartitionName[j] = 
(efi_char16_t)(PED_CPU_TO_LE16((uint16_t)(new_ptes[i].PartitionName[j])));
-               }
-       }
+       ptes_size = PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries) *
+               PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry);
 
-       rc = ped_device_write(dev, new_ptes, gpt->PartitionEntryLBA,
+       rc = ped_device_write(dev, ptes, 
PED_LE64_TO_CPU(gpt->PartitionEntryLBA),
                              ptes_size / dev->sector_size);
-       ped_free(new_ptes);
        if (!rc) return NULL;
        return ptes;
 }
 
 
+#ifdef GPT_DEBUG
 static void
 gpt_print_part_entry(GuidPartitionEntry_t * pte, int i)
 {
@@ -347,20 +311,23 @@
        }
        printf("GUID Partition Entry %d:\n", i);
        memcpy(uuid, &pte->PartitionTypeGuid, sizeof(uuid_t));
+       swap_uuid_and_efi_guid(uuid);
        uuid_unparse(uuid, uuid_buffer);
        printf("\tPartitionTypeGuid : %s\n", uuid_buffer);
        memcpy(uuid, &pte->UniquePartitionGuid, sizeof(uuid_t));
+       swap_uuid_and_efi_guid(uuid);
        uuid_unparse(uuid, uuid_buffer);
        printf("\tUniquePartitionGuid : %s\n", uuid_buffer);
-       printf("\tStartingLBA : " PRIx64 "\n", pte->StartingLBA);
-       printf("\tEndingLBA   : " PRIx64 "\n", pte->EndingLBA);
+       printf("\tStartingLBA : %" PRIx64 "\n", 
PED_LE64_TO_CPU(pte->StartingLBA));
+       printf("\tEndingLBA   : %" PRIx64 "\n", 
PED_LE64_TO_CPU(pte->EndingLBA));
        printf("\tAttributes  : ");
        printf("\tRequiredToFunction: %x",
-              pte->Attributes.RequiredToFunction);
+              PED_LE64_TO_CPU(pte->Attributes) >> 63);
        printf("\tGuidSpecific: %x\n",
-              pte->Attributes.GuidSpecific);
+              PED_LE64_TO_CPU(pte->Attributes) & 0xffff);
 
        //  printf("\tPartitionName : Unicode string.\n");
+       //  NOTE: PartitionName is in little-endian order
        return;
 }
 
@@ -371,24 +338,27 @@
        uuid_t uuid;
        printf("GUID Partition Table Header\n");
        PED_ASSERT(gpt != NULL, return);
-       printf("Signature      : 0x" PRIx64 "\n", gpt->Signature);
-       printf("Revision       : 0x%x\n", gpt->Revision);
-       printf("HeaderSize     : 0x%x\n", gpt->HeaderSize);
-       printf("HeaderCRC32    : 0x%x\n", gpt->HeaderCRC32);
-       printf("MyLBA          : 0x" PRIx64 "\n", gpt->MyLBA);
-       printf("AlternateLBA   : 0x" PRIx64 "\n", gpt->AlternateLBA);
-       printf("FirstUsableLBA : 0x" PRIx64 "\n", gpt->FirstUsableLBA);
-       printf("LastUsableLBA  : 0x" PRIx64 "\n", gpt->LastUsableLBA);
+       printf("Signature      : 0x%" PRIx64 "\n", 
PED_LE64_TO_CPU(gpt->Signature));
+       printf("Revision       : 0x%x\n", PED_LE32_TO_CPU(gpt->Revision));
+       printf("HeaderSize     : 0x%x\n", PED_LE32_TO_CPU(gpt->HeaderSize));
+       printf("HeaderCRC32    : 0x%x\n", PED_LE32_TO_CPU(gpt->HeaderCRC32));
+       printf("MyLBA          : 0x%" PRIx64 "\n", PED_LE64_TO_CPU(gpt->MyLBA));
+       printf("AlternateLBA   : 0x%" PRIx64 "\n", 
PED_LE64_TO_CPU(gpt->AlternateLBA));
+       printf("FirstUsableLBA : 0x%" PRIx64 "\n", 
PED_LE64_TO_CPU(gpt->FirstUsableLBA));
+       printf("LastUsableLBA  : 0x%" PRIx64 "\n", 
PED_LE64_TO_CPU(gpt->LastUsableLBA));
        memcpy(uuid, &gpt->DiskGUID, sizeof(uuid_t));
+       swap_uuid_and_efi_guid(uuid);
        uuid_unparse(uuid, uuid_buffer);
        printf("DiskGUID : %s\n", uuid_buffer);
-       printf("PartitionEntryLBA : " PRIx64 "\n", gpt->PartitionEntryLBA);
+       printf("PartitionEntryLBA : %" PRIx64 "\n", 
PED_LE64_TO_CPU(gpt->PartitionEntryLBA));
        printf("NumberOfPartitionEntries : %x\n",
-              gpt->NumberOfPartitionEntries);
-       printf("SizeOfPartitionEntry : %x\n", gpt->SizeOfPartitionEntry);
+              PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries));
+       printf("SizeOfPartitionEntry : %x\n", 
PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry));
        printf("PartitionEntryArrayCRC32 : %x\n",
-              gpt->PartitionEntryArrayCRC32); return;
+              PED_LE32_TO_CPU(gpt->PartitionEntryArrayCRC32));
+       return;
 }
+#endif
 
 
 /************************************************************
@@ -417,24 +387,6 @@
                return NULL;
        }
 
-
-       /* Fixup endianness */
-       gpt->Signature                = PED_LE64_TO_CPU(gpt->Signature);
-       gpt->Revision                 = PED_LE32_TO_CPU(gpt->Revision);
-       gpt->HeaderSize               = PED_LE32_TO_CPU(gpt->HeaderSize);
-       gpt->HeaderCRC32              = PED_LE32_TO_CPU(gpt->HeaderCRC32);
-       gpt->Reserved1                = PED_LE32_TO_CPU(gpt->Reserved1);
-       gpt->MyLBA                    = PED_LE64_TO_CPU(gpt->MyLBA);
-       gpt->AlternateLBA             = PED_LE64_TO_CPU(gpt->AlternateLBA);
-       gpt->FirstUsableLBA           = PED_LE64_TO_CPU(gpt->FirstUsableLBA);
-       gpt->LastUsableLBA            = PED_LE64_TO_CPU(gpt->LastUsableLBA);
-       gpt->PartitionEntryLBA        = PED_LE64_TO_CPU(gpt->PartitionEntryLBA);
-       gpt->NumberOfPartitionEntries = 
PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries);
-       gpt->SizeOfPartitionEntry     = 
PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry);
-       gpt->PartitionEntryArrayCRC32 = 
PED_LE32_TO_CPU(gpt->PartitionEntryArrayCRC32);
-       gpt_le_guid_to_cpu(&gpt->DiskGUID);
-       /* Ignore the reserved bytes */
-
        return gpt;
 }
 
@@ -454,34 +406,11 @@
 gpt_write_header(PedDevice *dev,
                 GuidPartitionTableHeader_t * gpt)
 {
-       GuidPartitionTableHeader_t *new_gpt;
        int rc;
 
        PED_ASSERT(gpt != NULL, return 0);
 
-       new_gpt = ped_malloc(sizeof(*gpt));
-       if (!new_gpt) return 0;
-       memcpy(new_gpt, gpt, sizeof(*gpt));
-
-       /* Fixup endianness */
-       new_gpt->Signature                = PED_CPU_TO_LE64(gpt->Signature);
-       new_gpt->Revision                 = PED_CPU_TO_LE32(gpt->Revision);
-       new_gpt->HeaderSize               = PED_CPU_TO_LE32(gpt->HeaderSize);
-       new_gpt->HeaderCRC32              = PED_CPU_TO_LE32(gpt->HeaderCRC32);
-       new_gpt->Reserved1                = PED_CPU_TO_LE32(gpt->Reserved1);
-       new_gpt->MyLBA                    = PED_CPU_TO_LE64(gpt->MyLBA);
-       new_gpt->AlternateLBA             = PED_CPU_TO_LE64(gpt->AlternateLBA);
-       new_gpt->FirstUsableLBA           = 
PED_CPU_TO_LE64(gpt->FirstUsableLBA);
-       new_gpt->LastUsableLBA            = PED_CPU_TO_LE64(gpt->LastUsableLBA);
-       new_gpt->PartitionEntryLBA        = 
PED_CPU_TO_LE64(gpt->PartitionEntryLBA);
-       new_gpt->NumberOfPartitionEntries = 
PED_CPU_TO_LE32(gpt->NumberOfPartitionEntries);
-       new_gpt->SizeOfPartitionEntry = 
PED_CPU_TO_LE32(gpt->SizeOfPartitionEntry);
-       new_gpt->PartitionEntryArrayCRC32 = 
PED_CPU_TO_LE32(gpt->PartitionEntryArrayCRC32);
-       gpt_cpu_to_le_guid(&new_gpt->DiskGUID);
-       /* Ignore the reserved bytes */
-
-       rc = ped_device_write(dev, new_gpt, gpt->MyLBA, GPT_HEADER_SECTORS);
-       ped_free(new_gpt);
+       rc = ped_device_write(dev, gpt, PED_LE64_TO_CPU(gpt->MyLBA), 
GPT_HEADER_SECTORS);
        return rc;
 }
 
@@ -513,39 +442,39 @@
        if (!(*gpt = gpt_read_header(dev, lba)))
                return 0;
        /* Check the GUID Partition Table Signature */
-       if ((*gpt)->Signature != GPT_HEADER_SIGNATURE) {
+       if (PED_LE64_TO_CPU((*gpt)->Signature) != GPT_HEADER_SIGNATURE) {
                ped_exception_throw (
                        PED_EXCEPTION_ERROR,
                        PED_EXCEPTION_CANCEL,
                        _("GUID Partition Table Header Signature is wrong: "
-                         "" PRIx64 " should be " PRIx64 ""),
-                       (*gpt)->Signature, GPT_HEADER_SIGNATURE);
+                         "%" PRIx64 " should be %" PRIx64 ""),
+                       PED_LE64_TO_CPU((*gpt)->Signature), 
GPT_HEADER_SIGNATURE);
                goto error_free_gpt;
        }
 
        /* Check the GUID Partition Table Header CRC */
-       origcrc = (*gpt)->HeaderCRC32;
+       origcrc = PED_LE32_TO_CPU((*gpt)->HeaderCRC32);
        (*gpt)->HeaderCRC32 = 0;
-       crc = efi_crc32(*gpt, (*gpt)->HeaderSize);
+       crc = efi_crc32(*gpt, PED_LE32_TO_CPU((*gpt)->HeaderSize));
        if (crc != origcrc) {
                ped_exception_throw (
                        PED_EXCEPTION_WARNING,
                        PED_EXCEPTION_CANCEL,
                        _("GPT Header CRC check failed, %x should be %x."),
                        origcrc, crc);
-               (*gpt)->HeaderCRC32 = origcrc;
+               (*gpt)->HeaderCRC32 = PED_CPU_TO_LE32(origcrc);
                goto error_free_gpt;
        }
-       (*gpt)->HeaderCRC32 = origcrc;
+       (*gpt)->HeaderCRC32 = PED_CPU_TO_LE32(origcrc);
 
        /* Check that the MyLBA entry points to the LBA
           that contains the GPT we read */
-       if ((*gpt)->MyLBA != lba) {
+       if (PED_LE64_TO_CPU((*gpt)->MyLBA) != lba) {
                ped_exception_throw (
                        PED_EXCEPTION_ERROR,
                        PED_EXCEPTION_CANCEL,
-                       "MyLBA " PRIx64 " != lba " PRIx64 ".\n",
-                       (*gpt)->MyLBA, lba);
+                       "MyLBA %" PRIx64 " != lba %" PRIx64 ".\n",
+                       PED_LE64_TO_CPU((*gpt)->MyLBA), lba);
                goto error_free_gpt;
        }
 
@@ -553,15 +482,15 @@
                goto error_free_gpt;
 
        /* Check the GUID Partition Entry Array CRC */
-       crc = efi_crc32(*ptes, (*gpt)->NumberOfPartitionEntries *
-                          (*gpt)->SizeOfPartitionEntry);
-       if (crc != (*gpt)->PartitionEntryArrayCRC32) {
+       crc = efi_crc32(*ptes, 
PED_LE32_TO_CPU((*gpt)->NumberOfPartitionEntries) *
+                          PED_LE32_TO_CPU((*gpt)->SizeOfPartitionEntry));
+       if (crc != PED_LE32_TO_CPU((*gpt)->PartitionEntryArrayCRC32)) {
                ped_exception_throw (
                        PED_EXCEPTION_WARNING,
                        PED_EXCEPTION_CANCEL,
                        _("GPT Partition Entry Array CRC check failed, "
                          "%x should be %x."),
-                       (*gpt)->PartitionEntryArrayCRC32, crc);
+                       PED_LE32_TO_CPU((*gpt)->PartitionEntryArrayCRC32), crc);
                goto error_free_ptes;
        }
 
@@ -625,14 +554,14 @@
        PED_ASSERT(ptes != NULL, return 0);
 
        pgpt->PartitionEntryArrayCRC32 =
-               agpt->PartitionEntryArrayCRC32 =
-               efi_crc32(ptes, pgpt->NumberOfPartitionEntries *
-                         pgpt->SizeOfPartitionEntry);
+               agpt->PartitionEntryArrayCRC32 = PED_CPU_TO_LE32(
+               efi_crc32(ptes, PED_LE32_TO_CPU(pgpt->NumberOfPartitionEntries) 
*
+                         PED_LE32_TO_CPU(pgpt->SizeOfPartitionEntry)));
 
        pgpt->HeaderCRC32 = 0;
-       pgpt->HeaderCRC32 = efi_crc32(pgpt, pgpt->HeaderSize);
+       pgpt->HeaderCRC32 = PED_CPU_TO_LE32(efi_crc32(pgpt, 
PED_LE32_TO_CPU(pgpt->HeaderSize)));
        agpt->HeaderCRC32 = 0;
-       agpt->HeaderCRC32 = efi_crc32(agpt, agpt->HeaderSize);
+       agpt->HeaderCRC32 = PED_CPU_TO_LE32(efi_crc32(agpt, 
PED_LE32_TO_CPU(agpt->HeaderSize)));
        return 1;
 }
 
@@ -649,33 +578,35 @@
 
        // printf("in CreateNewGuidPartitionTableHeader()\n");
        memset(&gpt, 0, sizeof(gpt));
-       gpt.Signature = GPT_HEADER_SIGNATURE;
-       gpt.Revision = GPT_HEADER_REVISION_V1_02;
-       gpt.HeaderSize = 92; /* per 1.02 spec */
-       gpt.MyLBA = 1;
-       gpt.AlternateLBA = last_lba(dev);
-       gpt.FirstUsableLBA = (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
-                             dev->sector_size) + 2;
-       gpt.LastUsableLBA =
-               gpt.AlternateLBA -
+       gpt.Signature = PED_CPU_TO_LE64(GPT_HEADER_SIGNATURE);
+       gpt.Revision = PED_CPU_TO_LE32(GPT_HEADER_REVISION_V1_02);
+       gpt.HeaderSize = PED_CPU_TO_LE32(92); /* per 1.02 spec */
+       gpt.MyLBA = PED_CPU_TO_LE64(1);
+       gpt.AlternateLBA = PED_CPU_TO_LE64(last_lba(dev));
+       gpt.FirstUsableLBA = 
PED_CPU_TO_LE64((GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
+                             dev->sector_size) + 2);
+       gpt.LastUsableLBA = PED_CPU_TO_LE64(
+               PED_LE64_TO_CPU(gpt.AlternateLBA) -
                (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
-                dev->sector_size) - 1;
+                dev->sector_size) - 1);
        uuid_generate(uuid);
+       swap_uuid_and_efi_guid(uuid);
        memcpy(&(gpt.DiskGUID), uuid, sizeof(uuid));
-       gpt.PartitionEntryLBA = 2;
-       gpt.NumberOfPartitionEntries = GPT_DEFAULT_RESERVED_PARTITION_ENTRIES;
-       gpt.SizeOfPartitionEntry = sizeof(GuidPartitionEntry_t);
+       gpt.PartitionEntryLBA = PED_CPU_TO_LE64(2);
+       gpt.NumberOfPartitionEntries = 
PED_CPU_TO_LE32(GPT_DEFAULT_RESERVED_PARTITION_ENTRIES);
+       gpt.SizeOfPartitionEntry = 
PED_CPU_TO_LE32(sizeof(GuidPartitionEntry_t));
 
        memset(ptes, 0,
-              gpt.NumberOfPartitionEntries * gpt.SizeOfPartitionEntry);
+              PED_LE32_TO_CPU(gpt.NumberOfPartitionEntries) *
+              PED_LE32_TO_CPU(gpt.SizeOfPartitionEntry));
 
        /* Fix up Alternate GPT */
        memcpy(&agpt, &gpt, sizeof(gpt));
        agpt.MyLBA        = gpt.AlternateLBA;
        agpt.AlternateLBA = gpt.MyLBA;
-       agpt.PartitionEntryLBA = agpt.MyLBA -
+       agpt.PartitionEntryLBA = PED_CPU_TO_LE64(PED_LE64_TO_CPU(agpt.MyLBA) -
                (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
-                dev->sector_size);
+                dev->sector_size));
 
        if (!gpt_update_headers(&gpt, &agpt, ptes))
                return 0;
@@ -744,24 +675,23 @@
 
        memcpy(*badgpt, goodgpt, sizeof(*goodgpt));
 
-       /* Change badgpt values */
+       /* Change badgpt values (both little-endian, no swapping) */
        (*badgpt)->MyLBA        = goodgpt->AlternateLBA;
        (*badgpt)->AlternateLBA = goodgpt->MyLBA;
 
 
-       if ((*badgpt)->MyLBA == 1) 
-               (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA + 1;
+       if (PED_LE64_TO_CPU((*badgpt)->MyLBA) == 1) 
+               (*badgpt)->PartitionEntryLBA = 
PED_CPU_TO_LE64(PED_LE64_TO_CPU((*badgpt)->MyLBA) + 1);
        else
-               (*badgpt)->PartitionEntryLBA = (*badgpt)->MyLBA - 
+               (*badgpt)->PartitionEntryLBA = 
PED_CPU_TO_LE64(PED_LE64_TO_CPU((*badgpt)->MyLBA) - 
                        (GPT_DEFAULT_RESERVED_PARTITION_ENTRY_ARRAY_SIZE /
-                        dev->sector_size);
+                        dev->sector_size));
 
        return gpt_update_headers(*badgpt, goodgpt, ptes);
 }
 
 
-
-
+#ifdef GPT_DEBUG
 static void
 gpt_print_legacy_part(PartitionRecord_t * pr, int i)
 {
@@ -796,6 +726,8 @@
        printf("Signature: %x\n", mbr->Signature);
        return;
 }
+#endif
+
 
 static void
 erase_gpt(PedDevice * dev, GuidPartitionTableHeader_t * gpt,
@@ -805,10 +737,10 @@
        PED_ASSERT(dev  != NULL, return);
        if (gpt == NULL || ptes == NULL) return;
 
-       header_lba = gpt->MyLBA;
+       header_lba = PED_LE64_TO_CPU(gpt->MyLBA);
        memset(ptes, 0,
-              gpt->NumberOfPartitionEntries *
-              gpt->SizeOfPartitionEntry);
+              PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries) *
+              PED_LE32_TO_CPU(gpt->SizeOfPartitionEntry));
        gpt_write_part_entries(dev, gpt, ptes);
        memset(gpt, 0, sizeof(*gpt));
        ped_device_write(dev, gpt, header_lba, GPT_HEADER_SECTORS);
@@ -973,7 +905,7 @@
        good_pgpt = gpt_is_valid(dev, 1, pgpt, &pptes);
        if (good_pgpt) {
                /* Primary GPT is OK, check the alternate and warn if bad */
-               good_agpt = gpt_is_valid(dev, (*pgpt)->AlternateLBA,
+               good_agpt = gpt_is_valid(dev, 
PED_LE64_TO_CPU((*pgpt)->AlternateLBA),
                                  agpt, &aptes);
 
                if (!good_agpt) {
@@ -1028,7 +960,7 @@
 
 #ifdef GPT_DEBUG
 static void
-print_disk_info(PedDevice *dev)
+gpt_print_disk_info(PedDevice *dev)
 {
        unsigned int i;
        LegacyMBR_t mbr;
@@ -1042,13 +974,6 @@
        }
 
        if (mbr.PartitionRecord[0].OSType == EFI_PMBR_OSTYPE_EFI_GPT) {
-               /* This is an EFI GPT disk */
-               if (!ped_device_read(dev, &pgpt,
-                                    GPT_PRIMARY_HEADER_LBA,
-                                    GPT_HEADER_SECTORS)) {
-                       printf("print_disk_info error: ped_device_read(gpt) 
error.\n");
-                       return;
-               }
                printf("This is an EFI GPT disk.\n");
                if (gpt_find_valid(dev, &pgpt, &agpt, &pte)) {
                        if (pgpt) gpt = pgpt;
@@ -1058,7 +983,8 @@
                        printf("GUID Partition Table is invalid.\n");
                        return;
                }
-               for (i = 0; pte && i < gpt->NumberOfPartitionEntries; i++) {
+               gpt_print_header(gpt);
+               for (i = 0; pte && i < 
PED_LE32_TO_CPU(gpt->NumberOfPartitionEntries); i++) {
                        /* Partition entry is unused if all bytes are 0 */
                        if (memcmp(&zeropte, &pte[i], sizeof(zeropte)))
                                gpt_print_part_entry(&pte[i], i);
@@ -1081,7 +1007,6 @@
 ped_disk_gpt_init()
 {
        PED_ASSERT(sizeof(GuidPartitionTableHeader_t) == 512, return);
-       PED_ASSERT(sizeof(GuidPartitionEntryAttributes_t) == 8, return);
        PED_ASSERT(sizeof(GuidPartitionEntry_t) == 128, return);
 
        ped_register_disk_type(&gpt_disk_type);
@@ -1138,6 +1063,9 @@
        if (!gpt_read(disk))
          goto error_free_disk_specific;
 
+#ifdef GPT_DEBUG
+       gpt_print_disk_info(dev);
+#endif
        return disk;
 
       error_free_disk_specific:
@@ -1228,14 +1156,14 @@
                                      gpt_disk_data->ptes);
        }
 
-       for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+       for (i = 0; i < 
PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries); i++) {
                
                if (!efi_guidcmp(gpt_disk_data->ptes[i].PartitionTypeGuid,
                                 unused)) continue;
 
                part = ped_partition_alloc(disk, PED_PARTITION_PRIMARY, NULL,
-                                          gpt_disk_data->ptes[i].StartingLBA,
-                                          gpt_disk_data->ptes[i].EndingLBA);
+                                          
PED_LE64_TO_CPU(gpt_disk_data->ptes[i].StartingLBA),
+                                          
PED_LE64_TO_CPU(gpt_disk_data->ptes[i].EndingLBA));
                if (!part)
                        return 0;
 
@@ -1286,8 +1214,8 @@
                PED_ASSERT(part->disk_specific != NULL, return 0);
                gpt_part_data = part->disk_specific;
                PED_ASSERT(gpt_part_data->pte != NULL, return 0);
-               gpt_part_data->pte->StartingLBA = part->geom.start;
-               gpt_part_data->pte->EndingLBA   = part->geom.end;
+               gpt_part_data->pte->StartingLBA = 
PED_CPU_TO_LE64(part->geom.start);
+               gpt_part_data->pte->EndingLBA   = 
PED_CPU_TO_LE64(part->geom.end);
        }
 
        return 1;
@@ -1407,22 +1335,23 @@
        PED_ASSERT(gpt_disk_data->ptes != NULL, return NULL);
 
 
-       for (i = 0; i < gpt_disk_data->pgpt->NumberOfPartitionEntries; i++) {
+       for (i = 0; i < 
PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries); i++) {
                if (!efi_guidcmp
                    (gpt_disk_data->ptes[i].PartitionTypeGuid, 
unused_entry_guid)) {
                        break;
                }
        }
        /* No unused entries */
-       if (i == gpt_disk_data->pgpt->NumberOfPartitionEntries){
+       if (i == 
PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries)){
                ped_free(part);
                return NULL;
        }
 
        part->num = i + 1;
-       gpt_disk_data->ptes[i].StartingLBA = part->geom.start;
-       gpt_disk_data->ptes[i].EndingLBA = part->geom.end;
+       gpt_disk_data->ptes[i].StartingLBA = PED_CPU_TO_LE64(part->geom.start);
+       gpt_disk_data->ptes[i].EndingLBA = PED_CPU_TO_LE64(part->geom.end);
        uuid_generate(uuid);
+       swap_uuid_and_efi_guid(uuid);
        memcpy(&(gpt_disk_data->ptes[i].UniquePartitionGuid), uuid, 
sizeof(uuid));
 
        gpt_disk_data->ptes[i].PartitionTypeGuid = PARTITION_BASIC_DATA_GUID;
@@ -1515,16 +1444,16 @@
        gpt_disk_data = disk->disk_specific;
 
        /* allocate space for the header */
-       gptlength = gpt_disk_data->pgpt->HeaderSize / disk->dev->sector_size;
-       if (gpt_disk_data->pgpt->HeaderSize % disk->dev->sector_size)
+       gptlength = PED_LE32_TO_CPU(gpt_disk_data->pgpt->HeaderSize) / 
disk->dev->sector_size;
+       if (PED_LE32_TO_CPU(gpt_disk_data->pgpt->HeaderSize) % 
disk->dev->sector_size)
                gptlength++;
        /* allocate space for the ptes */
        pteslength =
-           (gpt_disk_data->pgpt->NumberOfPartitionEntries *
-            gpt_disk_data->pgpt->SizeOfPartitionEntry) /
+           (PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries) *
+            PED_LE32_TO_CPU(gpt_disk_data->pgpt->SizeOfPartitionEntry)) /
                disk->dev->sector_size;
-       if ((gpt_disk_data->pgpt->NumberOfPartitionEntries *
-            gpt_disk_data->pgpt->SizeOfPartitionEntry) %
+       if ((PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries) *
+            PED_LE32_TO_CPU(gpt_disk_data->pgpt->SizeOfPartitionEntry)) %
            disk->dev->sector_size)
                pteslength++;
 
@@ -1767,7 +1696,7 @@
        memset(gpt_part_data->pte->PartitionName, 0, 
sizeof(gpt_part_data->pte->PartitionName));
 
        for (i=0; i < (72 / sizeof(efi_char16_t)) && i < strlen(name); i++) {
-               gpt_part_data->pte->PartitionName[i] = name[i];
+               gpt_part_data->pte->PartitionName[i] = PED_CPU_TO_LE16(name[i]);
        }
        return;
 }
@@ -1789,7 +1718,7 @@
        memset(name, 0, namelen);
 
        for (i=0; i < namelen ; i++) {
-               name[i] = gpt_part_data->pte->PartitionName[i];
+               name[i] = PED_LE16_TO_CPU(gpt_part_data->pte->PartitionName[i]);
        }
 
        return name;
@@ -1805,7 +1734,7 @@
        gpt_disk_data = disk->disk_specific;
 
        if (gpt_disk_data  && gpt_disk_data->pgpt)
-               rc = gpt_disk_data->pgpt->NumberOfPartitionEntries;
+               rc = 
PED_LE32_TO_CPU(gpt_disk_data->pgpt->NumberOfPartitionEntries);
        return rc;
 }
 
@@ -1827,8 +1756,9 @@
        /* Alignments can be on any sector */
        /* Geometry must reside within the usable LBAs */
        if (!ped_geometry_init (&max_geom, disk,
-                               gpt->FirstUsableLBA,
-                               gpt->LastUsableLBA - gpt->FirstUsableLBA + 1))
+                               PED_LE64_TO_CPU(gpt->FirstUsableLBA),
+                               PED_LE64_TO_CPU(gpt->LastUsableLBA) -
+                               PED_LE64_TO_CPU(gpt->FirstUsableLBA) + 1))
                return NULL;
 
        return ped_constraint_new (ped_alignment_any, ped_alignment_any,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]