private void createDynamicEntryPoints(ElfDynamicType dynamicEntryType,
			ElfDynamicType entryArraySizeType, String baseName, TaskMonitor monitor)
			throws CancelledException {

		ElfDynamicTable dynamicTable = elf.getDynamicTable();
		if (dynamicTable == null) {
			return;
		}

		try {
			long entryAddrOffset =
				elf.adjustAddressForPrelink(dynamicTable.getDynamicValue(dynamicEntryType));
			if (entryArraySizeType == null) {
				// single entry addr case
				createEntryFunction("_" + dynamicEntryType.name, entryAddrOffset);
				return;
			}

			// entryAddrOffset points to array of entry addresses
			Address entryArrayAddr = getDefaultAddress(entryAddrOffset);

			DataType dt = elf.is32Bit() ? DWordDataType.dataType : QWordDataType.dataType;
			if (program.getRelocationTable().hasRelocation(entryArrayAddr) ||
				(getImageBaseWordAdjustmentOffset() == 0 && elf.adjustAddressForPrelink(0) == 0)) {
				// apply pointers if relocations applied to array entries or no scalar adjustment
				dt = new PointerDataType(program.getDataTypeManager());
			}

			long arraySize = dynamicTable.getDynamicValue(entryArraySizeType);
			long elementCount = arraySize / dt.getLength();

			monitor.setMessage("Processing " + baseName + " array...");
			monitor.initialize(elementCount);
			for (int i = 0; i < elementCount; i++) {

				monitor.checkCancelled();
				monitor.incrementProgress(1);

				Address addr = entryArrayAddr.add(i * dt.getLength());
				Data data = createData(addr, dt);
				if (data == null) {
					break;
				}

				Object value = data.getValue();
				Address funcAddr;
				if (value instanceof Address) {
					funcAddr = (Address) value;
				}
				else {
					Scalar s = (Scalar) value;
					long funcAddrOffset = s.getValue();
					if (funcAddrOffset == 0) {
						continue;
					}
					funcAddrOffset = elf.adjustAddressForPrelink(funcAddrOffset);
					funcAddr = getDefaultAddress(funcAddrOffset);
					data.addOperandReference(0, funcAddr, RefType.DATA, SourceType.ANALYSIS);
				}
				createEntryFunction(baseName + i, funcAddr);
			}
		}
		catch (NotFoundException e) {
			// ignore
		}

	}
Transition memory range to read-only
@param range constrained read-only region or null for entire load segment
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java