@Override
	public boolean parse() throws IOException {
		long oldIndex = reader.getPointerIndex();
		try {
			int ptr = getPointer();
			if (ptr < 0) {
				return false;
			}
			reader.setPointerIndex(ptr);

			characteristics = reader.readNextInt();
			timeDateStamp = reader.readNextInt();
			majorVersion = reader.readNextShort();
			minorVersion = reader.readNextShort();
			name = reader.readNextInt();
			ptr = ntHeader.rvaToPointer(name);
			base = reader.readNextInt();
			numberOfFunctions = reader.readNextInt();
			numberOfNames = reader.readNextInt();
			addressOfFunctions = reader.readNextInt();
			addressOfNames = reader.readNextInt();
			addressOfNameOrdinals = reader.readNextInt();

			exportsStartRVA = getVirtualAddress();
			exportsEndRVA = exportsStartRVA + getSize();

			exportName = (ptr > 0) ? reader.readAsciiString(ptr) : "";

			// convert RVA's into pointers
			int pointerToFunctions = ntHeader.rvaToPointer(addressOfFunctions);
			if (numberOfFunctions > 0 && pointerToFunctions < 0) {
				Msg.error(this, "Invalid RVA " + Integer.toHexString(addressOfFunctions));
				numberOfFunctions = 0;
			}
			if (numberOfFunctions > NTHeader.MAX_SANE_COUNT) {
				Msg.error(this,
					"Large number of functions " + Integer.toHexString(numberOfFunctions));
				numberOfFunctions = 0;
			}
			int pointerToNames = ntHeader.rvaToPointer(addressOfNames);
			if (numberOfNames > 0 && pointerToNames < 0) {
				Msg.error(this, "Invalid RVA " + Integer.toHexString(addressOfNames));
				numberOfNames = 0;
			}
			int pointerToOrdinals = ntHeader.rvaToPointer(addressOfNameOrdinals);
			if (numberOfNames > 0 && pointerToOrdinals < 0) {
				Msg.error(this, "Invalid RVA " + Integer.toHexString(addressOfNameOrdinals));
				numberOfNames = 0;
			}
			if (numberOfNames > NTHeader.MAX_SANE_COUNT) {
				Msg.error(this, "Large number of names " + Integer.toHexString(numberOfNames));
				numberOfNames = 0;
			}

			List<ExportInfo> exportList = new ArrayList<>();

			for (int i = 0; i < numberOfFunctions; ++i) {
				int entryPointRVA = reader.readInt(pointerToFunctions);
				pointerToFunctions += 4;

				// Skip over gaps in exported function
				// ordinals (the entrypoint is 0 for
				// these functions).
				if (entryPointRVA == 0) {
					continue;
				}

				long addr = Integer.toUnsignedLong(entryPointRVA) +
					ntHeader.getOptionalHeader().getImageBase();

				if (!ntHeader.getOptionalHeader().is64bit()) {
					addr &= 0xffffffffL;
				}

				String lname = "";

				// See if this function has an associated name exported for it.
				for (int j = 0; j < numberOfNames; ++j) {
					int jthOrdinalVal = reader.readShort(pointerToOrdinals + (j * 2));
					if (jthOrdinalVal == i) {
						int jthNameRVA = reader.readInt(pointerToNames + (j * 4));
						int jthNamePtr = ntHeader.rvaToPointer(jthNameRVA);
						if (jthNamePtr < 0) {
							Msg.error(this, "Invalid RVA " + Integer.toHexString(jthNameRVA));
							return false;
						}
						// locate corresponding name
						lname = reader.readAsciiString(jthNamePtr);
						break;
					}
				}

				String cmt = "0x" + Integer.toHexString(entryPointRVA) + "  " +
					Integer.toString(i + base) + "  " + lname;

				boolean forwarded = false;

				if (entryPointRVA >= exportsStartRVA && entryPointRVA < exportsEndRVA) {
					int entryPointPtr = ntHeader.rvaToPointer(entryPointRVA);
					if (entryPointPtr < 0) {
						Msg.error(this, "Invalid RVA " + Integer.toHexString(entryPointRVA));
						return false;
					}
					String forwarder = reader.readAsciiString(entryPointPtr);

					cmt += "  ";
					cmt += "(forwarder -> " + forwarder + ")";

					forwarded = true;
				}

				exportList.add(new ExportInfo(addr, i + base, lname, cmt, forwarded));
			}

			exports = new ExportInfo[exportList.size()];
			exportList.toArray(exports);
		}
		finally {
			reader.setPointerIndex(oldIndex);
		}
		return true;
	}
Returns an array of the exports defined in this export data directory.
@return an array of the exports defined in this export data directory
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/ExportDataDirectory.java