{"record":{"id":"97555e8646bfed30","repo":"NationalSecurityAgency/ghidra","slug":"cannot-make-addresses-read-concrete-buffers","errorCode":null,"errorMessage":"Cannot make 'addresses read' concrete buffers","messagePattern":"Cannot make 'addresses read' concrete buffers","errorType":"exception","errorClass":"ConcretionError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/AddressesReadTracePcodeExecutorStatePiece.java","lineNumber":70,"sourceCode":"\t}\n\n\t/**\n\t * Construct the state piece\n\t * \n\t * @param data the trace data access shim\n\t */\n\tpublic AddressesReadTracePcodeExecutorStatePiece(PcodeTraceDataAccess data) {\n\t\tthis(data, new HashMap<>());\n\t}\n\n\t@Override\n\tprotected AddressSetView checkSize(int size, AddressSetView val) {\n\t\treturn val;\n\t}\n\n\t@Override\n\tpublic MemBuffer getConcreteBuffer(Address address, Purpose purpose) {\n\t\tthrow new ConcretionError(\"Cannot make 'addresses read' concrete buffers\", purpose);\n\t}\n\n\t@Override\n\tpublic AddressesReadTracePcodeExecutorStatePiece fork(PcodeStateCallbacks cb) {\n\t\treturn new AddressesReadTracePcodeExecutorStatePiece(data, new HashMap<>(unique));\n\t}\n\n\t@Override\n\tprotected Map<Register, AddressSetView> getRegisterValuesFromSpace(AddressSpace s,\n\t\t\tList<Register> registers) {\n\t\treturn Map.of();\n\t}\n\n\t@Override\n\tpublic Map<Register, AddressSetView> getRegisterValues() {\n\t\treturn Map.of();\n\t}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/pcode/exec/trace/AddressesReadTracePcodeExecutorStatePiece.java#L52-L88","documentation":"AddressesReadTracePcodeExecutorStatePiece is an auxiliary/abstract state piece: its values are AddressSetView (the union of address ranges read), never concrete byte arrays. When the p-code executor needs a concrete MemBuffer (e.g. to DECODE an instruction, or INSPECT a value), it calls getConcreteBuffer, which this piece always rejects with a ConcretionError. The piece exists to be paired on the abstract/right side with a concrete bytes piece, not to satisfy byte reads itself.","triggerScenarios":"Instantiating a PcodeExecutor whose only state piece (or whose left/concrete piece) is an AddressesReadTracePcodeExecutorStatePiece, then running anything that concretizes: SleighInstructionDecoder.getConcreteBuffer(addr, DECODE), EmulatorUtilities reading a pointer (INSPECT), or arithmetic.toConcrete. Also any p-code op that forces concretion (BRANCH/LOAD/STORE addresses, CONDITION).","commonSituations":"Using the addresses-read piece standalone for expression evaluation that touches memory it cannot represent as bytes. Wiring it as the left side of a PairedPcodeExecutorStatePiece (so getConcreteBuffer delegates to it) instead of the right. Running emulation that decodes instructions against a state built only from this piece.","solutions":["Pair this piece on the RIGHT/abstract side with a BytesPcodeExecutorStatePiece (or equivalent concrete piece) on the LEFT, so concrete-buffer requests route to the bytes piece: state.paired(new AddressesReadTracePcodeExecutorStatePiece(data)).","Never use this piece as the sole state piece for emulation or instruction decode; use a bytes state (e.g. via TraceEmulationIntegration.bytesImmediateWrite).","If you only need read-range tracking for a Sleigh expression, ensure the expression evaluation does not force concretion (avoid INSPECT-style reads over memory the piece abstracts)."],"exampleFix":"// before: only the addresses-read piece\nPcodeExecutorStatePiece<byte[],AddressSetView> piece =\n    new AddressesReadTracePcodeExecutorStatePiece(data);\nPcodeExecutor<AddressSetView> exec = new PcodeExecutor<>(language, arith, piece, Reason.INSPECT);\n// decode fails: getConcreteBuffer throws ConcretionError\n\n// after: pair with a concrete bytes piece on the left\nBytesPcodeExecutorState bytes = new BytesPcodeExecutorState(language, cb);\nPcodeExecutorState<Pair<byte[],AddressSetView>> paired =\n    bytes.paired(new AddressesReadTracePcodeExecutorStatePiece(data));","handlingStrategy":"validation","validationCode":"// Never request concrete buffers from this piece. Confirm a concrete piece backs the state.\nPcodeExecutorStatePiece<?, ?> left = ...; // your concrete bytes piece\nif (left instanceof AddressesReadTracePcodeExecutorStatePiece) {\n    throw new IllegalStateException(\n        \"AddressesRead piece cannot serve concrete buffers; pair it with a bytes piece on the left.\");\n}","typeGuard":"// A state piece that can never produce bytes — detect and exclude from the concrete role.\nstatic boolean canProvideBytes(PcodeExecutorStatePiece<?, ?> piece) {\n    return !(piece instanceof AddressesReadTracePcodeExecutorStatePiece);\n}","tryCatchPattern":"// ConcretionError is a PcodeExecutionException; catching it means a fundamental wiring mistake.\ntry {\n    exec.execute();\n} catch (ConcretionError e) {\n    PcodeArithmetic.Purpose p = e.getPurpose(); // DECODE/INSPECT/etc.\n    // Fix state wiring rather than swallowing: ensure a concrete bytes piece is on the left.\n    throw new IllegalStateException(\"state cannot concretize for purpose \" + p, e);\n}","preventionTips":["Always pair AddressesReadTracePcodeExecutorStatePiece on the right with a concrete bytes piece on the left.","Reserve this piece for read-range tracking, never for emulation that decodes instructions.","Unit-test any custom executor state by forcing a DECODE-purpose concrete-buffer read before deploying it."],"tags":["emulation","pcode-executor","abstract-state","concretion"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}