Reduce attributes size to comply with msc limitations.

It turned out that shared verified boot library fails to
work properly when compiled by msc in BIOS environment.

The culprit was identified as failing 64 bit logical
operations by preprocessor. It is probably possible to
come up with a certain compile flag set to fix the
operations, but it is not easy to modify and control the BIOS
compilation environment.

The alternative solution is to limit the size of the field
in question to 16 bits (especially since this is the only
part of the attributes field which is supposed to be
altered by firmware.

A union is being introduced in firmware/lib/cgptlib/include/gpt.h:GptEntry to allow
accessing the field both as a 64 bit entity and a top
16 bit field. All places where this field is used are
being modified appropriately.

tests/Makefile is being fixed to allow controlling test run
from the top level directory.

Tested by building everything and running tests.
All tests pass.

Review URL: http://codereview.chromium.org/2799019
diff --git a/cgpt/cgpt_common.c b/cgpt/cgpt_common.c
index f165f7a..8e8196b 100644
--- a/cgpt/cgpt_common.c
+++ b/cgpt/cgpt_common.c
@@ -522,15 +522,15 @@
   entry = GetEntry(gpt, secondary, entry_index);
 
   assert(priority >= 0 && priority <= CGPT_ATTRIBUTE_MAX_PRIORITY);
-  entry->attributes &= ~CGPT_ATTRIBUTE_PRIORITY_MASK;
-  entry->attributes |= (uint64_t)priority << CGPT_ATTRIBUTE_PRIORITY_OFFSET;
+  entry->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_PRIORITY_MASK;
+  entry->attrs.fields.gpt_att |= priority << CGPT_ATTRIBUTE_PRIORITY_OFFSET;
 }
 
 int GetPriority(GptData *gpt, int secondary, int entry_index) {
   GptEntry *entry;
   entry = GetEntry(gpt, secondary, entry_index);
-  return (entry->attributes & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
-         CGPT_ATTRIBUTE_PRIORITY_OFFSET;
+  return (entry->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
+      CGPT_ATTRIBUTE_PRIORITY_OFFSET;
 }
 
 void SetTries(GptData *gpt, int secondary, int entry_index, int tries) {
@@ -538,15 +538,15 @@
   entry = GetEntry(gpt, secondary, entry_index);
 
   assert(tries >= 0 && tries <= CGPT_ATTRIBUTE_MAX_TRIES);
-  entry->attributes &= ~CGPT_ATTRIBUTE_TRIES_MASK;
-  entry->attributes |= (uint64_t)tries << CGPT_ATTRIBUTE_TRIES_OFFSET;
+  entry->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_TRIES_MASK;
+  entry->attrs.fields.gpt_att |= tries << CGPT_ATTRIBUTE_TRIES_OFFSET;
 }
 
 int GetTries(GptData *gpt, int secondary, int entry_index) {
   GptEntry *entry;
   entry = GetEntry(gpt, secondary, entry_index);
-  return (entry->attributes & CGPT_ATTRIBUTE_TRIES_MASK) >>
-         CGPT_ATTRIBUTE_TRIES_OFFSET;
+  return (entry->attrs.fields.gpt_att & CGPT_ATTRIBUTE_TRIES_MASK) >>
+      CGPT_ATTRIBUTE_TRIES_OFFSET;
 }
 
 void SetSuccessful(GptData *gpt, int secondary, int entry_index, int success) {
@@ -554,14 +554,14 @@
   entry = GetEntry(gpt, secondary, entry_index);
 
   assert(success >= 0 && success <= CGPT_ATTRIBUTE_MAX_SUCCESSFUL);
-  entry->attributes &= ~CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
-  entry->attributes |= (uint64_t)success << CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
+  entry->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
+  entry->attrs.fields.gpt_att |= success << CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
 }
 
 int GetSuccessful(GptData *gpt, int secondary, int entry_index) {
   GptEntry *entry;
   entry = GetEntry(gpt, secondary, entry_index);
-  return (entry->attributes & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
+  return (entry->attrs.fields.gpt_att & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
          CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
 }
 
diff --git a/cgpt/cmd_add.c b/cgpt/cmd_add.c
index 18a0285..12ae57c 100644
--- a/cgpt/cmd_add.c
+++ b/cgpt/cmd_add.c
@@ -45,7 +45,7 @@
   int successful = 0;
   int tries = 0;
   int priority = 0;
-  uint64_t raw_value = 0;
+  uint16_t raw_value = 0;
   int set_begin = 0;
   int set_size = 0;
   int set_type = 0;
@@ -249,7 +249,7 @@
     memcpy(entry->name, buf, sizeof(entry->name));
   }
   if (set_raw) {
-    entry->attributes = raw_value;
+    entry->attrs.fields.gpt_att = raw_value;
   } else {
     if (set_successful)
       SetSuccessful(&drive.gpt, PRIMARY, index, successful);
diff --git a/cgpt/cmd_show.c b/cgpt/cmd_show.c
index 9146149..6ab537d 100644
--- a/cgpt/cmd_show.c
+++ b/cgpt/cmd_show.c
@@ -132,12 +132,15 @@
     GuidToStr(&entry->unique, unique);
     printf(PARTITION_MORE, "UUID: ", unique);
     if (!memcmp(&guid_chromeos_kernel, &entry->type, sizeof(Guid))) {
-      int tries = (entry->attributes & CGPT_ATTRIBUTE_TRIES_MASK) >>
-        CGPT_ATTRIBUTE_TRIES_OFFSET;
-      int successful = (entry->attributes & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
-        CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
-      int priority = (entry->attributes & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
-        CGPT_ATTRIBUTE_PRIORITY_OFFSET;
+      int tries = (entry->attrs.fields.gpt_att &
+                   CGPT_ATTRIBUTE_TRIES_MASK) >>
+          CGPT_ATTRIBUTE_TRIES_OFFSET;
+      int successful = (entry->attrs.fields.gpt_att &
+                        CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
+          CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
+      int priority = (entry->attrs.fields.gpt_att &
+                      CGPT_ATTRIBUTE_PRIORITY_MASK) >>
+          CGPT_ATTRIBUTE_PRIORITY_OFFSET;
       snprintf(contents, sizeof(contents),
                "priority=%d tries=%d successful=%d",
                priority, tries, successful);
@@ -155,7 +158,7 @@
     printf(PARTITION_MORE, "Type: ", type);
     GuidToStr(&entry->unique, unique);
     printf(PARTITION_MORE, "UUID: ", unique);
-    snprintf(contents, sizeof(contents), "[%" PRIx64 "]", entry->attributes);
+    snprintf(contents, sizeof(contents), "[%x]", entry->attrs.fields.gpt_att);
     printf(PARTITION_MORE, "Attr: ", contents);
   }
 }
@@ -299,7 +302,7 @@
         printf("%d\n", GetPriority(&drive.gpt, PRIMARY, index));
         break;
       case 'A':
-        printf("0x%" PRIx64 "\n", entry->attributes);
+        printf("0x%x\n", entry->attrs.fields.gpt_att);
         break;
       }
     } else {
diff --git a/firmware/lib/cgptlib/cgptlib.c b/firmware/lib/cgptlib/cgptlib.c
index 4856311..4d2ee6c 100644
--- a/firmware/lib/cgptlib/cgptlib.c
+++ b/firmware/lib/cgptlib/cgptlib.c
@@ -93,7 +93,7 @@
   GptHeader* header = (GptHeader*)gpt->primary_header;
   GptEntry* entries = (GptEntry*)gpt->primary_entries;
   GptEntry* e = entries + gpt->current_kernel;
-  uint64_t previous_attr = e->attributes;
+  uint16_t previous_attr = e->attrs.fields.gpt_att;
 
   if (gpt->current_kernel == CGPT_KERNEL_ENTRY_NOT_FOUND)
     return GPT_ERROR_INVALID_UPDATE_TYPE;
@@ -117,9 +117,10 @@
     }
     case GPT_UPDATE_ENTRY_BAD: {
       /* Giving up on this partition entirely. */
-      e->attributes &= ~(CGPT_ATTRIBUTE_SUCCESSFUL_MASK |
-                         CGPT_ATTRIBUTE_TRIES_MASK |
-                         CGPT_ATTRIBUTE_PRIORITY_MASK);
+      e->attrs.fields.gpt_att = previous_attr & ~(
+          CGPT_ATTRIBUTE_SUCCESSFUL_MASK |
+          CGPT_ATTRIBUTE_TRIES_MASK |
+          CGPT_ATTRIBUTE_PRIORITY_MASK);
       break;
     }
     default:
@@ -127,7 +128,7 @@
   }
 
   /* If no change to attributes, we're done */
-  if (e->attributes == previous_attr)
+  if (e->attrs.fields.gpt_att == previous_attr)
     return GPT_SUCCESS;
 
   /* Update the CRCs */
diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c
index 7faf383..85b4906 100644
--- a/firmware/lib/cgptlib/cgptlib_internal.c
+++ b/firmware/lib/cgptlib/cgptlib_internal.c
@@ -309,40 +309,40 @@
 
 
 int GetEntrySuccessful(const GptEntry* e) {
-  return (e->attributes & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
-         CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
+  return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
+      CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
 }
 
 
 int GetEntryPriority(const GptEntry* e) {
-  return (e->attributes & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
-         CGPT_ATTRIBUTE_PRIORITY_OFFSET;
+  return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_PRIORITY_MASK) >>
+      CGPT_ATTRIBUTE_PRIORITY_OFFSET;
 }
 
 
 int GetEntryTries(const GptEntry* e) {
-  return (e->attributes & CGPT_ATTRIBUTE_TRIES_MASK) >>
-         CGPT_ATTRIBUTE_TRIES_OFFSET;
+  return (e->attrs.fields.gpt_att & CGPT_ATTRIBUTE_TRIES_MASK) >>
+      CGPT_ATTRIBUTE_TRIES_OFFSET;
 }
 
 
 void SetEntrySuccessful(GptEntry* e, int successful) {
   if (successful)
-    e->attributes |= CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
+    e->attrs.fields.gpt_att |= CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
   else
-    e->attributes &= ~CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
+    e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_SUCCESSFUL_MASK;
 }
 
 
 void SetEntryPriority(GptEntry* e, int priority) {
-  e->attributes &= ~CGPT_ATTRIBUTE_PRIORITY_MASK;
-  e->attributes |= ((uint64_t)priority << CGPT_ATTRIBUTE_PRIORITY_OFFSET) &
+  e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_PRIORITY_MASK;
+  e->attrs.fields.gpt_att |= (priority << CGPT_ATTRIBUTE_PRIORITY_OFFSET) &
       CGPT_ATTRIBUTE_PRIORITY_MASK;
 }
 
 
 void SetEntryTries(GptEntry* e, int tries) {
-  e->attributes &= ~CGPT_ATTRIBUTE_TRIES_MASK;
-  e->attributes |= ((uint64_t)tries << CGPT_ATTRIBUTE_TRIES_OFFSET) &
+  e->attrs.fields.gpt_att &= ~CGPT_ATTRIBUTE_TRIES_MASK;
+  e->attrs.fields.gpt_att |= (tries << CGPT_ATTRIBUTE_TRIES_OFFSET) &
       CGPT_ATTRIBUTE_TRIES_MASK;
 }
diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h
index f4a4d19..5252b6a 100644
--- a/firmware/lib/cgptlib/include/cgptlib_internal.h
+++ b/firmware/lib/cgptlib/include/cgptlib_internal.h
@@ -28,17 +28,17 @@
  *      1  -- UEFI: partition is not mapped
  *      0  -- UEFI: partition is required
  */
-#define CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET 56
+#define CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET (56 - 48)
 #define CGPT_ATTRIBUTE_MAX_SUCCESSFUL (1ULL)
 #define CGPT_ATTRIBUTE_SUCCESSFUL_MASK (CGPT_ATTRIBUTE_MAX_SUCCESSFUL << \
                                      CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET)
 
-#define CGPT_ATTRIBUTE_TRIES_OFFSET 52
+#define CGPT_ATTRIBUTE_TRIES_OFFSET (52 - 48)
 #define CGPT_ATTRIBUTE_MAX_TRIES (15ULL)
 #define CGPT_ATTRIBUTE_TRIES_MASK (CGPT_ATTRIBUTE_MAX_TRIES << \
                                    CGPT_ATTRIBUTE_TRIES_OFFSET)
 
-#define CGPT_ATTRIBUTE_PRIORITY_OFFSET 48
+#define CGPT_ATTRIBUTE_PRIORITY_OFFSET (48 - 48)
 #define CGPT_ATTRIBUTE_MAX_PRIORITY (15ULL)
 #define CGPT_ATTRIBUTE_PRIORITY_MASK (CGPT_ATTRIBUTE_MAX_PRIORITY << \
                                       CGPT_ATTRIBUTE_PRIORITY_OFFSET)
diff --git a/firmware/lib/cgptlib/include/gpt.h b/firmware/lib/cgptlib/include/gpt.h
index a65317f..1e8f47f 100644
--- a/firmware/lib/cgptlib/include/gpt.h
+++ b/firmware/lib/cgptlib/include/gpt.h
@@ -96,7 +96,13 @@
   Guid unique;
   uint64_t starting_lba;
   uint64_t ending_lba;
-  uint64_t attributes;
+  union {
+    struct {
+     uint64_t         : 48;
+     uint16_t gpt_att : 16;
+    } __attribute__((packed)) fields;
+    uint64_t whole;
+  } attrs;
   uint16_t name[36];                    /* UTF-16 encoded partition name */
   uint8_t reserved[];                   /* nothing, really */
 } __attribute__((packed)) GptEntry;
diff --git a/tests/Makefile b/tests/Makefile
index 1e8fc9d..3259dfe 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -27,6 +27,10 @@
 
 LIBS := ${TEST_LIB} $(HOSTLIB) $(FWLIB)
 
+ifneq (${RUNTESTS},)
+EXTRA_TARGET = runtests
+endif
+
 all: $(TEST_BINS) ${EXTRA_TARGET}
 
 ${TEST_LIB}: ${TEST_LIB_OBJS}
@@ -56,11 +60,6 @@
 #		kernel_verify_benchmark 
 #		verify_kernel_fuzz_driver
 
-
-ifneq (${RUNTESTS},)
-EXTRA_TARGET = runtests
-endif
-
 # Generate test keys
 genkeys:
 	./gen_test_keys.sh
diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c
index f016b21..a100579 100644
--- a/tests/cgptlib_test.c
+++ b/tests/cgptlib_test.c
@@ -811,39 +811,39 @@
   GptData* gpt = GetEmptyGptData();
   GptEntry* e = (GptEntry*)(gpt->primary_entries);
 
-  e->attributes = 0x0000000000000000LLU;
+  e->attrs.whole = 0x0000000000000000LLU;
   SetEntrySuccessful(e, 1);
-  EXPECT(0x0100000000000000LLU == e->attributes);
+  EXPECT(0x0100000000000000LLU == e->attrs.whole);
   EXPECT(1 == GetEntrySuccessful(e));
-  e->attributes = 0xFFFFFFFFFFFFFFFFLLU;
+  e->attrs.whole = 0xFFFFFFFFFFFFFFFFLLU;
   SetEntrySuccessful(e, 0);
-  EXPECT(0xFEFFFFFFFFFFFFFFLLU == e->attributes);
+  EXPECT(0xFEFFFFFFFFFFFFFFLLU == e->attrs.whole);
   EXPECT(0 == GetEntrySuccessful(e));
 
-  e->attributes = 0x0000000000000000LLU;
+  e->attrs.whole = 0x0000000000000000LLU;
   SetEntryTries(e, 15);
   EXPECT(15 == GetEntryTries(e));
-  EXPECT(0x00F0000000000000LLU == e->attributes);
-  e->attributes = 0xFFFFFFFFFFFFFFFFLLU;
+  EXPECT(0x00F0000000000000LLU == e->attrs.whole);
+  e->attrs.whole = 0xFFFFFFFFFFFFFFFFLLU;
   SetEntryTries(e, 0);
-  EXPECT(0xFF0FFFFFFFFFFFFFLLU == e->attributes);
+  EXPECT(0xFF0FFFFFFFFFFFFFLLU == e->attrs.whole);
   EXPECT(0 == GetEntryTries(e));
 
-  e->attributes = 0x0000000000000000LLU;
+  e->attrs.whole = 0x0000000000000000LLU;
   SetEntryPriority(e, 15);
-  EXPECT(0x000F000000000000LLU == e->attributes);
+  EXPECT(0x000F000000000000LLU == e->attrs.whole);
   EXPECT(15 == GetEntryPriority(e));
-  e->attributes = 0xFFFFFFFFFFFFFFFFLLU;
+  e->attrs.whole = 0xFFFFFFFFFFFFFFFFLLU;
   SetEntryPriority(e, 0);
-  EXPECT(0xFFF0FFFFFFFFFFFFLLU == e->attributes);
+  EXPECT(0xFFF0FFFFFFFFFFFFLLU == e->attrs.whole);
   EXPECT(0 == GetEntryPriority(e));
 
-  e->attributes = 0xFFFFFFFFFFFFFFFFLLU;
+  e->attrs.whole = 0xFFFFFFFFFFFFFFFFLLU;
   EXPECT(1 == GetEntrySuccessful(e));
   EXPECT(15 == GetEntryPriority(e));
   EXPECT(15 == GetEntryTries(e));
 
-  e->attributes = 0x0123000000000000LLU;
+  e->attrs.whole = 0x0123000000000000LLU;
   EXPECT(1 == GetEntrySuccessful(e));
   EXPECT(2 == GetEntryTries(e));
   EXPECT(3 == GetEntryPriority(e));