private List<AddressRange> allocateSectionMemory(MemorySection section,
			AddressRangeObjectMap<AllocatedFileSectionRange> fileAllocationMap, TaskMonitor monitor)
			throws CancelledException {

		List<AddressRange> rangeList = new ArrayList<>();

		Address targetMinPhysicalAddr = section.getMinPhysicalAddress();
		Address targetMaxPhysicalAddr = section.getMaxPhysicalAddress();

		if (!section.isLoaded()) {
			// section should be assigned to named overlay in OTHER space
			if (section.getPhysicalAddressSpace() != AddressSpace.OTHER_SPACE) {
				throw new AssertException();
			}
			rangeList.add(new OverlayAddressRange(targetMinPhysicalAddr, targetMaxPhysicalAddr));
			return rangeList;
		}

		AddressSet physicalConflictAddrSet =
			getMemoryConflictSet(targetMinPhysicalAddr, targetMaxPhysicalAddr);
		boolean noConflict = physicalConflictAddrSet.isEmpty();
		if (noConflict || !section.isFragmentationOK) {
			if (noConflict) {
				// add normal non-conflicting section
				rangeList.add(section.getPhysicalAddressRange());
			}
			else {
				// if conflict and fragmentation not permitted bump section into overlay
				AddressRange physicalAddrRange = section.getPhysicalAddressRange();
				rangeList.add(
					new OverlayAddressRange(physicalAddrRange.getMinAddress(),
						physicalAddrRange.getMaxAddress()));
			}
			AllocatedFileSectionRange fileRange = new AllocatedFileSectionRange(section,
				section.getFileOffset(), section.length, targetMinPhysicalAddr);
			fileAllocationMap.setObject(targetMinPhysicalAddr, targetMaxPhysicalAddr, fileRange);
			return rangeList;
		}

		try {
			long fileOffset = section.getFileOffset(); // only used for initialized sections
			for (AddressRange physicalAddrRange : physicalConflictAddrSet.getAddressRanges()) {
				monitor.checkCancelled();

				Address physicalRangeMinAddr = physicalAddrRange.getMinAddress();
				Address physicalRangeMaxAddr = physicalAddrRange.getMaxAddress();

				// Handle chunk before range
				if (targetMinPhysicalAddr.compareTo(physicalRangeMinAddr) < 0) {
					// new range - no conflict
					fileOffset = addSectionRange(section, targetMinPhysicalAddr,
						physicalRangeMinAddr.subtract(1),
						fileOffset, rangeList);
					targetMinPhysicalAddr = physicalRangeMinAddr;
				}

				// Handle overlap/conflict region
				fileOffset = reconcileSectionRangeOverlap(section, physicalRangeMinAddr,
					physicalRangeMaxAddr, fileOffset,
					rangeList);
				targetMinPhysicalAddr = physicalRangeMaxAddr.addNoWrap(1); // could bump into end of space
			}

			// Handle residual chunk
			if (targetMinPhysicalAddr.compareTo(targetMaxPhysicalAddr) <= 0) {
				// new range - no conflict
				fileOffset = addSectionRange(section, targetMinPhysicalAddr, targetMaxPhysicalAddr,
					fileOffset, rangeList);
			}
		}
		catch (AddressOverflowException e) {
			// ignore - end of space
		}
		return rangeList;
	}
Allocate section to memory ranges based upon address-mapping of file offsets.
The fileAllocationMap is used to map regions of the section to previously processed 
sections or to identify new unclaimed address-mapped file regions.  Those ranges 
which match memory-mapped file ranges are identified using a ProxyAddressRange, 
memory-mapped file range conflicts are identified using an OverlayAddressRange, while
new ranges will be identified by an AddressRangeImpl.
@param section new section to be processed
@param fileAllocationMap address to file region map
@param monitor task monitor
@return address range list section memory assignment
@throws CancelledException
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MemorySectionResolver.java