@Override
	public AddressRange allocateLinkageBlock(int alignment, int size, String purpose) {

		ElfLoadAdapter loadAdapter = elf.getLoadAdapter();
		AddressSpace space = getDefaultAddressSpace();

		// Build range map: 1 marks valid addresses region, 2 marks defined blocks
		// Avoid minimum range of addresses
		AddressRangeObjectMap<Integer> map = new AddressRangeObjectMap<>();
		map.setObject(space.getAddress(alignment, true), space.getMaxAddress(), AVAILABLE_MEMORY);
		for (AddressRange range : allocatedRegions.getAddressRanges()) {
			// mark dynamic allocation region as allocated
			map.setObject(range.getMinAddress(), range.getMaxAddress(), ALLOCATED_MEMORY);
		}

		for (MemoryBlock block : memory.getBlocks()) {
			// only consider physical addresses
			Address blockStart = block.getStart().getPhysicalAddress();
			if (!space.equals(blockStart.getAddressSpace())) {
				continue;
			}
			Address blockEnd = block.getEnd().getPhysicalAddress();
			if (MemoryBlock.EXTERNAL_BLOCK_NAME.equals(block.getName())) {
				// allow for possible EXTERNAL block extension during relocation processing
				try {
					blockEnd = blockEnd.addNoWrap(loadAdapter.getExternalBlockReserveSize());
				}
				catch (AddressOverflowException e) {
					blockEnd = space.getMaxAddress();
				}
			}
			map.setObject(blockStart, block.getEnd().getPhysicalAddress(), ALLOCATED_MEMORY);
		}

		// Identify the largest unallocated range
		AddressRange maxRange = null;
		BigInteger maxRangeLength = null;

		// Give preference to last unallocated range whose size should be big-enough
		BigInteger preferredRangeSize =
			BigInteger.valueOf(size <= 0 ? loadAdapter.getPreferredExternalBlockSize() : size);

		AddressRange lastBigUnallocatedRange = null;

		// check AVAILABLE_MEMORY ranges
		AddressRangeIterator rangeIterator = map.getAddressRangeIterator();
		while (rangeIterator.hasNext()) {
			AddressRange range = rangeIterator.next();
			Integer value = map.getObject(range.getMinAddress());
			if (!AVAILABLE_MEMORY.equals(value)) {
				continue;
			}
			BigInteger rangeLength = range.getBigLength();
			if (maxRangeLength == null || maxRangeLength.compareTo(rangeLength) < 0) {
				maxRange = range;
				maxRangeLength = rangeLength;
			}
			Address addr = range.getMinAddress();
			Address alignedAddress = addr.getNewAddress(
				NumericUtilities.getUnsignedAlignedValue(addr.getOffset(), alignment));
			long alignAdjust = alignedAddress.subtract(addr);
			rangeLength = rangeLength.subtract(BigInteger.valueOf(alignAdjust));
			if (rangeLength.compareTo(preferredRangeSize) >= 0) {
				lastBigUnallocatedRange = range;
			}
		}

		if (maxRange == null ||
			(size > 0 && maxRange.getLength() > 0 && maxRange.getLength() < size)) {
			log("ELF unable to find unallocated memory required for " + purpose + ": " +
				program.getName());
			return null; // NOTE: this will likely cause other errors to follow
		}

		// Return aligned address range
		AddressRange freeRange = maxRange;
		if (lastBigUnallocatedRange != null &&
			lastBigUnallocatedRange.getMinAddress().compareTo(maxRange.getMinAddress()) > 0) {
			// prefer the last unallocated range if it is a big range (need not be the biggest)
			freeRange = lastBigUnallocatedRange;
		}

		Address addr = freeRange.getMinAddress();
		Address alignedAddress = addr.getNewAddress(
			NumericUtilities.getUnsignedAlignedValue(addr.getOffset(), alignment));

		AddressRange range = new AddressRangeImpl(alignedAddress, freeRange.getMaxAddress());
		if (size > 0) {
			long rangeLen = range.getLength();
			if (rangeLen < 0 || rangeLen > size) {
				// reduce size of allocation range
				range = new AddressRangeImpl(range.getMinAddress(),
					range.getMinAddress().add(size - 1));
			}
			// keep track if allocations other than the EXTERNAL block allocation
			allocatedRegions.add(range);
		}
		return range;
	}
Add reference to previously applied header structure (assumes markupElfHeader previously called)
@param componentOrdinal structure component ordinal
@param refAddr reference to-address
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/ElfProgramBuilder.java