NationalSecurityAgency/ghidra · error · LowlevelError
Unsupported p-code op at {}: {}
Error message
Unsupported p-code op at {}: {} What it means
Thrown (unchecked LowlevelError) by badOp() as the default case: the op's opcode is neither UNIMPLEMENTED nor one the evaluator's evaluateOp dispatch handles. Unlike the UNIMPLEMENTED case, this is an opcode the emulator simply doesn't support (e.g. exotic p-code ops not yet wired into the evaluator switch).
Source
Thrown at Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/eval/AbstractVarnodeEvaluator.java:428
default:
return badOp(op);
}
}
/**
* The method invoked when an unrecognized or unsupported operator is encountered
*
* @param op the op
* @return the value, but this usually throws an exception
*/
protected T badOp(PcodeOp op) {
switch (op.getOpcode()) {
case PcodeOp.UNIMPLEMENTED:
throw new LowlevelError(
"Encountered an unimplemented instruction at " +
op.getSeqnum().getTarget());
default:
throw new LowlevelError(
"Unsupported p-code op at " + op.getSeqnum().getTarget() + ": " + op);
}
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Override evaluateOp in your subclass to add cases for the missing opcode(s) named in the message.
- Inspect op.getOpcode() for the failing op and implement/redirect its handling (often return the value of the relevant input or a symbolic result).
- Catch LowlevelError and degrade gracefully for unsupported ops if full coverage isn't required.
- Track the Ghidra version's PcodeOp constants so newly added opcodes get handlers.
Example fix
// before: default badOp throws on unhandled opcode
T out = evaluator.evaluateOp(program, op, cache);
// after: add the missing case in your subclass's evaluateOp
@Override
protected T evaluateOp(Program p, PcodeOp op, Map<Varnode,T> cache) {
switch (op.getOpcode()) {
case PcodeOp.MULTIEQUAL:
return evaluateVarnode(p, op.getInput(0), cache);
default:
return super.evaluateOp(p, op, cache);
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check opcode coverage before delegating to the base evaluator
if (!isHandledByEvaluator(op.getOpcode())) {
// opcode has no case in evaluateOp -> badOp default; add a handler
} Try / catch
try {
T out = evaluator.evaluateOp(program, op, cache);
} catch (LowlevelError e) {
if (e.getMessage().startsWith("Unsupported p-code op")) { /* add handler / degrade */ }
else throw e;
} Prevention
- Override evaluateOp and add cases for every opcode your analysis may hit.
- Track new PcodeOp constants when upgrading Ghidra versions.
- Catch LowlevelError to degrade gracefully for unsupported ops.
When it happens
Trigger: Driving AbstractVarnodeEvaluator (or a subclass) over p-code whose opcode has no case in evaluateOp, so it falls through to badOp's default. Occurs with newer/rarer p-code ops (e.g. newly added ops, or ops your subclass didn't override) on standard instructions.
Common situations: A new Ghidra version adds p-code ops your evaluator subclass doesn't handle; analyzing code that exercises p-code ops (like MULTIEQUAL, INDIRECT, certain CALLOTHER ops) not covered by your override; partial evaluator implementation.
Related errors
- Encountered an unimplemented instruction at {}
- Unrecognized address space in {}
- No defining p-code op for {}
- Cannot evaluate unique $U%x:%d
- {} is not a constant
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/70b1ce2f5e21b187.
Report an issue: GitHub.