private void parseRelocationTables() throws IOException {

		ArrayList<ElfRelocationTable> relocationTableList = new ArrayList<>();

		// Order of parsing and processing dynamic relocation tables can be important to ensure that
		// GOT/PLT relocations are applied late.

		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_REL, ElfDynamicType.DT_RELENT,
			ElfDynamicType.DT_RELSZ, false);

		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_RELA,
			ElfDynamicType.DT_RELAENT, ElfDynamicType.DT_RELASZ, true);

		if (dynamicTable != null && dynamicTable.containsDynamicValue(ElfDynamicType.DT_PLTREL)) {
			try {
				boolean isRela = (dynamicTable
						.getDynamicValue(ElfDynamicType.DT_PLTREL) == ElfDynamicType.DT_RELA.value);
				parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_JMPREL, null,
					ElfDynamicType.DT_PLTRELSZ, isRela);
			}
			catch (NotFoundException e) {
				// ignore - skip (required dynamic table value is missing)
			}
		}

		// Android versions
		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_ANDROID_REL, null,
			ElfDynamicType.DT_ANDROID_RELSZ, false);

		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_ANDROID_RELA, null,
			ElfDynamicType.DT_ANDROID_RELASZ, true);

		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_RELR,
			ElfDynamicType.DT_RELRENT, ElfDynamicType.DT_RELRSZ, false);

		parseDynamicRelocTable(relocationTableList, ElfDynamicType.DT_ANDROID_RELR,
			ElfDynamicType.DT_ANDROID_RELRENT, ElfDynamicType.DT_ANDROID_RELRSZ, false);

		parseJMPRelocTable(relocationTableList);

		// In general the above dynamic relocation tables should cover most cases, we will
		// check section headers for possible custom relocation tables
		for (ElfSectionHeader section : sectionHeaders) {
			parseSectionBasedRelocationTable(section, relocationTableList);
		}

		relocationTables = new ElfRelocationTable[relocationTableList.size()];
		relocationTableList.toArray(relocationTables);
	}
Unadjust address offset for certain pre-linked binaries which do not adjust certain
header fields (e.g., dynamic table address entries).  This may be needed when updating
a header address field which requires pre-link adjustment.
@param address prelink-adjusted address offset
@return address with appropriate pre-link adjustment subtracted
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java