Remove validation bits

Discard invalid properties from json decode. JSON output should only
contain valid properties. This saves time in preventing post
processing of output for valid fields.

Ensure round trip validity with validation bits removed and required
properties populated.

Fix bugs in json decode.

Overhaul unit tests to use valijson. Add tests with static examples
to validate against schema. Use and nlohmann for better schema
validation over intrinsic libcper validation.

Example json output before:
{
  "ValidationBits": {
    "LevelValid": false,
    "CorrectedValid": true
  },
  "Level": 1,
  "Corrected": true
}

After:
{
  "Corrected": true
}

Change-Id: I188bdc2827a57d938c22a431238fadfcdc939ab8
Signed-off-by: Aushim Nagarkatti <anagarkatti@nvidia.com>
diff --git a/sections/cper-section-arm.c b/sections/cper-section-arm.c
index b07c829..067c4f8 100644
--- a/sections/cper-section-arm.c
+++ b/sections/cper-section-arm.c
@@ -6,6 +6,7 @@
  **/
 
 #include <stdio.h>
+#include <string.h>
 #include <json.h>
 #include <libcper/base64.h>
 #include <libcper/Cper.h>
@@ -48,10 +49,9 @@
 	EFI_ARM_ERROR_RECORD *record = (EFI_ARM_ERROR_RECORD *)section;
 	json_object *section_ir = json_object_new_object();
 
-	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		record->ValidFields, 4, ARM_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	//Length of ValidationBits from spec
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = record->ValidFields };
 
 	//Number of error info and context info structures, and length.
 	json_object_object_add(section_ir, "errorInfoNum",
@@ -62,33 +62,42 @@
 			       json_object_new_uint64(record->SectionLength));
 
 	//Error affinity.
-	json_object *error_affinity = json_object_new_object();
-	json_object_object_add(error_affinity, "value",
-			       json_object_new_int(record->ErrorAffinityLevel));
-	json_object_object_add(
-		error_affinity, "type",
-		json_object_new_string(record->ErrorAffinityLevel < 4 ?
-					       "Vendor Defined" :
-					       "Reserved"));
-	json_object_object_add(section_ir, "errorAffinity", error_affinity);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *error_affinity = json_object_new_object();
+		json_object_object_add(
+			error_affinity, "value",
+			json_object_new_int(record->ErrorAffinityLevel));
+		json_object_object_add(
+			error_affinity, "type",
+			json_object_new_string(record->ErrorAffinityLevel < 4 ?
+						       "Vendor Defined" :
+						       "Reserved"));
+		json_object_object_add(section_ir, "errorAffinity",
+				       error_affinity);
+	}
 
 	//Processor ID (MPIDR_EL1) and chip ID (MIDR_EL1).
-	uint64_t sock;
-	uint64_t mpidr_eli1 = record->MPIDR_EL1;
-	json_object_object_add(section_ir, "mpidrEl1",
-			       json_object_new_uint64(mpidr_eli1));
-	//Arm Processor socket info
-	sock = (mpidr_eli1 & ARM_SOCK_MASK) >> 32;
-	json_object_object_add(section_ir, "affinity3",
-			       json_object_new_uint64(sock));
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		uint64_t mpidr_eli1 = record->MPIDR_EL1;
+		uint64_t sock;
+		json_object_object_add(section_ir, "mpidrEl1",
+				       json_object_new_uint64(mpidr_eli1));
+
+		//Arm Processor socket info dependes on mpidr_eli1
+		sock = (mpidr_eli1 & ARM_SOCK_MASK) >> 32;
+		json_object_object_add(section_ir, "affinity3",
+				       json_object_new_uint64(sock));
+	}
 
 	json_object_object_add(section_ir, "midrEl1",
 			       json_object_new_uint64(record->MIDR_EL1));
 
-	//Whether the processor is running, and the state of it if so.
-	json_object_object_add(section_ir, "running",
-			       json_object_new_boolean(record->RunningState &
-						       0x1));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		//Whether the processor is running, and the state of it if so.
+		json_object_object_add(
+			section_ir, "running",
+			json_object_new_boolean(record->RunningState & 0x1));
+	}
 	if (!(record->RunningState >> 31)) {
 		//Bit 32 of running state is on, so PSCI state information is included.
 		//This can't be made human readable, as it is unknown whether this will be the pre-PSCI 1.0 format
@@ -124,23 +133,28 @@
 	json_object_object_add(section_ir, "contextInfo", context_info_array);
 
 	//Is there any vendor-specific information following?
-	if (cur_pos < (uint8_t *)section + record->SectionLength) {
-		json_object *vendor_specific = json_object_new_object();
-		size_t input_size =
-			(uint8_t *)section + record->SectionLength - cur_pos;
-		int32_t encoded_len = 0;
-		char *encoded =
-			base64_encode(cur_pos, input_size, &encoded_len);
-		if (encoded == NULL) {
-			return NULL;
-		}
-		json_object_object_add(vendor_specific, "data",
-				       json_object_new_string_len(encoded,
-								  encoded_len));
-		free(encoded);
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		if (cur_pos < (uint8_t *)section + record->SectionLength) {
+			json_object *vendor_specific = json_object_new_object();
+			size_t input_size = (uint8_t *)section +
+					    record->SectionLength - cur_pos;
+			int32_t encoded_len = 0;
+			char *encoded = base64_encode(cur_pos, input_size,
+						      &encoded_len);
+			if (encoded == NULL) {
+				printf("base64 encode of vendorSpecificInfo failed\n");
+				return NULL;
+			}
+			json_object_object_add(vendor_specific, "data",
+					       json_object_new_string_len(
+						       encoded, encoded_len));
+			free(encoded);
 
-		json_object_object_add(section_ir, "vendorSpecificInfo",
-				       vendor_specific);
+			json_object_object_add(section_ir, "vendorSpecificInfo",
+					       vendor_specific);
+		} else {
+			printf("vendorSpecificInfo is marked valid but not present in binary\n");
+		}
 	}
 
 	return section_ir;
@@ -159,10 +173,8 @@
 			       json_object_new_int(error_info->Length));
 
 	//Validation bitfield.
-	json_object *validation =
-		bitfield_to_ir(error_info->ValidationBits, 5,
-			       ARM_ERROR_INFO_ENTRY_VALID_BITFIELD_NAMES);
-	json_object_object_add(error_info_ir, "validationBits", validation);
+	ValidationTypes ui16Type = { UINT_16T,
+				     .value.ui16 = error_info->ValidationBits };
 
 	//The type of error information in this log.
 	json_object *error_type = integer_to_readable_pair(
@@ -171,51 +183,65 @@
 	json_object_object_add(error_info_ir, "errorType", error_type);
 
 	//Multiple error count.
-	json_object *multiple_error = json_object_new_object();
-	json_object_object_add(multiple_error, "value",
-			       json_object_new_int(error_info->MultipleError));
-	json_object_object_add(
-		multiple_error, "type",
-		json_object_new_string(error_info->MultipleError < 1 ?
-					       "Single Error" :
-					       "Multiple Errors"));
-	json_object_object_add(error_info_ir, "multipleError", multiple_error);
+	if (isvalid_prop_to_ir(&ui16Type, 0)) {
+		json_object *multiple_error = json_object_new_object();
+		json_object_object_add(
+			multiple_error, "value",
+			json_object_new_int(error_info->MultipleError));
+		json_object_object_add(
+			multiple_error, "type",
+			json_object_new_string(error_info->MultipleError < 1 ?
+						       "Single Error" :
+						       "Multiple Errors"));
+		json_object_object_add(error_info_ir, "multipleError",
+				       multiple_error);
+	}
 
 	//Flags.
-	json_object *flags = bitfield_to_ir(error_info->Flags, 4,
-					    ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
-	json_object_object_add(error_info_ir, "flags", flags);
+	if (isvalid_prop_to_ir(&ui16Type, 1)) {
+		json_object *flags = bitfield_to_ir(
+			error_info->Flags, 4, ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
+		json_object_object_add(error_info_ir, "flags", flags);
+	}
 
 	//Error information, split by type.
-	json_object *error_subinfo = NULL;
-	switch (error_info->Type) {
-	case ARM_ERROR_INFORMATION_TYPE_CACHE: //Cache
-	case ARM_ERROR_INFORMATION_TYPE_TLB:   //TLB
-		error_subinfo = cper_arm_cache_tlb_error_to_ir(
-			(EFI_ARM_CACHE_ERROR_STRUCTURE *)&error_info
-				->ErrorInformation,
-			error_info);
-		break;
-	case ARM_ERROR_INFORMATION_TYPE_BUS: //Bus
-		error_subinfo = cper_arm_bus_error_to_ir(
-			(EFI_ARM_BUS_ERROR_STRUCTURE *)&error_info
-				->ErrorInformation);
-		break;
+	if (isvalid_prop_to_ir(&ui16Type, 2)) {
+		json_object *error_subinfo = NULL;
+		switch (error_info->Type) {
+		case ARM_ERROR_INFORMATION_TYPE_CACHE: //Cache
+		case ARM_ERROR_INFORMATION_TYPE_TLB:   //TLB
+			error_subinfo = cper_arm_cache_tlb_error_to_ir(
+				(EFI_ARM_CACHE_ERROR_STRUCTURE *)&error_info
+					->ErrorInformation,
+				error_info);
+			break;
+		case ARM_ERROR_INFORMATION_TYPE_BUS: //Bus
+			error_subinfo = cper_arm_bus_error_to_ir(
+				(EFI_ARM_BUS_ERROR_STRUCTURE *)&error_info
+					->ErrorInformation);
+			break;
 
-	default:
-		//Unknown/microarch, will not support.
-		break;
+		default:
+			//Unknown/microarch, will not support.
+			break;
+		}
+		json_object_object_add(error_info_ir, "errorInformation",
+				       error_subinfo);
 	}
-	json_object_object_add(error_info_ir, "errorInformation",
-			       error_subinfo);
 
 	//Virtual fault address, physical fault address.
-	json_object_object_add(
-		error_info_ir, "virtualFaultAddress",
-		json_object_new_uint64(error_info->VirtualFaultAddress));
-	json_object_object_add(
-		error_info_ir, "physicalFaultAddress",
-		json_object_new_uint64(error_info->PhysicalFaultAddress));
+	if (isvalid_prop_to_ir(&ui16Type, 3)) {
+		json_object_object_add(
+			error_info_ir, "virtualFaultAddress",
+			json_object_new_uint64(
+				error_info->VirtualFaultAddress));
+	}
+	if (isvalid_prop_to_ir(&ui16Type, 4)) {
+		json_object_object_add(
+			error_info_ir, "physicalFaultAddress",
+			json_object_new_uint64(
+				error_info->PhysicalFaultAddress));
+	}
 
 	return error_info_ir;
 }
@@ -230,59 +256,83 @@
 	char *cache_tlb_propname;
 
 	//Validation bitfield.
-	json_object *validation =
-		bitfield_to_ir(cache_tlb_error->ValidationBits, 7,
-			       ARM_CACHE_TLB_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(cache_tlb_error_ir, "validationBits",
-			       validation);
+	ValidationTypes ui64Type = {
+		UINT_64T, .value.ui64 = cache_tlb_error->ValidationBits
+	};
 
 	//Transaction type.
-	json_object *transaction_type = integer_to_readable_pair(
-		cache_tlb_error->TransactionType, 3,
-		ARM_ERROR_TRANSACTION_TYPES_KEYS,
-		ARM_ERROR_TRANSACTION_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(cache_tlb_error_ir, "transactionType",
-			       transaction_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *transaction_type = integer_to_readable_pair(
+			cache_tlb_error->TransactionType, 3,
+			ARM_ERROR_TRANSACTION_TYPES_KEYS,
+			ARM_ERROR_TRANSACTION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(cache_tlb_error_ir, "transactionType",
+				       transaction_type);
+	}
 
 	//Operation.
-	json_object *operation;
+	bool cacheErrorFlag = 1;
 	if (error_info->Type == 0) {
-		//Cache operation.
-		operation = integer_to_readable_pair(
-			cache_tlb_error->Operation, 11,
-			ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
-			ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
-			"Unknown (Reserved)");
 		cache_tlb_propname = "cacheError";
 	} else {
 		//TLB operation.
-		operation = integer_to_readable_pair(
-			cache_tlb_error->Operation, 9,
-			ARM_TLB_OPERATION_TYPES_KEYS,
-			ARM_TLB_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
 		cache_tlb_propname = "tlbError";
+		cacheErrorFlag = 0;
 	}
-	json_object_object_add(cache_tlb_error_ir, "operation", operation);
+
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *operation;
+
+		if (cacheErrorFlag) {
+			//Cache operation.
+			operation = integer_to_readable_pair(
+				cache_tlb_error->Operation, 11,
+				ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
+				ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
+				"Unknown (Reserved)");
+		} else {
+			operation = integer_to_readable_pair(
+				cache_tlb_error->Operation, 9,
+				ARM_TLB_OPERATION_TYPES_KEYS,
+				ARM_TLB_OPERATION_TYPES_VALUES,
+				"Unknown (Reserved)");
+		}
+		json_object_object_add(cache_tlb_error_ir, "operation",
+				       operation);
+	}
 
 	//Miscellaneous remaining fields.
-	json_object_object_add(cache_tlb_error_ir, "level",
-			       json_object_new_int(cache_tlb_error->Level));
-	json_object_object_add(
-		cache_tlb_error_ir, "processorContextCorrupt",
-		json_object_new_boolean(
-			cache_tlb_error->ProcessorContextCorrupt));
-	json_object_object_add(
-		cache_tlb_error_ir, "corrected",
-		json_object_new_boolean(cache_tlb_error->Corrected));
-	json_object_object_add(
-		cache_tlb_error_ir, "precisePC",
-		json_object_new_boolean(cache_tlb_error->PrecisePC));
-	json_object_object_add(
-		cache_tlb_error_ir, "restartablePC",
-		json_object_new_boolean(cache_tlb_error->RestartablePC));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			cache_tlb_error_ir, "level",
+			json_object_new_int(cache_tlb_error->Level));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			cache_tlb_error_ir, "processorContextCorrupt",
+			json_object_new_boolean(
+				cache_tlb_error->ProcessorContextCorrupt));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			cache_tlb_error_ir, "corrected",
+			json_object_new_boolean(cache_tlb_error->Corrected));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			cache_tlb_error_ir, "precisePC",
+			json_object_new_boolean(cache_tlb_error->PrecisePC));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(cache_tlb_error_ir, "restartablePC",
+				       json_object_new_boolean(
+					       cache_tlb_error->RestartablePC));
+	}
 
 	json_object_object_add(cache_tlb_prop, cache_tlb_propname,
 			       cache_tlb_error_ir);
+
 	return cache_tlb_prop;
 }
 
@@ -290,73 +340,111 @@
 json_object *cper_arm_bus_error_to_ir(EFI_ARM_BUS_ERROR_STRUCTURE *bus_error)
 {
 	json_object *bus_error_ir = json_object_new_object();
+	json_object *bus_prop = json_object_new_object();
+	char *bus_propname = "busError";
 
 	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(bus_error->ValidationBits, 12,
-			       ARM_BUS_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(bus_error_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = bus_error->ValidationBits };
 
 	//Transaction type.
-	json_object *transaction_type = integer_to_readable_pair(
-		bus_error->TransactionType, 3, ARM_ERROR_TRANSACTION_TYPES_KEYS,
-		ARM_ERROR_TRANSACTION_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(bus_error_ir, "transactionType",
-			       transaction_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *transaction_type = integer_to_readable_pair(
+			bus_error->TransactionType, 3,
+			ARM_ERROR_TRANSACTION_TYPES_KEYS,
+			ARM_ERROR_TRANSACTION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(bus_error_ir, "transactionType",
+				       transaction_type);
+	}
 
 	//Operation.
-	json_object *operation = integer_to_readable_pair(
-		bus_error->Operation, 7, ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
-		ARM_CACHE_BUS_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(bus_error_ir, "operation", operation);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *operation = integer_to_readable_pair(
+			bus_error->Operation, 7,
+			ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
+			ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(bus_error_ir, "operation", operation);
+	}
 
-	//Affinity level of bus error, + miscellaneous fields.
-	json_object_object_add(bus_error_ir, "level",
-			       json_object_new_int(bus_error->Level));
-	json_object_object_add(
-		bus_error_ir, "processorContextCorrupt",
-		json_object_new_boolean(bus_error->ProcessorContextCorrupt));
-	json_object_object_add(bus_error_ir, "corrected",
-			       json_object_new_boolean(bus_error->Corrected));
-	json_object_object_add(bus_error_ir, "precisePC",
-			       json_object_new_boolean(bus_error->PrecisePC));
-	json_object_object_add(
-		bus_error_ir, "restartablePC",
-		json_object_new_boolean(bus_error->RestartablePC));
-	json_object_object_add(bus_error_ir, "timedOut",
-			       json_object_new_boolean(bus_error->TimeOut));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		//Affinity level of bus error, + miscellaneous fields.
+		json_object_object_add(bus_error_ir, "level",
+				       json_object_new_int(bus_error->Level));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			bus_error_ir, "processorContextCorrupt",
+			json_object_new_boolean(
+				bus_error->ProcessorContextCorrupt));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			bus_error_ir, "corrected",
+			json_object_new_boolean(bus_error->Corrected));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			bus_error_ir, "precisePC",
+			json_object_new_boolean(bus_error->PrecisePC));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(
+			bus_error_ir, "restartablePC",
+			json_object_new_boolean(bus_error->RestartablePC));
+	}
 
 	//Participation type.
-	json_object *participation_type = integer_to_readable_pair(
-		bus_error->ParticipationType, 4,
-		ARM_BUS_PARTICIPATION_TYPES_KEYS,
-		ARM_BUS_PARTICIPATION_TYPES_VALUES, "Unknown");
-	json_object_object_add(bus_error_ir, "participationType",
-			       participation_type);
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object *participation_type = integer_to_readable_pair(
+			bus_error->ParticipationType, 4,
+			ARM_BUS_PARTICIPATION_TYPES_KEYS,
+			ARM_BUS_PARTICIPATION_TYPES_VALUES, "Unknown");
+		json_object_object_add(bus_error_ir, "participationType",
+				       participation_type);
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object_object_add(
+			bus_error_ir, "timedOut",
+			json_object_new_boolean(bus_error->TimeOut));
+	}
 
 	//Address space.
-	json_object *address_space = integer_to_readable_pair(
-		bus_error->AddressSpace, 3, ARM_BUS_ADDRESS_SPACE_TYPES_KEYS,
-		ARM_BUS_ADDRESS_SPACE_TYPES_VALUES, "Unknown");
-	json_object_object_add(bus_error_ir, "addressSpace", address_space);
+	if (isvalid_prop_to_ir(&ui64Type, 9)) {
+		json_object *address_space = integer_to_readable_pair(
+			bus_error->AddressSpace, 3,
+			ARM_BUS_ADDRESS_SPACE_TYPES_KEYS,
+			ARM_BUS_ADDRESS_SPACE_TYPES_VALUES, "Unknown");
+		json_object_object_add(bus_error_ir, "addressSpace",
+				       address_space);
+	}
 
 	//Memory access attributes.
 	//todo: find the specification of these in the ARM ARM
-	json_object_object_add(
-		bus_error_ir, "memoryAttributes",
-		json_object_new_int(bus_error->MemoryAddressAttributes));
+	if (isvalid_prop_to_ir(&ui64Type, 10)) {
+		json_object_object_add(
+			bus_error_ir, "memoryAttributes",
+			json_object_new_int(
+				bus_error->MemoryAddressAttributes));
+	}
 
 	//Access Mode
-	json_object *access_mode = json_object_new_object();
-	json_object_object_add(access_mode, "value",
-			       json_object_new_int(bus_error->AccessMode));
-	json_object_object_add(
-		access_mode, "name",
-		json_object_new_string(bus_error->AccessMode == 0 ? "Secure" :
-								    "Normal"));
-	json_object_object_add(bus_error_ir, "accessMode", access_mode);
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object *access_mode = json_object_new_object();
+		json_object_object_add(
+			access_mode, "value",
+			json_object_new_int(bus_error->AccessMode));
+		json_object_object_add(
+			access_mode, "name",
+			json_object_new_string(bus_error->AccessMode == 0 ?
+						       "Secure" :
+						       "Normal"));
+		json_object_object_add(bus_error_ir, "accessMode", access_mode);
+	}
+	json_object_object_add(bus_prop, bus_propname, bus_error_ir);
 
-	return bus_error_ir;
+	return bus_prop;
 }
 
 //Converts a single ARM processor context block into JSON IR.
@@ -389,67 +477,67 @@
 	switch (header->RegisterContextType) {
 	case EFI_ARM_CONTEXT_TYPE_AARCH32_GPR:
 		register_array = uniform_struct_to_ir(
-			(UINT32 *)cur_pos,
+			(UINT32 *)*cur_pos,
 			sizeof(EFI_ARM_V8_AARCH32_GPR) / sizeof(UINT32),
 			ARM_AARCH32_GPR_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL1:
 		register_array = uniform_struct_to_ir(
-			(UINT32 *)cur_pos,
+			(UINT32 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS) /
 				sizeof(UINT32),
 			ARM_AARCH32_EL1_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH32_EL2:
 		register_array = uniform_struct_to_ir(
-			(UINT32 *)cur_pos,
+			(UINT32 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS) /
 				sizeof(UINT32),
 			ARM_AARCH32_EL2_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE:
 		register_array = uniform_struct_to_ir(
-			(UINT32 *)cur_pos,
+			(UINT32 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS) /
 				sizeof(UINT32),
 			ARM_AARCH32_SECURE_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH64_GPR:
 		register_array = uniform_struct64_to_ir(
-			(UINT64 *)cur_pos,
+			(UINT64 *)*cur_pos,
 			sizeof(EFI_ARM_V8_AARCH64_GPR) / sizeof(UINT64),
 			ARM_AARCH64_GPR_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL1:
 		register_array = uniform_struct64_to_ir(
-			(UINT64 *)cur_pos,
+			(UINT64 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS) /
 				sizeof(UINT64),
 			ARM_AARCH64_EL1_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL2:
 		register_array = uniform_struct64_to_ir(
-			(UINT64 *)cur_pos,
+			(UINT64 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS) /
 				sizeof(UINT64),
 			ARM_AARCH64_EL2_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_AARCH64_EL3:
 		register_array = uniform_struct64_to_ir(
-			(UINT64 *)cur_pos,
+			(UINT64 *)*cur_pos,
 			sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS) /
 				sizeof(UINT64),
 			ARM_AARCH64_EL3_REGISTER_NAMES);
 		break;
 	case EFI_ARM_CONTEXT_TYPE_MISC:
 		register_array = cper_arm_misc_register_array_to_ir(
-			(EFI_ARM_MISC_CONTEXT_REGISTER *)cur_pos);
+			(EFI_ARM_MISC_CONTEXT_REGISTER *)*cur_pos);
 		break;
 	default:
 		//Unknown register array type, add as base64 data instead.
 		register_array = json_object_new_object();
 		int32_t encoded_len = 0;
-		char *encoded = base64_encode((UINT8 *)cur_pos,
+		char *encoded = base64_encode((UINT8 *)*cur_pos,
 					      header->RegisterArraySize,
 					      &encoded_len);
 		if (encoded == NULL) {
@@ -497,45 +585,60 @@
 //Converts a single CPER-JSON ARM error section into CPER binary, outputting to the given stream.
 void ir_section_arm_to_cper(json_object *section, FILE *out)
 {
-	EFI_ARM_ERROR_RECORD *section_cper =
-		(EFI_ARM_ERROR_RECORD *)calloc(1, sizeof(EFI_ARM_ERROR_RECORD));
+	EFI_ARM_ERROR_RECORD section_cper;
+	memset(&section_cper, 0, sizeof(section_cper));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 4,
-		ARM_ERROR_VALID_BITFIELD_NAMES);
+	struct json_object *obj = NULL;
+	ValidationTypes u32Type = { UINT_32T, .value.ui32 = 0 };
 
 	//Count of error/context info structures.
-	section_cper->ErrInfoNum = json_object_get_int(
+	section_cper.ErrInfoNum = json_object_get_int(
 		json_object_object_get(section, "errorInfoNum"));
-	section_cper->ContextInfoNum = json_object_get_int(
+	section_cper.ContextInfoNum = json_object_get_int(
 		json_object_object_get(section, "contextInfoNum"));
 
 	//Miscellaneous raw value fields.
-	section_cper->SectionLength = json_object_get_uint64(
+	section_cper.SectionLength = json_object_get_uint64(
 		json_object_object_get(section, "sectionLength"));
-	section_cper->ErrorAffinityLevel = readable_pair_to_integer(
-		json_object_object_get(section, "errorAffinity"));
-	section_cper->MPIDR_EL1 = json_object_get_uint64(
-		json_object_object_get(section, "mpidrEl1"));
-	section_cper->MIDR_EL1 = json_object_get_uint64(
+	if (json_object_object_get_ex(section, "mpidrEl1", &obj)) {
+		section_cper.MPIDR_EL1 = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&u32Type, 0);
+	}
+	if (json_object_object_get_ex(section, "errorAffinity", &obj)) {
+		section_cper.ErrorAffinityLevel = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&u32Type, 1);
+	}
+	section_cper.MIDR_EL1 = json_object_get_uint64(
 		json_object_object_get(section, "midrEl1"));
-	section_cper->RunningState = json_object_get_boolean(
-		json_object_object_get(section, "running"));
+	if (json_object_object_get_ex(section, "running", &obj)) {
+		section_cper.RunningState = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&u32Type, 2);
+	}
 
 	//Optional PSCI state.
 	json_object *psci_state = json_object_object_get(section, "psciState");
 	if (psci_state != NULL) {
-		section_cper->PsciState = json_object_get_uint64(psci_state);
+		section_cper.PsciState = json_object_get_uint64(psci_state);
 	}
 
+	//Validationbits for EFI_ARM_ERROR_RECORD should also consider vendorSpecificInfo
+	bool vendorSpecificPresent =
+		json_object_object_get_ex(section, "vendorSpecificInfo", &obj);
+	json_object *vendor_specific_info = obj;
+	if (vendorSpecificPresent) {
+		add_to_valid_bitfield(&u32Type, 3);
+	}
+
+	section_cper.ValidFields = u32Type.value.ui32;
+
 	//Flush header to stream.
-	fwrite(section_cper, sizeof(EFI_ARM_ERROR_RECORD), 1, out);
-	fflush(out);
+	fwrite(&section_cper, sizeof(section_cper), 1, out);
 
 	//Error info structure array.
+
 	json_object *error_info = json_object_object_get(section, "errorInfo");
-	for (int i = 0; i < section_cper->ErrInfoNum; i++) {
+	for (int i = 0; i < section_cper.ErrInfoNum; i++) {
 		ir_arm_error_info_to_cper(
 			json_object_array_get_idx(error_info, i), out);
 	}
@@ -543,15 +646,13 @@
 	//Context info structure array.
 	json_object *context_info =
 		json_object_object_get(section, "contextInfo");
-	for (int i = 0; i < section_cper->ContextInfoNum; i++) {
+	for (int i = 0; i < section_cper.ContextInfoNum; i++) {
 		ir_arm_context_info_to_cper(
 			json_object_array_get_idx(context_info, i), out);
 	}
 
 	//Vendor specific error info.
-	json_object *vendor_specific_info =
-		json_object_object_get(section, "vendorSpecificInfo");
-	if (vendor_specific_info != NULL) {
+	if (vendorSpecificPresent) {
 		json_object *vendor_info_string =
 			json_object_object_get(vendor_specific_info, "data");
 		int vendor_specific_len =
@@ -565,18 +666,19 @@
 
 		//Write out to file.
 		fwrite(decoded, decoded_len, 1, out);
-		fflush(out);
 		free(decoded);
 	}
 
-	//Free remaining resources.
-	free(section_cper);
+	fflush(out);
 }
 
 //Converts a single ARM error information structure into CPER binary, outputting to the given stream.
 void ir_arm_error_info_to_cper(json_object *error_info, FILE *out)
 {
 	EFI_ARM_ERROR_INFORMATION_ENTRY error_info_cper;
+	memset(&error_info_cper, 0, sizeof(error_info_cper));
+	struct json_object *obj = NULL;
+	ValidationTypes ui16Type = { UINT_16T, .value.ui16 = 0 };
 
 	//Version, length.
 	error_info_cper.Version = json_object_get_int(
@@ -584,64 +686,88 @@
 	error_info_cper.Length = json_object_get_int(
 		json_object_object_get(error_info, "length"));
 
-	//Validation bits.
-	error_info_cper.ValidationBits = ir_to_bitfield(
-		json_object_object_get(error_info, "validationBits"), 5,
-		ARM_ERROR_INFO_ENTRY_VALID_BITFIELD_NAMES);
-
 	//Type, multiple error.
 	error_info_cper.Type = (UINT8)readable_pair_to_integer(
-		json_object_object_get(error_info, "type"));
-	error_info_cper.MultipleError = (UINT16)readable_pair_to_integer(
-		json_object_object_get(error_info, "multipleError"));
+		json_object_object_get(error_info, "errorType"));
+
+	if (json_object_object_get_ex(error_info, "multipleError", &obj)) {
+		error_info_cper.MultipleError =
+			(UINT16)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui16Type, 0);
+	} else {
+		error_info_cper.MultipleError = 0;
+	}
 
 	//Flags object.
-	error_info_cper.Flags = (UINT8)ir_to_bitfield(
-		json_object_object_get(error_info, "flags"), 4,
-		ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
+	if (json_object_object_get_ex(error_info, "flags", &obj)) {
+		error_info_cper.Flags = (UINT8)ir_to_bitfield(
+			obj, 4, ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
+		add_to_valid_bitfield(&ui16Type, 1);
+	} else {
+		error_info_cper.Flags = 0;
+	}
 
 	//Error information.
-	json_object *error_info_information =
-		json_object_object_get(error_info, "errorInformation");
-	json_object *error_info_prop = NULL;
+	if (json_object_object_get_ex(error_info, "errorInformation", &obj)) {
+		json_object *error_info_information = obj;
+		json_object *error_info_prop = NULL;
+		switch (error_info_cper.Type) {
+		case ARM_ERROR_INFORMATION_TYPE_CACHE:
+			error_info_cper.ErrorInformation.Value = 0;
+			error_info_prop = json_object_object_get(
+				error_info_information, "cacheError");
+			ir_arm_error_cache_tlb_info_to_cper(
+				error_info_prop,
+				&error_info_cper.ErrorInformation.CacheError);
+			break;
+		case ARM_ERROR_INFORMATION_TYPE_TLB:
+			error_info_cper.ErrorInformation.Value = 0;
+			error_info_prop = json_object_object_get(
+				error_info_information, "tlbError");
+			ir_arm_error_cache_tlb_info_to_cper(
+				error_info_prop,
+				&error_info_cper.ErrorInformation.CacheError);
+			break;
 
-	switch (error_info_cper.Type) {
-	case ARM_ERROR_INFORMATION_TYPE_CACHE:
-		error_info_prop = json_object_object_get(error_info_information,
-							 "cacheError");
-		ir_arm_error_cache_tlb_info_to_cper(
-			error_info_prop,
-			&error_info_cper.ErrorInformation.CacheError);
-		break;
-	case ARM_ERROR_INFORMATION_TYPE_TLB:
-		error_info_prop = json_object_object_get(error_info_information,
-							 "tlbError");
-		ir_arm_error_cache_tlb_info_to_cper(
-			error_info_prop,
-			&error_info_cper.ErrorInformation.CacheError);
-		break;
+		case ARM_ERROR_INFORMATION_TYPE_BUS:
+			error_info_cper.ErrorInformation.Value = 0;
+			error_info_prop = json_object_object_get(
+				error_info_information, "busError");
+			ir_arm_error_bus_info_to_cper(
+				error_info_prop,
+				&error_info_cper.ErrorInformation.BusError);
+			break;
 
-	case ARM_ERROR_INFORMATION_TYPE_BUS:
-		ir_arm_error_bus_info_to_cper(
-			error_info_information,
-			&error_info_cper.ErrorInformation.BusError);
-		break;
-
-	default:
-		//Unknown error information type.
-		break;
+		default:
+			//Unknown error information type.
+			break;
+		}
+		add_to_valid_bitfield(&ui16Type, 2);
 	}
 
 	//Virtual/physical fault address.
-	error_info_cper.VirtualFaultAddress = json_object_get_uint64(
-		json_object_object_get(error_info, "virtualFaultAddress"));
-	error_info_cper.PhysicalFaultAddress = json_object_get_uint64(
-		json_object_object_get(error_info, "physicalFaultAddress"));
+	if (json_object_object_get_ex(error_info, "virtualFaultAddress",
+				      &obj)) {
+		error_info_cper.VirtualFaultAddress =
+			json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui16Type, 3);
+	} else {
+		error_info_cper.VirtualFaultAddress = 0;
+	}
+
+	if (json_object_object_get_ex(error_info, "physicalFaultAddress",
+				      &obj)) {
+		error_info_cper.PhysicalFaultAddress =
+			json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui16Type, 4);
+	} else {
+		error_info_cper.PhysicalFaultAddress = 0;
+	}
+	error_info_cper.ValidationBits = ui16Type.value.ui16;
 
 	//Write out to stream.
 	fwrite(&error_info_cper, sizeof(EFI_ARM_ERROR_INFORMATION_ENTRY), 1,
 	       out);
-	fflush(out);
 }
 
 //Converts a single ARM cache/TLB error information structure into a CPER structure.
@@ -649,28 +775,46 @@
 	json_object *error_information,
 	EFI_ARM_CACHE_ERROR_STRUCTURE *error_info_cper)
 {
-	//Validation bits.
-	error_info_cper->ValidationBits = ir_to_bitfield(
-		json_object_object_get(error_information, "validationBits"), 7,
-		ARM_CACHE_TLB_ERROR_VALID_BITFIELD_NAMES);
+	// //Validation bits.
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Miscellaneous value fields.
-	error_info_cper->TransactionType = readable_pair_to_integer(
-		json_object_object_get(error_information, "transactionType"));
-	error_info_cper->Operation = readable_pair_to_integer(
-		json_object_object_get(error_information, "operation"));
-	error_info_cper->Level = json_object_get_uint64(
-		json_object_object_get(error_information, "level"));
-	error_info_cper->ProcessorContextCorrupt = json_object_get_boolean(
-		json_object_object_get(error_information,
-				       "processorContextCorrupt"));
-	error_info_cper->Corrected = json_object_get_boolean(
-		json_object_object_get(error_information, "corrected"));
-	error_info_cper->PrecisePC = json_object_get_boolean(
-		json_object_object_get(error_information, "precisePC"));
-	error_info_cper->RestartablePC = json_object_get_boolean(
-		json_object_object_get(error_information, "restartablePC"));
+	if (json_object_object_get_ex(error_information, "transactionType",
+				      &obj)) {
+		error_info_cper->TransactionType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(error_information, "operation", &obj)) {
+		error_info_cper->Operation = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(error_information, "level", &obj)) {
+		error_info_cper->Level = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(error_information,
+				      "processorContextCorrupt", &obj)) {
+		error_info_cper->ProcessorContextCorrupt =
+			json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(error_information, "corrected", &obj)) {
+		error_info_cper->Corrected = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(error_information, "precisePC", &obj)) {
+		error_info_cper->PrecisePC = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(error_information, "restartablePC",
+				      &obj)) {
+		error_info_cper->RestartablePC = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
 	error_info_cper->Reserved = 0;
+	error_info_cper->ValidationBits = ui64Type.value.ui64;
 }
 
 //Converts a single ARM bus error information structure into a CPER structure.
@@ -678,35 +822,96 @@
 				   EFI_ARM_BUS_ERROR_STRUCTURE *error_info_cper)
 {
 	//Validation bits.
-	error_info_cper->ValidationBits = ir_to_bitfield(
-		json_object_object_get(error_information, "validationBits"), 7,
-		ARM_BUS_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
+
+	memset(error_info_cper, 0, sizeof(EFI_ARM_BUS_ERROR_STRUCTURE));
 
 	//Miscellaneous value fields.
-	error_info_cper->TransactionType = readable_pair_to_integer(
-		json_object_object_get(error_information, "transactionType"));
-	error_info_cper->Operation = readable_pair_to_integer(
-		json_object_object_get(error_information, "operation"));
-	error_info_cper->Level = json_object_get_uint64(
-		json_object_object_get(error_information, "level"));
-	error_info_cper->ProcessorContextCorrupt = json_object_get_boolean(
-		json_object_object_get(error_information,
-				       "processorContextCorrupt"));
-	error_info_cper->Corrected = json_object_get_boolean(
-		json_object_object_get(error_information, "corrected"));
-	error_info_cper->PrecisePC = json_object_get_boolean(
-		json_object_object_get(error_information, "precisePC"));
-	error_info_cper->RestartablePC = json_object_get_boolean(
-		json_object_object_get(error_information, "restartablePC"));
-	error_info_cper->ParticipationType = readable_pair_to_integer(
-		json_object_object_get(error_information, "participationType"));
-	error_info_cper->AddressSpace = readable_pair_to_integer(
-		json_object_object_get(error_information, "addressSpace"));
-	error_info_cper->AccessMode = readable_pair_to_integer(
-		json_object_object_get(error_information, "accessMode"));
-	error_info_cper->MemoryAddressAttributes = json_object_get_uint64(
-		json_object_object_get(error_information, "memoryAttributes"));
+	if (json_object_object_get_ex(error_information, "transactionType",
+				      &obj)) {
+		error_info_cper->TransactionType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	} else {
+		error_info_cper->TransactionType = 0;
+	}
+	if (json_object_object_get_ex(error_information, "operation", &obj)) {
+		error_info_cper->Operation = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	} else {
+		error_info_cper->Operation = 0;
+	}
+	if (json_object_object_get_ex(error_information, "level", &obj)) {
+		error_info_cper->Level = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	} else {
+		error_info_cper->Level = 0;
+	}
+	if (json_object_object_get_ex(error_information,
+				      "processorContextCorrupt", &obj)) {
+		error_info_cper->ProcessorContextCorrupt =
+			json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	} else {
+		error_info_cper->ProcessorContextCorrupt = 0;
+	}
+	if (json_object_object_get_ex(error_information, "corrected", &obj)) {
+		error_info_cper->Corrected = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	} else {
+		error_info_cper->Corrected = 0;
+	}
+	if (json_object_object_get_ex(error_information, "precisePC", &obj)) {
+		error_info_cper->PrecisePC = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	} else {
+		error_info_cper->PrecisePC = 0;
+	}
+	if (json_object_object_get_ex(error_information, "restartablePC",
+				      &obj)) {
+		error_info_cper->RestartablePC = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	} else {
+		error_info_cper->RestartablePC = 0;
+	}
+	if (json_object_object_get_ex(error_information, "participationType",
+				      &obj)) {
+		error_info_cper->ParticipationType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	} else {
+		error_info_cper->ParticipationType = 0;
+	}
+	if (json_object_object_get_ex(error_information, "timedOut", &obj)) {
+		error_info_cper->TimeOut = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	} else {
+		error_info_cper->TimeOut = 0;
+	}
+	if (json_object_object_get_ex(error_information, "addressSpace",
+				      &obj)) {
+		error_info_cper->AddressSpace = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 9);
+	} else {
+		error_info_cper->AddressSpace = 0;
+	}
+	if (json_object_object_get_ex(error_information, "accessMode", &obj)) {
+		error_info_cper->AccessMode = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 11);
+	} else {
+		error_info_cper->AccessMode = 0;
+	}
+	if (json_object_object_get_ex(error_information, "memoryAttributes",
+				      &obj)) {
+		error_info_cper->MemoryAddressAttributes =
+			json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 10);
+	} else {
+		error_info_cper->MemoryAddressAttributes = 0;
+	}
 	error_info_cper->Reserved = 0;
+	error_info_cper->ValidationBits = ui64Type.value.ui64;
 }
 
 //Converts a single ARM context information structure into CPER binary, outputting to the given stream.
diff --git a/sections/cper-section-ccix-per.c b/sections/cper-section-ccix-per.c
index 9081fe2..6f85939 100644
--- a/sections/cper-section-ccix-per.c
+++ b/sections/cper-section-ccix-per.c
@@ -17,39 +17,46 @@
 {
 	EFI_CCIX_PER_LOG_DATA *ccix_error = (EFI_CCIX_PER_LOG_DATA *)section;
 	json_object *section_ir = json_object_new_object();
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = ccix_error->ValidBits };
 
 	//Length (bytes) for the entire structure.
 	json_object_object_add(section_ir, "length",
 			       json_object_new_uint64(ccix_error->Length));
 
-	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		ccix_error->ValidBits, 3, CCIX_PER_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
-
 	//CCIX source/port IDs.
-	json_object_object_add(section_ir, "ccixSourceID",
-			       json_object_new_int(ccix_error->CcixSourceId));
-	json_object_object_add(section_ir, "ccixPortID",
-			       json_object_new_int(ccix_error->CcixPortId));
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object_object_add(
+			section_ir, "ccixSourceID",
+			json_object_new_int(ccix_error->CcixSourceId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(
+			section_ir, "ccixPortID",
+			json_object_new_int(ccix_error->CcixPortId));
+	}
 
 	//CCIX PER Log.
-	//This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
-	const char *cur_pos = (const char *)(ccix_error + 1);
-	int remaining_length =
-		ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
-	if (remaining_length > 0) {
-		int32_t encoded_len = 0;
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		//This is formatted as described in Section 7.3.2 of CCIX Base Specification (Rev 1.0).
+		const char *cur_pos = (const char *)(ccix_error + 1);
+		int remaining_length =
+			ccix_error->Length - sizeof(EFI_CCIX_PER_LOG_DATA);
+		if (remaining_length > 0) {
+			int32_t encoded_len = 0;
 
-		char *encoded = base64_encode((UINT8 *)cur_pos,
-					      remaining_length, &encoded_len);
-		if (encoded == NULL) {
-			printf("Failed to allocate encode output buffer. \n");
-		} else {
-			json_object_object_add(section_ir, "ccixPERLog",
-					       json_object_new_string_len(
-						       encoded, encoded_len));
-			free(encoded);
+			char *encoded = base64_encode((UINT8 *)cur_pos,
+						      remaining_length,
+						      &encoded_len);
+			if (encoded == NULL) {
+				printf("Failed to allocate encode output buffer. \n");
+			} else {
+				json_object_object_add(
+					section_ir, "ccixPERLog",
+					json_object_new_string_len(
+						encoded, encoded_len));
+				free(encoded);
+			}
 		}
 	}
 
@@ -62,6 +69,9 @@
 	EFI_CCIX_PER_LOG_DATA *section_cper = (EFI_CCIX_PER_LOG_DATA *)calloc(
 		1, sizeof(EFI_CCIX_PER_LOG_DATA));
 
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
+
 	//Length.
 	section_cper->Length = json_object_get_uint64(
 		json_object_object_get(section, "length"));
@@ -72,28 +82,41 @@
 		CCIX_PER_ERROR_VALID_BITFIELD_NAMES);
 
 	//CCIX source/port IDs.
-	section_cper->CcixSourceId = (UINT8)json_object_get_int(
-		json_object_object_get(section, "ccixSourceID"));
-	section_cper->CcixPortId = (UINT8)json_object_get_int(
-		json_object_object_get(section, "ccixPortID"));
+	if (json_object_object_get_ex(section, "ccixSourceID", &obj)) {
+		section_cper->CcixSourceId = (UINT8)json_object_get_int(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(section, "ccixPortID", &obj)) {
+		section_cper->CcixPortId = (UINT8)json_object_get_int(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+
+	bool perlog_exists = false;
+	if (json_object_object_get_ex(section, "ccixPERLog", &obj)) {
+		perlog_exists = true;
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	section_cper->ValidBits = ui64Type.value.ui64;
 
 	//Write header out to stream.
 	fwrite(section_cper, sizeof(EFI_CCIX_PER_LOG_DATA), 1, out);
 	fflush(out);
 
 	//Write CCIX PER log itself to stream.
-	json_object *encoded = json_object_object_get(section, "ccixPERLog");
-	int32_t decoded_len = 0;
+	if (perlog_exists) {
+		json_object *encoded = obj;
+		int32_t decoded_len = 0;
 
-	UINT8 *decoded = base64_decode(json_object_get_string(encoded),
-				       json_object_get_string_len(encoded),
-				       &decoded_len);
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		fwrite(decoded, decoded_len, 1, out);
-		fflush(out);
-		free(decoded);
+		UINT8 *decoded = base64_decode(
+			json_object_get_string(encoded),
+			json_object_get_string_len(encoded), &decoded_len);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			fwrite(decoded, decoded_len, 1, out);
+			fflush(out);
+			free(decoded);
+		}
 	}
 	//Free resources.
 	free(section_cper);
diff --git a/sections/cper-section-cxl-component.c b/sections/cper-section-cxl-component.c
index a5c6846..f915b28 100644
--- a/sections/cper-section-cxl-component.c
+++ b/sections/cper-section-cxl-component.c
@@ -23,62 +23,68 @@
 			       json_object_new_uint64(cxl_error->Length));
 
 	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(cxl_error->ValidBits, 3,
-			       CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = cxl_error->ValidBits };
 
 	//Device ID.
-	json_object *device_id = json_object_new_object();
-	json_object_object_add(
-		device_id, "vendorID",
-		json_object_new_int(cxl_error->DeviceId.VendorId));
-	json_object_object_add(
-		device_id, "deviceID",
-		json_object_new_int(cxl_error->DeviceId.DeviceId));
-	json_object_object_add(
-		device_id, "functionNumber",
-		json_object_new_int(cxl_error->DeviceId.FunctionNumber));
-	json_object_object_add(
-		device_id, "deviceNumber",
-		json_object_new_int(cxl_error->DeviceId.DeviceNumber));
-	json_object_object_add(
-		device_id, "busNumber",
-		json_object_new_int(cxl_error->DeviceId.BusNumber));
-	json_object_object_add(
-		device_id, "segmentNumber",
-		json_object_new_int(cxl_error->DeviceId.SegmentNumber));
-	json_object_object_add(
-		device_id, "slotNumber",
-		json_object_new_int(cxl_error->DeviceId.SlotNumber));
-	json_object_object_add(section_ir, "deviceID", device_id);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *device_id = json_object_new_object();
+		json_object_object_add(
+			device_id, "vendorID",
+			json_object_new_int(cxl_error->DeviceId.VendorId));
+		json_object_object_add(
+			device_id, "deviceID",
+			json_object_new_int(cxl_error->DeviceId.DeviceId));
+		json_object_object_add(
+			device_id, "functionNumber",
+			json_object_new_int(
+				cxl_error->DeviceId.FunctionNumber));
+		json_object_object_add(
+			device_id, "deviceNumber",
+			json_object_new_int(cxl_error->DeviceId.DeviceNumber));
+		json_object_object_add(
+			device_id, "busNumber",
+			json_object_new_int(cxl_error->DeviceId.BusNumber));
+		json_object_object_add(
+			device_id, "segmentNumber",
+			json_object_new_int(cxl_error->DeviceId.SegmentNumber));
+		json_object_object_add(
+			device_id, "slotNumber",
+			json_object_new_int(cxl_error->DeviceId.SlotNumber));
+		json_object_object_add(section_ir, "deviceID", device_id);
+	}
 
 	//Device serial.
-	json_object_object_add(section_ir, "deviceSerial",
-			       json_object_new_uint64(cxl_error->DeviceSerial));
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(
+			section_ir, "deviceSerial",
+			json_object_new_uint64(cxl_error->DeviceSerial));
+	}
 
 	//The specification for this is defined within the CXL Specification Section 8.2.9.1.
-	const char *cur_pos = (const char *)(cxl_error + 1);
-	int remaining_len =
-		cxl_error->Length - sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
-	if (remaining_len > 0) {
-		json_object *event_log = json_object_new_object();
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		const char *cur_pos = (const char *)(cxl_error + 1);
+		int remaining_len = cxl_error->Length -
+				    sizeof(EFI_CXL_COMPONENT_EVENT_HEADER);
+		if (remaining_len > 0) {
+			json_object *event_log = json_object_new_object();
 
-		int32_t encoded_len = 0;
+			int32_t encoded_len = 0;
 
-		char *encoded = base64_encode((UINT8 *)cur_pos, remaining_len,
-					      &encoded_len);
-		if (encoded == NULL) {
-			printf("Failed to allocate encode output buffer. \n");
-			return NULL;
+			char *encoded = base64_encode(
+				(UINT8 *)cur_pos, remaining_len, &encoded_len);
+			if (encoded == NULL) {
+				printf("Failed to allocate encode output buffer. \n");
+				return NULL;
+			}
+			json_object_object_add(event_log, "data",
+					       json_object_new_string_len(
+						       encoded, encoded_len));
+
+			free(encoded);
+			json_object_object_add(
+				section_ir, "cxlComponentEventLog", event_log);
 		}
-		json_object_object_add(event_log, "data",
-				       json_object_new_string_len(encoded,
-								  encoded_len));
-
-		free(encoded);
-		json_object_object_add(section_ir, "cxlComponentEventLog",
-				       event_log);
 	}
 
 	return section_ir;
@@ -97,52 +103,64 @@
 		json_object_object_get(section, "length"));
 
 	//Validation bits.
-	section_cper->ValidBits = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 3,
-		CXL_COMPONENT_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Device ID information.
-	json_object *device_id = json_object_object_get(section, "deviceID");
-	section_cper->DeviceId.VendorId = json_object_get_uint64(
-		json_object_object_get(device_id, "vendorID"));
-	section_cper->DeviceId.DeviceId = json_object_get_uint64(
-		json_object_object_get(device_id, "deviceID"));
-	section_cper->DeviceId.FunctionNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "functionNumber"));
-	section_cper->DeviceId.DeviceNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "deviceNumber"));
-	section_cper->DeviceId.BusNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "busNumber"));
-	section_cper->DeviceId.SegmentNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "segmentNumber"));
-	section_cper->DeviceId.SlotNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "slotNumber"));
+	if (json_object_object_get_ex(section, "deviceID", &obj)) {
+		json_object *device_id = obj;
+		section_cper->DeviceId.VendorId = json_object_get_uint64(
+			json_object_object_get(device_id, "vendorID"));
+		section_cper->DeviceId.DeviceId = json_object_get_uint64(
+			json_object_object_get(device_id, "deviceID"));
+		section_cper->DeviceId.FunctionNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "functionNumber"));
+		section_cper->DeviceId.DeviceNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "deviceNumber"));
+		section_cper->DeviceId.BusNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "busNumber"));
+		section_cper->DeviceId.SegmentNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "segmentNumber"));
+		section_cper->DeviceId.SlotNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "slotNumber"));
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Device serial number.
-	section_cper->DeviceSerial = json_object_get_uint64(
-		json_object_object_get(section, "deviceSerial"));
+	if (json_object_object_get_ex(section, "deviceSerial", &obj)) {
+		section_cper->DeviceSerial = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+
+	//CXL component event log, decoded from base64.
+	json_object *event_log = NULL;
+	if (json_object_object_get_ex(section, "cxlComponentEventLog", &obj)) {
+		event_log = obj;
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	section_cper->ValidBits = ui64Type.value.ui64;
 
 	//Write header out to stream.
 	fwrite(section_cper, sizeof(EFI_CXL_COMPONENT_EVENT_HEADER), 1, out);
 	fflush(out);
 
-	//CXL component event log, decoded from base64.
-	json_object *event_log =
-		json_object_object_get(section, "cxlComponentEventLog");
-	json_object *encoded = json_object_object_get(event_log, "data");
+	if (event_log != NULL) {
+		json_object *encoded =
+			json_object_object_get(event_log, "data");
 
-	int32_t decoded_len = 0;
+		int32_t decoded_len = 0;
 
-	UINT8 *decoded = base64_decode(json_object_get_string(encoded),
-				       json_object_get_string_len(encoded),
-				       &decoded_len);
+		UINT8 *decoded = base64_decode(
+			json_object_get_string(encoded),
+			json_object_get_string_len(encoded), &decoded_len);
 
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		fwrite(decoded, decoded_len, 1, out);
-		fflush(out);
-		free(decoded);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			fwrite(decoded, decoded_len, 1, out);
+			fflush(out);
+			free(decoded);
+		}
 	}
 
 	free(section_cper);
diff --git a/sections/cper-section-cxl-protocol.c b/sections/cper-section-cxl-protocol.c
index 141f26b..151943f 100644
--- a/sections/cper-section-cxl-protocol.c
+++ b/sections/cper-section-cxl-protocol.c
@@ -17,19 +17,19 @@
 	EFI_CXL_PROTOCOL_ERROR_DATA *cxl_protocol_error =
 		(EFI_CXL_PROTOCOL_ERROR_DATA *)section;
 	json_object *section_ir = json_object_new_object();
-
-	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(cxl_protocol_error->ValidBits, 7,
-			       CXL_PROTOCOL_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = {
+		UINT_64T, .value.ui64 = cxl_protocol_error->ValidBits
+	};
 
 	//Type of detecting agent.
-	json_object *agent_type = integer_to_readable_pair(
-		cxl_protocol_error->CxlAgentType, 2,
-		CXL_PROTOCOL_ERROR_AGENT_TYPES_KEYS,
-		CXL_PROTOCOL_ERROR_AGENT_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(section_ir, "agentType", agent_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *agent_type = integer_to_readable_pair(
+			cxl_protocol_error->CxlAgentType, 2,
+			CXL_PROTOCOL_ERROR_AGENT_TYPES_KEYS,
+			CXL_PROTOCOL_ERROR_AGENT_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(section_ir, "agentType", agent_type);
+	}
 
 	//CXL agent address, depending on the agent type.
 	json_object *agent_address = json_object_new_object();
@@ -65,48 +65,62 @@
 				cxl_protocol_error->CxlAgentAddress
 					.PortRcrbBaseAddress));
 	}
-	json_object_object_add(section_ir, "cxlAgentAddress", agent_address);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(section_ir, "cxlAgentAddress",
+				       agent_address);
+	} else {
+		json_object_put(agent_address);
+	}
 
-	//Device ID.
 	json_object *device_id = json_object_new_object();
 	json_object_object_add(
 		device_id, "vendorID",
 		json_object_new_uint64(cxl_protocol_error->DeviceId.VendorId));
-	json_object_object_add(
-		device_id, "deviceID",
-		json_object_new_uint64(cxl_protocol_error->DeviceId.DeviceId));
-	json_object_object_add(
-		device_id, "subsystemVendorID",
-		json_object_new_uint64(
-			cxl_protocol_error->DeviceId.SubsystemVendorId));
-	json_object_object_add(
-		device_id, "subsystemDeviceID",
-		json_object_new_uint64(
-			cxl_protocol_error->DeviceId.SubsystemDeviceId));
-	json_object_object_add(
-		device_id, "classCode",
-		json_object_new_uint64(cxl_protocol_error->DeviceId.ClassCode));
-	json_object_object_add(
-		device_id, "slotNumber",
-		json_object_new_uint64(
-			cxl_protocol_error->DeviceId.SlotNumber));
-	json_object_object_add(section_ir, "deviceID", device_id);
+
+	//Device ID.
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			device_id, "deviceID",
+			json_object_new_uint64(
+				cxl_protocol_error->DeviceId.DeviceId));
+		json_object_object_add(
+			device_id, "subsystemVendorID",
+			json_object_new_uint64(
+				cxl_protocol_error->DeviceId.SubsystemVendorId));
+		json_object_object_add(
+			device_id, "subsystemDeviceID",
+			json_object_new_uint64(
+				cxl_protocol_error->DeviceId.SubsystemDeviceId));
+		json_object_object_add(
+			device_id, "classCode",
+			json_object_new_uint64(
+				cxl_protocol_error->DeviceId.ClassCode));
+		json_object_object_add(
+			device_id, "slotNumber",
+			json_object_new_uint64(
+				cxl_protocol_error->DeviceId.SlotNumber));
+		json_object_object_add(section_ir, "deviceID", device_id);
+	}
 
 	char *encoded;
-	//Device serial & capability structure (if CXL 1.1 device).
-	if (cxl_protocol_error->CxlAgentType ==
-	    CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
-		json_object_object_add(
-			section_ir, "deviceSerial",
-			json_object_new_uint64(
-				cxl_protocol_error->DeviceSerial));
 
-		//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
-		//(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). There does not seem
-		//to be a way to differentiate these, so this is left as a b64 dump.
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		//Device serial & capability structure (if CXL 1.1 device).
+		if (cxl_protocol_error->CxlAgentType ==
+		    CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
+			json_object_object_add(
+				section_ir, "deviceSerial",
+				json_object_new_uint64(
+					cxl_protocol_error->DeviceSerial));
+		}
+	}
 
-		int32_t encoded_len = 0;
+	int32_t encoded_len = 0;
 
+	//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
+	//(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). There does not seem
+	//to be a way to differentiate these, so this is left as a b64 dump.
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
 		encoded = base64_encode(
 			(UINT8 *)cxl_protocol_error->CapabilityStructure.PcieCap,
 			60, &encoded_len);
@@ -120,50 +134,57 @@
 		free(encoded);
 	}
 
-	//CXL DVSEC & error log length.
-	json_object_object_add(
-		section_ir, "dvsecLength",
-		json_object_new_int(cxl_protocol_error->CxlDvsecLength));
-	json_object_object_add(
-		section_ir, "errorLogLength",
-		json_object_new_int(cxl_protocol_error->CxlErrorLogLength));
-
-	//CXL DVSEC
-	//For CXL 1.1 devices, this is the "CXL DVSEC For Flex Bus Device" structure as in CXL 1.1 spec.
-	//For CXL 1.1 host downstream ports, this is the "CXL DVSEC For Flex Bus Port" structure as in CXL 1.1 spec.
 	const char *cur_pos = (const char *)(cxl_protocol_error + 1);
-	int32_t encoded_len = 0;
 
-	encoded = base64_encode((UINT8 *)cur_pos,
-				cxl_protocol_error->CxlDvsecLength,
-				&encoded_len);
-	if (encoded == NULL) {
-		return NULL;
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		//CXL DVSEC & error log length.
+		json_object_object_add(
+			section_ir, "dvsecLength",
+			json_object_new_int(
+				cxl_protocol_error->CxlDvsecLength));
+		//CXL DVSEC
+		//For CXL 1.1 devices, this is the "CXL DVSEC For Flex Bus Device" structure as in CXL 1.1 spec.
+		//For CXL 1.1 host downstream ports, this is the "CXL DVSEC For Flex Bus Port" structure as in CXL 1.1 spec.
+		int32_t encoded_len = 0;
+
+		encoded = base64_encode((UINT8 *)cur_pos,
+					cxl_protocol_error->CxlDvsecLength,
+					&encoded_len);
+		if (encoded == NULL) {
+			return NULL;
+		}
+		json_object_object_add(section_ir, "cxlDVSEC",
+				       json_object_new_string_len(encoded,
+								  encoded_len));
+
+		free(encoded);
 	}
-	json_object_object_add(section_ir, "cxlDVSEC",
-			       json_object_new_string_len(encoded,
-							  encoded_len));
-
-	free(encoded);
 
 	cur_pos += cxl_protocol_error->CxlDvsecLength;
 
-	//CXL Error Log
-	//This is the "CXL RAS Capability Structure" as in CXL 1.1 spec.
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(
+			section_ir, "errorLogLength",
+			json_object_new_int(
+				cxl_protocol_error->CxlErrorLogLength));
 
-	encoded_len = 0;
-	encoded = base64_encode((UINT8 *)cur_pos,
-				cxl_protocol_error->CxlErrorLogLength,
-				&encoded_len);
+		//CXL Error Log
+		//This is the "CXL RAS Capability Structure" as in CXL 1.1 spec.
 
-	if (encoded == NULL) {
-		printf("Failed to allocate encode output buffer. \n");
-		return NULL;
+		encoded_len = 0;
+		encoded = base64_encode((UINT8 *)cur_pos,
+					cxl_protocol_error->CxlErrorLogLength,
+					&encoded_len);
+
+		if (encoded == NULL) {
+			printf("Failed to allocate encode output buffer. \n");
+			return NULL;
+		}
+		json_object_object_add(section_ir, "cxlErrorLog",
+				       json_object_new_string_len(encoded,
+								  encoded_len));
+		free(encoded);
 	}
-	json_object_object_add(section_ir, "cxlErrorLog",
-			       json_object_new_string_len(encoded,
-							  encoded_len));
-	free(encoded);
 
 	return section_ir;
 }
@@ -174,80 +195,99 @@
 	EFI_CXL_PROTOCOL_ERROR_DATA *section_cper =
 		(EFI_CXL_PROTOCOL_ERROR_DATA *)calloc(
 			1, sizeof(EFI_CXL_PROTOCOL_ERROR_DATA));
+	struct json_object *obj = NULL;
 
 	//Validation bits.
-	section_cper->ValidBits = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 7,
-		CXL_PROTOCOL_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
 
 	//Detecting agent type.
-	section_cper->CxlAgentType = readable_pair_to_integer(
-		json_object_object_get(section, "agentType"));
+	if (json_object_object_get_ex(section, "agentType", &obj)) {
+		section_cper->CxlAgentType = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Based on the agent type, set the address.
-	json_object *address =
-		json_object_object_get(section, "cxlAgentAddress");
-	if (section_cper->CxlAgentType == CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
-		//Address is split by function, device, bus & segment.
-		UINT64 function = json_object_get_uint64(
-			json_object_object_get(address, "functionNumber"));
-		UINT64 device = json_object_get_uint64(
-			json_object_object_get(address, "deviceNumber"));
-		UINT64 bus = json_object_get_uint64(
-			json_object_object_get(address, "busNumber"));
-		UINT64 segment = json_object_get_uint64(
-			json_object_object_get(address, "segmentNumber"));
-		section_cper->CxlAgentAddress.DeviceAddress.FunctionNumber =
-			function;
-		section_cper->CxlAgentAddress.DeviceAddress.DeviceNumber =
-			device;
-		section_cper->CxlAgentAddress.DeviceAddress.BusNumber = bus;
-		section_cper->CxlAgentAddress.DeviceAddress.SegmentNumber =
-			segment;
-	} else if (section_cper->CxlAgentType ==
-		   CXL_PROTOCOL_ERROR_HOST_DOWNSTREAM_PORT_AGENT) {
-		//Plain RCRB base address.
-		section_cper->CxlAgentAddress.PortRcrbBaseAddress =
-			json_object_get_uint64(
-				json_object_object_get(address, "value"));
+	if (json_object_object_get_ex(section, "cxlAgentAddress", &obj)) {
+		json_object *address = obj;
+		if (section_cper->CxlAgentType ==
+		    CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
+			//Address is split by function, device, bus & segment.
+			UINT64 function = json_object_get_uint64(
+				json_object_object_get(address,
+						       "functionNumber"));
+			UINT64 device = json_object_get_uint64(
+				json_object_object_get(address,
+						       "deviceNumber"));
+			UINT64 bus = json_object_get_uint64(
+				json_object_object_get(address, "busNumber"));
+			UINT64 segment = json_object_get_uint64(
+				json_object_object_get(address,
+						       "segmentNumber"));
+			section_cper->CxlAgentAddress.DeviceAddress
+				.FunctionNumber = function;
+			section_cper->CxlAgentAddress.DeviceAddress
+				.DeviceNumber = device;
+			section_cper->CxlAgentAddress.DeviceAddress.BusNumber =
+				bus;
+			section_cper->CxlAgentAddress.DeviceAddress
+				.SegmentNumber = segment;
+		} else if (section_cper->CxlAgentType ==
+			   CXL_PROTOCOL_ERROR_HOST_DOWNSTREAM_PORT_AGENT) {
+			//Plain RCRB base address.
+			section_cper->CxlAgentAddress.PortRcrbBaseAddress =
+				json_object_get_uint64(json_object_object_get(
+					address, "value"));
+		}
+		add_to_valid_bitfield(&ui64Type, 1);
 	}
 
 	//Device ID information.
-	json_object *device_id = json_object_object_get(section, "deviceID");
-	section_cper->DeviceId.VendorId = json_object_get_uint64(
-		json_object_object_get(device_id, "vendorID"));
-	section_cper->DeviceId.DeviceId = json_object_get_uint64(
-		json_object_object_get(device_id, "deviceID"));
-	section_cper->DeviceId.SubsystemVendorId = json_object_get_uint64(
-		json_object_object_get(device_id, "subsystemVendorID"));
-	section_cper->DeviceId.SubsystemDeviceId = json_object_get_uint64(
-		json_object_object_get(device_id, "subsystemDeviceID"));
-	section_cper->DeviceId.ClassCode = json_object_get_uint64(
-		json_object_object_get(device_id, "classCode"));
-	section_cper->DeviceId.SlotNumber = json_object_get_uint64(
-		json_object_object_get(device_id, "slotNumber"));
+	if (json_object_object_get_ex(section, "deviceID", &obj)) {
+		json_object *device_id = obj;
+		section_cper->DeviceId.VendorId = json_object_get_uint64(
+			json_object_object_get(device_id, "vendorID"));
+		section_cper->DeviceId.DeviceId = json_object_get_uint64(
+			json_object_object_get(device_id, "deviceID"));
+		section_cper->DeviceId.SubsystemVendorId =
+			json_object_get_uint64(json_object_object_get(
+				device_id, "subsystemVendorID"));
+		section_cper->DeviceId.SubsystemDeviceId =
+			json_object_get_uint64(json_object_object_get(
+				device_id, "subsystemDeviceID"));
+		section_cper->DeviceId.ClassCode = json_object_get_uint64(
+			json_object_object_get(device_id, "classCode"));
+		section_cper->DeviceId.SlotNumber = json_object_get_uint64(
+			json_object_object_get(device_id, "slotNumber"));
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
 
 	//If CXL 1.1 device, the serial number & PCI capability structure.
 	UINT8 *decoded;
 	if (section_cper->CxlAgentType == CXL_PROTOCOL_ERROR_DEVICE_AGENT) {
-		section_cper->DeviceSerial = json_object_get_uint64(
-			json_object_object_get(section, "deviceSerial"));
+		if (json_object_object_get_ex(section, "deviceSerial", &obj)) {
+			section_cper->DeviceSerial =
+				json_object_get_uint64(obj);
+			add_to_valid_bitfield(&ui64Type, 3);
+		}
+		if (json_object_object_get_ex(section, "capabilityStructure",
+					      &obj)) {
+			json_object *encoded = obj;
 
-		json_object *encoded =
-			json_object_object_get(section, "capabilityStructure");
+			int32_t decoded_len = 0;
 
-		int32_t decoded_len = 0;
+			decoded = base64_decode(
+				json_object_get_string(encoded),
+				json_object_get_string_len(encoded),
+				&decoded_len);
 
-		decoded = base64_decode(json_object_get_string(encoded),
-					json_object_get_string_len(encoded),
-					&decoded_len);
-
-		if (decoded == NULL) {
-			printf("Failed to allocate decode output buffer. \n");
-		} else {
-			memcpy(section_cper->CapabilityStructure.PcieCap,
-			       decoded, decoded_len);
-			free(decoded);
+			if (decoded == NULL) {
+				printf("Failed to allocate decode output buffer. \n");
+			} else {
+				memcpy(section_cper->CapabilityStructure.PcieCap,
+				       decoded, decoded_len);
+				free(decoded);
+				add_to_valid_bitfield(&ui64Type, 4);
+			}
 		}
 	}
 
@@ -257,39 +297,54 @@
 	section_cper->CxlErrorLogLength = (UINT16)json_object_get_int(
 		json_object_object_get(section, "errorLogLength"));
 
+	json_object *encodedsrc = NULL;
+	json_object *encodederr = NULL;
+
+	//DVSEC out: write valid bits
+	if (json_object_object_get_ex(section, "cxlDVSEC", &obj)) {
+		add_to_valid_bitfield(&ui64Type, 5);
+		encodedsrc = obj;
+	}
+
+	//Error log: write valid bits
+	if (json_object_object_get_ex(section, "cxlErrorLog", &obj)) {
+		add_to_valid_bitfield(&ui64Type, 6);
+		encodederr = obj;
+	}
+	section_cper->ValidBits = ui64Type.value.ui64;
+
 	//Write header to stream.
 	fwrite(section_cper, sizeof(EFI_CXL_PROTOCOL_ERROR_DATA), 1, out);
 	fflush(out);
 
 	//DVSEC out to stream.
-	json_object *encoded = json_object_object_get(section, "cxlDVSEC");
-
 	int32_t decoded_len = 0;
-
-	decoded = base64_decode(json_object_get_string(encoded),
-				json_object_get_string_len(encoded),
-				&decoded_len);
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		fwrite(decoded, decoded_len, 1, out);
-		fflush(out);
-		free(decoded);
+	if (encodedsrc != NULL) {
+		decoded = base64_decode(json_object_get_string(encodedsrc),
+					json_object_get_string_len(encodedsrc),
+					&decoded_len);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			fwrite(decoded, decoded_len, 1, out);
+			fflush(out);
+			free(decoded);
+		}
 	}
 
 	//Error log out to stream.
-	encoded = json_object_object_get(section, "cxlErrorLog");
 	decoded_len = 0;
-
-	decoded = base64_decode(json_object_get_string(encoded),
-				json_object_get_string_len(encoded),
-				&decoded_len);
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		fwrite(decoded, decoded_len, 1, out);
-		fflush(out);
-		free(decoded);
+	if (encodederr != NULL) {
+		decoded = base64_decode(json_object_get_string(encodederr),
+					json_object_get_string_len(encodederr),
+					&decoded_len);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			fwrite(decoded, decoded_len, 1, out);
+			fflush(out);
+			free(decoded);
+		}
 	}
 
 	free(section_cper);
diff --git a/sections/cper-section-generic.c b/sections/cper-section-generic.c
index ebbd628..36a5d89 100644
--- a/sections/cper-section-generic.c
+++ b/sections/cper-section-generic.c
@@ -19,78 +19,112 @@
 		(EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
 	json_object *section_ir = json_object_new_object();
 
-	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(section_generic->ValidFields, 13,
-			       GENERIC_VALIDATION_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = {
+		UINT_64T, .value.ui64 = section_generic->ValidFields
+	};
 
-	//Processor type, with human readable name if possible.
-	json_object *processor_type = integer_to_readable_pair(
-		section_generic->Type,
-		sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
-		GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(section_ir, "processorType", processor_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		//Processor type, with human readable name if possible.
+		json_object *processor_type = integer_to_readable_pair(
+			section_generic->Type,
+			sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
+			GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(section_ir, "processorType",
+				       processor_type);
+	}
 
-	//Processor ISA, with human readable name if possible.
-	json_object *processor_isa = integer_to_readable_pair(
-		section_generic->Isa,
-		sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
-		GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(section_ir, "processorISA", processor_isa);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		//Processor ISA, with human readable name if possible.
+		json_object *processor_isa = integer_to_readable_pair(
+			section_generic->Isa,
+			sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
+			GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(section_ir, "processorISA",
+				       processor_isa);
+	}
 
-	//Processor error type, with human readable name if possible.
-	json_object *processor_error_type = integer_to_readable_pair(
-		section_generic->ErrorType,
-		sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
-		GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(section_ir, "errorType", processor_error_type);
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		//Processor error type, with human readable name if possible.
+		json_object *processor_error_type = integer_to_readable_pair(
+			section_generic->ErrorType,
+			sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
+			GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(section_ir, "errorType",
+				       processor_error_type);
+	}
 
-	//The operation performed, with a human readable name if possible.
-	json_object *operation = integer_to_readable_pair(
-		section_generic->Operation,
-		sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
-		GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(section_ir, "operation", operation);
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		//The operation performed, with a human readable name if possible.
+		json_object *operation = integer_to_readable_pair(
+			section_generic->Operation,
+			sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
+			GENERIC_OPERATION_TYPES_KEYS,
+			GENERIC_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
+		json_object_object_add(section_ir, "operation", operation);
+	}
 
-	//Flags, additional information about the error.
-	json_object *flags = bitfield_to_ir(section_generic->Flags, 4,
-					    GENERIC_FLAGS_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "flags", flags);
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		//Flags, additional information about the error.
+		json_object *flags =
+			bitfield_to_ir(section_generic->Flags, 4,
+				       GENERIC_FLAGS_BITFIELD_NAMES);
+		json_object_object_add(section_ir, "flags", flags);
+	}
 
-	//The level of the error.
-	json_object_object_add(section_ir, "level",
-			       json_object_new_int(section_generic->Level));
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		//The level of the error.
+		json_object_object_add(
+			section_ir, "level",
+			json_object_new_int(section_generic->Level));
+	}
 
-	//CPU version information.
-	json_object_object_add(
-		section_ir, "cpuVersionInfo",
-		json_object_new_uint64(section_generic->VersionInfo));
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		//CPU version information.
+		json_object_object_add(
+			section_ir, "cpuVersionInfo",
+			json_object_new_uint64(section_generic->VersionInfo));
+	}
 
-	//CPU brand string. May not exist if on ARM.
-	json_object_object_add(
-		section_ir, "cpuBrandString",
-		json_object_new_string(section_generic->BrandString));
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		//CPU brand string. May not exist if on ARM.
+		json_object_object_add(
+			section_ir, "cpuBrandString",
+			json_object_new_string(section_generic->BrandString));
+	}
 
-	//Remaining 64-bit fields.
-	json_object_object_add(section_ir, "processorID",
-			       json_object_new_uint64(section_generic->ApicId));
-	json_object_object_add(
-		section_ir, "targetAddress",
-		json_object_new_uint64(section_generic->TargetAddr));
-	json_object_object_add(
-		section_ir, "requestorID",
-		json_object_new_uint64(section_generic->RequestorId));
-	json_object_object_add(
-		section_ir, "responderID",
-		json_object_new_uint64(section_generic->ResponderId));
-	json_object_object_add(
-		section_ir, "instructionIP",
-		json_object_new_uint64(section_generic->InstructionIP));
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		//Remaining 64-bit fields.
+		json_object_object_add(
+			section_ir, "processorID",
+			json_object_new_uint64(section_generic->ApicId));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 9)) {
+		json_object_object_add(
+			section_ir, "targetAddress",
+			json_object_new_uint64(section_generic->TargetAddr));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 10)) {
+		json_object_object_add(
+			section_ir, "requestorID",
+			json_object_new_uint64(section_generic->RequestorId));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 11)) {
+		json_object_object_add(
+			section_ir, "responderID",
+			json_object_new_uint64(section_generic->ResponderId));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 12)) {
+		json_object_object_add(
+			section_ir, "instructionIP",
+			json_object_new_uint64(section_generic->InstructionIP));
+	}
 
 	return section_ir;
 }
@@ -104,51 +138,79 @@
 			1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 13,
-		GENERIC_VALIDATION_BITFIELD_NAMES);
-
+	//Remove
+	// section_cper->ValidFields = ir_to_bitfield(
+	// 	json_object_object_get(section, "validationBits"), 13,
+	// 	GENERIC_VALIDATION_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 	//Various name/value pair fields.
-	section_cper->Type = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "processorType"));
-	section_cper->Isa = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "processorISA"));
-	section_cper->ErrorType = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "errorType"));
-	section_cper->Operation = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "operation"));
-
+	if (json_object_object_get_ex(section, "processorType", &obj)) {
+		section_cper->Type = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(section, "processorISA", &obj)) {
+		section_cper->Isa = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(section, "errorType", &obj)) {
+		section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(section, "operation", &obj)) {
+		section_cper->Operation = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
 	//Flags.
-	section_cper->Flags =
-		(UINT8)ir_to_bitfield(json_object_object_get(section, "flags"),
-				      4, GENERIC_FLAGS_BITFIELD_NAMES);
+	if (json_object_object_get_ex(section, "flags", &obj)) {
+		section_cper->Flags = (UINT8)ir_to_bitfield(
+			obj, 4, GENERIC_FLAGS_BITFIELD_NAMES);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
 
 	//Various numeric/string fields.
-	section_cper->Level = (UINT8)json_object_get_int(
-		json_object_object_get(section, "level"));
-	section_cper->VersionInfo = json_object_get_uint64(
-		json_object_object_get(section, "cpuVersionInfo"));
-	section_cper->ApicId = json_object_get_uint64(
-		json_object_object_get(section, "processorID"));
-	section_cper->TargetAddr = json_object_get_uint64(
-		json_object_object_get(section, "targetAddress"));
-	section_cper->RequestorId = json_object_get_uint64(
-		json_object_object_get(section, "requestorID"));
-	section_cper->ResponderId = json_object_get_uint64(
-		json_object_object_get(section, "responderID"));
-	section_cper->InstructionIP = json_object_get_uint64(
-		json_object_object_get(section, "instructionIP"));
+	if (json_object_object_get_ex(section, "level", &obj)) {
+		section_cper->Level = (UINT8)json_object_get_int(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(section, "cpuVersionInfo", &obj)) {
+		section_cper->VersionInfo = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
+	if (json_object_object_get_ex(section, "processorID", &obj)) {
+		section_cper->ApicId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	}
+	if (json_object_object_get_ex(section, "targetAddress", &obj)) {
+		section_cper->TargetAddr = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 9);
+	}
+	if (json_object_object_get_ex(section, "requestorID", &obj)) {
+		section_cper->RequestorId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 10);
+	}
+	if (json_object_object_get_ex(section, "responderID", &obj)) {
+		section_cper->ResponderId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 11);
+	}
+	if (json_object_object_get_ex(section, "instructionIP", &obj)) {
+		section_cper->InstructionIP = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 12);
+	}
 
 	//CPU brand string.
-	const char *brand_string = json_object_get_string(
-		json_object_object_get(section, "cpuBrandString"));
-	if (brand_string != NULL) {
-		strncpy(section_cper->BrandString, brand_string,
-			sizeof(section_cper->BrandString) - 1);
-		section_cper
-			->BrandString[sizeof(section_cper->BrandString) - 1] =
-			'\0';
+	if (json_object_object_get_ex(section, "cpuBrandString", &obj)) {
+		const char *brand_string = json_object_get_string(obj);
+		if (brand_string != NULL) {
+			strncpy(section_cper->BrandString, brand_string,
+				sizeof(section_cper->BrandString) - 1);
+			section_cper
+				->BrandString[sizeof(section_cper->BrandString) -
+					      1] = '\0';
+		}
+		add_to_valid_bitfield(&ui64Type, 7);
 	}
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write & flush out to file, free memory.
 	fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
diff --git a/sections/cper-section-ia32x64.c b/sections/cper-section-ia32x64.c
index bdeb4fa..8e89ee3 100644
--- a/sections/cper-section-ia32x64.c
+++ b/sections/cper-section-ia32x64.c
@@ -50,38 +50,40 @@
 	json_object *record_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validationBits = json_object_new_object();
-	json_object_object_add(validationBits, "localAPICIDValid",
-			       json_object_new_boolean(record->ValidFields &
-						       0x1));
-	json_object_object_add(
-		validationBits, "cpuIDInfoValid",
-		json_object_new_boolean((record->ValidFields >> 1) & 0x1));
+	//validation bits contain information
+	//about processorErrorInfoNum and processorContextInfoNum.
+	//Ensure this is decoded properly in IR->CPER
 	int processor_error_info_num = (record->ValidFields >> 2) & 0x3F;
-	json_object_object_add(validationBits, "processorErrorInfoNum",
+	json_object_object_add(record_ir, "processorErrorInfoNum",
 			       json_object_new_int(processor_error_info_num));
 	int processor_context_info_num = (record->ValidFields >> 8) & 0x3F;
-	json_object_object_add(validationBits, "processorContextInfoNum",
+	json_object_object_add(record_ir, "processorContextInfoNum",
 			       json_object_new_int(processor_context_info_num));
-	json_object_object_add(record_ir, "validationBits", validationBits);
+
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = record->ValidFields };
 
 	//APIC ID.
-	json_object_object_add(record_ir, "localAPICID",
-			       json_object_new_uint64(record->ApicId));
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object_object_add(record_ir, "localAPICID",
+				       json_object_new_uint64(record->ApicId));
+	}
 
 	//CPUID information.
-	json_object *cpuid_info_ir = json_object_new_object();
-	EFI_IA32_X64_CPU_ID *cpuid_info =
-		(EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
-	json_object_object_add(cpuid_info_ir, "eax",
-			       json_object_new_uint64(cpuid_info->Eax));
-	json_object_object_add(cpuid_info_ir, "ebx",
-			       json_object_new_uint64(cpuid_info->Ebx));
-	json_object_object_add(cpuid_info_ir, "ecx",
-			       json_object_new_uint64(cpuid_info->Ecx));
-	json_object_object_add(cpuid_info_ir, "edx",
-			       json_object_new_uint64(cpuid_info->Edx));
-	json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *cpuid_info_ir = json_object_new_object();
+		EFI_IA32_X64_CPU_ID *cpuid_info =
+			(EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
+		json_object_object_add(cpuid_info_ir, "eax",
+				       json_object_new_uint64(cpuid_info->Eax));
+		json_object_object_add(cpuid_info_ir, "ebx",
+				       json_object_new_uint64(cpuid_info->Ebx));
+		json_object_object_add(cpuid_info_ir, "ecx",
+				       json_object_new_uint64(cpuid_info->Ecx));
+		json_object_object_add(cpuid_info_ir, "edx",
+				       json_object_new_uint64(cpuid_info->Edx));
+		json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
+	}
 
 	//Processor error information, of the amount described above.
 	EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
@@ -148,44 +150,60 @@
 	json_object_object_add(error_info_ir, "type", type);
 
 	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(error_info->ValidFields, 5,
-			       IA32X64_PROCESSOR_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(error_info_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = error_info->ValidFields };
 
 	//Add the check information on a per-structure basis.
 	//Cache and TLB check information are identical, so can be equated.
-	json_object *check_information = NULL;
-	if (guid_equal(&error_info->ErrorType,
-		       &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
-	    guid_equal(&error_info->ErrorType,
-		       &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
-		check_information = cper_ia32x64_cache_tlb_check_to_ir(
-			(EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info->CheckInfo);
-	} else if (guid_equal(&error_info->ErrorType,
-			      &gEfiIa32x64ErrorTypeBusCheckGuid)) {
-		check_information = cper_ia32x64_bus_check_to_ir(
-			(EFI_IA32_X64_BUS_CHECK_INFO *)&error_info->CheckInfo);
-	} else if (guid_equal(&error_info->ErrorType,
-			      &gEfiIa32x64ErrorTypeMsCheckGuid)) {
-		check_information = cper_ia32x64_ms_check_to_ir(
-			(EFI_IA32_X64_MS_CHECK_INFO *)&error_info->CheckInfo);
-	} else {
-		//Unknown check information.
-		printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *check_information = NULL;
+		if (guid_equal(&error_info->ErrorType,
+			       &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
+		    guid_equal(&error_info->ErrorType,
+			       &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
+			check_information = cper_ia32x64_cache_tlb_check_to_ir(
+				(EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
+					->CheckInfo);
+		} else if (guid_equal(&error_info->ErrorType,
+				      &gEfiIa32x64ErrorTypeBusCheckGuid)) {
+			check_information = cper_ia32x64_bus_check_to_ir(
+				(EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
+					->CheckInfo);
+		} else if (guid_equal(&error_info->ErrorType,
+				      &gEfiIa32x64ErrorTypeMsCheckGuid)) {
+			check_information = cper_ia32x64_ms_check_to_ir(
+				(EFI_IA32_X64_MS_CHECK_INFO *)&error_info
+					->CheckInfo);
+
+		} else {
+			//Unknown check information.
+			printf("WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
+		}
+		json_object_object_add(error_info_ir, "checkInfo",
+				       check_information);
 	}
-	json_object_object_add(error_info_ir, "checkInfo", check_information);
 
 	//Target, requestor, and responder identifiers.
-	json_object_object_add(error_info_ir, "targetAddressID",
-			       json_object_new_uint64(error_info->TargetId));
-	json_object_object_add(error_info_ir, "requestorID",
-			       json_object_new_uint64(error_info->RequestorId));
-	json_object_object_add(error_info_ir, "responderID",
-			       json_object_new_uint64(error_info->ResponderId));
-	json_object_object_add(
-		error_info_ir, "instructionPointer",
-		json_object_new_uint64(error_info->InstructionIP));
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(
+			error_info_ir, "targetAddressID",
+			json_object_new_uint64(error_info->TargetId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			error_info_ir, "requestorID",
+			json_object_new_uint64(error_info->RequestorId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			error_info_ir, "responderID",
+			json_object_new_uint64(error_info->ResponderId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			error_info_ir, "instructionPointer",
+			json_object_new_uint64(error_info->InstructionIP));
+	}
 
 	return error_info_ir;
 }
@@ -197,49 +215,67 @@
 	json_object *cache_tlb_check_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(cache_tlb_check->ValidFields, 8,
-			       IA32X64_CHECK_INFO_VALID_BITFIELD_NAMES);
-	json_object_object_add(cache_tlb_check_ir, "validationBits",
-			       validation);
+	ValidationTypes ui64Type = {
+		UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
+	};
 
 	//Transaction type.
-	json_object *transaction_type = integer_to_readable_pair(
-		cache_tlb_check->TransactionType, 3,
-		IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
-		IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(cache_tlb_check_ir, "transactionType",
-			       transaction_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *transaction_type = integer_to_readable_pair(
+			cache_tlb_check->TransactionType, 3,
+			IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
+			IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(cache_tlb_check_ir, "transactionType",
+				       transaction_type);
+	}
 
 	//Operation.
-	json_object *operation = integer_to_readable_pair(
-		cache_tlb_check->Operation, 9,
-		IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
-		IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(cache_tlb_check_ir, "operation", operation);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *operation = integer_to_readable_pair(
+			cache_tlb_check->Operation, 9,
+			IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
+			IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(cache_tlb_check_ir, "operation",
+				       operation);
+	}
 
 	//Affected cache/TLB level.
-	json_object_object_add(cache_tlb_check_ir, "level",
-			       json_object_new_uint64(cache_tlb_check->Level));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			cache_tlb_check_ir, "level",
+			json_object_new_uint64(cache_tlb_check->Level));
+	}
 
 	//Miscellaneous boolean fields.
-	json_object_object_add(
-		cache_tlb_check_ir, "processorContextCorrupt",
-		json_object_new_boolean(cache_tlb_check->ContextCorrupt));
-	json_object_object_add(
-		cache_tlb_check_ir, "uncorrected",
-		json_object_new_boolean(cache_tlb_check->ErrorUncorrected));
-	json_object_object_add(
-		cache_tlb_check_ir, "preciseIP",
-		json_object_new_boolean(cache_tlb_check->PreciseIp));
-	json_object_object_add(
-		cache_tlb_check_ir, "restartableIP",
-		json_object_new_boolean(cache_tlb_check->RestartableIp));
-	json_object_object_add(
-		cache_tlb_check_ir, "overflow",
-		json_object_new_boolean(cache_tlb_check->Overflow));
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			cache_tlb_check_ir, "processorContextCorrupt",
+			json_object_new_boolean(
+				cache_tlb_check->ContextCorrupt));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			cache_tlb_check_ir, "uncorrected",
+			json_object_new_boolean(
+				cache_tlb_check->ErrorUncorrected));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			cache_tlb_check_ir, "preciseIP",
+			json_object_new_boolean(cache_tlb_check->PreciseIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(cache_tlb_check_ir, "restartableIP",
+				       json_object_new_boolean(
+					       cache_tlb_check->RestartableIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object_object_add(
+			cache_tlb_check_ir, "overflow",
+			json_object_new_boolean(cache_tlb_check->Overflow));
+	}
 
 	return cache_tlb_check_ir;
 }
@@ -251,63 +287,90 @@
 	json_object *bus_check_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(bus_check->ValidFields, 11,
-			       IA32X64_CHECK_INFO_VALID_BITFIELD_NAMES);
-	json_object_object_add(bus_check_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = bus_check->ValidFields };
 
 	//Transaction type.
-	json_object *transaction_type = integer_to_readable_pair(
-		bus_check->TransactionType, 3,
-		IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
-		IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(bus_check_ir, "transactionType",
-			       transaction_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *transaction_type = integer_to_readable_pair(
+			bus_check->TransactionType, 3,
+			IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
+			IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(bus_check_ir, "transactionType",
+				       transaction_type);
+	}
 
 	//Operation.
-	json_object *operation = integer_to_readable_pair(
-		bus_check->Operation, 9,
-		IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
-		IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
-		"Unknown (Reserved)");
-	json_object_object_add(bus_check_ir, "operation", operation);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *operation = integer_to_readable_pair(
+			bus_check->Operation, 9,
+			IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
+			IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
+			"Unknown (Reserved)");
+		json_object_object_add(bus_check_ir, "operation", operation);
+	}
 
 	//Affected bus level.
-	json_object_object_add(bus_check_ir, "level",
-			       json_object_new_uint64(bus_check->Level));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			bus_check_ir, "level",
+			json_object_new_uint64(bus_check->Level));
+	}
 
 	//Miscellaneous boolean fields.
-	json_object_object_add(
-		bus_check_ir, "processorContextCorrupt",
-		json_object_new_boolean(bus_check->ContextCorrupt));
-	json_object_object_add(
-		bus_check_ir, "uncorrected",
-		json_object_new_boolean(bus_check->ErrorUncorrected));
-	json_object_object_add(bus_check_ir, "preciseIP",
-			       json_object_new_boolean(bus_check->PreciseIp));
-	json_object_object_add(
-		bus_check_ir, "restartableIP",
-		json_object_new_boolean(bus_check->RestartableIp));
-	json_object_object_add(bus_check_ir, "overflow",
-			       json_object_new_boolean(bus_check->Overflow));
-	json_object_object_add(bus_check_ir, "timedOut",
-			       json_object_new_boolean(bus_check->TimeOut));
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			bus_check_ir, "processorContextCorrupt",
+			json_object_new_boolean(bus_check->ContextCorrupt));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			bus_check_ir, "uncorrected",
+			json_object_new_boolean(bus_check->ErrorUncorrected));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			bus_check_ir, "preciseIP",
+			json_object_new_boolean(bus_check->PreciseIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(
+			bus_check_ir, "restartableIP",
+			json_object_new_boolean(bus_check->RestartableIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object_object_add(
+			bus_check_ir, "overflow",
+			json_object_new_boolean(bus_check->Overflow));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 9)) {
+		json_object_object_add(
+			bus_check_ir, "timedOut",
+			json_object_new_boolean(bus_check->TimeOut));
+	}
 
 	//Participation type.
-	json_object *participation_type = integer_to_readable_pair(
-		bus_check->ParticipationType, 4,
-		IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
-		IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES, "Unknown");
-	json_object_object_add(bus_check_ir, "participationType",
-			       participation_type);
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object *participation_type = integer_to_readable_pair(
+			bus_check->ParticipationType, 4,
+			IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
+			IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
+			"Unknown");
+		json_object_object_add(bus_check_ir, "participationType",
+				       participation_type);
+	}
 
 	//Address space.
-	json_object *address_space = integer_to_readable_pair(
-		bus_check->AddressSpace, 4,
-		IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
-		IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES, "Unknown");
-	json_object_object_add(bus_check_ir, "addressSpace", address_space);
+	if (isvalid_prop_to_ir(&ui64Type, 10)) {
+		json_object *address_space = integer_to_readable_pair(
+			bus_check->AddressSpace, 4,
+			IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
+			IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
+			"Unknown");
+		json_object_object_add(bus_check_ir, "addressSpace",
+				       address_space);
+	}
 
 	return bus_check_ir;
 }
@@ -316,34 +379,45 @@
 json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
 {
 	json_object *ms_check_ir = json_object_new_object();
-
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = ms_check->ValidFields };
 	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		ms_check->ValidFields, 6,
-		IA32X64_CHECK_INFO_MS_CHECK_VALID_BITFIELD_NAMES);
-	json_object_object_add(ms_check_ir, "validationBits", validation);
-
 	//Error type (operation that caused the error).
-	json_object *error_type = integer_to_readable_pair(
-		ms_check->ErrorType, 4, IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
-		IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
-		"Unknown (Processor Specific)");
-	json_object_object_add(ms_check_ir, "errorType", error_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *error_type = integer_to_readable_pair(
+			ms_check->ErrorType, 4,
+			IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
+			IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
+			"Unknown (Processor Specific)");
+		json_object_object_add(ms_check_ir, "errorType", error_type);
+	}
 
 	//Miscellaneous fields.
-	json_object_object_add(
-		ms_check_ir, "processorContextCorrupt",
-		json_object_new_boolean(ms_check->ContextCorrupt));
-	json_object_object_add(
-		ms_check_ir, "uncorrected",
-		json_object_new_boolean(ms_check->ErrorUncorrected));
-	json_object_object_add(ms_check_ir, "preciseIP",
-			       json_object_new_boolean(ms_check->PreciseIp));
-	json_object_object_add(
-		ms_check_ir, "restartableIP",
-		json_object_new_boolean(ms_check->RestartableIp));
-	json_object_object_add(ms_check_ir, "overflow",
-			       json_object_new_boolean(ms_check->Overflow));
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(
+			ms_check_ir, "processorContextCorrupt",
+			json_object_new_boolean(ms_check->ContextCorrupt));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			ms_check_ir, "uncorrected",
+			json_object_new_boolean(ms_check->ErrorUncorrected));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			ms_check_ir, "preciseIP",
+			json_object_new_boolean(ms_check->PreciseIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			ms_check_ir, "restartableIP",
+			json_object_new_boolean(ms_check->RestartableIp));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			ms_check_ir, "overflow",
+			json_object_new_boolean(ms_check->Overflow));
+	}
 
 	return ms_check_ir;
 }
@@ -568,43 +642,42 @@
 		(EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
 			1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
 
-	//Validation bits.
-	json_object *validation =
-		json_object_object_get(section, "validationBits");
-	section_cper->ValidFields = 0x0;
-	section_cper->ValidFields |= json_object_get_boolean(
-		json_object_object_get(validation, "localAPICIDValid"));
-	section_cper->ValidFields |=
-		json_object_get_boolean(
-			json_object_object_get(validation, "cpuIDInfoValid"))
-		<< 1;
-	int proc_error_info_num =
-		json_object_get_int(json_object_object_get(
-			validation, "processorErrorInfoNum")) &
-		0x3F;
-	int proc_ctx_info_num =
-		json_object_get_int(json_object_object_get(
-			validation, "processorContextInfoNum")) &
-		0x3F;
-	section_cper->ValidFields |= proc_error_info_num << 2;
-	section_cper->ValidFields |= proc_ctx_info_num << 8;
+	uint64_t valid = 0x0;
+
+	int proc_error_info_num = json_object_get_int(json_object_object_get(
+					  section, "processorErrorInfoNum")) &
+				  0x3F;
+	int proc_ctx_info_num = json_object_get_int(json_object_object_get(
+					section, "processorContextInfoNum")) &
+				0x3F;
+	valid |= proc_error_info_num << 2;
+	valid |= proc_ctx_info_num << 8;
+
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
+	struct json_object *obj = NULL;
 
 	//Local APIC ID.
-	section_cper->ApicId = json_object_get_uint64(
-		json_object_object_get(section, "localAPICID"));
+	if (json_object_object_get_ex(section, "localAPICID", &obj)) {
+		section_cper->ApicId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//CPUID info.
-	json_object *cpuid_info = json_object_object_get(section, "cpuidInfo");
-	EFI_IA32_X64_CPU_ID *cpuid_info_cper =
-		(EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
-	cpuid_info_cper->Eax = json_object_get_uint64(
-		json_object_object_get(cpuid_info, "eax"));
-	cpuid_info_cper->Ebx = json_object_get_uint64(
-		json_object_object_get(cpuid_info, "ebx"));
-	cpuid_info_cper->Ecx = json_object_get_uint64(
-		json_object_object_get(cpuid_info, "ecx"));
-	cpuid_info_cper->Edx = json_object_get_uint64(
-		json_object_object_get(cpuid_info, "edx"));
+	if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
+		json_object *cpuid_info = obj;
+		EFI_IA32_X64_CPU_ID *cpuid_info_cper =
+			(EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
+		cpuid_info_cper->Eax = json_object_get_uint64(
+			json_object_object_get(cpuid_info, "eax"));
+		cpuid_info_cper->Ebx = json_object_get_uint64(
+			json_object_object_get(cpuid_info, "ebx"));
+		cpuid_info_cper->Ecx = json_object_get_uint64(
+			json_object_object_get(cpuid_info, "ecx"));
+		cpuid_info_cper->Edx = json_object_get_uint64(
+			json_object_object_get(cpuid_info, "edx"));
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Flush the header to file before dealing w/ info sections.
 	fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
@@ -642,45 +715,55 @@
 		json_object_get_string(json_object_object_get(type, "guid")));
 
 	//Validation bits.
-	error_info_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(error_info, "validationBits"), 5,
-		IA32X64_PROCESSOR_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Check information, parsed based on the error type.
-	json_object *check_info =
-		json_object_object_get(error_info, "checkInfo");
-	if (guid_equal(&error_info_cper->ErrorType,
-		       &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
-	    guid_equal(&error_info_cper->ErrorType,
-		       &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
-		ir_ia32x64_cache_tlb_check_error_to_cper(
-			check_info,
-			(EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info_cper
-				->CheckInfo);
-	} else if (guid_equal(&error_info_cper->ErrorType,
-			      &gEfiIa32x64ErrorTypeBusCheckGuid)) {
-		ir_ia32x64_bus_check_error_to_cper(
-			check_info,
-			(EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
-				->CheckInfo);
-	} else if (guid_equal(&error_info_cper->ErrorType,
-			      &gEfiIa32x64ErrorTypeMsCheckGuid)) {
-		ir_ia32x64_ms_check_error_to_cper(
-			check_info,
-			(EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
-				->CheckInfo);
+	if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
+		json_object *check_info = obj;
+		if (guid_equal(&error_info_cper->ErrorType,
+			       &gEfiIa32x64ErrorTypeCacheCheckGuid) ||
+		    guid_equal(&error_info_cper->ErrorType,
+			       &gEfiIa32x64ErrorTypeTlbCheckGuid)) {
+			ir_ia32x64_cache_tlb_check_error_to_cper(
+				check_info,
+				(EFI_IA32_X64_CACHE_CHECK_INFO
+					 *)&error_info_cper->CheckInfo);
+		} else if (guid_equal(&error_info_cper->ErrorType,
+				      &gEfiIa32x64ErrorTypeBusCheckGuid)) {
+			ir_ia32x64_bus_check_error_to_cper(
+				check_info,
+				(EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
+					->CheckInfo);
+		} else if (guid_equal(&error_info_cper->ErrorType,
+				      &gEfiIa32x64ErrorTypeMsCheckGuid)) {
+			ir_ia32x64_ms_check_error_to_cper(
+				check_info,
+				(EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
+					->CheckInfo);
+		}
+		add_to_valid_bitfield(&ui64Type, 0);
 	}
 
 	//Miscellaneous numeric fields.
-	error_info_cper->TargetId = json_object_get_uint64(
-		json_object_object_get(error_info, "targetAddressID"));
-	error_info_cper->RequestorId = json_object_get_uint64(
-		json_object_object_get(error_info, "requestorID"));
-	error_info_cper->ResponderId = json_object_get_uint64(
-		json_object_object_get(error_info, "responderID"));
-	error_info_cper->InstructionIP = json_object_get_uint64(
-		json_object_object_get(error_info, "instructionPointer"));
+	if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
+		error_info_cper->TargetId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
+		error_info_cper->RequestorId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(error_info, "responderID", &obj)) {
+		error_info_cper->ResponderId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
+		error_info_cper->InstructionIP = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
 
+	error_info_cper->ValidFields = ui64Type.value.ui64;
 	//Write out to stream, then free resources.
 	fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
 	       out);
@@ -693,29 +776,48 @@
 	json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
 {
 	//Validation bits.
-	check_info_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(check_info, "validationBits"), 8,
-		IA32X64_CHECK_INFO_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Transaction type, operation.
-	check_info_cper->TransactionType = readable_pair_to_integer(
-		json_object_object_get(check_info, "transactionType"));
-	check_info_cper->Operation = readable_pair_to_integer(
-		json_object_object_get(check_info, "operation"));
+	if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
+		check_info_cper->TransactionType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(check_info, "operation", &obj)) {
+		check_info_cper->Operation = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
 
 	//Miscellaneous raw value fields.
-	check_info_cper->Level = json_object_get_uint64(
-		json_object_object_get(check_info, "level"));
-	check_info_cper->ContextCorrupt = json_object_get_boolean(
-		json_object_object_get(check_info, "processorContextCorrupt"));
-	check_info_cper->ErrorUncorrected = json_object_get_boolean(
-		json_object_object_get(check_info, "uncorrected"));
-	check_info_cper->PreciseIp = json_object_get_boolean(
-		json_object_object_get(check_info, "preciseIP"));
-	check_info_cper->RestartableIp = json_object_get_boolean(
-		json_object_object_get(check_info, "restartableIP"));
-	check_info_cper->Overflow = json_object_get_boolean(
-		json_object_object_get(check_info, "overflow"));
+	if (json_object_object_get_ex(check_info, "level", &obj)) {
+		check_info_cper->Level = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(check_info, "processorContextCorrupt",
+				      &obj)) {
+		check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
+		check_info_cper->ErrorUncorrected =
+			json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
+		check_info_cper->PreciseIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
+		check_info_cper->RestartableIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
+	if (json_object_object_get_ex(check_info, "overflow", &obj)) {
+		check_info_cper->Overflow = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	}
+	check_info_cper->ValidFields = ui64Type.value.ui64;
 }
 
 //Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
@@ -723,35 +825,62 @@
 	json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
 {
 	//Validation bits.
-	check_info_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(check_info, "validationBits"), 11,
-		IA32X64_CHECK_INFO_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Readable pair fields.
-	check_info_cper->TransactionType = readable_pair_to_integer(
-		json_object_object_get(check_info, "transactionType"));
-	check_info_cper->Operation = readable_pair_to_integer(
-		json_object_object_get(check_info, "operation"));
-	check_info_cper->ParticipationType = readable_pair_to_integer(
-		json_object_object_get(check_info, "participationType"));
-	check_info_cper->AddressSpace = readable_pair_to_integer(
-		json_object_object_get(check_info, "addressSpace"));
+	if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
+		check_info_cper->TransactionType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(check_info, "operation", &obj)) {
+		check_info_cper->Operation = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(check_info, "participationType", &obj)) {
+		check_info_cper->ParticipationType =
+			readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	}
+
+	if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
+		check_info_cper->AddressSpace = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 10);
+	}
 
 	//Miscellaneous raw value fields.
-	check_info_cper->Level = json_object_get_uint64(
-		json_object_object_get(check_info, "level"));
-	check_info_cper->ContextCorrupt = json_object_get_boolean(
-		json_object_object_get(check_info, "processorContextCorrupt"));
-	check_info_cper->ErrorUncorrected = json_object_get_boolean(
-		json_object_object_get(check_info, "uncorrected"));
-	check_info_cper->PreciseIp = json_object_get_boolean(
-		json_object_object_get(check_info, "preciseIP"));
-	check_info_cper->RestartableIp = json_object_get_boolean(
-		json_object_object_get(check_info, "restartableIP"));
-	check_info_cper->Overflow = json_object_get_boolean(
-		json_object_object_get(check_info, "overflow"));
-	check_info_cper->TimeOut = json_object_get_boolean(
-		json_object_object_get(check_info, "timedOut"));
+	if (json_object_object_get_ex(check_info, "level", &obj)) {
+		check_info_cper->Level = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(check_info, "processorContextCorrupt",
+				      &obj)) {
+		check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
+		check_info_cper->ErrorUncorrected =
+			json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
+		check_info_cper->PreciseIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
+		check_info_cper->RestartableIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
+	if (json_object_object_get_ex(check_info, "overflow", &obj)) {
+		check_info_cper->Overflow = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	}
+	if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
+		check_info_cper->TimeOut = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 9);
+	}
+	check_info_cper->ValidFields = ui64Type.value.ui64;
 }
 
 //Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
@@ -759,25 +888,39 @@
 	json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
 {
 	//Validation bits.
-	check_info_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(check_info, "validationBits"), 6,
-		IA32X64_CHECK_INFO_MS_CHECK_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Type of MS check error.
-	check_info_cper->ErrorType = readable_pair_to_integer(
-		json_object_object_get(check_info, "errorType"));
+	if (json_object_object_get_ex(check_info, "errorType", &obj)) {
+		check_info_cper->ErrorType = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Miscellaneous raw value fields.
-	check_info_cper->ContextCorrupt = json_object_get_boolean(
-		json_object_object_get(check_info, "processorContextCorrupt"));
-	check_info_cper->ErrorUncorrected = json_object_get_boolean(
-		json_object_object_get(check_info, "uncorrected"));
-	check_info_cper->PreciseIp = json_object_get_boolean(
-		json_object_object_get(check_info, "preciseIP"));
-	check_info_cper->RestartableIp = json_object_get_boolean(
-		json_object_object_get(check_info, "restartableIP"));
-	check_info_cper->Overflow = json_object_get_boolean(
-		json_object_object_get(check_info, "overflow"));
+	if (json_object_object_get_ex(check_info, "processorContextCorrupt",
+				      &obj)) {
+		check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
+		check_info_cper->ErrorUncorrected =
+			json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
+		check_info_cper->PreciseIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
+		check_info_cper->RestartableIp = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(check_info, "overflow", &obj)) {
+		check_info_cper->Overflow = json_object_get_boolean(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	check_info_cper->ValidFields = ui64Type.value.ui64;
 }
 
 //Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
diff --git a/sections/cper-section-memory.c b/sections/cper-section-memory.c
index 4aeae43..ce9119d 100644
--- a/sections/cper-section-memory.c
+++ b/sections/cper-section-memory.c
@@ -17,20 +17,19 @@
 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
 	json_object *section_ir = json_object_new_object();
 
-	//Validation bitfield.
-	json_object *validation =
-		bitfield_to_ir(memory_error->ValidFields, 22,
-			       MEMORY_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = memory_error->ValidFields };
 
 	//Error status.
-	json_object *error_status =
-		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
-	json_object_object_add(section_ir, "errorStatus", error_status);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *error_status = cper_generic_error_status_to_ir(
+			&memory_error->ErrorStatus);
+		json_object_object_add(section_ir, "errorStatus", error_status);
+	}
 
-	//Bank.
+	//Bank
 	json_object *bank = json_object_new_object();
-	if ((memory_error->ValidFields >> 5) & 0x1) {
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
 		//Entire bank address mode.
 		json_object_object_add(
 			bank, "value",
@@ -47,71 +46,121 @@
 	json_object_object_add(section_ir, "bank", bank);
 
 	//Memory error type.
-	json_object *memory_error_type = integer_to_readable_pair(
-		memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
-		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(section_ir, "memoryErrorType",
-			       memory_error_type);
+	if (isvalid_prop_to_ir(&ui64Type, 14)) {
+		json_object *memory_error_type = integer_to_readable_pair(
+			memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
+			MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
+		json_object_object_add(section_ir, "memoryErrorType",
+				       memory_error_type);
+	}
 
 	//"Extended" row/column indication field + misc.
-	json_object *extended = json_object_new_object();
-	json_object_object_add(extended, "rowBit16",
-			       json_object_new_boolean(memory_error->Extended &
-						       0x1));
-	json_object_object_add(
-		extended, "rowBit17",
-		json_object_new_boolean((memory_error->Extended >> 1) & 0x1));
-	json_object_object_add(extended, "chipIdentification",
-			       json_object_new_int(memory_error->Extended >>
-						   5));
-	json_object_object_add(section_ir, "extended", extended);
+	// Review this
+	if (isvalid_prop_to_ir(&ui64Type, 18)) {
+		json_object *extended = json_object_new_object();
+		json_object_object_add(
+			extended, "rowBit16",
+			json_object_new_boolean(memory_error->Extended & 0x1));
+		json_object_object_add(
+			extended, "rowBit17",
+			json_object_new_boolean((memory_error->Extended >> 1) &
+						0x1));
+		if (isvalid_prop_to_ir(&ui64Type, 21)) {
+			json_object_object_add(
+				extended, "chipIdentification",
+				json_object_new_int(memory_error->Extended >>
+						    5));
+		}
+		json_object_object_add(section_ir, "extended", extended);
+
+		//bit 16 and 17 are valid only if extended is valid
+		if (isvalid_prop_to_ir(&ui64Type, 16)) {
+			json_object_object_add(
+				section_ir, "cardSmbiosHandle",
+				json_object_new_uint64(
+					memory_error->CardHandle));
+		}
+		if (isvalid_prop_to_ir(&ui64Type, 17)) {
+			json_object_object_add(
+				section_ir, "moduleSmbiosHandle",
+				json_object_new_uint64(
+					memory_error->ModuleHandle));
+		}
+	}
 
 	//Miscellaneous numeric fields.
-	json_object_object_add(
-		section_ir, "physicalAddress",
-		json_object_new_uint64(memory_error->PhysicalAddress));
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object_object_add(
+			section_ir, "physicalAddress",
+			json_object_new_uint64(memory_error->PhysicalAddress));
 
-	char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
-		 memory_error->PhysicalAddress);
-	json_object_object_add(section_ir, "physicalAddressHex",
-			       json_object_new_string(hexstring_buf));
-
-	json_object_object_add(
-		section_ir, "physicalAddressMask",
-		json_object_new_uint64(memory_error->PhysicalAddressMask));
-	json_object_object_add(section_ir, "node",
-			       json_object_new_uint64(memory_error->Node));
-	json_object_object_add(section_ir, "card",
-			       json_object_new_uint64(memory_error->Card));
-	json_object_object_add(
-		section_ir, "moduleRank",
-		json_object_new_uint64(memory_error->ModuleRank));
-	json_object_object_add(section_ir, "device",
-			       json_object_new_uint64(memory_error->Device));
-	json_object_object_add(section_ir, "row",
-			       json_object_new_uint64(memory_error->Row));
-	json_object_object_add(section_ir, "column",
-			       json_object_new_uint64(memory_error->Column));
-	json_object_object_add(
-		section_ir, "bitPosition",
-		json_object_new_uint64(memory_error->BitPosition));
-	json_object_object_add(
-		section_ir, "requestorID",
-		json_object_new_uint64(memory_error->RequestorId));
-	json_object_object_add(
-		section_ir, "responderID",
-		json_object_new_uint64(memory_error->ResponderId));
-	json_object_object_add(section_ir, "targetID",
-			       json_object_new_uint64(memory_error->TargetId));
-	json_object_object_add(section_ir, "rankNumber",
-			       json_object_new_uint64(memory_error->RankNum));
-	json_object_object_add(
-		section_ir, "cardSmbiosHandle",
-		json_object_new_uint64(memory_error->CardHandle));
-	json_object_object_add(
-		section_ir, "moduleSmbiosHandle",
-		json_object_new_uint64(memory_error->ModuleHandle));
+		char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
+			 memory_error->PhysicalAddress);
+		json_object_object_add(section_ir, "physicalAddressHex",
+				       json_object_new_string(hexstring_buf));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			section_ir, "physicalAddressMask",
+			json_object_new_uint64(
+				memory_error->PhysicalAddressMask));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			section_ir, "node",
+			json_object_new_uint64(memory_error->Node));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			section_ir, "card",
+			json_object_new_uint64(memory_error->Card));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			section_ir, "moduleRank",
+			json_object_new_uint64(memory_error->ModuleRank));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object_object_add(
+			section_ir, "device",
+			json_object_new_uint64(memory_error->Device));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object_object_add(
+			section_ir, "row",
+			json_object_new_uint64(memory_error->Row));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 9)) {
+		json_object_object_add(
+			section_ir, "column",
+			json_object_new_uint64(memory_error->Column));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 10)) {
+		json_object_object_add(
+			section_ir, "bitPosition",
+			json_object_new_uint64(memory_error->BitPosition));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 11)) {
+		json_object_object_add(
+			section_ir, "requestorID",
+			json_object_new_uint64(memory_error->RequestorId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 12)) {
+		json_object_object_add(
+			section_ir, "responderID",
+			json_object_new_uint64(memory_error->ResponderId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 13)) {
+		json_object_object_add(
+			section_ir, "targetID",
+			json_object_new_uint64(memory_error->TargetId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 15)) {
+		json_object_object_add(
+			section_ir, "rankNumber",
+			json_object_new_uint64(memory_error->RankNum));
+	}
 
 	return section_ir;
 }
@@ -123,20 +172,19 @@
 		(EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
 	json_object *section_ir = json_object_new_object();
 
-	//Validation bits.
-	json_object *validation =
-		bitfield_to_ir(memory_error->ValidFields, 22,
-			       MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = memory_error->ValidFields };
 
 	//Error status.
-	json_object *error_status =
-		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
-	json_object_object_add(section_ir, "errorStatus", error_status);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *error_status = cper_generic_error_status_to_ir(
+			&memory_error->ErrorStatus);
+		json_object_object_add(section_ir, "errorStatus", error_status);
+	}
 
 	//Bank.
 	json_object *bank = json_object_new_object();
-	if ((memory_error->ValidFields >> 5) & 0x1) {
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
 		//Entire bank address mode.
 		json_object_object_add(
 			bank, "value",
@@ -153,27 +201,35 @@
 	json_object_object_add(section_ir, "bank", bank);
 
 	//Memory error type.
-	json_object *memory_error_type = integer_to_readable_pair(
-		memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
-		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(section_ir, "memoryErrorType",
-			       memory_error_type);
+	if (isvalid_prop_to_ir(&ui64Type, 13)) {
+		json_object *memory_error_type = integer_to_readable_pair(
+			memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
+			MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
+		json_object_object_add(section_ir, "memoryErrorType",
+				       memory_error_type);
+	}
 
 	//Status.
-	json_object *status = json_object_new_object();
-	json_object_object_add(status, "value",
-			       json_object_new_int(memory_error->Status));
-	json_object_object_add(
-		status, "state",
-		json_object_new_string((memory_error->Status & 0x1) == 0 ?
-					       "Corrected" :
-					       "Uncorrected"));
-	json_object_object_add(section_ir, "status", status);
+	if (isvalid_prop_to_ir(&ui64Type, 14)) {
+		json_object *status = json_object_new_object();
+		json_object_object_add(
+			status, "value",
+			json_object_new_int(memory_error->Status));
+		json_object_object_add(
+			status, "state",
+			json_object_new_string((memory_error->Status & 0x1) ==
+							       0 ?
+						       "Corrected" :
+						       "Uncorrected"));
+		json_object_object_add(section_ir, "status", status);
+	}
 
 	//Miscellaneous numeric fields.
-	json_object_object_add(
-		section_ir, "physicalAddress",
-		json_object_new_uint64(memory_error->PhysicalAddress));
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object_object_add(
+			section_ir, "physicalAddress",
+			json_object_new_uint64(memory_error->PhysicalAddress));
+	}
 
 	char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
 	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
@@ -181,42 +237,82 @@
 	json_object_object_add(section_ir, "physicalAddressHex",
 			       json_object_new_string(hexstring_buf));
 
-	json_object_object_add(
-		section_ir, "physicalAddressMask",
-		json_object_new_uint64(memory_error->PhysicalAddressMask));
-	json_object_object_add(section_ir, "node",
-			       json_object_new_uint64(memory_error->Node));
-	json_object_object_add(section_ir, "card",
-			       json_object_new_uint64(memory_error->Card));
-	json_object_object_add(section_ir, "module",
-			       json_object_new_uint64(memory_error->Module));
-	json_object_object_add(section_ir, "device",
-			       json_object_new_uint64(memory_error->Device));
-	json_object_object_add(section_ir, "row",
-			       json_object_new_uint64(memory_error->Row));
-	json_object_object_add(section_ir, "column",
-			       json_object_new_uint64(memory_error->Column));
-	json_object_object_add(section_ir, "rank",
-			       json_object_new_uint64(memory_error->Rank));
-	json_object_object_add(
-		section_ir, "bitPosition",
-		json_object_new_uint64(memory_error->BitPosition));
-	json_object_object_add(section_ir, "chipID",
-			       json_object_new_uint64(memory_error->ChipId));
-	json_object_object_add(
-		section_ir, "requestorID",
-		json_object_new_uint64(memory_error->RequestorId));
-	json_object_object_add(
-		section_ir, "responderID",
-		json_object_new_uint64(memory_error->ResponderId));
-	json_object_object_add(section_ir, "targetID",
-			       json_object_new_uint64(memory_error->TargetId));
-	json_object_object_add(
-		section_ir, "cardSmbiosHandle",
-		json_object_new_uint64(memory_error->CardHandle));
-	json_object_object_add(
-		section_ir, "moduleSmbiosHandle",
-		json_object_new_uint64(memory_error->ModuleHandle));
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			section_ir, "physicalAddressMask",
+			json_object_new_uint64(
+				memory_error->PhysicalAddressMask));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			section_ir, "node",
+			json_object_new_uint64(memory_error->Node));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			section_ir, "card",
+			json_object_new_uint64(memory_error->Card));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			section_ir, "module",
+			json_object_new_uint64(memory_error->Module));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object_object_add(
+			section_ir, "device",
+			json_object_new_uint64(memory_error->Device));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object_object_add(
+			section_ir, "row",
+			json_object_new_uint64(memory_error->Row));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 9)) {
+		json_object_object_add(
+			section_ir, "column",
+			json_object_new_uint64(memory_error->Column));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 10)) {
+		json_object_object_add(
+			section_ir, "rank",
+			json_object_new_uint64(memory_error->Rank));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 11)) {
+		json_object_object_add(
+			section_ir, "bitPosition",
+			json_object_new_uint64(memory_error->BitPosition));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 12)) {
+		json_object_object_add(
+			section_ir, "chipID",
+			json_object_new_uint64(memory_error->ChipId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 15)) {
+		json_object_object_add(
+			section_ir, "requestorID",
+			json_object_new_uint64(memory_error->RequestorId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 16)) {
+		json_object_object_add(
+			section_ir, "responderID",
+			json_object_new_uint64(memory_error->ResponderId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 17)) {
+		json_object_object_add(
+			section_ir, "targetID",
+			json_object_new_uint64(memory_error->TargetId));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 18)) {
+		json_object_object_add(
+			section_ir, "cardSmbiosHandle",
+			json_object_new_uint64(memory_error->CardHandle));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 19)) {
+		json_object_object_add(
+			section_ir, "moduleSmbiosHandle",
+			json_object_new_uint64(memory_error->ModuleHandle));
+	}
 
 	return section_ir;
 }
@@ -228,77 +324,122 @@
 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
 			1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
 
-	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 22,
-		MEMORY_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Error status.
-	ir_generic_error_status_to_cper(json_object_object_get(section,
-							       "errorStatus"),
-					&section_cper->ErrorStatus);
+	if (json_object_object_get_ex(section, "errorStatus", &obj)) {
+		ir_generic_error_status_to_cper(obj,
+						&section_cper->ErrorStatus);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Bank.
-	json_object *bank = json_object_object_get(section, "bank");
-	if ((section_cper->ValidFields >> 5) & 0x1) {
-		//Bank just uses simple address.
-		section_cper->Bank = (UINT16)json_object_get_uint64(
-			json_object_object_get(bank, "value"));
-	} else {
-		//Bank uses address/group style address.
-		UINT16 address = (UINT8)json_object_get_uint64(
-			json_object_object_get(bank, "address"));
-		UINT16 group = (UINT8)json_object_get_uint64(
-			json_object_object_get(bank, "group"));
-		section_cper->Bank = address + (group << 8);
+	if (json_object_object_get_ex(section, "bank", &obj)) {
+		json_object *bank = obj;
+		if (json_object_object_get_ex(bank, "value", &obj)) {
+			//Bank just uses simple address.
+			section_cper->Bank =
+				(UINT16)json_object_get_uint64(obj);
+			add_to_valid_bitfield(&ui64Type, 6);
+		} else {
+			//Bank uses address/group style address.
+			UINT16 address = (UINT8)json_object_get_uint64(
+				json_object_object_get(bank, "address"));
+			UINT16 group = (UINT8)json_object_get_uint64(
+				json_object_object_get(bank, "group"));
+			section_cper->Bank = address + (group << 8);
+			add_to_valid_bitfield(&ui64Type, 19);
+			add_to_valid_bitfield(&ui64Type, 20);
+		}
 	}
 
 	//"Extended" field.
-	json_object *extended = json_object_object_get(section, "extended");
-	section_cper->Extended = 0;
-	section_cper->Extended |= json_object_get_boolean(
-		json_object_object_get(extended, "rowBit16"));
-	section_cper->Extended |=
-		json_object_get_boolean(
-			json_object_object_get(extended, "rowBit17"))
-		<< 1;
-	section_cper->Extended |= json_object_get_int(json_object_object_get(
-					  extended, "chipIdentification"))
-				  << 5;
+	if (json_object_object_get_ex(section, "extended", &obj)) {
+		json_object *extended = obj;
+		section_cper->Extended = 0;
+		section_cper->Extended |= json_object_get_boolean(
+			json_object_object_get(extended, "rowBit16"));
+		section_cper->Extended |=
+			json_object_get_boolean(
+				json_object_object_get(extended, "rowBit17"))
+			<< 1;
+		if (json_object_object_get_ex(extended, "chipIdentification",
+					      &obj)) {
+			section_cper->Extended |= json_object_get_int(obj) << 5;
+			add_to_valid_bitfield(&ui64Type, 21);
+		}
+		add_to_valid_bitfield(&ui64Type, 18);
+	}
 
 	//Miscellaneous value fields.
-	section_cper->ErrorType = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "memoryErrorType"));
-	section_cper->PhysicalAddress = json_object_get_uint64(
-		json_object_object_get(section, "physicalAddress"));
-	section_cper->PhysicalAddressMask = json_object_get_uint64(
-		json_object_object_get(section, "physicalAddressMask"));
-	section_cper->Node = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "node"));
-	section_cper->Card = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "card"));
-	section_cper->ModuleRank = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "moduleRank"));
-	section_cper->Device = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "device"));
-	section_cper->Row = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "row"));
-	section_cper->Column = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "column"));
-	section_cper->BitPosition = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "bitPosition"));
-	section_cper->RequestorId = json_object_get_uint64(
-		json_object_object_get(section, "requestorID"));
-	section_cper->ResponderId = json_object_get_uint64(
-		json_object_object_get(section, "responderID"));
-	section_cper->TargetId = json_object_get_uint64(
-		json_object_object_get(section, "targetID"));
-	section_cper->RankNum = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "rankNumber"));
-	section_cper->CardHandle = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "cardSmbiosHandle"));
-	section_cper->ModuleHandle = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "moduleSmbiosHandle"));
+	if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
+		section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 14);
+	}
+	if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
+		section_cper->PhysicalAddress = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
+		section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(section, "node", &obj)) {
+		section_cper->Node = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(section, "card", &obj)) {
+		section_cper->Card = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(section, "moduleRank", &obj)) {
+		section_cper->ModuleRank = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(section, "device", &obj)) {
+		section_cper->Device = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	}
+	if (json_object_object_get_ex(section, "row", &obj)) {
+		section_cper->Row = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	}
+	if (json_object_object_get_ex(section, "column", &obj)) {
+		section_cper->Column = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 9);
+	}
+	if (json_object_object_get_ex(section, "bitPosition", &obj)) {
+		section_cper->BitPosition = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 10);
+	}
+	if (json_object_object_get_ex(section, "requestorID", &obj)) {
+		section_cper->RequestorId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 11);
+	}
+	if (json_object_object_get_ex(section, "responderID", &obj)) {
+		section_cper->ResponderId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 12);
+	}
+	if (json_object_object_get_ex(section, "targetID", &obj)) {
+		section_cper->TargetId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 13);
+	}
+	if (json_object_object_get_ex(section, "rankNumber", &obj)) {
+		section_cper->RankNum = (UINT16)json_object_get_uint64(
+			json_object_object_get(section, "rankNumber"));
+		add_to_valid_bitfield(&ui64Type, 15);
+	}
+	if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
+		section_cper->CardHandle = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 16);
+	}
+	if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
+		section_cper->ModuleHandle =
+			(UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 17);
+	}
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write to stream, free up resources.
 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
@@ -314,21 +455,22 @@
 			1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 22,
-		MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Error status.
-	ir_generic_error_status_to_cper(json_object_object_get(section,
-							       "errorStatus"),
-					&section_cper->ErrorStatus);
+	if (json_object_object_get_ex(section, "errorStatus", &obj)) {
+		ir_generic_error_status_to_cper(obj,
+						&section_cper->ErrorStatus);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Bank.
 	json_object *bank = json_object_object_get(section, "bank");
-	if ((section_cper->ValidFields >> 5) & 0x1) {
+	if (json_object_object_get_ex(bank, "value", &obj)) {
 		//Bank just uses simple address.
-		section_cper->Bank = (UINT16)json_object_get_uint64(
-			json_object_object_get(bank, "value"));
+		section_cper->Bank = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
 	} else {
 		//Bank uses address/group style address.
 		UINT16 address = (UINT8)json_object_get_uint64(
@@ -336,45 +478,86 @@
 		UINT16 group = (UINT8)json_object_get_uint64(
 			json_object_object_get(bank, "group"));
 		section_cper->Bank = address + (group << 8);
+		add_to_valid_bitfield(&ui64Type, 20);
+		add_to_valid_bitfield(&ui64Type, 21);
 	}
 
 	//Miscellaneous value fields.
-	section_cper->MemErrorType = readable_pair_to_integer(
-		json_object_object_get(section, "memoryErrorType"));
-	section_cper->Status = (UINT8)readable_pair_to_integer(
-		json_object_object_get(section, "status"));
-	section_cper->PhysicalAddress = json_object_get_uint64(
-		json_object_object_get(section, "physicalAddress"));
-	section_cper->PhysicalAddressMask = json_object_get_uint64(
-		json_object_object_get(section, "physicalAddressMask"));
-	section_cper->Node = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "node"));
-	section_cper->Card = (UINT16)json_object_get_uint64(
-		json_object_object_get(section, "card"));
-	section_cper->Module = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "module"));
-	section_cper->Device = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "device"));
-	section_cper->Row = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "row"));
-	section_cper->Column = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "column"));
-	section_cper->Rank = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "rank"));
-	section_cper->BitPosition = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "bitPosition"));
-	section_cper->ChipId = (UINT8)json_object_get_uint64(
-		json_object_object_get(section, "chipID"));
-	section_cper->RequestorId = json_object_get_uint64(
-		json_object_object_get(section, "requestorID"));
-	section_cper->ResponderId = json_object_get_uint64(
-		json_object_object_get(section, "responderID"));
-	section_cper->TargetId = json_object_get_uint64(
-		json_object_object_get(section, "targetID"));
-	section_cper->CardHandle = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "cardSmbiosHandle"));
-	section_cper->ModuleHandle = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "moduleSmbiosHandle"));
+	if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
+		section_cper->MemErrorType = readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 13);
+	}
+	if (json_object_object_get_ex(section, "status", &obj)) {
+		section_cper->Status = (UINT8)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 14);
+	}
+	if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
+		section_cper->PhysicalAddress = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
+		section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(section, "node", &obj)) {
+		section_cper->Node = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(section, "card", &obj)) {
+		section_cper->Card = (UINT16)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(section, "module", &obj)) {
+		section_cper->Module = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(section, "device", &obj)) {
+		section_cper->Device = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	}
+	if (json_object_object_get_ex(section, "row", &obj)) {
+		section_cper->Row = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	}
+	if (json_object_object_get_ex(section, "column", &obj)) {
+		section_cper->Column = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 9);
+	}
+	if (json_object_object_get_ex(section, "rank", &obj)) {
+		section_cper->Rank = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 10);
+	}
+	if (json_object_object_get_ex(section, "bitPosition", &obj)) {
+		section_cper->BitPosition = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 11);
+	}
+	if (json_object_object_get_ex(section, "chipID", &obj)) {
+		section_cper->ChipId = (UINT8)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 12);
+	}
+	if (json_object_object_get_ex(section, "requestorID", &obj)) {
+		section_cper->RequestorId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 15);
+	}
+	if (json_object_object_get_ex(section, "responderID", &obj)) {
+		section_cper->ResponderId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 16);
+	}
+	if (json_object_object_get_ex(section, "targetID", &obj)) {
+		section_cper->TargetId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 17);
+	}
+	if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
+		section_cper->CardHandle = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 18);
+	}
+	if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
+		section_cper->ModuleHandle =
+			(UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 19);
+	}
+
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write to stream, free up resources.
 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
diff --git a/sections/cper-section-pci-bus.c b/sections/cper-section-pci-bus.c
index ab6e921..2884f61 100644
--- a/sections/cper-section-pci-bus.c
+++ b/sections/cper-section-pci-bus.c
@@ -19,58 +19,83 @@
 	json_object *section_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		bus_error->ValidFields, 9, PCI_BUS_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = bus_error->ValidFields };
 
 	//Error status.
-	json_object *error_status =
-		cper_generic_error_status_to_ir(&bus_error->ErrorStatus);
-	json_object_object_add(section_ir, "errorStatus", error_status);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *error_status = cper_generic_error_status_to_ir(
+			&bus_error->ErrorStatus);
+		json_object_object_add(section_ir, "errorStatus", error_status);
+	}
 
 	//PCI bus error type.
-	json_object *error_type = integer_to_readable_pair(
-		bus_error->Type, 8, PCI_BUS_ERROR_TYPES_KEYS,
-		PCI_BUS_ERROR_TYPES_VALUES, "Unknown (Reserved)");
-	json_object_object_add(section_ir, "errorType", error_type);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *error_type = integer_to_readable_pair(
+			bus_error->Type, 8, PCI_BUS_ERROR_TYPES_KEYS,
+			PCI_BUS_ERROR_TYPES_VALUES, "Unknown (Reserved)");
+		json_object_object_add(section_ir, "errorType", error_type);
+	}
 
 	//Bus ID.
-	json_object *bus_id = json_object_new_object();
-	json_object_object_add(bus_id, "busNumber",
-			       json_object_new_int(bus_error->BusId & 0xFF));
-	json_object_object_add(bus_id, "segmentNumber",
-			       json_object_new_int(bus_error->BusId >> 8));
-	json_object_object_add(section_ir, "busID", bus_id);
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object *bus_id = json_object_new_object();
+		json_object_object_add(bus_id, "busNumber",
+				       json_object_new_int(bus_error->BusId &
+							   0xFF));
+		json_object_object_add(bus_id, "segmentNumber",
+				       json_object_new_int(bus_error->BusId >>
+							   8));
+		json_object_object_add(section_ir, "busID", bus_id);
+	}
 
 	//Miscellaneous numeric fields.
 	UINT8 command_type = (bus_error->BusCommand >> 56) &
 			     0x1; //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(command_type == 0 ? "PCI" : "PCI-X"));
-
-	json_object_object_add(section_ir, "busRequestorID",
-			       json_object_new_uint64(bus_error->RequestorId));
-
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			section_ir, "busAddress",
+			json_object_new_uint64(bus_error->BusAddress));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			section_ir, "busData",
+			json_object_new_uint64(bus_error->BusData));
+	}
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object_object_add(
+			section_ir, "busCommandType",
+			json_object_new_string(command_type == 0 ? "PCI" :
+								   "PCI-X"));
+	}
 	char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
-		 bus_error->RequestorId);
-	json_object_object_add(section_ir, "busRequestorIDHex",
-			       json_object_new_string(hexstring_buf));
 
-	json_object_object_add(section_ir, "busCompleterID",
-			       json_object_new_uint64(bus_error->ResponderId));
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
-		 bus_error->ResponderId);
-	json_object_object_add(section_ir, "busCompleterIDHex",
-			       json_object_new_string(hexstring_buf));
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		json_object_object_add(
+			section_ir, "busRequestorID",
+			json_object_new_uint64(bus_error->RequestorId));
 
-	json_object_object_add(section_ir, "targetID",
-			       json_object_new_uint64(bus_error->TargetId));
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
+			 bus_error->RequestorId);
+		json_object_object_add(section_ir, "busRequestorIDHex",
+				       json_object_new_string(hexstring_buf));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object_object_add(
+			section_ir, "busCompleterID",
+			json_object_new_uint64(bus_error->ResponderId));
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
+			 bus_error->ResponderId);
+		json_object_object_add(section_ir, "busCompleterIDHex",
+				       json_object_new_string(hexstring_buf));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 8)) {
+		json_object_object_add(
+			section_ir, "targetID",
+			json_object_new_uint64(bus_error->TargetId));
+	}
 
 	return section_ir;
 }
@@ -84,41 +109,62 @@
 			1, sizeof(EFI_PCI_PCIX_BUS_ERROR_DATA));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 9,
-		PCI_BUS_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Error status.
-	ir_generic_error_status_to_cper(json_object_object_get(section,
-							       "errorStatus"),
-					&section_cper->ErrorStatus);
+	if (json_object_object_get_ex(section, "errorStatus", &obj)) {
+		ir_generic_error_status_to_cper(obj,
+						&section_cper->ErrorStatus);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Bus ID.
-	json_object *bus_id = json_object_object_get(section, "busID");
-	UINT16 bus_number = (UINT8)json_object_get_int(
-		json_object_object_get(bus_id, "busNumber"));
-	UINT16 segment_number = (UINT8)json_object_get_int(
-		json_object_object_get(bus_id, "segmentNumber"));
-	section_cper->BusId = bus_number + (segment_number << 8);
+	if (json_object_object_get_ex(section, "busID", &obj)) {
+		json_object *bus_id = json_object_object_get(section, "busID");
+		UINT16 bus_number = (UINT8)json_object_get_int(
+			json_object_object_get(bus_id, "busNumber"));
+		UINT16 segment_number = (UINT8)json_object_get_int(
+			json_object_object_get(bus_id, "segmentNumber"));
+		section_cper->BusId = bus_number + (segment_number << 8);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
 
 	//Remaining fields.
 	UINT64 pcix_command = (UINT64)0x1 << 56;
-	const char *bus_command = json_object_get_string(
-		json_object_object_get(section, "busCommandType"));
-	section_cper->Type = (UINT16)readable_pair_to_integer(
-		json_object_object_get(section, "errorType"));
-	section_cper->BusAddress = json_object_get_uint64(
-		json_object_object_get(section, "busAddress"));
-	section_cper->BusData = json_object_get_uint64(
-		json_object_object_get(section, "busData"));
-	section_cper->BusCommand =
-		strcmp(bus_command, "PCI") == 0 ? 0 : pcix_command;
-	section_cper->RequestorId = json_object_get_uint64(
-		json_object_object_get(section, "busRequestorID"));
-	section_cper->ResponderId = json_object_get_uint64(
-		json_object_object_get(section, "busCompleterID"));
-	section_cper->TargetId = json_object_get_uint64(
-		json_object_object_get(section, "targetID"));
+
+	if (json_object_object_get_ex(section, "errorType", &obj)) {
+		section_cper->Type = (UINT16)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
+	if (json_object_object_get_ex(section, "busAddress", &obj)) {
+		section_cper->BusAddress = json_object_get_uint64(
+			json_object_object_get(section, "busAddress"));
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	if (json_object_object_get_ex(section, "busData", &obj)) {
+		section_cper->BusData = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+	if (json_object_object_get_ex(section, "busCommandType", &obj)) {
+		const char *bus_command = json_object_get_string(obj);
+		section_cper->BusCommand =
+			strcmp(bus_command, "PCI") == 0 ? 0 : pcix_command;
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+	if (json_object_object_get_ex(section, "busRequestorID", &obj)) {
+		section_cper->RequestorId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
+	if (json_object_object_get_ex(section, "busCompleterID", &obj)) {
+		section_cper->ResponderId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 7);
+	}
+	if (json_object_object_get_ex(section, "targetID", &obj)) {
+		section_cper->TargetId = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 8);
+	}
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write to stream, free resources.
 	fwrite(section_cper, sizeof(EFI_PCI_PCIX_BUS_ERROR_DATA), 1, out);
diff --git a/sections/cper-section-pci-dev.c b/sections/cper-section-pci-dev.c
index ccf9f0c..8dc899b 100644
--- a/sections/cper-section-pci-dev.c
+++ b/sections/cper-section-pci-dev.c
@@ -18,67 +18,85 @@
 	json_object *section_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		dev_error->ValidFields, 5, PCI_DEV_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = dev_error->ValidFields };
 
 	//Error status.
-	json_object *error_status =
-		cper_generic_error_status_to_ir(&dev_error->ErrorStatus);
-	json_object_object_add(section_ir, "errorStatus", error_status);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *error_status = cper_generic_error_status_to_ir(
+			&dev_error->ErrorStatus);
+		json_object_object_add(section_ir, "errorStatus", error_status);
+	}
 
 	//ID information.
-	json_object *id_info = json_object_new_object();
-	json_object_object_add(
-		id_info, "vendorID",
-		json_object_new_uint64(dev_error->IdInfo.VendorId));
-	json_object_object_add(
-		id_info, "deviceID",
-		json_object_new_uint64(dev_error->IdInfo.DeviceId));
-	json_object_object_add(
-		id_info, "classCode",
-		json_object_new_uint64(dev_error->IdInfo.ClassCode));
-	json_object_object_add(
-		id_info, "functionNumber",
-		json_object_new_uint64(dev_error->IdInfo.FunctionNumber));
-	json_object_object_add(
-		id_info, "deviceNumber",
-		json_object_new_uint64(dev_error->IdInfo.DeviceNumber));
-	json_object_object_add(
-		id_info, "busNumber",
-		json_object_new_uint64(dev_error->IdInfo.BusNumber));
-	json_object_object_add(
-		id_info, "segmentNumber",
-		json_object_new_uint64(dev_error->IdInfo.SegmentNumber));
-	json_object_object_add(section_ir, "idInfo", id_info);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *id_info = json_object_new_object();
+		json_object_object_add(
+			id_info, "vendorID",
+			json_object_new_uint64(dev_error->IdInfo.VendorId));
+		json_object_object_add(
+			id_info, "deviceID",
+			json_object_new_uint64(dev_error->IdInfo.DeviceId));
+		json_object_object_add(
+			id_info, "classCode",
+			json_object_new_uint64(dev_error->IdInfo.ClassCode));
+		json_object_object_add(
+			id_info, "functionNumber",
+			json_object_new_uint64(
+				dev_error->IdInfo.FunctionNumber));
+		json_object_object_add(
+			id_info, "deviceNumber",
+			json_object_new_uint64(dev_error->IdInfo.DeviceNumber));
+		json_object_object_add(
+			id_info, "busNumber",
+			json_object_new_uint64(dev_error->IdInfo.BusNumber));
+		json_object_object_add(
+			id_info, "segmentNumber",
+			json_object_new_uint64(
+				dev_error->IdInfo.SegmentNumber));
+		json_object_object_add(section_ir, "idInfo", id_info);
+	}
 
 	//Number of following register data pairs.
-	json_object_object_add(section_ir, "memoryNumber",
-			       json_object_new_uint64(dev_error->MemoryNumber));
-	json_object_object_add(section_ir, "ioNumber",
-			       json_object_new_uint64(dev_error->IoNumber));
-	int num_data_pairs = dev_error->MemoryNumber + dev_error->IoNumber;
-
-	//Register pairs, described by the numeric fields.
-	//The actual "pairs" of address and data aren't necessarily 8 bytes long, so can't assume the contents.
-	//Hence the naming "firstHalf" and "secondHalf" rather than "address" and "data".
-	json_object *register_data_pair_array = json_object_new_array();
-	UINT64 *cur_pos = (UINT64 *)(dev_error + 1);
-	for (int i = 0; i < num_data_pairs; i++) {
-		//Save current pair to array.
-		json_object *register_data_pair = json_object_new_object();
-		json_object_object_add(register_data_pair, "firstHalf",
-				       json_object_new_uint64(*cur_pos));
-		json_object_object_add(register_data_pair, "secondHalf",
-				       json_object_new_uint64(*(cur_pos + 1)));
-		json_object_array_add(register_data_pair_array,
-				      register_data_pair);
-
-		//Move to next pair.
-		cur_pos += 2;
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object_object_add(
+			section_ir, "memoryNumber",
+			json_object_new_uint64(dev_error->MemoryNumber));
 	}
-	json_object_object_add(section_ir, "registerDataPairs",
-			       register_data_pair_array);
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object_object_add(
+			section_ir, "ioNumber",
+			json_object_new_uint64(dev_error->IoNumber));
+	}
+
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		int num_data_pairs =
+			dev_error->MemoryNumber + dev_error->IoNumber;
+
+		//Register pairs, described by the numeric fields.
+		//The actual "pairs" of address and data aren't necessarily 8 bytes long, so can't assume the contents.
+		//Hence the naming "firstHalf" and "secondHalf" rather than "address" and "data".
+		json_object *register_data_pair_array = json_object_new_array();
+		UINT64 *cur_pos = (UINT64 *)(dev_error + 1);
+		for (int i = 0; i < num_data_pairs; i++) {
+			//Save current pair to array.
+			json_object *register_data_pair =
+				json_object_new_object();
+			json_object_object_add(
+				register_data_pair, "firstHalf",
+				json_object_new_uint64(*cur_pos));
+			json_object_object_add(
+				register_data_pair, "secondHalf",
+				json_object_new_uint64(*(cur_pos + 1)));
+			json_object_array_add(register_data_pair_array,
+					      register_data_pair);
+
+			//Move to next pair.
+			cur_pos += 2;
+		}
+		json_object_object_add(section_ir, "registerDataPairs",
+				       register_data_pair_array);
+	}
 
 	return section_ir;
 }
@@ -90,37 +108,53 @@
 			1, sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 5,
-		PCI_DEV_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Error status.
-	ir_generic_error_status_to_cper(json_object_object_get(section,
-							       "errorStatus"),
-					&section_cper->ErrorStatus);
+	if (json_object_object_get_ex(section, "errorStatus", &obj)) {
+		ir_generic_error_status_to_cper(obj,
+						&section_cper->ErrorStatus);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
 
 	//Device ID information.
-	json_object *id_info = json_object_object_get(section, "idInfo");
-	section_cper->IdInfo.VendorId = json_object_get_uint64(
-		json_object_object_get(id_info, "vendorID"));
-	section_cper->IdInfo.DeviceId = json_object_get_uint64(
-		json_object_object_get(id_info, "deviceID"));
-	section_cper->IdInfo.ClassCode = json_object_get_uint64(
-		json_object_object_get(id_info, "classCode"));
-	section_cper->IdInfo.FunctionNumber = json_object_get_uint64(
-		json_object_object_get(id_info, "functionNumber"));
-	section_cper->IdInfo.DeviceNumber = json_object_get_uint64(
-		json_object_object_get(id_info, "deviceNumber"));
-	section_cper->IdInfo.BusNumber = json_object_get_uint64(
-		json_object_object_get(id_info, "busNumber"));
-	section_cper->IdInfo.SegmentNumber = json_object_get_uint64(
-		json_object_object_get(id_info, "segmentNumber"));
+	if (json_object_object_get_ex(section, "idInfo", &obj)) {
+		json_object *id_info = obj;
+		section_cper->IdInfo.VendorId = json_object_get_uint64(
+			json_object_object_get(id_info, "vendorID"));
+		section_cper->IdInfo.DeviceId = json_object_get_uint64(
+			json_object_object_get(id_info, "deviceID"));
+		section_cper->IdInfo.ClassCode = json_object_get_uint64(
+			json_object_object_get(id_info, "classCode"));
+		section_cper->IdInfo.FunctionNumber = json_object_get_uint64(
+			json_object_object_get(id_info, "functionNumber"));
+		section_cper->IdInfo.DeviceNumber = json_object_get_uint64(
+			json_object_object_get(id_info, "deviceNumber"));
+		section_cper->IdInfo.BusNumber = json_object_get_uint64(
+			json_object_object_get(id_info, "busNumber"));
+		section_cper->IdInfo.SegmentNumber = json_object_get_uint64(
+			json_object_object_get(id_info, "segmentNumber"));
+		add_to_valid_bitfield(&ui64Type, 1);
+	}
 
 	//Amount of following data pairs.
-	section_cper->MemoryNumber = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "memoryNumber"));
-	section_cper->IoNumber = (UINT32)json_object_get_uint64(
-		json_object_object_get(section, "ioNumber"));
+	if (json_object_object_get_ex(section, "memoryNumber", &obj)) {
+		section_cper->MemoryNumber =
+			(UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+	if (json_object_object_get_ex(section, "ioNumber", &obj)) {
+		section_cper->IoNumber = (UINT32)json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+	json_object *register_pairs = NULL;
+	if (json_object_object_get_ex(section, "registerDataPairs", &obj)) {
+		register_pairs = obj;
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write header out to stream, free it.
 	fwrite(section_cper, sizeof(EFI_PCI_PCIX_DEVICE_ERROR_DATA), 1, out);
@@ -128,23 +162,23 @@
 	free(section_cper);
 
 	//Begin writing register pairs.
-	json_object *register_pairs =
-		json_object_object_get(section, "registerDataPairs");
-	int num_pairs = json_object_array_length(register_pairs);
-	for (int i = 0; i < num_pairs; i++) {
-		//Get the pair array item out.
-		json_object *register_pair =
-			json_object_array_get_idx(register_pairs, i);
+	if (register_pairs != NULL) {
+		int num_pairs = json_object_array_length(register_pairs);
+		for (int i = 0; i < num_pairs; i++) {
+			//Get the pair array item out.
+			json_object *register_pair =
+				json_object_array_get_idx(register_pairs, i);
 
-		//Create the pair array.
-		UINT64 pair[2];
-		pair[0] = json_object_get_uint64(
-			json_object_object_get(register_pair, "firstHalf"));
-		pair[1] = json_object_get_uint64(
-			json_object_object_get(register_pair, "secondHalf"));
+			//Create the pair array.
+			UINT64 pair[2];
+			pair[0] = json_object_get_uint64(json_object_object_get(
+				register_pair, "firstHalf"));
+			pair[1] = json_object_get_uint64(json_object_object_get(
+				register_pair, "secondHalf"));
 
-		//Push to stream.
-		fwrite(pair, sizeof(UINT64), 2, out);
-		fflush(out);
+			//Push to stream.
+			fwrite(pair, sizeof(UINT64), 2, out);
+			fflush(out);
+		}
 	}
 }
diff --git a/sections/cper-section-pcie.c b/sections/cper-section-pcie.c
index ae91cc1..05c1a53 100644
--- a/sections/cper-section-pcie.c
+++ b/sections/cper-section-pcie.c
@@ -30,181 +30,214 @@
 	json_object *section_ir = json_object_new_object();
 
 	//Validation bits.
-	json_object *validation = bitfield_to_ir(
-		pcie_error->ValidFields, 8, PCIE_ERROR_VALID_BITFIELD_NAMES);
-	json_object_object_add(section_ir, "validationBits", validation);
+	ValidationTypes ui64Type = { UINT_64T,
+				     .value.ui64 = pcie_error->ValidFields };
 
 	//Port type.
-	json_object *port_type = integer_to_readable_pair(
-		pcie_error->PortType, 9, PCIE_ERROR_PORT_TYPES_KEYS,
-		PCIE_ERROR_PORT_TYPES_VALUES, "Unknown");
-	json_object_object_add(section_ir, "portType", port_type);
+	if (isvalid_prop_to_ir(&ui64Type, 0)) {
+		json_object *port_type = integer_to_readable_pair(
+			pcie_error->PortType, 9, PCIE_ERROR_PORT_TYPES_KEYS,
+			PCIE_ERROR_PORT_TYPES_VALUES, "Unknown");
+		json_object_object_add(section_ir, "portType", port_type);
+	}
 
 	//Version, provided each half in BCD.
-	json_object *version = json_object_new_object();
-	json_object_object_add(
-		version, "minor",
-		json_object_new_int(bcd_to_int(pcie_error->Version & 0xFF)));
-	json_object_object_add(
-		version, "major",
-		json_object_new_int(bcd_to_int(pcie_error->Version >> 8)));
-	json_object_object_add(section_ir, "version", version);
+	if (isvalid_prop_to_ir(&ui64Type, 1)) {
+		json_object *version = json_object_new_object();
+		json_object_object_add(version, "minor",
+				       json_object_new_int(bcd_to_int(
+					       pcie_error->Version & 0xFF)));
+		json_object_object_add(version, "major",
+				       json_object_new_int(bcd_to_int(
+					       pcie_error->Version >> 8)));
+		json_object_object_add(section_ir, "version", version);
+	}
 
 	//Command & status.
-	json_object *command_status = json_object_new_object();
-	json_object_object_add(
-		command_status, "commandRegister",
-		json_object_new_uint64(pcie_error->CommandStatus & 0xFFFF));
-	json_object_object_add(
-		command_status, "statusRegister",
-		json_object_new_uint64(pcie_error->CommandStatus >> 16));
-	json_object_object_add(section_ir, "commandStatus", command_status);
+	if (isvalid_prop_to_ir(&ui64Type, 2)) {
+		json_object *command_status = json_object_new_object();
+		json_object_object_add(
+			command_status, "commandRegister",
+			json_object_new_uint64(pcie_error->CommandStatus &
+					       0xFFFF));
+		json_object_object_add(
+			command_status, "statusRegister",
+			json_object_new_uint64(pcie_error->CommandStatus >>
+					       16));
+		json_object_object_add(section_ir, "commandStatus",
+				       command_status);
+	}
 
 	//PCIe Device ID.
-	json_object *device_id = json_object_new_object();
-	UINT64 class_id = (pcie_error->DevBridge.ClassCode[0] << 16) +
-			  (pcie_error->DevBridge.ClassCode[1] << 8) +
-			  pcie_error->DevBridge.ClassCode[2];
-	json_object_object_add(
-		device_id, "vendorID",
-		json_object_new_uint64(pcie_error->DevBridge.VendorId));
-	json_object_object_add(
-		device_id, "deviceID",
-		json_object_new_uint64(pcie_error->DevBridge.DeviceId));
-
 	char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%0X",
-		 pcie_error->DevBridge.DeviceId);
-	json_object_object_add(device_id, "deviceIDHex",
-			       json_object_new_string(hexstring_buf));
+	if (isvalid_prop_to_ir(&ui64Type, 3)) {
+		json_object *device_id = json_object_new_object();
+		UINT64 class_id = (pcie_error->DevBridge.ClassCode[0] << 16) +
+				  (pcie_error->DevBridge.ClassCode[1] << 8) +
+				  pcie_error->DevBridge.ClassCode[2];
+		json_object_object_add(
+			device_id, "vendorID",
+			json_object_new_uint64(pcie_error->DevBridge.VendorId));
+		json_object_object_add(
+			device_id, "deviceID",
+			json_object_new_uint64(pcie_error->DevBridge.DeviceId));
 
-	json_object_object_add(device_id, "classCode",
-			       json_object_new_uint64(class_id));
-	json_object_object_add(
-		device_id, "functionNumber",
-		json_object_new_uint64(pcie_error->DevBridge.Function));
-	json_object_object_add(
-		device_id, "deviceNumber",
-		json_object_new_uint64(pcie_error->DevBridge.Device));
-	json_object_object_add(
-		device_id, "segmentNumber",
-		json_object_new_uint64(pcie_error->DevBridge.Segment));
-	json_object_object_add(
-		device_id, "primaryOrDeviceBusNumber",
-		json_object_new_uint64(
-			pcie_error->DevBridge.PrimaryOrDeviceBus));
-	json_object_object_add(
-		device_id, "secondaryBusNumber",
-		json_object_new_uint64(pcie_error->DevBridge.SecondaryBus));
-	json_object_object_add(
-		device_id, "slotNumber",
-		json_object_new_uint64(pcie_error->DevBridge.Slot.Number));
-	json_object_object_add(section_ir, "deviceID", device_id);
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%0X",
+			 pcie_error->DevBridge.DeviceId);
+		json_object_object_add(device_id, "deviceIDHex",
+				       json_object_new_string(hexstring_buf));
+
+		json_object_object_add(device_id, "classCode",
+				       json_object_new_uint64(class_id));
+		json_object_object_add(
+			device_id, "functionNumber",
+			json_object_new_uint64(pcie_error->DevBridge.Function));
+		json_object_object_add(
+			device_id, "deviceNumber",
+			json_object_new_uint64(pcie_error->DevBridge.Device));
+		json_object_object_add(
+			device_id, "segmentNumber",
+			json_object_new_uint64(pcie_error->DevBridge.Segment));
+		json_object_object_add(
+			device_id, "primaryOrDeviceBusNumber",
+			json_object_new_uint64(
+				pcie_error->DevBridge.PrimaryOrDeviceBus));
+		json_object_object_add(
+			device_id, "secondaryBusNumber",
+			json_object_new_uint64(
+				pcie_error->DevBridge.SecondaryBus));
+		json_object_object_add(
+			device_id, "slotNumber",
+			json_object_new_uint64(
+				pcie_error->DevBridge.Slot.Number));
+		json_object_object_add(section_ir, "deviceID", device_id);
+	}
 
 	//Device serial number.
-	json_object_object_add(section_ir, "deviceSerialNumber",
-			       json_object_new_uint64(pcie_error->SerialNo));
+	if (isvalid_prop_to_ir(&ui64Type, 4)) {
+		json_object_object_add(
+			section_ir, "deviceSerialNumber",
+			json_object_new_uint64(pcie_error->SerialNo));
+	}
 
 	//Bridge control status.
-	json_object *bridge_control_status = json_object_new_object();
-	json_object_object_add(
-		bridge_control_status, "secondaryStatusRegister",
-		json_object_new_uint64(pcie_error->BridgeControlStatus &
-				       0xFFFF));
-	json_object_object_add(
-		bridge_control_status, "controlRegister",
-		json_object_new_uint64(pcie_error->BridgeControlStatus >> 16));
-	json_object_object_add(section_ir, "bridgeControlStatus",
-			       bridge_control_status);
+	if (isvalid_prop_to_ir(&ui64Type, 5)) {
+		json_object *bridge_control_status = json_object_new_object();
+		json_object_object_add(
+			bridge_control_status, "secondaryStatusRegister",
+			json_object_new_uint64(pcie_error->BridgeControlStatus &
+					       0xFFFF));
+		json_object_object_add(
+			bridge_control_status, "controlRegister",
+			json_object_new_uint64(
+				pcie_error->BridgeControlStatus >> 16));
+		json_object_object_add(section_ir, "bridgeControlStatus",
+				       bridge_control_status);
+	}
 
 	//Capability structure.
 	//The PCIe capability structure provided here could either be PCIe 1.1 Capability Structure
 	//(36-byte, padded to 60 bytes) or PCIe 2.0 Capability Structure (60-byte). There does not seem
 	//to be a way to differentiate these, so this is left as a b64 dump.
 	int32_t encoded_len = 0;
-
-	char *encoded = base64_encode((UINT8 *)pcie_error->Capability.PcieCap,
+	char *encoded = NULL;
+	if (isvalid_prop_to_ir(&ui64Type, 6)) {
+		char *encoded =
+			base64_encode((UINT8 *)pcie_error->Capability.PcieCap,
 				      60, &encoded_len);
-	if (encoded == NULL) {
-		printf("Failed to allocate encode output buffer. \n");
-	} else {
-		json_object *capability = json_object_new_object();
-		json_object_object_add(capability, "data",
-				       json_object_new_string_len(encoded,
-								  encoded_len));
-		free(encoded);
+		if (encoded == NULL) {
+			printf("Failed to allocate encode output buffer. \n");
+		} else {
+			json_object *capability = json_object_new_object();
+			json_object_object_add(capability, "data",
+					       json_object_new_string_len(
+						       encoded, encoded_len));
+			free(encoded);
 
-		json_object_object_add(section_ir, "capabilityStructure",
-				       capability);
+			json_object_object_add(
+				section_ir, "capabilityStructure", capability);
+		}
 	}
 
 	//AER information.
-	json_object *aer_capability_ir = json_object_new_object();
 	encoded_len = 0;
+	encoded = NULL;
+	if (isvalid_prop_to_ir(&ui64Type, 7)) {
+		json_object *aer_capability_ir = json_object_new_object();
 
-	encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer, 96,
-				&encoded_len);
-	if (encoded == NULL) {
-		printf("Failed to allocate encode output buffer. \n");
-	} else {
-		json_object_object_add(aer_capability_ir, "data",
-				       json_object_new_string_len(encoded,
-								  encoded_len));
-		free(encoded);
+		encoded = base64_encode((UINT8 *)pcie_error->AerInfo.PcieAer,
+					96, &encoded_len);
+		if (encoded == NULL) {
+			printf("Failed to allocate encode output buffer. \n");
+		} else {
+			json_object_object_add(aer_capability_ir, "data",
+					       json_object_new_string_len(
+						       encoded, encoded_len));
+			free(encoded);
+		}
+
+		struct aer_info_registers *aer_decode;
+		aer_decode = (struct aer_info_registers *)&pcie_error->AerInfo
+				     .PcieAer;
+		json_object_object_add(
+			aer_capability_ir, "capability_header",
+			json_object_new_uint64(
+				aer_decode->pcie_capability_header));
+		json_object_object_add(
+			aer_capability_ir, "uncorrectable_error_status",
+			json_object_new_uint64(
+				aer_decode->uncorrectable_error_status));
+
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN,
+			 "0x%08" PRIX32,
+			 aer_decode->uncorrectable_error_status);
+		json_object_object_add(aer_capability_ir,
+				       "uncorrectable_error_status_hex",
+				       json_object_new_string(hexstring_buf));
+
+		json_object_object_add(
+			aer_capability_ir, "uncorrectable_error_mask",
+			json_object_new_uint64(
+				aer_decode->uncorrectable_error_mask));
+		json_object_object_add(
+			aer_capability_ir, "uncorrectable_error_severity",
+			json_object_new_uint64(
+				aer_decode->uncorrectable_error_severity));
+		json_object_object_add(
+			aer_capability_ir, "correctable_error_status",
+			json_object_new_uint64(
+				aer_decode->correctable_error_status));
+
+		snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN,
+			 "0x%08" PRIX32, aer_decode->correctable_error_status);
+		json_object_object_add(aer_capability_ir,
+				       "correctable_error_status_hex",
+				       json_object_new_string(hexstring_buf));
+
+		json_object_object_add(
+			aer_capability_ir, "correctable_error_mask",
+			json_object_new_uint64(
+				aer_decode->correctable_error_mask));
+		json_object_object_add(
+			aer_capability_ir, "capabilites_control",
+			json_object_new_uint64(
+				aer_decode->aer_capabilites_control));
+		json_object_object_add(
+			aer_capability_ir, "tlp_header_0",
+			json_object_new_uint64(aer_decode->tlp_header_log[0]));
+		json_object_object_add(
+			aer_capability_ir, "tlp_header_1",
+			json_object_new_uint64(aer_decode->tlp_header_log[1]));
+		json_object_object_add(
+			aer_capability_ir, "tlp_header_2",
+			json_object_new_uint64(aer_decode->tlp_header_log[2]));
+		json_object_object_add(
+			aer_capability_ir, "tlp_header_3",
+			json_object_new_uint64(aer_decode->tlp_header_log[3]));
+		json_object_object_add(section_ir, "aerInfo",
+				       aer_capability_ir);
 	}
 
-	struct aer_info_registers *aer_decode;
-	aer_decode = (struct aer_info_registers *)&pcie_error->AerInfo.PcieAer;
-	json_object_object_add(
-		aer_capability_ir, "capability_header",
-		json_object_new_uint64(aer_decode->pcie_capability_header));
-	json_object_object_add(
-		aer_capability_ir, "uncorrectable_error_status",
-		json_object_new_uint64(aer_decode->uncorrectable_error_status));
-
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%08" PRIX32,
-		 aer_decode->uncorrectable_error_status);
-	json_object_object_add(aer_capability_ir,
-			       "uncorrectable_error_status_hex",
-			       json_object_new_string(hexstring_buf));
-
-	json_object_object_add(
-		aer_capability_ir, "uncorrectable_error_mask",
-		json_object_new_uint64(aer_decode->uncorrectable_error_mask));
-	json_object_object_add(
-		aer_capability_ir, "uncorrectable_error_severity",
-		json_object_new_uint64(
-			aer_decode->uncorrectable_error_severity));
-	json_object_object_add(
-		aer_capability_ir, "correctable_error_status",
-		json_object_new_uint64(aer_decode->correctable_error_status));
-
-	snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%08" PRIX32,
-		 aer_decode->correctable_error_status);
-	json_object_object_add(aer_capability_ir,
-			       "correctable_error_status_hex",
-			       json_object_new_string(hexstring_buf));
-
-	json_object_object_add(
-		aer_capability_ir, "correctable_error_mask",
-		json_object_new_uint64(aer_decode->correctable_error_mask));
-	json_object_object_add(
-		aer_capability_ir, "capabilites_control",
-		json_object_new_uint64(aer_decode->aer_capabilites_control));
-	json_object_object_add(
-		aer_capability_ir, "tlp_header_0",
-		json_object_new_uint64(aer_decode->tlp_header_log[0]));
-	json_object_object_add(
-		aer_capability_ir, "tlp_header_1",
-		json_object_new_uint64(aer_decode->tlp_header_log[1]));
-	json_object_object_add(
-		aer_capability_ir, "tlp_header_2",
-		json_object_new_uint64(aer_decode->tlp_header_log[2]));
-	json_object_object_add(
-		aer_capability_ir, "tlp_header_3",
-		json_object_new_uint64(aer_decode->tlp_header_log[3]));
-	json_object_object_add(section_ir, "aerInfo", aer_capability_ir);
-
 	return section_ir;
 }
 
@@ -215,101 +248,136 @@
 		(EFI_PCIE_ERROR_DATA *)calloc(1, sizeof(EFI_PCIE_ERROR_DATA));
 
 	//Validation bits.
-	section_cper->ValidFields = ir_to_bitfield(
-		json_object_object_get(section, "validationBits"), 8,
-		PCIE_ERROR_VALID_BITFIELD_NAMES);
+	ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
+	struct json_object *obj = NULL;
 
 	//Version.
-	json_object *version = json_object_object_get(section, "version");
-	UINT32 minor = int_to_bcd(
-		json_object_get_int(json_object_object_get(version, "minor")));
-	UINT32 major = int_to_bcd(
-		json_object_get_int(json_object_object_get(version, "major")));
-	section_cper->Version = minor + (major << 8);
-
-	//Command/status registers.
-	json_object *command_status =
-		json_object_object_get(section, "commandStatus");
-	UINT32 command = (UINT16)json_object_get_uint64(
-		json_object_object_get(command_status, "commandRegister"));
-	UINT32 status = (UINT16)json_object_get_uint64(
-		json_object_object_get(command_status, "statusRegister"));
-	section_cper->CommandStatus = command + (status << 16);
-
-	//Device ID.
-	json_object *device_id = json_object_object_get(section, "deviceID");
-	UINT64 class_id = json_object_get_uint64(
-		json_object_object_get(device_id, "classCode"));
-	section_cper->DevBridge.VendorId = (UINT16)json_object_get_uint64(
-		json_object_object_get(device_id, "vendorID"));
-	section_cper->DevBridge.DeviceId = (UINT16)json_object_get_uint64(
-		json_object_object_get(device_id, "deviceID"));
-	section_cper->DevBridge.ClassCode[0] = class_id >> 16;
-	section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF;
-	section_cper->DevBridge.ClassCode[2] = class_id & 0xFF;
-	section_cper->DevBridge.Function = (UINT8)json_object_get_uint64(
-		json_object_object_get(device_id, "functionNumber"));
-	section_cper->DevBridge.Device = (UINT8)json_object_get_uint64(
-		json_object_object_get(device_id, "deviceNumber"));
-	section_cper->DevBridge.Segment = (UINT16)json_object_get_uint64(
-		json_object_object_get(device_id, "segmentNumber"));
-	section_cper->DevBridge.PrimaryOrDeviceBus =
-		(UINT8)json_object_get_uint64(json_object_object_get(
-			device_id, "primaryOrDeviceBusNumber"));
-	section_cper->DevBridge.SecondaryBus = (UINT8)json_object_get_uint64(
-		json_object_object_get(device_id, "secondaryBusNumber"));
-	section_cper->DevBridge.Slot.Number = (UINT16)json_object_get_uint64(
-		json_object_object_get(device_id, "slotNumber"));
-
-	//Bridge/control status.
-	json_object *bridge_control =
-		json_object_object_get(section, "bridgeControlStatus");
-	UINT32 bridge_status = (UINT16)json_object_get_uint64(
-		json_object_object_get(bridge_control,
-				       "secondaryStatusRegister"));
-	UINT32 control_status = (UINT16)json_object_get_uint64(
-		json_object_object_get(bridge_control, "controlRegister"));
-	section_cper->BridgeControlStatus =
-		bridge_status + (control_status << 16);
-
-	//Capability structure.
-	json_object *capability =
-		json_object_object_get(section, "capabilityStructure");
-	json_object *encoded = json_object_object_get(capability, "data");
-
-	int32_t decoded_len = 0;
-
-	UINT8 *decoded = base64_decode(json_object_get_string(encoded),
-				       json_object_get_string_len(encoded),
-				       &decoded_len);
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		memcpy(section_cper->Capability.PcieCap, decoded, decoded_len);
-		free(decoded);
+	if (json_object_object_get_ex(section, "version", &obj)) {
+		json_object *version = obj;
+		UINT32 minor = int_to_bcd(json_object_get_int(
+			json_object_object_get(version, "minor")));
+		UINT32 major = int_to_bcd(json_object_get_int(
+			json_object_object_get(version, "major")));
+		section_cper->Version = minor + (major << 8);
+		add_to_valid_bitfield(&ui64Type, 1);
 	}
 
+	//Command/status registers.
+	if (json_object_object_get_ex(section, "commandStatus", &obj)) {
+		json_object *command_status = obj;
+		UINT32 command = (UINT16)json_object_get_uint64(
+			json_object_object_get(command_status,
+					       "commandRegister"));
+		UINT32 status = (UINT16)json_object_get_uint64(
+			json_object_object_get(command_status,
+					       "statusRegister"));
+		section_cper->CommandStatus = command + (status << 16);
+		add_to_valid_bitfield(&ui64Type, 2);
+	}
+
+	//Device ID.
+	if (json_object_object_get_ex(section, "deviceID", &obj)) {
+		json_object *device_id = obj;
+		UINT64 class_id = json_object_get_uint64(
+			json_object_object_get(device_id, "classCode"));
+		section_cper->DevBridge.VendorId =
+			(UINT16)json_object_get_uint64(
+				json_object_object_get(device_id, "vendorID"));
+		section_cper->DevBridge.DeviceId =
+			(UINT16)json_object_get_uint64(
+				json_object_object_get(device_id, "deviceID"));
+		section_cper->DevBridge.ClassCode[0] = class_id >> 16;
+		section_cper->DevBridge.ClassCode[1] = (class_id >> 8) & 0xFF;
+		section_cper->DevBridge.ClassCode[2] = class_id & 0xFF;
+		section_cper->DevBridge.Function =
+			(UINT8)json_object_get_uint64(json_object_object_get(
+				device_id, "functionNumber"));
+		section_cper->DevBridge.Device = (UINT8)json_object_get_uint64(
+			json_object_object_get(device_id, "deviceNumber"));
+		section_cper->DevBridge.Segment =
+			(UINT16)json_object_get_uint64(json_object_object_get(
+				device_id, "segmentNumber"));
+		section_cper->DevBridge.PrimaryOrDeviceBus =
+			(UINT8)json_object_get_uint64(json_object_object_get(
+				device_id, "primaryOrDeviceBusNumber"));
+		section_cper->DevBridge.SecondaryBus =
+			(UINT8)json_object_get_uint64(json_object_object_get(
+				device_id, "secondaryBusNumber"));
+		section_cper->DevBridge.Slot.Number =
+			(UINT16)json_object_get_uint64(json_object_object_get(
+				device_id, "slotNumber"));
+		add_to_valid_bitfield(&ui64Type, 3);
+	}
+
+	//Bridge/control status.
+	if (json_object_object_get_ex(section, "bridgeControlStatus", &obj)) {
+		json_object *bridge_control = obj;
+		UINT32 bridge_status = (UINT16)json_object_get_uint64(
+			json_object_object_get(bridge_control,
+					       "secondaryStatusRegister"));
+		UINT32 control_status = (UINT16)json_object_get_uint64(
+			json_object_object_get(bridge_control,
+					       "controlRegister"));
+		section_cper->BridgeControlStatus =
+			bridge_status + (control_status << 16);
+		add_to_valid_bitfield(&ui64Type, 5);
+	}
+
+	//Capability structure.
+	int32_t decoded_len = 0;
+	UINT8 *decoded = NULL;
+	json_object *encoded = NULL;
+	if (json_object_object_get_ex(section, "capabilityStructure", &obj)) {
+		json_object *capability = obj;
+		json_object *encoded =
+			json_object_object_get(capability, "data");
+
+		UINT8 *decoded = base64_decode(
+			json_object_get_string(encoded),
+			json_object_get_string_len(encoded), &decoded_len);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			memcpy(section_cper->Capability.PcieCap, decoded,
+			       decoded_len);
+			free(decoded);
+		}
+		add_to_valid_bitfield(&ui64Type, 6);
+	}
+
+	decoded = NULL;
+	encoded = NULL;
 	//AER capability structure.
-	json_object *aer_info = json_object_object_get(section, "aerInfo");
-	encoded = json_object_object_get(aer_info, "data");
-	decoded_len = 0;
+	if (json_object_object_get_ex(section, "aerInfo", &obj)) {
+		json_object *aer_info = obj;
+		encoded = json_object_object_get(aer_info, "data");
+		decoded_len = 0;
 
-	decoded = base64_decode(json_object_get_string(encoded),
-				json_object_get_string_len(encoded),
-				&decoded_len);
+		decoded = base64_decode(json_object_get_string(encoded),
+					json_object_get_string_len(encoded),
+					&decoded_len);
 
-	if (decoded == NULL) {
-		printf("Failed to allocate decode output buffer. \n");
-	} else {
-		memcpy(section_cper->AerInfo.PcieAer, decoded, decoded_len);
-		free(decoded);
+		if (decoded == NULL) {
+			printf("Failed to allocate decode output buffer. \n");
+		} else {
+			memcpy(section_cper->AerInfo.PcieAer, decoded,
+			       decoded_len);
+			free(decoded);
+		}
+		add_to_valid_bitfield(&ui64Type, 7);
 	}
 
 	//Miscellaneous value fields.
-	section_cper->PortType = (UINT32)readable_pair_to_integer(
-		json_object_object_get(section, "portType"));
-	section_cper->SerialNo = json_object_get_uint64(
-		json_object_object_get(section, "deviceSerialNumber"));
+	if (json_object_object_get_ex(section, "portType", &obj)) {
+		section_cper->PortType = (UINT32)readable_pair_to_integer(obj);
+		add_to_valid_bitfield(&ui64Type, 0);
+	}
+	if (json_object_object_get_ex(section, "deviceSerialNumber", &obj)) {
+		section_cper->SerialNo = json_object_get_uint64(obj);
+		add_to_valid_bitfield(&ui64Type, 4);
+	}
+
+	section_cper->ValidFields = ui64Type.value.ui64;
 
 	//Write out to stream, free resources.
 	fwrite(section_cper, sizeof(EFI_PCIE_ERROR_DATA), 1, out);