don't create COPY in ActionConstantPtr

This commit is contained in:
caheckman 2019-09-16 11:32:45 -04:00
parent 8a77197187
commit e2a9e9db84

View file

@ -290,7 +290,6 @@ Varnode *Funcdata::findSpacebaseInput(AddrSpace *id) const
void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize) void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const Address &rampoint,uintb origval,int4 origsize)
{ {
PcodeOp *addop;
int4 sz = rampoint.getAddrSize(); int4 sz = rampoint.getAddrSize();
AddrSpace *spaceid = rampoint.getSpace(); AddrSpace *spaceid = rampoint.getSpace();
Datatype *sb_type = glb->types->getTypeSpacebase(spaceid,Address()); Datatype *sb_type = glb->types->getTypeSpacebase(spaceid,Address());
@ -300,21 +299,47 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
uintb extra = rampoint.getOffset() - entry->getAddr().getOffset(); // Offset from beginning of entry uintb extra = rampoint.getOffset() - entry->getAddr().getOffset(); // Offset from beginning of entry
extra = AddrSpace::byteToAddress(extra,rampoint.getSpace()->getWordSize()); // Convert to address units extra = AddrSpace::byteToAddress(extra,rampoint.getSpace()->getWordSize()); // Convert to address units
PcodeOp *addOp = (PcodeOp *)0;
PcodeOp *extraOp = (PcodeOp *)0;
PcodeOp *zextOp = (PcodeOp *)0;
PcodeOp *subOp = (PcodeOp *)0;
bool isCopy = false;
if (op->code() == CPUI_COPY) { // We replace COPY with final op of this calculation
isCopy = true;
if (sz < origsize)
zextOp = op;
else {
op->insertInput(1); // PTRSUB, ADD, SUBPIECE all take 2 parameters
if (origsize < sz)
subOp = op;
else if (extra != 0)
extraOp = op;
else
addOp = op;
}
}
spacebase_vn = newConstant(sz,0); spacebase_vn = newConstant(sz,0);
spacebase_vn->updateType(sb_type,true,true); spacebase_vn->updateType(sb_type,true,true);
spacebase_vn->setFlags(Varnode::spacebase); spacebase_vn->setFlags(Varnode::spacebase);
addop = newOp(2,op->getAddr()); if (addOp == (PcodeOp *)0) {
opSetOpcode(addop,CPUI_PTRSUB); addOp = newOp(2,op->getAddr());
outvn = newUniqueOut(sz,addop); opSetOpcode(addOp,CPUI_PTRSUB);
newUniqueOut(sz,addOp);
opInsertBefore(addOp,op);
}
else {
opSetOpcode(addOp,CPUI_PTRSUB);
}
outvn = addOp->getOut();
// Make sure newconstant and extra preserve origval in address units // Make sure newconstant and extra preserve origval in address units
uintb newconstoff = origval - extra; // everything is already in address units uintb newconstoff = origval - extra; // everything is already in address units
newconst = newConstant(sz,newconstoff); newconst = newConstant(sz,newconstoff);
newconst->setPtrCheck(); // No longer need to check this constant as a pointer newconst->setPtrCheck(); // No longer need to check this constant as a pointer
if (spaceid->isTruncated()) if (spaceid->isTruncated())
addop->setPtrFlow(); addOp->setPtrFlow();
opSetInput(addop,spacebase_vn,0); opSetInput(addOp,spacebase_vn,0);
opSetInput(addop,newconst,1); opSetInput(addOp,newconst,1);
opInsertBefore(addop,op);
Symbol *sym = entry->getSymbol(); Symbol *sym = entry->getSymbol();
Datatype *entrytype = sym->getType(); Datatype *entrytype = sym->getType();
Datatype *ptrentrytype = glb->types->getTypePointer(sz,entrytype,spaceid->getWordSize()); Datatype *ptrentrytype = glb->types->getTypePointer(sz,entrytype,spaceid->getWordSize());
@ -323,34 +348,47 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
typelock = false; typelock = false;
outvn->updateType(ptrentrytype,typelock,true); outvn->updateType(ptrentrytype,typelock,true);
if (extra != 0) { if (extra != 0) {
PcodeOp *extraop = newOp(2,op->getAddr()); if (extraOp == (PcodeOp *)0) {
opSetOpcode(extraop,CPUI_INT_ADD); extraOp = newOp(2,op->getAddr());
Varnode *outvn2 = newUniqueOut(sz,extraop); opSetOpcode(extraOp,CPUI_INT_ADD);
newUniqueOut(sz,extraOp);
opInsertBefore(extraOp,op);
}
else
opSetOpcode(extraOp,CPUI_INT_ADD);
Varnode *extconst = newConstant(sz,extra); Varnode *extconst = newConstant(sz,extra);
extconst->setPtrCheck(); extconst->setPtrCheck();
opSetInput(extraop,outvn,0); opSetInput(extraOp,outvn,0);
opSetInput(extraop,extconst,1); opSetInput(extraOp,extconst,1);
outvn = outvn2; outvn = extraOp->getOut();
opInsertBefore(extraop,op);
} }
if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it
PcodeOp *zextop = newOp(1,op->getAddr()); if (zextOp == (PcodeOp *)0) {
Varnode *outvn2 = newUniqueOut(origsize,zextop); zextOp = newOp(1,op->getAddr());
opSetOpcode(zextop,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size opSetOpcode(zextOp,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size
opSetInput(zextop,outvn,0); newUniqueOut(origsize,zextOp);
opInsertBefore(zextop,op); opInsertBefore(zextOp,op);
outvn = outvn2; }
else
opSetOpcode(extraOp,CPUI_INT_ZEXT);
opSetInput(zextOp,outvn,0);
outvn = zextOp->getOut();
} }
else if (origsize < sz) { // The new constant is bigger than the original varnode, truncate it else if (origsize < sz) { // The new constant is bigger than the original varnode, truncate it
PcodeOp *subOp = newOp(2,op->getAddr()); if (subOp == (PcodeOp *)0) {
Varnode *outvn3 = newUniqueOut(origsize,subOp); subOp = newOp(2,op->getAddr());
opSetOpcode(subOp,CPUI_SUBPIECE); opSetOpcode(subOp,CPUI_SUBPIECE);
newUniqueOut(origsize,subOp);
opInsertBefore(subOp,op);
}
else
opSetOpcode(subOp,CPUI_SUBPIECE);
opSetInput(subOp,outvn,0); opSetInput(subOp,outvn,0);
opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece
opInsertBefore(subOp,op); outvn = subOp->getOut();
outvn = outvn3;
} }
opSetInput(op,outvn,slot); if (!isCopy)
opSetInput(op,outvn,slot);
} }
void Funcdata::clearCallSpecs(void) void Funcdata::clearCallSpecs(void)