private void processProgramHeader(ElfProgramHeader elfProgramHeader, int segmentNumber)
			throws AddressOutOfBoundsException {

// FIXME: If physical and virtual addresses do not match this may be an overlay situation.
// If sections exist they should use file offsets to correlate to overlay segment - the
// problem is that we can only handle a single memory block per overlay range - we may need to
// not load segment in this case and defer to section!!  Such situations may also
// occur for mapped memory regions as seen with some Harvard Architecture processors.  The
// process-specific extension should control the outcome.

		Address address = getSegmentLoadAddress(elfProgramHeader);
		AddressSpace space = address.getAddressSpace();

		long addr = elfProgramHeader.getVirtualAddress();
		long loadSizeBytes = elfProgramHeader.getAdjustedLoadSize();
		long fullSizeBytes = elfProgramHeader.getAdjustedMemorySize();

		boolean maintainExecuteBit = elf.getSectionHeaderCount() == 0;

		if (fullSizeBytes <= 0) {
			if (!space.isLoadedMemorySpace() && loadSizeBytes > 0) {
				fullSizeBytes = loadSizeBytes;
			}
			else {
				log("Skipping zero-length segment [" + segmentNumber + "," +
					elfProgramHeader.getDescription() + "] at address " + address.toString(true));
				return;
			}
		}

		if (!space.isValidRange(address.getOffset(), fullSizeBytes)) {
			log("Skipping unloadable segment [" + segmentNumber + "] at address " +
				address.toString(true) + " (size=" + fullSizeBytes + ")");
			return;
		}

		try {
			// Only allow segment fragmentation if section headers are defined
			boolean isFragmentationOK = (elf.getSectionHeaderCount() != 0);

			String comment = getSectionComment(addr, fullSizeBytes, space.getAddressableUnitSize(),
				elfProgramHeader.getDescription(), address.isLoadedMemoryAddress());
			if (!maintainExecuteBit && elfProgramHeader.isExecute()) {
				comment += " (disabled execute bit)";
			}

			String blockName = getSegmentName(elfProgramHeader, segmentNumber);
			if (loadSizeBytes != 0) {
				addInitializedMemorySection(elfProgramHeader, elfProgramHeader.getOffset(),
					loadSizeBytes, address, blockName, elfProgramHeader.isRead(),
					elfProgramHeader.isWrite(),
					maintainExecuteBit ? elfProgramHeader.isExecute() : false, comment,
					isFragmentationOK,
					elfProgramHeader.getType() == ElfProgramHeaderConstants.PT_LOAD);
			}

			// NOTE: Uninitialized portions of segments will be added via expandProgramHeaderBlocks
			// when no sections are present.  When sections are present, we assume sections will
			// be created which correspond to these areas.
		}
		catch (AddressOverflowException e) {
			log("Failed to load segment [" + segmentNumber + "]: " + getMessage(e));
		}
	}
Process the specified program header by ensuring that it has a suitable memory address assigned
and added to the memory resolver.
@param elfProgramHeader ELF program header to be processed
@param segmentNumber program header index number
@throws AddressOutOfBoundsException if an invalid memory address is encountered
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java