public static ByteProvider extractMapping(DyldCacheEntry entry, String segmentName,
			SplitDyldCache splitDyldCache,
			Map<DyldCacheMappingInfo, Map<Long, DyldFixup>> slideFixupMap, FSRL fsrl,
			TaskMonitor monitor) throws IOException, MachException, CancelledException {

		int magic = MachConstants.MH_MAGIC_64;
		List<Range<Long>> ranges = new ArrayList<>(entry.rangeSet().asRanges());
		DyldCacheMappingInfo mappingInfo = entry.mappingInfo();
		int allSegmentsSize = SegmentCommand.size(magic) * ranges.size();

		// Mach-O Header
		byte[] header = MachHeader.create(magic, 0x100000c, 0x80000002, 6, ranges.size(),
			allSegmentsSize, 0x42100085, 0);

		// Segment commands and data
		List<byte[]> segments = new ArrayList<>();
		List<byte[]> data = new ArrayList<>();
		int current = header.length + allSegmentsSize;
		try (ByteProvider slidProvider =
			new DyldCacheSlidProvider(entry.mappingInfo(), splitDyldCache, entry.splitCacheIndex(),
				slideFixupMap, monitor)) {
			for (int i = 0; i < ranges.size(); i++) {
				Range<Long> range = ranges.get(i);

				// Segment Command
				long dataSize = range.upperEndpoint() - range.lowerEndpoint();
				segments.add(
					SegmentCommand.create(magic,
						"%s.%d.%d".formatted(segmentName, entry.splitCacheIndex(), i),
						range.lowerEndpoint(), dataSize, current, dataSize,
						mappingInfo.getMaxProtection(), mappingInfo.getMaxProtection(), 0));

				// Data
				data.add(slidProvider.readBytes(
					range.lowerEndpoint() - mappingInfo.getAddress() + mappingInfo.getFileOffset(),
					dataSize));

				current += dataSize;
			}
		}

		// Combine pieces
		int dataSize = data.stream().mapToInt(d -> d.length).sum();
		int totalSize = header.length + allSegmentsSize + dataSize;
		byte[] result = new byte[totalSize + FOOTER_V1.length];
		System.arraycopy(header, 0, result, 0, header.length);
		current = header.length;
		for (byte[] segment : segments) {
			System.arraycopy(segment, 0, result, current, segment.length);
			current += segment.length;
		}
		for (byte[] d : data) {
			System.arraycopy(d, 0, result, current, d.length);
			current += d.length;
		}

		// Add footer
		System.arraycopy(FOOTER_V1, 0, result, result.length - FOOTER_V1.length, FOOTER_V1.length);

		return new ByteArrayProvider(result, fsrl);
	}
Gets a {@link ByteProvider} that contains a byte mapping from a {@link DyldCacheFileSystem}

@param entry The mapping's {@link DyldCacheEntry}
@param segmentName The name of the segment in the resulting Mach-O
@param splitDyldCache The {@link SplitDyldCache}
@param slideFixupMap A {@link Map} of {@link DyldFixup}s to perform
@param fsrl {@link FSRL} to assign to the resulting {@link ByteProvider}
@param monitor {@link TaskMonitor}
@return {@link ByteProvider} containing the bytes of the mapping
@throws MachException If there was an error creating Mach-O headers
@throws IOException If there was an IO-related issue with extracting the mapping
@throws CancelledException If the user cancelled the operation
Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dyldcache/DyldCacheExtractor.java