From 54525fcbf8b474b7d4c3100a58595dd3db98edaf Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Fri, 16 Sep 2022 19:18:41 -0400 Subject: [PATCH] GP-2566 Check for output varnode on CALL ops --- .../src/decompile/cpp/coreaction.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc index 3a0b813366..7345ceee60 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/coreaction.cc @@ -1481,15 +1481,29 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data) void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) { + PcodeOp *callop = fc->getOp(); + if (callop->getOut() != (Varnode *)0) { + // CALL ops are expected to have no output, but its possible an override has produced one + if (callop->getOut()->getSpace()->getType() == IPTR_INTERNAL) { + // Removing a varnode in the unique space will likely produce an input varnode in the unique space + ostringstream s; + s << "CALL op at "; + callop->getAddr().printRaw(s); + s << " has an unexpected output varnode"; + throw LowlevelError(s.str()); + } + // Otherwise just remove the Varnode and assume return recovery will reintroduce it if necessary + data.opUnsetOutput(callop); + } if (fc->isOutputLocked()) { ProtoParameter *outparam = fc->getOutput(); Datatype *outtype = outparam->getType(); if (outtype->getMetatype() != TYPE_VOID) { int4 sz = outparam->getSize(); if (sz == 1 && outtype->getMetatype() == TYPE_BOOL) - data.opMarkCalculatedBool(fc->getOp()); + data.opMarkCalculatedBool(callop); Address addr = outparam->getAddress(); - data.newVarnodeOut(sz,addr,fc->getOp()); + data.newVarnodeOut(sz,addr,callop); VarnodeData vdata; OpCode res = fc->assumedOutputExtension(addr,sz,vdata); if (res == CPUI_PIECE) { // Pick an extension based on type @@ -1499,7 +1513,6 @@ void ActionFuncLink::funcLinkOutput(FuncCallSpecs *fc,Funcdata &data) res = CPUI_INT_ZEXT; } if (res != CPUI_COPY) { // We assume the (smallsize) output is extended to a full register - PcodeOp *callop = fc->getOp(); // Create the extension operation to eliminate artifact PcodeOp *op = data.newOp(1,callop->getAddr()); data.newVarnodeOut(vdata.size,vdata.getAddr(),op);