public void resolve(TaskMonitor monitor) throws CancelledException {

		monitor.setMessage("Loading memory blocks...");

		if (sectionMemoryMap != null) {
			throw new IllegalStateException("already resolved");
		}

		if (!program.getMemory().isEmpty()) {
			throw new IllegalStateException("program memory blocks already exist - unsupported");
		}

		// Maintain file allocation map for resolving file section overlap (i.e., shared bytes)
		// AddressRange -> section loaded from file
		AddressRangeObjectMap<AllocatedFileSectionRange> fileAllocationMap =
			new AddressRangeObjectMap<>();

		// build-up mapping of sections to a sequence of memory ranges
		sectionMemoryMap = new HashMap<>();

		physicalLoadedOverlaySet = new AddressSet();
		for (MemoryBlock block : getMemory().getBlocks()) {
			Address minAddr = block.getStart();
			Address maxAddr = block.getEnd();
			if (minAddr.isLoadedMemoryAddress() && minAddr.getAddressSpace().isOverlaySpace()) {
				physicalLoadedOverlaySet.add(minAddr.getPhysicalAddress(),
					maxAddr.getPhysicalAddress());
			}
		}

		// process sections in reverse order - last-in takes precedence
		int sectionCount = sections.size();
		monitor.initialize(sectionCount);
		for (int index = sectionCount - 1; index >= 0; --index) {
			monitor.checkCancelled();
			resolveSectionMemory(sections.get(index), fileAllocationMap, monitor);
			monitor.incrementProgress(1);
		}
	}
Perform final resolve of all defined memory "sections" to establish final memory mappings.
This method will resolve all conflicts and create memory blocks within the associated program.
@param monitor
@throws CancelledException
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MemorySectionResolver.java