private void processRelocations(CoffFileHeader header, Program program,
			Map<CoffSectionHeader, Address> sectionsMap, Map<CoffSymbol, Symbol> symbolsMap,
			MessageLog log, TaskMonitor monitor) {

		CoffRelocationHandler handler = CoffRelocationHandlerFactory.getHandler(header);
		if (handler == null) {
			String msg = String.format("No COFF relocation handler for machine type 0x%x",
				(Short) header.getMachine());
			log.appendMsg(msg);
			Msg.error(this, program.getName() + ": " + msg);
		}

		CoffRelocationContext relocationContext =
			new CoffRelocationContext(program, header, symbolsMap);
		int failureCount = 0;

		for (CoffSectionHeader section : header.getSections()) {
			if (monitor.isCancelled()) {
				break;
			}

			Address sectionStartAddr = sectionsMap.get(section);
			if (sectionStartAddr == null) {
				int relocCount = section.getRelocationCount();
				if (relocCount > 0) {
					failureCount += relocCount;
					String msg = "Unable to process " + relocCount + " relocations for section " +
						section.getName() + ". No memory block was created.";
					log.appendMsg(msg);
					Msg.error(this, program.getName() + ": " + msg);
				}
				continue;
			}

			relocationContext.resetContext(section);

			Address failedAddr = null;
			for (CoffRelocation relocation : section.getRelocations()) {
				if (monitor.isCancelled()) {
					break;
				}

				// Sections are defined with physical address while relocations use virtual address.
				// Must adjust relocation address to physical.
				// NOTE: Relocation address offset assumed to always be a byte-offset
				Address address =
					sectionStartAddr.add(relocation.getAddress() - section.getVirtualAddress());
				short relocationType = relocation.getType();

				Status status = Status.FAILURE;
				int byteLength = 0;

				if (handler == null) {
					++failureCount;
					handleRelocationError(program, address, relocationType,
						"No COFF relocation handler", null);
				}
				else {
					try {
						if (address.equals(failedAddr)) {
							// skip relocation if previous failed relocation was at the same address
							// since it is likely dependent on the previous failed relocation result
							++failureCount;
							status = Status.SKIPPED;

							String logMessage =
								String.format("Skipped dependent COFF Relocation type 0x%x at %s",
									relocationType, address.toString());
							Msg.error(this, program.getName() + ": " + logMessage);
						}
						else {
							RelocationResult result =
								handler.relocate(address, relocation, relocationContext);
							status = result.status();
							byteLength = result.byteLength();

							if (status == Status.UNSUPPORTED) {
								++failureCount;
								failedAddr = address;
								handleRelocationError(program, address, relocationType,
									"unsupported type", null);
							}
							else if (status == Status.FAILURE) {
								++failureCount;
								failedAddr = address;
								handleRelocationError(program, address, relocationType,
									"unknown reason", null);
							}
						}
					}
					catch (MemoryAccessException e) {
						++failureCount;
						failedAddr = address;
						handleRelocationError(program, address, relocationType,
							"error accessing memory", null);
					}
					catch (RelocationException e) {
						++failureCount;
						failedAddr = address;
						handleRelocationError(program, address, relocationType, e.getMessage(),
							null);
					}
					catch (Exception e) { // handle unexpected exceptions
						++failureCount;
						failedAddr = address;
						String msg = e.getMessage();
						if (msg == null) {
							msg = e.toString();
						}
						handleRelocationError(program, address, relocationType, msg, e);
					}
				}

				// The relocation symbol may be null when either not required by a relocation or
				// not found with symbol index
				Symbol symbol =
					symbolsMap.get(header.getSymbolAtIndex(relocation.getSymbolIndex()));

				program.getRelocationTable()
						.add(address, status, relocation.getType(),
							new long[] { relocation.getSymbolIndex() }, byteLength,
							symbol != null ? symbol.getName() : "<null>");
			}
		}

		if (failureCount != 0) {
			String msg = "Failed to process a total of " + failureCount +
				" relocations.  See log and error bookmarks for details.";
			log.appendMsg(msg);
			Msg.error(this, program.getName() + ": " + msg);
		}
	}
Query a section header for alignment information. The base version of this method assumes 
no alignment information is stored in the section header. Subclasses may implement a 
platform-specific check for alignment information.

@param section header object for the section 
@return the alignment requested by the section
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/CoffLoader.java