Squash minor ARM CPER issues, add ARM generation.
diff --git a/generator/cper-generate.c b/generator/cper-generate.c
index dd336fe..90ad460 100644
--- a/generator/cper-generate.c
+++ b/generator/cper-generate.c
@@ -9,10 +9,9 @@
 #include <string.h>
 #include "../edk/Cper.h"
 #include "gen-utils.h"
-#include "sections/gen-section-generic.h"
-#include "sections/gen-section-ia32x64.h"
+#include "sections/gen-sections.h"
 
-EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index);
+EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index, int num_sections);
 size_t generate_section(void** location, char* type);
 void print_help();
 
@@ -54,17 +53,20 @@
         (EFI_COMMON_ERROR_RECORD_HEADER*)calloc(1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER));
     header->SignatureStart = 0x52455043; //CPER
     header->SectionCount = num_sections;
-    printf("%d sections\n", num_sections);
     header->SignatureEnd = 0xFFFFFFFF;
     header->Flags = 4; //HW_ERROR_FLAGS_SIMULATED
+    header->RecordID = (UINT64)rand();
+    header->ErrorSeverity = rand() % 4;
+    *((UINT64*)&header->TimeStamp) = (UINT64)rand();
+    header->ValidationBits = rand() % 0b1000;
 
     //Generate the section descriptors given the number of sections.
     EFI_ERROR_SECTION_DESCRIPTOR* section_descriptors[num_sections];
     for (int i=0; i<num_sections; i++)
-        section_descriptors[i] = generate_section_descriptor(argv[4 + i], section_lengths, i);
+        section_descriptors[i] = generate_section_descriptor(argv[4 + i], section_lengths, i, num_sections);
 
     //Calculate total length of structure, set in header.
-    size_t total_len = sizeof(header);
+    size_t total_len = sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
     for (int i=0; i<num_sections; i++)
         total_len += section_lengths[i];
     total_len += num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
@@ -98,7 +100,7 @@
 }
 
 //Generates a single section descriptor for a section with the given properties.
-EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index)
+EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index, int num_sections)
 {
     EFI_ERROR_SECTION_DESCRIPTOR* descriptor = 
         (EFI_ERROR_SECTION_DESCRIPTOR*)generate_random_bytes(sizeof(EFI_ERROR_SECTION_DESCRIPTOR));
@@ -110,7 +112,8 @@
 
     //Set length, offset from base record.
     descriptor->SectionLength = (UINT32)lengths[index];
-    descriptor->SectionOffset = sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
+    descriptor->SectionOffset = sizeof(EFI_COMMON_ERROR_RECORD_HEADER)
+        + (num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR));
     for (int i=0; i<index; i++)
         descriptor->SectionOffset += lengths[i];
 
@@ -191,8 +194,8 @@
         length = generate_section_ia32x64(location);
     // else if (strcmp(type, "ipf") == 0)
     //     length = generate_section_ipf(location);
-    // else if (strcmp(type, "arm") == 0)
-    //     length = generate_section_arm(location);
+    else if (strcmp(type, "arm") == 0)
+        length = generate_section_arm(location);
     // else if (strcmp(type, "memory") == 0)
     //     length = generate_section_memory(location);
     // else if (strcmp(type, "memory2") == 0)
diff --git a/generator/sections/gen-section-arm.c b/generator/sections/gen-section-arm.c
new file mode 100644
index 0000000..53fb24c
--- /dev/null
+++ b/generator/sections/gen-section-arm.c
@@ -0,0 +1,176 @@
+/**
+ * Functions for generating psuedo-random CPER ARM processor sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+#define ARM_ERROR_INFO_SIZE 32
+
+void* generate_arm_error_info();
+size_t generate_arm_context_info(void** location);
+
+//Generates a single psuedo-random ARM processor section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_arm(void** location)
+{
+    //Set up for generation of error/context structures.
+    UINT16 error_structure_num = rand() % 4 + 1; //Must be at least 1.
+    UINT16 context_structure_num = rand() % 3;
+    void* error_structures[error_structure_num];
+    void* context_structures[context_structure_num];
+    size_t context_structure_lengths[context_structure_num];
+
+    //Generate the structures.
+    for (int i=0; i<error_structure_num; i++)
+        error_structures[i] = generate_arm_error_info();
+    for (int i=0; i<context_structure_num; i++)
+        context_structure_lengths[i] = generate_arm_context_info(context_structures + i);
+
+    //Determine a random amount of vendor specific info.
+    int vendor_info_len = rand() % 16;
+
+    //Create the section as a whole.
+    size_t total_len = 40 + (error_structure_num * ARM_ERROR_INFO_SIZE);
+    for (int i=0; i<context_structure_num; i++)
+        total_len += context_structure_lengths[i];
+    total_len += vendor_info_len;
+    UINT8* section = generate_random_bytes(total_len);
+
+    //Set header information.
+    UINT16* info_nums = (UINT16*)(section + 4);
+    *info_nums = error_structure_num;
+    *(info_nums + 1) = context_structure_num;
+    UINT32* section_length = (UINT32*)(section + 8);
+    *section_length = total_len;
+    
+    //Error affinity.
+    *(section + 12) = rand() % 4;
+
+    //Reserved zero bytes.
+    memset(section + 13, 0, 3);
+
+    //Copy in the sections/context structures, free resources.
+    UINT8* cur_pos = section + 40;
+    for (int i=0; i<error_structure_num; i++)
+    {
+        memcpy(cur_pos, error_structures[i], ARM_ERROR_INFO_SIZE);
+        free(error_structures[i]);
+        cur_pos += ARM_ERROR_INFO_SIZE;
+    }
+    for (int i=0; i<context_structure_num; i++)
+    {
+        memcpy(cur_pos, context_structures[i], context_structure_lengths[i]);
+        free(context_structures[i]);
+        cur_pos += context_structure_lengths[i];
+    }
+
+    //Set return values and exit.
+    *location = section;
+    return total_len;
+}
+
+//Generates a single pseudo-random ARM error info structure. Must be later freed.
+void* generate_arm_error_info()
+{
+    UINT8* error_info = generate_random_bytes(ARM_ERROR_INFO_SIZE);
+
+    //Version (zero for revision of table referenced), length.
+    *error_info = 0;
+    *(error_info + 1) = ARM_ERROR_INFO_SIZE;
+
+    //Type of error.
+    UINT8 error_type = rand() % 4;
+    *(error_info + 4) = error_type;
+
+    //Make sure reserved bits are zero according with the type.
+    UINT64* error_subinfo = (UINT64*)(error_info + 8);
+    switch (error_type)
+    {
+        //Cache/TLB
+        case 0:
+        case 1:
+            *error_subinfo &= 0xFFFFFFF;
+            break;
+
+        //Bus
+        case 2:
+            *error_subinfo &= 0xFFFFFFFFFFF;
+            break;
+
+        //Microarch/other.
+        default:
+            break;
+    }
+
+    return error_info;
+}
+
+//Generates a single pseudo-random ARM context info structure. Must be later freed.
+size_t generate_arm_context_info(void** location)
+{
+    //Initial length is 8 bytes. Add extra based on type.
+    UINT16 reg_type = rand() % 9;
+    UINT32 reg_size = 0;
+
+    //Set register size.
+    switch (reg_type)
+    {
+        //AARCH32 GPR, AARCH32 EL2
+        case 0:
+        case 2:
+            reg_size = 64;
+            break;
+
+        //AARCH32 EL1
+        case 1:
+            reg_size = 96;
+            break;
+
+        //AARCH32 EL3
+        case 3:
+            reg_size = 8;
+            break;
+
+        //AARCH64 GPR
+        case 4:
+            reg_size = 256;
+            break;
+
+        //AARCH64 EL1
+        case 5:
+            reg_size = 136;
+            break;
+        
+        //AARCH64 EL2
+        case 6:
+            reg_size = 120;
+            break;
+
+        //AARCH64 EL3
+        case 7:
+            reg_size = 80;
+            break;
+
+        //Misc. single register.
+        case 8:
+            reg_size = 10;
+            break;
+    }
+
+    //Create context structure randomly.
+    int total_size = 8 + reg_size;
+    UINT16* context_info = (UINT16*)generate_random_bytes(total_size);
+
+    //Set header information.
+    *(context_info + 1) = reg_type;
+    *((UINT32*)(context_info + 2)) = reg_size;
+
+    //Set return values and exit.
+    *location = context_info;
+    return total_size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-generic.c b/generator/sections/gen-section-generic.c
index 205fea1..b2bda16 100644
--- a/generator/sections/gen-section-generic.c
+++ b/generator/sections/gen-section-generic.c
@@ -7,7 +7,7 @@
 #include <stdlib.h>
 #include "../../edk/BaseTypes.h"
 #include "../gen-utils.h"
-#include "gen-section-generic.h"
+#include "gen-sections.h"
 
 //Generates a single psuedo-random generic processor section, saving the resulting address to the given
 //location. Returns the size of the newly created section.
diff --git a/generator/sections/gen-section-generic.h b/generator/sections/gen-section-generic.h
deleted file mode 100644
index 49ff655..0000000
--- a/generator/sections/gen-section-generic.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef GEN_SECTION_GENERIC_H
-#define GEN_SECTION_GENERIC_H
-
-#include <stdlib.h>
-
-size_t generate_section_generic(void** location);
-
-#endif
\ No newline at end of file
diff --git a/generator/sections/gen-section-ia32x64.c b/generator/sections/gen-section-ia32x64.c
index b06a237..7412ca3 100644
--- a/generator/sections/gen-section-ia32x64.c
+++ b/generator/sections/gen-section-ia32x64.c
@@ -8,7 +8,8 @@
 #include <string.h>
 #include "../../edk/Cper.h"
 #include "../gen-utils.h"
-#include "gen-section-ia32x64.h"
+#include "gen-sections.h"
+#define IA32X64_ERROR_STRUCTURE_SIZE 64
 
 void* generate_ia32x64_error_structure();
 size_t generate_ia32x64_context_structure(void** location);
diff --git a/generator/sections/gen-section-ia32x64.h b/generator/sections/gen-section-ia32x64.h
deleted file mode 100644
index 78f5052..0000000
--- a/generator/sections/gen-section-ia32x64.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef GEN_SECTION_IA32X64_H
-#define GEN_SECTION_IA32X64_H
-
-#include <stdlib.h>
-
-#define IA32X64_ERROR_STRUCTURE_SIZE 64
-
-size_t generate_section_ia32x64(void** location);
-
-#endif
\ No newline at end of file
diff --git a/generator/sections/gen-sections.h b/generator/sections/gen-sections.h
new file mode 100644
index 0000000..33ecd39
--- /dev/null
+++ b/generator/sections/gen-sections.h
@@ -0,0 +1,10 @@
+#ifndef GEN_SECTIONS_H
+#define GEN_SECTIONS_H
+
+#include <stdlib.h>
+
+size_t generate_section_generic(void** location);
+size_t generate_section_ia32x64(void** location);
+size_t generate_section_arm(void** location);
+
+#endif
\ No newline at end of file