mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
Parameters with persist property
This commit is contained in:
parent
84e4b8c6fe
commit
7329198ad7
10 changed files with 96 additions and 36 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue