public static List<DyldFixup> getChainedFixups(BinaryReader reader,
			DyldChainedImports chainedImports, DyldChainType pointerFormat, long page, long nextOff,
			long auth_value_add, long imagebase, SymbolTable symbolTable, MessageLog log,
			TaskMonitor monitor) throws IOException, CancelledException {
		List<DyldFixup> fixups = new ArrayList<>();

		long next = -1;
		while (next != 0) {
			monitor.checkCancelled();

			long chainLoc = page + nextOff;
			final long chainValue = DyldChainedPtr.getChainValue(reader, chainLoc, pointerFormat);
			Long newChainValue = chainValue;
			boolean isAuthenticated = DyldChainedPtr.isAuthenticated(pointerFormat, chainValue);
			boolean isBound = DyldChainedPtr.isBound(pointerFormat, chainValue);
			String symbol = null;
			Integer libOrdinal = null;

			if (isBound) {
				if (chainedImports == null) {
					log.appendMsg(
						"Error: dyld_chained_import array required to process bound chain fixup at " +
							chainLoc);
					return List.of();
				}
				if (symbolTable == null) {
					log.appendMsg(
						"Error: symbol table required to process bound chain fixup at " + chainLoc);
					return List.of();
				}
				int chainOrdinal = (int) DyldChainedPtr.getOrdinal(pointerFormat, chainValue);
				long addend = DyldChainedPtr.getAddend(pointerFormat, chainValue);
				DyldChainedImport chainedImport = chainedImports.getChainedImport(chainOrdinal);
				symbol = SymbolUtilities.replaceInvalidChars(chainedImport.getName(), true);
				libOrdinal = chainedImport.getLibOrdinal();
				List<Symbol> globalSymbols = symbolTable.getGlobalSymbols(symbol);
				if (globalSymbols.size() > 0) {
					newChainValue = globalSymbols.getFirst().getAddress().getOffset();
					newChainValue += isAuthenticated ? auth_value_add : addend;
				}
				else {
					newChainValue = null;
				}
			}
			else {
				if (isAuthenticated) {
					newChainValue = imagebase +
						DyldChainedPtr.getTarget(pointerFormat, chainValue) + auth_value_add;
				}
				else {
					newChainValue = DyldChainedPtr.getTarget(pointerFormat, chainValue);
					if (DyldChainedPtr.isRelative(pointerFormat)) {
						newChainValue += imagebase;
					}
				}
			}

			fixups.add(new DyldFixup(chainLoc, newChainValue, DyldChainedPtr.getSize(pointerFormat),
				symbol, libOrdinal));

			next = DyldChainedPtr.getNext(pointerFormat, chainValue);
			nextOff += next * DyldChainedPtr.getStride(pointerFormat);
		}
		return fixups;
	}
Walks the chained fixup information and collects a {@link List} of {@link DyldFixup}s that 
will need to be applied to the image

@param reader A {@link BinaryReader} that can read the image
@param chainedImports chained imports (could be null)
@param pointerFormat format of pointers within this chain
@param page within data pages that has pointers to be unchained
@param nextOff offset within the page that is the chain start
@param auth_value_add value to be added to each chain pointer
@param imagebase The image base
@param symbolTable The {@link SymbolTable}, or null if not available
@param log The log
@param monitor A cancellable monitor
@return A {@link List} of {@link DyldFixup}s
@throws IOException If there was an IO-related issue
@throws CancelledException If the user cancelled the operation
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java