private void expandProgramHeaderBlocks(TaskMonitor monitor) throws CancelledException {

		ElfProgramHeader[] elfProgramHeaders = elf.getProgramHeaders();

		monitor.setMessage("Exapanding Program Segments...");
		monitor.initialize(elfProgramHeaders.length);
		for (int i = 0; i < elfProgramHeaders.length; ++i) {
			monitor.checkCancelled();
			monitor.incrementProgress(1);

			ElfProgramHeader elfProgramHeader = elfProgramHeaders[i];
			if (elfProgramHeaders[i].getType() == ElfProgramHeaderConstants.PT_LOAD) {

				MemoryBlock block = null;
				AddressSpace space;
				Address expandStart;

				long segmentMemorySizeBytes = elfProgramHeader.getAdjustedMemorySize();
				if (segmentMemorySizeBytes <= 0) {
					continue;
				}

				long loadSizeBytes = elfProgramHeader.getAdjustedLoadSize();
				if (loadSizeBytes == 0) {
					expandStart = getSegmentLoadAddress(elfProgramHeader);
					space = expandStart.getAddressSpace();
				}
				else {
					// Identify resolved segment block tail-end
					List<AddressRange> resolvedLoadAddresses =
						getResolvedLoadAddresses(elfProgramHeader);
					if (resolvedLoadAddresses == null) {
						continue;
					}
					AddressRange addressRange =
						resolvedLoadAddresses.get(resolvedLoadAddresses.size() - 1);
					Address endAddr = addressRange.getMaxAddress();
					space = endAddr.getAddressSpace();
					if (space.isOverlaySpace()) {
						continue; // tail-end was displaced by another - do not extend
					}
					block = memory.getBlock(endAddr);
					if (!block.getEnd().equals(endAddr)) {
						continue; // tail-end merged with another - do not extend
					}
					expandStart = endAddr.add(1);
				}

				long fullSizeBytes = segmentMemorySizeBytes;
				if (expandStart == null || fullSizeBytes <= loadSizeBytes) {
					continue; //
				}

				try {
					long expandSize = fullSizeBytes - loadSizeBytes;
					Address expandEnd = expandStart.addNoWrap(expandSize - 1);
					AddressSet intersectRange = memory.intersectRange(expandStart, expandEnd);
					if (!intersectRange.isEmpty()) {
						Address firstIntersectAddr = intersectRange.getFirstRange().getMinAddress();
						if (expandStart.equals(firstIntersectAddr)) {
							continue; // no room for expansion
						}
						expandEnd = firstIntersectAddr.previous();
					}
					if (block == null) {
						// Create new zeroed segment block with no bytes from file
						String blockName = String.format("%s%d", SEGMENT_NAME_PREFIX, i);
						MemoryBlock newBlock = memory.createInitializedBlock(blockName, expandStart,
							expandSize, (byte) 0, monitor, false);
						newBlock.setSourceName(BLOCK_SOURCE_NAME);
						newBlock.setComment("Zero-initialized segment");
					}
					else {
						// Expand tail end of segment which had portion loaded from file
						Address oldBlockEnd = block.getEnd();
						MemoryBlock expandBlock =
							memory.createInitializedBlock(block.getName() + ".expand", expandStart,
								expandSize, (byte) 0, monitor, false);
						MemoryBlock extBlock = memory.join(block, expandBlock);
						extBlock.setComment(extBlock.getComment() + " (zero-extended)");
						joinProgramTreeFragments(oldBlockEnd, expandStart);
					}
				}
				catch (Exception e) {
					log("Failed to " + (block != null ? "expand" : "create") + " segment [" + i +
						"," + elfProgramHeader.getDescription() + "] at address " +
						expandStart.toString(true));
				}
			}
		}
	}
Expand/create PT_LOAD program header block regions which are zeroed
- to the extent possible.  This should only be done when section headers are
not present.
@param monitor load task monitor
@throws CancelledException if load task is cancelled
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java