private void parseProgramHeaders() throws IOException {
		boolean missing = false;
		programHeaders = new ElfProgramHeader[e_phnum];
		for (int i = 0; i < e_phnum; ++i) {
			long index = e_phoff + (i * e_phentsize);
			if (!missing && !providerContainsRegion(index, e_phentsize)) {
				int unreadCnt = e_phnum - i;
				errorConsumer.accept(unreadCnt + " of " + e_phnum +
					" program headers are truncated/missing from file");
				missing = true;
			}
			programHeaders[i] = new ElfProgramHeader(reader.clone(index), this);
		}

		// TODO: Find sample file which requires this hack to verify its necessity
		// HACK: 07/01/2013 - Added hack for malformed ELF file with only program header sections
		long size = 0;
		for (ElfProgramHeader pheader : programHeaders) {
			size += pheader.getFileSize();
		}
		if (size == reader.length()) {
			// adjust program section file offset to be based on relative read offset
			long relOffset = 0;
			for (ElfProgramHeader pheader : programHeaders) {
				pheader.setOffset(relOffset);
				relOffset += pheader.getFileSize();
			}
		}
	}
Perform offset region check against byte provider.
This is done against the byte provider since the
reader is unbounded.
@param offset starting offset
@param length length of range
@return true if provider contains specified byte offset range
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfHeader.java