public static List<Address> fixupChainedPointers(List<DyldFixup> fixups, Program program,
			Address imagebase, List<String> libraryPaths, MessageLog log, TaskMonitor monitor)
			throws CancelledException {
		if (fixups.isEmpty()) {
			return List.of();
		}

		Memory memory = program.getMemory();
		SymbolTable symbolTable = program.getSymbolTable();
		ExternalManager extMgr = program.getExternalManager();

		// Figure out how much space in the EXTERNAL block we need, and make it
		Address extAddr = null;
		try {
			long externalSize = fixups.stream()
					.filter(e -> e.value() == null && e.symbol() != null && e.libOrdinal() != null)
					.mapToLong(DyldFixup::size)
					.sum();
			if (externalSize > 0) {
				extAddr = MachoProgramUtils.addExternalBlock(program, externalSize, log);
			}
		}
		catch (Exception e) {
			log.appendMsg(
				"Failed to create space in EXTERNAL block for chained fixups: " + e.getMessage());
		}

		List<Address> fixedAddrs = new ArrayList<>();
		monitor.initialize(fixups.size(), "Fixing up chained pointers...");
		for (DyldFixup fixup : fixups) {
			monitor.increment();
			Status status = Status.UNSUPPORTED;
			Address fixupAddr = imagebase.add(fixup.offset());
			Long fixupValue = fixup.value();
			String fixupSymbol = fixup.symbol();
			long[] value = new long[] {};
			try {
				if (fixupValue == null && fixupSymbol != null && fixup.libOrdinal() != null &&
					extAddr != null) {
					try {
						symbolTable.createLabel(extAddr, fixupSymbol, SourceType.IMPORTED);
						fixupValue = extAddr.getOffset();
						Function stubFunc = MachoProgramBuilder.createOneByteFunction(program,
							fixupSymbol, extAddr);
						if (stubFunc != null) {
							ExternalLocation loc = extMgr.addExtLocation(Library.UNKNOWN,
								fixupSymbol, null, SourceType.IMPORTED);
							stubFunc.setThunkedFunction(loc.createFunction());
						}
					}
					finally {
						extAddr = extAddr.add(fixup.size());
					}
				}
				if (fixupValue != null) {
					if (fixup.size() == 8 || fixup.size() == 4) {
						if (fixup.size() == 8) {
							memory.setLong(fixupAddr, fixupValue);
						}
						else {
							memory.setInt(fixupAddr, fixupValue.intValue());
						}
						fixedAddrs.add(fixupAddr);
						status = Status.APPLIED;
					}
					value = new long[] { fixupValue };
				}
				if (fixupSymbol != null && fixup.libOrdinal() != null) {
					value = new long[] { fixup.libOrdinal() };
					try {
						MachoProgramBuilder.fixupExternalLibrary(program, libraryPaths,
							fixup.libOrdinal(), fixupSymbol);
					}
					catch (Exception e) {
						log.appendMsg("WARNING: Problem fixing up symbol '%s' - %s"
								.formatted(fixupSymbol, e.getMessage()));
					}
				}
			}
			catch (Exception e) {
				status = Status.FAILURE;
			}
			finally {
				program.getRelocationTable()
						.add(fixupAddr, status, RELOCATION_TYPE, value, fixup.size(), fixupSymbol);
			}
		}
		log.appendMsg("Fixed up " + fixedAddrs.size() + " chained pointers.");
		return fixedAddrs;
	}
Fixes up the program's chained pointers

@param fixups A {@link List} of the fixups
@param program The {@link Program}
@param imagebase The image base
@param libraryPaths A {@link List} of library paths
@param log The log
@param monitor A cancellable monitor
@return A {@link List} of fixed up {@link Address}'s
@throws CancelledException If the user cancelled the operation
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java