mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-09-18 01:31:53 +00:00
GP-2566 Check for output varnode on CALL ops
This commit is contained in:
parent
742e69eb31
commit
54525fcbf8
|
@ -1481,15 +1481,29 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data)
|
||||||
void ActionFuncLink::funcLinkOutput(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()) {
|
if (fc->isOutputLocked()) {
|
||||||
ProtoParameter *outparam = fc->getOutput();
|
ProtoParameter *outparam = fc->getOutput();
|
||||||
Datatype *outtype = outparam->getType();
|
Datatype *outtype = outparam->getType();
|
||||||
if (outtype->getMetatype() != TYPE_VOID) {
|
if (outtype->getMetatype() != TYPE_VOID) {
|
||||||
int4 sz = outparam->getSize();
|
int4 sz = outparam->getSize();
|
||||||
if (sz == 1 && outtype->getMetatype() == TYPE_BOOL)
|
if (sz == 1 && outtype->getMetatype() == TYPE_BOOL)
|
||||||
data.opMarkCalculatedBool(fc->getOp());
|
data.opMarkCalculatedBool(callop);
|
||||||
Address addr = outparam->getAddress();
|
Address addr = outparam->getAddress();
|
||||||
data.newVarnodeOut(sz,addr,fc->getOp());
|
data.newVarnodeOut(sz,addr,callop);
|
||||||
VarnodeData vdata;
|
VarnodeData vdata;
|
||||||
OpCode res = fc->assumedOutputExtension(addr,sz,vdata);
|
OpCode res = fc->assumedOutputExtension(addr,sz,vdata);
|
||||||
if (res == CPUI_PIECE) { // Pick an extension based on type
|
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;
|
res = CPUI_INT_ZEXT;
|
||||||
}
|
}
|
||||||
if (res != CPUI_COPY) { // We assume the (smallsize) output is extended to a full register
|
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
|
// Create the extension operation to eliminate artifact
|
||||||
PcodeOp *op = data.newOp(1,callop->getAddr());
|
PcodeOp *op = data.newOp(1,callop->getAddr());
|
||||||
data.newVarnodeOut(vdata.size,vdata.getAddr(),op);
|
data.newVarnodeOut(vdata.size,vdata.getAddr(),op);
|
||||||
|
|
Loading…
Reference in a new issue