protected Address readCodePointer(MemBuffer buffer, int bufferOffset, boolean updateReference) throws MemoryAccessException {
		Address codePtr = readPointer(buffer, bufferOffset, codeSpace, updateReference);

		// treat null pointer as special case - just return it
		if (codePtr.getOffset() == 0) {
			return codePtr;
		}

		// shift the pointer if code pointers are stored in memory shifted.
		int ptrShift = program.getDataTypeManager().getDataOrganization().getPointerShift();
		if (ptrShift != 0) {
			codePtr = codePtr.getNewAddress(codePtr.getOffset() << ptrShift);
		}

		// Check for potential procedure descriptor indirection (e.g., PPC64 .opd)
		// in which case a function pointer may refer to a procedure descriptor
		// record (we assume here that the first entry has been marked-up by the importer
		// and corresponds to the true function address

		Address ptr = readDefinedDataPointer(codePtr);
		if (ptr != null) {
			// use stored pointer from procedure descriptor table
			codePtr = ptr;
		}
		else {
			// if pointer refers to simple jump/thunk - follow it
			Address addr = PseudoDisassembler.getNormalizedDisassemblyAddress(program, codePtr);
			InstructionBlock codeBlock = disassembler.pseudoDisassembleBlock(addr, null, 1);
			if (codeBlock == null || codeBlock.isEmpty() || codeBlock.hasInstructionError()) {
				throw new MemoryAccessException(
					"Code pointer " + codePtr.toString(true) + " does not refer to valid code");
			}
			// TODO: may need to handle more complex thunks
			Instruction instr = codeBlock.getInstructionAt(addr);
			FlowType flowType = instr.getFlowType();
			if (flowType.isJump()) {
				Address[] flows = instr.getFlows();
				if (flows.length == 1) {
					codePtr = flows[0];
				}
			}
		}

		return codePtr;
	}
Check for a Data pointer at the specified address and return the referenced
address.
@param addr address of stored pointer
@return pointer referenced address or null if no pointer found
Ghidra/Features/Base/src/main/java/ghidra/test/processors/support/PCodeTestAbstractControlBlock.java