Add generation for remaining, fix invalid fseek().
diff --git a/cper-parse.c b/cper-parse.c
index 0bc801e..1fd5f74 100644
--- a/cper-parse.c
+++ b/cper-parse.c
@@ -290,6 +290,9 @@
 //Converts the section described by a single given section descriptor.
 json_object* cper_section_to_ir(FILE* handle, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
 {
+    //Save our current position in the stream.
+    long position = ftell(handle);
+
     //Read section as described by the section descriptor.
     fseek(handle, descriptor->SectionOffset, SEEK_SET);
     void* section = malloc(descriptor->SectionLength);
@@ -302,6 +305,9 @@
         return NULL;
     }
 
+    //Seek back to our original position.
+    fseek(handle, position, SEEK_SET);
+
     //Parse section to IR based on GUID.
     json_object* result = NULL;
     if (guid_equal(&descriptor->SectionType, &gEfiProcessorGenericErrorSectionGuid))
diff --git a/generator/cper-generate.c b/generator/cper-generate.c
index 90ad460..23fad1d 100644
--- a/generator/cper-generate.c
+++ b/generator/cper-generate.c
@@ -196,32 +196,32 @@
     //     length = generate_section_ipf(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)
-    //     length = generate_section_memory2(location);
-    // else if (strcmp(type, "pcie") == 0)
-    //     length = generate_section_pcie(location);
-    // else if (strcmp(type, "firmware") == 0)
-    //     length = generate_section_firmware(location);
-    // else if (strcmp(type, "pcibus") == 0)
-    //     length = generate_section_pci_bus(location);
-    // else if (strcmp(type, "pcidev") == 0)
-    //     length = generate_section_pci_dev(location);
-    // else if (strcmp(type, "dmargeneric") == 0)
-    //     length = generate_section_dmar_generic(location);
-    // else if (strcmp(type, "dmarvtd") == 0)
-    //     length = generate_section_dmar_vtd(location);
-    // else if (strcmp(type, "dmariommu") == 0)
-    //     length = generate_section_dmar_iommu(location);
-    // else if (strcmp(type, "ccixper") == 0)
-    //     length = generate_section_ccix_per(location);
-    // else if (strcmp(type, "cxlprotocol") == 0)
-    //     length = generate_section_cxl_protocol(location);
-    // else if (strcmp(type, "cxlcomponent") == 0)
-    //     length = generate_section_cxl_component(location);
-    // else if (strcmp(type, "unknown") == 0)
-    //     length = generate_section_unknown(location);
+    else if (strcmp(type, "memory") == 0)
+        length = generate_section_memory(location);
+    else if (strcmp(type, "memory2") == 0)
+        length = generate_section_memory2(location);
+    else if (strcmp(type, "pcie") == 0)
+        length = generate_section_pcie(location);
+    else if (strcmp(type, "firmware") == 0)
+        length = generate_section_firmware(location);
+    else if (strcmp(type, "pcibus") == 0)
+        length = generate_section_pci_bus(location);
+    else if (strcmp(type, "pcidev") == 0)
+        length = generate_section_pci_dev(location);
+    else if (strcmp(type, "dmargeneric") == 0)
+        length = generate_section_dmar_generic(location);
+    else if (strcmp(type, "dmarvtd") == 0)
+        length = generate_section_dmar_vtd(location);
+    else if (strcmp(type, "dmariommu") == 0)
+        length = generate_section_dmar_iommu(location);
+    else if (strcmp(type, "ccixper") == 0)
+        length = generate_section_ccix_per(location);
+    else if (strcmp(type, "cxlprotocol") == 0)
+        length = generate_section_cxl_protocol(location);
+    else if (strcmp(type, "cxlcomponent") == 0)
+        length = generate_section_cxl_component(location);
+    else if (strcmp(type, "unknown") == 0)
+        length = generate_random_section(location, rand() % 256);
     else 
     {
         //Undefined section, show error.
diff --git a/generator/gen-utils.c b/generator/gen-utils.c
index a0f6e3c..1ab318f 100644
--- a/generator/gen-utils.c
+++ b/generator/gen-utils.c
@@ -25,6 +25,19 @@
     return bytes;
 }
 
+//Creates a valid common CPER error section, given the start of the error section.
+//Clears reserved bits.
+void create_valid_error_section(UINT8* start)
+{
+    //Fix reserved bits.
+    UINT64* error_section = (UINT64*)start;
+    *error_section &= ~0xFF; //Reserved bits 0-7.
+    *error_section &= 0x7FFFFF; //Reserved bits 23-63
+
+    //Ensure error type has a valid value.
+    *(start + 1) = CPER_ERROR_TYPES_KEYS[rand() % (sizeof(CPER_ERROR_TYPES_KEYS) / sizeof(int))];
+}
+
 //Initializes the random seed for rand() using the current time.
 void init_random()
 {
diff --git a/generator/gen-utils.h b/generator/gen-utils.h
index 4a966db..5dc9a56 100644
--- a/generator/gen-utils.h
+++ b/generator/gen-utils.h
@@ -4,8 +4,11 @@
 #include <stdlib.h>
 #include "../edk/BaseTypes.h"
 
+#define CPER_ERROR_TYPES_KEYS (int []){1, 16, 4, 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
+
 size_t generate_random_section(void** location, size_t size);
 UINT8* generate_random_bytes(size_t size);
 void init_random();
+void create_valid_error_section(UINT8* start);
 
 #endif
\ No newline at end of file
diff --git a/generator/sections/gen-section-ccix-per.c b/generator/sections/gen-section-ccix-per.c
new file mode 100644
index 0000000..a61983b
--- /dev/null
+++ b/generator/sections/gen-section-ccix-per.c
@@ -0,0 +1,34 @@
+/**
+ * Functions for generating psuedo-random CCIX PER error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random CCIX PER error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_ccix_per(void** location)
+{
+    //Create a random length for the CCIX PER log.
+    //The log attached here does not necessarily conform to the CCIX specification, and is simply random.
+    int log_len = (rand() % 5 + 1) * 32;
+
+    //Create random bytes.
+    int size = 16 + log_len;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)(bytes + 4);
+    *validation &= 0b111; //Validation bits 3-63.
+    *(bytes + 13) &= 0b11111; //CCIX port ID bits 5-7.
+    UINT16* reserved = (UINT16*)(bytes + 14);
+    *reserved = 0; //Reserved bytes 14-15.
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-cxl-component.c b/generator/sections/gen-section-cxl-component.c
new file mode 100644
index 0000000..d08dc90
--- /dev/null
+++ b/generator/sections/gen-section-cxl-component.c
@@ -0,0 +1,38 @@
+/**
+ * Functions for generating psuedo-random CXL component error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random CXL component error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_cxl_component(void** location)
+{
+    //Create a random length for the CXL component event log.
+    //The logs attached here do not necessarily conform to the specification, and are simply random.
+    int log_len = rand() % 64;
+
+    //Create random bytes.
+    int size = 32 + log_len;
+    UINT8* bytes = generate_random_bytes(size);
+
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)(bytes + 4);
+    *validation &= 0b111;
+    UINT16* slot_number = (UINT16*)(bytes + 21);
+    *slot_number &= ~0b111; //Device ID slot number bits 0-2.
+    *(bytes + 23) = 0; //Device ID byte 11.
+
+    //Set expected values.
+    UINT32* length = (UINT32*)bytes;
+    *length = size;
+    
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-cxl-protocol.c b/generator/sections/gen-section-cxl-protocol.c
new file mode 100644
index 0000000..64326f9
--- /dev/null
+++ b/generator/sections/gen-section-cxl-protocol.c
@@ -0,0 +1,57 @@
+/**
+ * Functions for generating psuedo-random CXL protocol error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random CXL protocol error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_cxl_protocol(void** location)
+{
+    //Create a random length for the CXL DVSEC and CXL error log.
+    //The logs attached here do not necessarily conform to the specification, and are simply random.
+    int dvsec_len = rand() % 64;
+    int error_log_len = rand() % 64;
+
+    //Create random bytes.
+    int size = 116 + dvsec_len + error_log_len;
+    UINT8* bytes = generate_random_bytes(size);
+
+    //Set CXL agent type.
+    int cxl_agent_type = rand() % 2;
+    *(bytes + 8) = cxl_agent_type;
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0b111111; //Validation bits 6-63.
+    for (int i=0; i<7; i++)
+        *(bytes + 9 + i) = 0; //Reserved bytes 9-15.
+
+    //We only reserve bytes if it's a CXL 1.1 device, and not a host downstream port.
+    if (cxl_agent_type == 0)
+    {
+        for (int i=0; i<3; i++)
+            *(bytes + 20 + i) = 0; //CXL agent address bytes 5-7.
+    }
+    
+    *(bytes + 34) &= ~0b111; //Device ID byte 10 bits 0-2.
+    UINT32* reserved = (UINT32*)(bytes + 36);
+    *reserved = 0; //Device ID bytes 12-15.
+    reserved = (UINT32*)(bytes + 112);
+    *reserved = 0; //Reserved bytes 112-115.
+
+    //Set expected values.
+    UINT16* dvsec_length_field = (UINT16*)(bytes + 108);
+    UINT16* error_log_len_field = (UINT16*)(bytes + 110);
+    *dvsec_length_field = dvsec_len;
+    *error_log_len_field = error_log_len;
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-dmar.c b/generator/sections/gen-section-dmar.c
new file mode 100644
index 0000000..d0bbb5e
--- /dev/null
+++ b/generator/sections/gen-section-dmar.c
@@ -0,0 +1,72 @@
+/**
+ * Functions for generating psuedo-random CPER DMAr error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random generic DMAr error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_dmar_generic(void** location)
+{
+    //Create random bytes.
+    int size = 32;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* reserved = (UINT64*)(bytes + 16);
+    *reserved = 0;
+    *(reserved + 1) = 0;
+
+    //Set expected values.
+    *(bytes + 4) = rand() % 0xC; //Fault reason.
+    *(bytes + 5) = rand() % 2; //Access type.
+    *(bytes + 6) = rand() % 2; //Address type.
+    *(bytes + 7) = rand() % 2 + 1; //Architecture type.
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
+
+//Generates a single psuedo-random VT-d DMAr error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_dmar_vtd(void** location)
+{
+    //Create random bytes.
+    int size = 144;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    for (int i=0; i<12; i++)
+        *(bytes + 36 + i) = 0; //Reserved bytes 36-47.
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
+
+//Generates a single psuedo-random IOMMU DMAr error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_dmar_iommu(void** location)
+{
+    //Create random bytes.
+    int size = 144;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    for (int i=0; i<7; i++)
+        *(bytes + 1 + i) + 0; //Reserved bytes 1 to 7.
+    UINT64* reserved = (UINT64*)(bytes + 24);
+    *reserved = 0; //Reserved bytes 24-31.
+    for (int i=0; i<16; i++)
+        *(bytes + 48 + i) = 0; //Reserved bytes 48-63.
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-firmware.c b/generator/sections/gen-section-firmware.c
new file mode 100644
index 0000000..09c47ff
--- /dev/null
+++ b/generator/sections/gen-section-firmware.c
@@ -0,0 +1,33 @@
+/**
+ * Functions for generating psuedo-random CPER firmware error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random firmware error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_firmware(void** location)
+{
+    //Create random bytes.
+    int size = 32;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    for (int i=0; i<7; i++)
+        *(bytes + 2 + i) = 0; //Reserved bytes 2-9.
+
+    //Set expected values.
+    *(bytes + 1) = 2; //Revision, referenced version of spec is 2.
+    UINT64* record_id = (UINT64*)(bytes + 8);
+    *record_id = 0; //Record ID, should be forced to NULL.
+    *bytes = rand() % 3; //Record type.
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-memory.c b/generator/sections/gen-section-memory.c
new file mode 100644
index 0000000..dfa713f
--- /dev/null
+++ b/generator/sections/gen-section-memory.c
@@ -0,0 +1,59 @@
+/**
+ * Functions for generating psuedo-random CPER platform memory error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random platform memory error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_memory(void** location)
+{
+    //Create random bytes.
+    int size = 80;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0x2FFFFF; //Validation 22-63
+    *(bytes + 73) &= ~0b11100; //Extended bits 2-4
+
+    //Fix values that could be above range.
+    *(bytes + 72) = rand() % 16; //Memory error type
+
+    //Fix error status.
+    create_valid_error_section(bytes + 8);
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
+
+//Generates a single psuedo-random memory 2 error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_memory2(void** location)
+{
+    //Create random bytes.
+    int size = 96;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0x2FFFFF; //Validation 22-63
+    *(bytes + 63) = 0; //Reserved byte 63
+
+    //Fix values that could be above range.
+    *(bytes + 61) = rand() % 16; //Memory error type
+    *(bytes + 62) = rand() % 2; //Status
+
+    //Fix error status.
+    create_valid_error_section(bytes + 8);
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-pci-bus.c b/generator/sections/gen-section-pci-bus.c
new file mode 100644
index 0000000..9afd9ad
--- /dev/null
+++ b/generator/sections/gen-section-pci-bus.c
@@ -0,0 +1,38 @@
+/**
+ * Functions for generating psuedo-random CPER PCI/PCI-X bus error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random PCI/PCI-X bus error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_pci_bus(void** location)
+{
+    //Create random bytes.
+    int size = 208;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0x1FF; //Validation 9-63
+    UINT32* reserved = (UINT32*)(bytes + 20);
+    *reserved = 0;
+    UINT64* bus_command = (UINT64*)(bytes + 40);
+    *bus_command &= 0x100000000000000; //Bus command bytes bar bit 56.
+
+    //Fix values that could be above range.
+    UINT16* error_type = (UINT16*)(bytes + 16);
+    *error_type = rand() % 8;
+
+    //Fix error status.
+    create_valid_error_section(bytes + 8);
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-pci-dev.c b/generator/sections/gen-section-pci-dev.c
new file mode 100644
index 0000000..1882d6c
--- /dev/null
+++ b/generator/sections/gen-section-pci-dev.c
@@ -0,0 +1,37 @@
+/**
+ * Functions for generating psuedo-random CPER PCI component error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+//Generates a single psuedo-random PCI component error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_pci_dev(void** location)
+{
+    //Generate how many register pairs will be attached to this section.
+    UINT32 num_memory_pairs = rand() % 4;
+    UINT32 num_io_pairs = rand() % 4;
+    UINT32 num_registers = num_memory_pairs + num_io_pairs;
+
+    //Create random bytes.
+    int size = 40 + (num_registers * 16);
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0b11111; //Validation 5-63
+    for (int i=0; i<5; i++)
+        *(bytes + 27 + i) = 0; //Bytes 11-15 of ID info.
+
+    //Fix error status.
+    create_valid_error_section(bytes + 8);
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-pcie.c b/generator/sections/gen-section-pcie.c
new file mode 100644
index 0000000..5f67c09
--- /dev/null
+++ b/generator/sections/gen-section-pcie.c
@@ -0,0 +1,38 @@
+/**
+ * Functions for generating psuedo-random CPER PCIe error sections.
+ * 
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+
+#define PCIE_PORT_TYPES (int []){0, 1, 4, 5, 6, 7, 8, 9, 10}
+
+//Generates a single psuedo-random PCIe error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_pcie(void** location)
+{
+    //Create random bytes.
+    int size = 208;
+    UINT8* bytes = generate_random_bytes(size);
+    
+    //Set reserved areas to zero.
+    UINT64* validation = (UINT64*)bytes;
+    *validation &= 0xFF; //Validation 8-63
+    UINT32* version = (UINT32*)(bytes + 12);
+    *version &= 0xFFFF; //Version bytes 2-3
+    UINT32* reserved = (UINT32*)(bytes + 20);
+    *reserved = 0; //Reserved bytes 20-24
+    *(bytes + 39) = 0; //Device ID byte 15
+
+    //Fix values that could be above range.
+    UINT32* port_type = (UINT32*)(bytes + 8);
+    *port_type = PCIE_PORT_TYPES[rand() % (sizeof(PCIE_PORT_TYPES) / sizeof(int))];
+
+    //Set return values, exit.
+    *location = bytes;
+    return size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-sections.h b/generator/sections/gen-sections.h
index 33ecd39..50f9350 100644
--- a/generator/sections/gen-sections.h
+++ b/generator/sections/gen-sections.h
@@ -6,5 +6,17 @@
 size_t generate_section_generic(void** location);
 size_t generate_section_ia32x64(void** location);
 size_t generate_section_arm(void** location);
+size_t generate_section_memory(void** location);
+size_t generate_section_memory2(void** location);
+size_t generate_section_pcie(void** location);
+size_t generate_section_pci_bus(void** location);
+size_t generate_section_pci_dev(void** location);
+size_t generate_section_firmware(void** location);
+size_t generate_section_dmar_generic(void** location);
+size_t generate_section_dmar_vtd(void** location);
+size_t generate_section_dmar_iommu(void** location);
+size_t generate_section_ccix_per(void** location);
+size_t generate_section_cxl_protocol(void** location);
+size_t generate_section_cxl_component(void** location);
 
 #endif
\ No newline at end of file
diff --git a/sections/cper-section-pci-bus.c b/sections/cper-section-pci-bus.c
index db034d1..d12a6fe 100644
--- a/sections/cper-section-pci-bus.c
+++ b/sections/cper-section-pci-bus.c
@@ -38,9 +38,10 @@
     json_object_object_add(section_ir, "busID", bus_id);
 
     //Miscellaneous numeric fields.
+    UINT8 command_type = (bus_error->BusCommand >> 56) & 0b1; //Byte 7, bit 0.
     json_object_object_add(section_ir, "busAddress", json_object_new_uint64(bus_error->BusAddress));
     json_object_object_add(section_ir, "busData", json_object_new_uint64(bus_error->BusData));
-    json_object_object_add(section_ir, "busCommandType", json_object_new_string(bus_error->BusCommand == 0 ? "PCI" : "PCI-X"));
+    json_object_object_add(section_ir, "busCommandType", json_object_new_string(command_type == 0 ? "PCI" : "PCI-X"));
     json_object_object_add(section_ir, "busRequestorID", json_object_new_uint64(bus_error->RequestorId));
     json_object_object_add(section_ir, "busCompleterID", json_object_new_uint64(bus_error->ResponderId));
     json_object_object_add(section_ir, "targetID", json_object_new_uint64(bus_error->TargetId));