private void processSections(ContainerHeader header, Program program, FileBytes fileBytes,
			ImportStateCache importState, MessageLog log, TaskMonitor monitor)
			throws AddressOverflowException, IOException {

		List<SectionHeader> sections = header.getSections();
		for (SectionHeader section : sections) {
			if (monitor.isCancelled()) {
				return;
			}

			Address start = getSectionAddressAligned(section, program);

			monitor.setMessage("Creating section at 0x" + start + "...");

			if (!section.getSectionKind().isInstantiated()) {
				continue;
			}

			if (section.getSectionKind() == SectionKind.PackedData) {
				byte[] unpackedData = section.getUnpackedData(monitor);
				ByteArrayInputStream is = new ByteArrayInputStream(unpackedData);
				MemoryBlockUtils.createInitializedBlock(program, false, section.getName(), start,
					is, unpackedData.length, section.getSectionKind().toString(), null,
					section.isRead(), section.isWrite(), section.isExecute(), log, monitor);
			}
			else {
				MemoryBlockUtils.createInitializedBlock(program, false, section.getName(), start,
					fileBytes, section.getContainerOffset(), section.getUnpackedLength(),
					section.getSectionKind().toString(), null, section.isRead(), section.isWrite(),
					section.isExecute(), log);
			}

			importState.setMemoryBlockForSection(section, program.getMemory().getBlock(start));

			if (section.getUnpackedLength() < section.getTotalLength()) {
				start = start.add(section.getUnpackedLength());

				MemoryBlockUtils.createUninitializedBlock(program, false, section.getName(), start,
					section.getTotalLength() - section.getUnpackedLength(),
					section.getSectionKind().toString(), null, section.isRead(), section.isWrite(),
					section.isExecute(), log);
			}
		}
	}
TODO determine how to correctly identify TOC location
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/PefLoader.java