private void performRelocations(LinkedHashMap<RelocationInfo, Address> relocationMap)
			throws CancelledException {

		if (relocationMap.isEmpty()) {
			return;
		}

		MachoRelocationHandler handler = MachoRelocationHandlerFactory.getHandler(machoHeader);
		if (handler == null) {
			log.appendMsg(String.format("No relocation handler for machine type 0x%x",
				machoHeader.getCpuType()));
		}

		Iterator<RelocationInfo> iter = relocationMap.keySet().iterator();
		while (iter.hasNext()) {
			RelocationInfo relocationInfo = iter.next();
			Address address = relocationMap.get(relocationInfo);
			MachoRelocation relocation = null;

			RelocationResult result = RelocationResult.FAILURE;
			if (handler != null) {
				relocation = handler.isPairedRelocation(relocationInfo)
						? new MachoRelocation(program, machoHeader, address, relocationInfo,
							iter.next())
						: new MachoRelocation(program, machoHeader, address, relocationInfo);
				try {
					result = handler.relocate(relocation);

					if (result.status() == Status.UNSUPPORTED) {
						handleRelocationError(address,
							String.format("Relocation type 0x%x at address %s is not supported",
								relocationInfo.getType(), address));
					}
				}
				catch (MemoryAccessException e) {
					handleRelocationError(address, String.format(
						"Relocation failure at address %s: error accessing memory.", address));
				}
				catch (RelocationException e) {
					handleRelocationError(address, String.format(
						"Relocation failure at address %s: %s", address, e.getMessage()));
				}
				catch (Exception e) { // handle unexpected exceptions
					String msg = e.getMessage();
					if (msg == null) {
						msg = e.toString();
					}
					msg = String.format("Relocation failure at address %s: %s", address, msg);
					handleRelocationError(address, msg);
					Msg.error(this, msg, e);
				}
			}
			program.getRelocationTable()
					.add(address, result.status(), relocationInfo.getType(),
						new long[] { relocationInfo.getValue(), relocationInfo.getLength(),
							relocationInfo.isPcRelocated() ? 1 : 0,
							relocationInfo.isExternal() ? 1 : 0,
							relocationInfo.isScattered() ? 1 : 0 },
						result.byteLength(),
						relocation != null ? relocation.getTargetDescription() : null);
		}
	}
Performs the given relocations.

@param relocationMap The relocations to perform, mapped to the addresses they should get
  performed at.  The relocations must be performed in their supplied order.
@throws CancelledException if the operation was cancelled.
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java