NationalSecurityAgency/ghidra · error · IllegalArgumentException
Return address must be in {}
Error message
Return address must be in {} What it means
AbstractUnwoundFrame.setReturnAddress() writes the return address into the frame's program counter. It validates that the supplied address belongs to the frame's code address space (codeSpace) — i.e. the executable space — because the PC register must live there. An address from any other space (stack, register, external, etc.) is rejected with IllegalArgumentException("Return address must be in " + codeSpace).
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/AbstractUnwoundFrame.java:342
}
@Override
protected ByteBuffer catenate(int total, ByteBuffer value, ByteBuffer piece, int size) {
return value;
}
@Override
public ByteBuffer evaluateStorage(Program program, VariableStorage storage) {
return evaluateStorage(program, storage, buf);
}
}.evaluateStorage(program, storage);
return fence.ready();
}
@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(computeAddressOfReturnAddress(), bytes);
}
@Override
public T zext(T value, int length) {
PcodeArithmetic<T> arithmetic = state.getArithmetic();
return arithmetic.unaryOp(PcodeOp.INT_ZEXT, length, (int) arithmetic.sizeOf(value), value);
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Pass an address in the frame's code space: verify addr.getAddressSpace().equals(codeSpace) first.
- If you hold an offset, resolve it into the code space via the language's code address space before calling.
- For non-code 'return' targets, reconsider whether setReturnAddress is the right API.
Example fix
// before
frame.setReturnAddress(editor, stackAddr); // throws: stackAddr not in codeSpace
// after
AddressSpace codeSpace = frame.getLanguage().getDefaultSpace(); // the code space
if (!addr.getAddressSpace().equals(codeSpace)) {
throw new IllegalArgumentException("return address must be in code space");
}
frame.setReturnAddress(editor, 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")) {
// resolve addr into the code space and retry
} else throw e;
} Prevention
- Always pass a code-space address to setReturnAddress; the PC register lives there.
- Resolve raw offsets into the language's code space before calling.
- Distinguish return-address (code) from stack/value locations.
When it happens
Trigger: Passing a stack address, a register-space address, or a constant/external-space address to setReturnAddress. Using an address from a different program/address space than the one the frame's language defines as code.
Common situations: Scripts that hand a computed stack pointer or a raw offset into setReturnAddress. Confusing the return-address location (code) with the return-value/stack location. Languages with non-standard code spaces.
Related errors
- Return address must be in {}
- No such address space: %s
- Range [%s:%x+%x] entirely exceeds space min
- AddressSpace '{}' is not in this trace (language={})
- Invalid address space for overlay: {}
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/83c3d38fb6b4a4d6.
Report an issue: GitHub.