NationalSecurityAgency/ghidra · warning · InvalidDataException

Missing MinGW __RUNTIME_PSEUDO_RELOC_LIST_END__ symbol

Error message

Missing MinGW __RUNTIME_PSEUDO_RELOC_LIST_END__ symbol

What it means

Thrown as InvalidDataException by findLabeledPseudoRelocList when the list-START label (PSEUDO_RELOC_LIST_START_NAME) was found but the list-END label (PSEUDO_RELOC_LIST_END_NAME, i.e. __RUNTIME_PSEUDO_RELOC_LIST_END__) was not. The two labels are expected as a pair; finding only the start indicates a partially labeled or tampered binary.

Source

Thrown at Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/MingwRelocationAnalyzer.java:339

				return false;
			}
		}
		return true;
	}

	private boolean findLabeledPseudoRelocList() throws InvalidDataException {
		Symbol pdwListStart = getLabel(program, PSEUDO_RELOC_LIST_START_NAME);
		if (pdwListStart == null) {
			return false;
		}
		Symbol pdwListEnd = getLabel(program, PSEUDO_RELOC_LIST_END_NAME);
		if (pdwListEnd != null) {
			listLabelsFound = true;
			pdwListStartAddr = pdwListStart.getAddress();
			pdwListEndAddr = pdwListEnd.getAddress();
			return true;
		}
		throw new InvalidDataException("Missing MinGW " + PSEUDO_RELOC_LIST_END_NAME + " symbol");
	}

	private static Symbol getLabel(Program program, String name) {
		return SymbolUtilities.getExpectedLabelOrFunctionSymbol(program, name, m -> {
			/* ignore */});
	}

	private Symbol createPrimaryLabel(Address address, String name) {
		try {
			SymbolTable SymbolList = program.getSymbolTable();
			Symbol symbol = SymbolList.createLabel(address, name, null, SourceType.ANALYSIS);
			if (!symbol.isPrimary()) {
				symbol.setPrimary();
			}
			return symbol;
		}
		catch (InvalidInputException e) {
			throw new AssertException("unexpected", e);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Re-import the original, unstripped PE so both marker symbols are present.
  2. Manually create the missing __RUNTIME_PSEUDO_RELOC_LIST_END__ label at the correct address before re-running the analyzer.
  3. Disable the analyzer for binaries missing the marker pair.
  4. Catch InvalidDataException and fall back to the unlabeled discovery path.

Example fix

// before — findLabeledPseudoRelocList throws because END label is absent
// (start found, end missing)

// after — create the missing END label, then retry
Symbol start = SymbolUtilities.getExpectedLabelOrFunctionSymbol(program, PSEUDO_RELOC_LIST_START_NAME, m -> {});
Symbol end = SymbolUtilities.getExpectedLabelOrFunctionSymbol(program, PSEUDO_RELOC_LIST_END_NAME, m -> {});
if (start != null && end == null) {
    Address endAddr = computeListEnd(program, start.getAddress());
    program.getSymbolTable().createLabel(endAddr, PSEUDO_RELOC_LIST_END_NAME, null, SourceType.ANALYSIS);
}
Defensive patterns

Strategy: validation

Validate before calling

Symbol start = SymbolUtilities.getExpectedLabelOrFunctionSymbol(program, PSEUDO_RELOC_LIST_START_NAME, m -> {});
Symbol end = SymbolUtilities.getExpectedLabelOrFunctionSymbol(program, PSEUDO_RELOC_LIST_END_NAME, m -> {});
if (start != null && end == null) {
    // create the missing END label at the computed end address before running
}

Type guard

boolean bothLabels = start != null && end != null;

Try / catch

try {
    findLabeledPseudoRelocList();
} catch (InvalidDataException e) {
    // fall back to unlabeled discovery
    findUnlabeledPseudoRelocList(monitor);
}

Prevention

When it happens

Trigger: Symbol lookup for the START label succeeds (non-null) but the END label lookup returns null — e.g. the end symbol was stripped/renamed, or only the start label survived a symbol-table edit.

Common situations: Stripped MinGW binary where one of the pair was removed; hand-edited symbol table; a partially linked object; mismatched MinGW runtime versions that emit only one marker.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/905b6daf6d833aa0. Report an issue: GitHub.