NationalSecurityAgency/ghidra · error · IllegalArgumentException

Return address must be in {}

Error message

Return address must be in {}

What it means

AnalysisUnwoundFrame.setReturnAddress() mirrors the abstract one: it writes the given address to the return-address location (info.ofReturn(base)). It requires addr.getAddressSpace() == codeSpace; any other space throws IllegalArgumentException("Return address must be in " + codeSpace). The PC must be written into the executable code space.

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/AnalysisUnwoundFrame.java:163

	@Override
	protected SavedRegisterMap computeRegisterMap() {
		return registerMap;
	}

	@Override
	protected Address computeAddressOfReturnAddress() {
		return info.ofReturn(base);
	}

	@Override
	public Address getReturnAddress() {
		return info.computeNextPc(base, state, codeSpace, pc);
	}

	@Override
	public CompletableFuture<Void> setReturnAddress(StateEditor editor, Address addr) {
		if (addr.getAddressSpace() != codeSpace) {
			throw new IllegalArgumentException("Return address must be in " + codeSpace);
		}
		BytesPcodeArithmetic bytesArithmetic = BytesPcodeArithmetic.forLanguage(language);
		byte[] bytes = bytesArithmetic.fromConst(addr.getOffset(), pc.getNumBytes());
		return editor.setVariable(info.ofReturn(base), bytes);
	}

	@Override
	public int getLevel() {
		return level;
	}

	@Override
	public String getDescription() {
		return String.format("%s %s pc=%s sp=%s base=%s", level, info.function(),
			pcVal == null ? null : pcVal.toString(false),
			spVal == null ? null : spVal.toString(false),
			base == null ? null : base.toString(false));
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the address is in the code space: check addr.getAddressSpace().equals(codeSpace) before calling.
  2. Resolve any raw offset into the code space of the frame's language first.
  3. Use a different API if the target is genuinely not a code address.

Example fix

// before
frame.setReturnAddress(editor, addrFromWrongSpace); // throws

// after
if (addr.getAddressSpace().equals(codeSpace)) {
    frame.setReturnAddress(editor, addr);
} else {
    throw new IllegalArgumentException("return address not in code space: " + addr);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!addr.getAddressSpace().equals(codeSpace)) {
    throw new IllegalArgumentException("return address must be in code space " + codeSpace);
}
frame.setReturnAddress(editor, addr);

Type guard

public static boolean isInCodeSpace(Address addr, AddressSpace codeSpace) {
    return addr != null && codeSpace != null && addr.getAddressSpace().equals(codeSpace);
}

Try / catch

try {
    frame.setReturnAddress(editor, addr);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Return address must be in")) {
        addr = codeSpace.getAddress(addr.getOffset());
        frame.setReturnAddress(editor, addr);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling setReturnAddress with an address not in the frame's code space (stack, register, constant, external). Passing a return address derived from a different language's space layout.

Common situations: Setting a return address from a script using the wrong address space. Misidentifying the return storage as a stack slot. Languages with separate code/data spaces.

Related errors


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