private void processResourceTable(MessageLog log, Program program, ResourceTable rt,
			SegmentedAddressSpace space, FileBytes fileBytes, TaskMonitor monitor) {
		Listing listing = program.getListing();

		if (rt == null) {
			return; //there is not a resource table in this program...
		}

		int id = 0;//this is used to name rsrc mem blocks...
		ResourceType[] types = rt.getResourceTypes();
		for (ResourceType type : types) {
			//String type = types[t].toString();
			Resource[] resources = type.getResources();
			for (Resource resource : resources) {

				int segidx = space.getNextOpenSegment(program.getMemory().getMaxAddress());
				Address addr = space.getAddress(segidx, 0);

				try {
					long offset = Integer.toUnsignedLong(resource.getFileOffsetShifted());
					long length = Integer.toUnsignedLong(resource.getFileLengthShifted());
					long extra = offset + length - fileBytes.getSize();
					if (extra > 0) {
						log.appendMsg(
							"Resource at 0x%x exceeds file length by 0x%x bytes...truncating"
									.formatted(offset, extra));
						length -= extra;
					}
					if (length > 0) {
						MemoryBlockUtils.createInitializedBlock(program, false, "Rsrc" + (id++),
							addr, fileBytes, offset, length, "", "", true, false, false, log);
					}
				}
				catch (AddressOverflowException e) {
					throw new RuntimeException(e);
				}

				//create a comment to describe this resource...
				StringBuilder buf = new StringBuilder();
				buf.append("Resource Type:  " + Conv.toHexString(type.getTypeID()) + " (" + type +
					")" + "\n");
				buf.append(
					"File Length:    " + Conv.toHexString(resource.getFileLengthShifted()) + "\n");
				buf.append(
					"File Offset:    " + Conv.toHexString(resource.getFileOffsetShifted()) + "\n");
				buf.append("Attributes:     " + Conv.toHexString(resource.getFlagword()) + " (");
				if (resource.isMoveable()) {
					buf.append("Moveable");
				}
				if (resource.isPreload()) {
					buf.append(",Preload");
				}
				if (resource.isPure()) {
					buf.append(",Pure");
				}
				buf.append(")" + "\n");
				buf.append("Resource ID:    " + resource + "\n");
				buf.append("Handle:         " + Conv.toHexString(resource.getHandle()) + "\n");
				buf.append("Usage:          " + Conv.toHexString(resource.getUsage()) + "\n");
				CodeUnit cu = listing.getCodeUnitAt(addr);
				if (cu != null) {
					cu.setComment(CommentType.PRE, buf.toString());
				}

				//if this resource is a string table,
				//then go and create the strings...
				if (resource instanceof ResourceStringTable) {
					ResourceStringTable rst = (ResourceStringTable) resource;
					LengthStringSet[] strings = rst.getStrings();
					for (LengthStringSet string : strings) {
						try {
							long dis = string.getIndex() - resource.getFileOffsetShifted();
							Address straddr = addr.addNoWrap(dis);
							listing.createData(straddr, new ByteDataType(), 1);
							straddr = straddr.addNoWrap(1);
							listing.createData(straddr, new StringDataType(),
								Byte.toUnsignedInt(string.getLength()));
						}
						catch (AddressOverflowException | CodeUnitInsertionException e) {
							log.appendMsg("Error creating data");
							log.appendException(e);
						}
					}
				}
			}
		}
	}
A {@link Loader} for processing Microsoft New Executable (NE) files.
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java