Parameters with persist property

This commit is contained in:
caheckman 2020-06-22 15:13:35 -04:00
parent 84e4b8c6fe
commit 7329198ad7
10 changed files with 96 additions and 36 deletions

View file

@ -3924,9 +3924,9 @@ int4 ActionInputPrototype::apply(Funcdata &data)
}
}
if (data.isHighOn())
data.getFuncProto().updateInputTypes(triallist,&active);
data.getFuncProto().updateInputTypes(data,triallist,&active);
else
data.getFuncProto().updateInputNoTypes(triallist,&active,data.getArch()->types);
data.getFuncProto().updateInputNoTypes(data,triallist,&active);
}
data.clearDeadVarnodes();
#ifdef OPACTION_DEBUG

View file

@ -1069,13 +1069,23 @@ void Scope::removeRange(AddrSpace *spc,uintb first,uintb last)
/// In particular, the SymbolEntry is assumed to map the entire Symbol.
/// \param entry is the given SymbolEntry
/// \return a SymbolEntry which has been fully integrated
SymbolEntry *Scope::addMap(const SymbolEntry &entry)
SymbolEntry *Scope::addMap(SymbolEntry &entry)
{
// First set properties of this symbol based on scope
// entry.symbol->flags |= Varnode::mapped;
if (isGlobal())
entry.symbol->flags |= Varnode::persist;
else if (!entry.addr.isInvalid()) {
// If this is not a global scope, but the address is in the global discovery range
// we still mark the symbol as persistent
Scope *glbScope = glb->symboltab->getGlobalScope();
Address addr;
if (glbScope->inScope(entry.addr, 1, addr)) {
entry.symbol->flags |= Varnode::persist;
entry.uselimit.clear(); // FIXME: Kludge for incorrectly generated XML
}
}
SymbolEntry *res;
int4 consumeSize = entry.symbol->getBytesConsumed();

View file

@ -492,7 +492,7 @@ protected:
/// \return the newly created SymbolEntry
virtual SymbolEntry *addDynamicMapInternal(Symbol *sym,uint4 exfl,uint8 hash,int4 off,int4 sz,
const RangeList &uselim)=0;
SymbolEntry *addMap(const SymbolEntry &entry); ///< Integrate a SymbolEntry into the range maps
SymbolEntry *addMap(SymbolEntry &entry); ///< Integrate a SymbolEntry into the range maps
void setSymbolId(Symbol *sym,uint8 id) const { sym->symbolId = id; } ///< Adjust the id associated with a symbol
public:
#ifdef OPACTION_DEBUG

View file

@ -3182,9 +3182,10 @@ void FuncProto::cancelInjectId(void)
/// given a list of Varnodes and their associated trial information,
/// create an input parameter for each trial in order, grabbing data-type
/// information from the Varnode. Any old input parameters are cleared.
/// \param data is the function containing the trial Varnodes
/// \param triallist is the list of Varnodes
/// \param activeinput is the trial container
void FuncProto::updateInputTypes(const vector<Varnode *> &triallist,ParamActive *activeinput)
void FuncProto::updateInputTypes(Funcdata &data,const vector<Varnode *> &triallist,ParamActive *activeinput)
{
if (isInputLocked()) return; // Input is locked, do no updating
@ -3195,15 +3196,25 @@ void FuncProto::updateInputTypes(const vector<Varnode *> &triallist,ParamActive
ParamTrial &trial(activeinput->getTrial(i));
if (trial.isUsed()) {
Varnode *vn = triallist[trial.getSlot()-1];
if (!vn->isMark()) {
if (vn->isMark()) continue;
ParameterPieces pieces;
if (vn->isPersist()) {
int4 sz;
pieces.addr = data.findDisjointCover(vn, sz);
if (sz == vn->getSize())
pieces.type = vn->getHigh()->getType();
else
pieces.type = data.getArch()->types->getBase(sz, TYPE_UNKNOWN);
pieces.flags = 0;
}
else {
pieces.addr = trial.getAddress();
pieces.type = vn->getHigh()->getType();
pieces.flags = 0;
}
store->setInput(count,"",pieces);
count += 1;
vn->setMark(); // Make sure vn is used only once
}
vn->setMark();
}
}
for(int4 i=0;i<triallist.size();++i)
@ -3215,31 +3226,38 @@ void FuncProto::updateInputTypes(const vector<Varnode *> &triallist,ParamActive
/// This is accomplished in the same way as if there were data-types but instead of
/// pulling a data-type from the Varnode, only the size is used.
/// Undefined data-types are pulled from the given TypeFactory
/// \param data is the function containing the trial Varnodes
/// \param triallist is the list of Varnodes
/// \param activeinput is the trial container
/// \param factory is the given TypeFactory
void FuncProto::updateInputNoTypes(const vector<Varnode *> &triallist,ParamActive *activeinput,
TypeFactory *factory)
void FuncProto::updateInputNoTypes(Funcdata &data,const vector<Varnode *> &triallist,ParamActive *activeinput)
{
if (isInputLocked()) return; // Input is locked, do no updating
store->clearAllInputs();
int4 count = 0;
int4 numtrials = activeinput->getNumTrials();
TypeFactory *factory = data.getArch()->types;
for(int4 i=0;i<numtrials;++i) {
ParamTrial &trial(activeinput->getTrial(i));
if (trial.isUsed()) {
Varnode *vn = triallist[trial.getSlot()-1];
if (!vn->isMark()) {
if (vn->isMark()) continue;
ParameterPieces pieces;
pieces.type = factory->getBase(vn->getSize(),TYPE_UNKNOWN);
pieces.addr = trial.getAddress();
if (vn->isPersist()) {
int4 sz;
pieces.addr = data.findDisjointCover(vn, sz);
pieces.type = factory->getBase(sz, TYPE_UNKNOWN);
pieces.flags = 0;
}
else {
pieces.addr = trial.getAddress();
pieces.type = factory->getBase(vn->getSize(),TYPE_UNKNOWN);
pieces.flags = 0;
}
store->setInput(count,"",pieces);
count += 1;
vn->setMark(); // Make sure vn is used only once
}
}
}
for(int4 i=0;i<triallist.size();++i)
triallist[i]->clearMark();
}

View file

@ -1327,8 +1327,8 @@ public:
bool checkInputSplit(const Address &loc,int4 size,int4 splitpoint) const {
return model->checkInputSplit(loc,size,splitpoint); }
void updateInputTypes(const vector<Varnode *> &triallist,ParamActive *activeinput);
void updateInputNoTypes(const vector<Varnode *> &triallist,ParamActive *activeinput,TypeFactory *factory);
void updateInputTypes(Funcdata &data,const vector<Varnode *> &triallist,ParamActive *activeinput);
void updateInputNoTypes(Funcdata &data,const vector<Varnode *> &triallist,ParamActive *activeinput);
void updateOutputTypes(const vector<Varnode *> &triallist);
void updateOutputNoTypes(const vector<Varnode *> &triallist,TypeFactory *factory);
void updateAllTypes(const vector<string> &namelist,const vector<Datatype *> &typelist,bool dtdtdt);

View file

@ -266,6 +266,8 @@ public:
void adjustInputVarnodes(const Address &addr,int4 size);
void deleteVarnode(Varnode *vn) { vbank.destroy(vn); } ///< Delete the given varnode
Address findDisjointCover(Varnode *vn,int4 &sz); ///< Find range covering given Varnode and any intersecting Varnodes
/// \brief Find the first input Varnode covered by the given range
///
/// \param s is the size of the range in bytes

View file

@ -1308,6 +1308,35 @@ void Funcdata::splitUses(Varnode *vn)
// Dead-code actions should remove original op
}
/// Find the minimal Address range covering the given Varnode that doesn't split other Varnodes
/// \param vn is the given Varnode
/// \param sz is used to pass back the size of the resulting range
/// \return the starting address of the resulting range
Address Funcdata::findDisjointCover(Varnode *vn,int4 &sz)
{
Address addr = vn->getAddr();
Address endaddr = addr + vn->getSize();
VarnodeLocSet::const_iterator iter = vn->lociter;
while(iter != beginLoc()) {
--iter;
Varnode *curvn = *iter;
Address curEnd = curvn->getAddr() + curvn->getSize();
if (curEnd <= addr) break;
addr = curvn->getAddr();
}
iter = vn->lociter;
while(iter != endLoc()) {
Varnode *curvn = *iter;
++iter;
if (endaddr <= curvn->getAddr()) break;
endaddr = curvn->getAddr() + curvn->getSize();
}
sz = (int4)(endaddr.getOffset() - addr.getOffset());
return addr;
}
/// Search for \e addrtied Varnodes whose storage falls in the global Scope, then
/// build a new global Symbol if one didn't exist before.
void Funcdata::mapGlobals(void)

View file

@ -66,7 +66,7 @@ LocationMap::iterator LocationMap::add(Address addr,int4 size,int4 pass,int4 &in
/// describing the associated range and when it was heritaged.
/// \param addr is the given address
/// \return the iterator to the SizeMap entry or the end iterator is the address is unheritaged
LocationMap::iterator LocationMap::find(Address addr)
LocationMap::iterator LocationMap::find(const Address &addr)
{
iterator iter = themap.upper_bound(addr); // First range after address
@ -80,7 +80,7 @@ LocationMap::iterator LocationMap::find(Address addr)
/// Return the pass number when the given address was heritaged, or -1 if it was not heritaged
/// \param addr is the given address
/// \return the pass number of -1
int4 LocationMap::findPass(Address addr) const
int4 LocationMap::findPass(const Address &addr) const
{
map<Address,SizePass>::const_iterator iter = themap.upper_bound(addr); // First range after address

View file

@ -47,8 +47,8 @@ private:
map<Address,SizePass> themap; ///< Heritaged addresses mapped to range size and pass number
public:
iterator add(Address addr,int4 size,int4 pass,int4 &intersect); ///< Mark new address as \b heritaged
iterator find(Address addr); ///< Look up if/how given address was heritaged
int4 findPass(Address addr) const; ///< Look up if/how given address was heritaged
iterator find(const Address &addr); ///< Look up if/how given address was heritaged
int4 findPass(const Address &addr) const; ///< Look up if/how given address was heritaged
void erase(iterator iter) { themap.erase(iter); } ///< Remove a particular entry from the map
iterator begin(void) { return themap.begin(); } ///< Get starting iterator over heritaged ranges
iterator end(void) { return themap.end(); } ///< Get ending iterator over heritaged ranges

View file

@ -17,8 +17,7 @@ package ghidra.program.model.pcode;
import java.util.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressIterator;
import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Undefined;
import ghidra.program.model.listing.*;
@ -184,16 +183,18 @@ public class LocalSymbolMap {
if (symbol != null) {
id = symbol.getID();
}
Address defAddr = null;
if (!storage.isStackStorage()) {
defAddr = dbFunction.getEntryPoint().addWrap(local.getFirstUseOffset());
}
HighSymbol sym;
if (storage.isHashStorage()) {
Address defAddr = dbFunction.getEntryPoint().addWrap(local.getFirstUseOffset());
sym =
newDynamicSymbol(id, name, dt, storage.getFirstVarnode().getOffset(), defAddr);
}
else {
Address defAddr = null;
int addrType = storage.getFirstVarnode().getAddress().getAddressSpace().getType();
if (addrType != AddressSpace.TYPE_STACK && addrType != AddressSpace.TYPE_RAM) {
defAddr = dbFunction.getEntryPoint().addWrap(local.getFirstUseOffset());
}
sym = newMappedSymbol(id, name, dt, storage, defAddr, -1);
}
sym.setTypeLock(istypelock);