@Override
	protected void readControlBlock(boolean applyStruct)
			throws InvalidControlBlockException, CodeUnitInsertionException {

		super.readControlBlock(applyStruct);

		int ptrSzOffset = getStructureComponent(infoProgramStruct, "ptrSz");
		int byteOrderOffset = getStructureComponent(infoProgramStruct, "byteOrder");
		int onPassPtrOffset = getStructureComponent(infoProgramStruct, "onPass");
		int onErrorPtrOffset = getStructureComponent(infoProgramStruct, "onError");
		int onDonePtrOffset = getStructureComponent(infoProgramStruct, "onDone");

		int sprintfPtrOffset = getStructureComponent(infoProgramStruct, "sprintf5");
		int sprintfBufferPtrOffset = getStructureComponent(infoProgramStruct, "sprintf5buffer");

		if (applyStruct) {
			forceCodePointer(infoStructAddr.add(onPassPtrOffset));
			forceCodePointer(infoStructAddr.add(onErrorPtrOffset));
			forceCodePointer(infoStructAddr.add(onDonePtrOffset));
			forceCodePointer(infoStructAddr.add(sprintfBufferPtrOffset));
		}

		DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), infoStructAddr);
		try {

			// Check byte-order
			int byteOrder = memBuffer.getInt(byteOrderOffset);
			if (byteOrder != 0x1020304) {
				throw new InvalidControlBlockException(
					"TestInfo @ " + infoStructAddr.toString(true) +
						" has invalid byteOrder - language endianness may be incorrect (" +
						Integer.toHexString(byteOrder) + ")");
			}

			// Check pointer size
			// Must adjust size recorded by compiler
			int ptrSize = memBuffer.getInt(ptrSzOffset);
			DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization();
			ptrSize *= dataOrganization.getCharSize();
			if (ptrSize < 2 || ptrSize > 8) {
				throw new InvalidControlBlockException("TestInfo @ " +
					infoStructAddr.toString(true) + " has unsupported pointer size: " + ptrSize);
			}
			if (ptrSize != pointerSize) {
				String id =
					program.getLanguageID() + ":" + program.getCompilerSpec().getCompilerSpecID();
				Msg.warn(this, "TestInfo @ " + infoStructAddr.toString(true) + " ptrSz=" + ptrSize +
					" differs from data-organization size of " + pointerSize + " (" + id + ")");
			}

			// get onPass function pointer		
			onPassFunctionAddress = readCodePointer(memBuffer, onPassPtrOffset, applyStruct);

			// get onError function pointer		
			onErrorFunctionAddress = readCodePointer(memBuffer, onErrorPtrOffset, applyStruct);

			// get onDone function pointer		
			onDoneFunctionAddress = readCodePointer(memBuffer, onDonePtrOffset, applyStruct);

			// get sprintf function pointer		
			sprintfFunctionAddress = readCodePointer(memBuffer, sprintfPtrOffset, applyStruct);

			// get sprintf buffer pointer		
			sprintfBufferAddress = readCodePointer(memBuffer, sprintfBufferPtrOffset, applyStruct);

		}
		catch (MemoryAccessException e) {
			throw new InvalidControlBlockException("TestInfo program read error", e);
		}

		// Find all test groups by locating corresponding TestInfo structure	
		findTestGroups(applyStruct);

	}
Find Main TestInfo structure within memory and return instance of PCodeTestControlBlock
@param program
@param testFile original binary test file
@param restrictedSet a restricted set to be searched for control structures
@param cachedProgramPath program path within program file cache
@param testInfoStruct TestInfo structure definition
@param groupInfoStruct GroupInfo structure definition
@param applyStruct create structure Data within program if true
@param testResults test results storage object
@return instance of PCodeTestControlBlock
@throws InvalidControlBlockException
@throws CodeUnitInsertionException
Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/PCodeTestControlBlock.java