{"record":{"id":"9ceec77f40695b67","repo":"NationalSecurityAgency/ghidra","slug":"cannot-evaluate-unique-u-x-d","errorCode":null,"errorMessage":"Cannot evaluate unique $U%x:%d","messagePattern":"Cannot evaluate unique \\$U%x:(.+?)","errorType":"exception","errorClass":"PcodeExecutionException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/eval/AbstractVarnodeEvaluator.java","lineNumber":281,"sourceCode":"\t * @param address the address of the variable\n\t * @param size the size of the variable in bytes\n\t * @return the value\n\t */\n\tprotected abstract T evaluateMemory(Address address, int size);\n\n\t/**\n\t * Evaluate a unique variable\n\t * \n\t * <p>\n\t * This is only invoked when trying to evaluate a leaf, which should never occur for a unique\n\t * variable. Thus, by default, this throws a {@link PcodeExecutionException}.\n\t * \n\t * @param offset the offset of the variable\n\t * @param size the size of the variable in bytes\n\t * @return the value\n\t */\n\tprotected T evaluateUnique(long offset, int size) {\n\t\tthrow new PcodeExecutionException(\n\t\t\tString.format(\"Cannot evaluate unique $U%x:%d\", offset, size));\n\t}\n\n\t/**\n\t * Evaluate a variable with an abstract offset\n\t * \n\t * <p>\n\t * The three parameters {@code space}, {@code offset}, and {@code size} imitate the varnode\n\t * triple, except that the offset is abstract. This is typically invoked for a\n\t * {@link PcodeOp#LOAD}, i.e., a dereference.\n\t * \n\t * @param program the program defining the static context\n\t * @param space the address space of the variable\n\t * @param offset the offset of the variable\n\t * @param size the size of the variable in bytes\n\t * @param already a cache of already-evaluated varnodes and their values\n\t * @return the value\n\t */","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/pcode/eval/AbstractVarnodeEvaluator.java#L263-L299","documentation":"Thrown (unchecked PcodeExecutionException) by the default evaluateUnique when a unique-space varnode ($U offset) is evaluated as a leaf. Uniques are p-code temporaries that only have meaning through their defining op; the base implementation deliberately rejects leaf evaluation of them because a unique has no independent value.","triggerScenarios":"The evaluator's cache ('already') lacks an entry for a unique varnode and evaluation reaches it as a leaf instead of through its defining p-code op. This indicates the unique's defining op was not evaluated first, or the varnode was reached out of order.","commonSituations":"Symbolic/abstract execution that follows data flow but skips the op that defines a temporary; analyzing partial p-code where the defining op for a $U varnode is outside the examined window; a custom evaluator that doesn't seed the cache from defining ops.","solutions":["Ensure unique varnodes are always reached via their defining op so the result is cached before leaf evaluation (evaluate defining ops in topological/data-flow order).","Override evaluateUnique in your subclass to return a symbolic/unknown value instead of throwing, if leaf evaluation of uniques is expected in your analysis.","Pre-populate the 'already' cache with modelled values for the uniques you will encounter."],"exampleFix":"// before: default evaluateUnique throws\n// (occurs when a $U varnode is reached as a leaf)\n\n// after: override in your evaluator subclass to model uniques symbolically\n@Override\nprotected T evaluateUnique(long offset, int size) {\n    return model.newUnique(offset, size); // symbolic value, no throw\n}","handlingStrategy":"try-catch","validationCode":"// Ensure uniques are reached via their defining op, not as a leaf\nPcodeOp def = vn.getDef();\nboolean isUniqueLeaf = vn.isUniqueAddress() && (def == null || !cache.containsKey(vn));\nif (isUniqueLeaf) {\n    // will throw by default; override evaluateUnique or seed the cache first\n}","typeGuard":null,"tryCatchPattern":"try {\n    T val = evaluator.evaluateVarnode(program, vn, cache);\n} catch (PcodeExecutionException e) {\n    if (e.getMessage().startsWith(\"Cannot evaluate unique\")) { /* model symbolically */ }\n    else throw e;\n}","preventionTips":["Evaluate defining p-code ops in data-flow order so uniques are cached before use.","Override evaluateUnique in your subclass to return a symbolic value.","Pre-seed the cache for uniques you expect to encounter."],"tags":["pcode","emulation","unique-space","varnode","unchecked-exception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}