mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 02:09:44 +02:00
adjustments to resolveConstant
This commit is contained in:
parent
612c0d6f3e
commit
4edff2b9f0
10 changed files with 51 additions and 20 deletions
|
@ -1135,7 +1135,7 @@ void Architecture::init(DocumentStorage &store)
|
|||
fillinReadOnlyFromLoader();
|
||||
}
|
||||
|
||||
Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point)
|
||||
Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point,uintb &fullEncoding)
|
||||
|
||||
{
|
||||
int4 innersz = segop->getInnerSize();
|
||||
|
@ -1145,6 +1145,7 @@ Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point)
|
|||
// (as with near pointers)
|
||||
if (segop->getResolve().space != (AddrSpace *)0) {
|
||||
uintb base = glb->context->getTrackedValue(segop->getResolve(),point);
|
||||
fullEncoding = (base << 8 * innersz) + (val & calc_mask(innersz));
|
||||
vector<uintb> seginput;
|
||||
seginput.push_back(val);
|
||||
seginput.push_back(base);
|
||||
|
@ -1153,6 +1154,7 @@ Address SegmentedResolver::resolve(uintb val,int4 sz,const Address &point)
|
|||
}
|
||||
}
|
||||
else { // For anything else, consider it a "far" pointer
|
||||
fullEncoding = val;
|
||||
int4 outersz = segop->getBaseSize();
|
||||
uintb base = (val >> 8*innersz) & calc_mask(outersz);
|
||||
val = val & calc_mask(innersz);
|
||||
|
|
|
@ -284,7 +284,7 @@ public:
|
|||
/// \param sp is the segmented space
|
||||
/// \param sop is the segment operator
|
||||
SegmentedResolver(Architecture *g,AddrSpace *sp,SegmentOp *sop) { glb=g; spc=sp; segop=sop; }
|
||||
virtual Address resolve(uintb val,int4 sz,const Address &point);
|
||||
virtual Address resolve(uintb val,int4 sz,const Address &point,uintb &fullEncoding);
|
||||
};
|
||||
|
||||
/// The Translate object keeps track of address ranges for which
|
||||
|
|
|
@ -827,14 +827,14 @@ int4 ActionShadowVar::apply(Funcdata &data)
|
|||
/// \param rampoint will hold the Address of the resolved symbol
|
||||
/// \param data is the function being analyzed
|
||||
/// \return the recovered symbol or NULL
|
||||
SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,Address &rampoint,Funcdata &data)
|
||||
SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,Address &rampoint,uintb &fullEncoding,Funcdata &data)
|
||||
|
||||
{
|
||||
bool needexacthit;
|
||||
Architecture *glb = data.getArch();
|
||||
Varnode *outvn;
|
||||
if (vn->getType()->getMetatype() == TYPE_PTR) { // Are we explicitly marked as a pointer
|
||||
rampoint = glb->resolveConstant(spc,vn->getOffset(),vn->getSize(),op->getAddr());
|
||||
rampoint = glb->resolveConstant(spc,vn->getOffset(),vn->getSize(),op->getAddr(),fullEncoding);
|
||||
needexacthit = false;
|
||||
}
|
||||
else {
|
||||
|
@ -881,7 +881,7 @@ SymbolEntry *ActionConstantPtr::isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op
|
|||
// Check if the constant looks like a single bit or mask
|
||||
if (bit_transitions(vn->getOffset(),vn->getSize()) < 3)
|
||||
return (SymbolEntry *)0;
|
||||
rampoint = glb->resolveConstant(spc,vn->getOffset(),vn->getSize(),op->getAddr());
|
||||
rampoint = glb->resolveConstant(spc,vn->getOffset(),vn->getSize(),op->getAddr(),fullEncoding);
|
||||
}
|
||||
|
||||
if (rampoint.isInvalid()) return (SymbolEntry *)0;
|
||||
|
@ -943,10 +943,11 @@ int4 ActionConstantPtr::apply(Funcdata &data)
|
|||
else if ((opc == CPUI_PTRSUB)||(opc==CPUI_PTRADD))
|
||||
continue;
|
||||
Address rampoint;
|
||||
entry = isPointer(rspc,vn,op,rampoint,data);
|
||||
uintb fullEncoding;
|
||||
entry = isPointer(rspc,vn,op,rampoint,fullEncoding,data);
|
||||
vn->setPtrCheck(); // Set check flag AFTER searching for symbol
|
||||
if (entry != (SymbolEntry *)0) {
|
||||
data.spacebaseConstant(op,slot,entry,rampoint,vn->getOffset(),vn->getSize());
|
||||
data.spacebaseConstant(op,slot,entry,rampoint,fullEncoding,vn->getSize());
|
||||
if ((opc == CPUI_INT_ADD)&&(slot==1))
|
||||
data.opSwapInput(op,0,1);
|
||||
count += 1;
|
||||
|
|
|
@ -162,7 +162,7 @@ public:
|
|||
/// \brief Check for constants, with pointer type, that correspond to global symbols
|
||||
class ActionConstantPtr : public Action {
|
||||
int4 localcount; ///< Number of passes made for this function
|
||||
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,Address &rampoint,Funcdata &data);
|
||||
static SymbolEntry *isPointer(AddrSpace *spc,Varnode *vn,PcodeOp *op,Address &rampoint,uintb &fullEncoding,Funcdata &data);
|
||||
public:
|
||||
ActionConstantPtr(const string &g) : Action(0,"constantptr",g) {} ///< Constructor
|
||||
virtual void reset(Funcdata &data) { localcount = 0; }
|
||||
|
|
|
@ -333,7 +333,7 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
|
|||
outvn = outvn2;
|
||||
opInsertBefore(extraop,op);
|
||||
}
|
||||
if (sz != origsize) { // There is a change in size from address -> varnode
|
||||
if (sz < origsize) { // The new constant is smaller than the original varnode, so we extend it
|
||||
PcodeOp *zextop = newOp(1,op->getAddr());
|
||||
Varnode *outvn2 = newUniqueOut(origsize,zextop);
|
||||
opSetOpcode(zextop,CPUI_INT_ZEXT); // Create an extension to get back to original varnode size
|
||||
|
@ -341,6 +341,15 @@ void Funcdata::spacebaseConstant(PcodeOp *op,int4 slot,SymbolEntry *entry,const
|
|||
opInsertBefore(zextop,op);
|
||||
outvn = outvn2;
|
||||
}
|
||||
else if (origsize < sz) { // The new constant is bigger than the original varnode, truncate it
|
||||
PcodeOp *subOp = newOp(2,op->getAddr());
|
||||
Varnode *outvn3 = newUniqueOut(origsize,subOp);
|
||||
opSetOpcode(subOp,CPUI_SUBPIECE);
|
||||
opSetInput(subOp,outvn,0);
|
||||
opSetInput(subOp,newConstant(4, 0), 1); // Take least significant piece
|
||||
opInsertBefore(subOp,op);
|
||||
outvn = outvn3;
|
||||
}
|
||||
opSetInput(op,outvn,slot);
|
||||
}
|
||||
|
||||
|
|
|
@ -1403,7 +1403,8 @@ bool PrintC::pushPtrCharConstant(uintb val,const TypePointer *ct,const Varnode *
|
|||
{
|
||||
if (val==0) return false;
|
||||
AddrSpace *spc = glb->getDefaultSpace();
|
||||
Address stringaddr = glb->resolveConstant(spc,val,ct->getSize(),op->getAddr());
|
||||
uintb fullEncoding;
|
||||
Address stringaddr = glb->resolveConstant(spc,val,ct->getSize(),op->getAddr(),fullEncoding);
|
||||
if (stringaddr.isInvalid()) return false;
|
||||
if (!glb->symboltab->getGlobalScope()->isReadOnly(stringaddr,1,Address()))
|
||||
return false; // Check that string location is readonly
|
||||
|
|
|
@ -485,15 +485,27 @@ AddrSpace *AddrSpaceManager::getSpaceByShortcut(char sc) const
|
|||
return (*iter).second;
|
||||
}
|
||||
|
||||
Address AddrSpaceManager::resolveConstant(AddrSpace *spc,uintb val,int4 sz,const Address &point) const
|
||||
/// \brief Resolve a native constant into an Address
|
||||
///
|
||||
/// If there is a special resolver for the AddrSpace, this is invoked, otherwise
|
||||
/// basic wordsize conversion and wrapping is performed. If the address encoding is
|
||||
/// partial (as in a \e near pointer) and the full encoding can be recovered, it is passed back.
|
||||
/// \param spc is the space to generate the address from
|
||||
/// \param val is the constant encoding of the address
|
||||
/// \param sz is the size of the constant encoding
|
||||
/// \param point is the context address (for recovering full encoding info if necessary)
|
||||
/// \param fullEncoding is used to pass back the recovered full encoding of the pointer
|
||||
/// \return the formal Address associated with the encoding
|
||||
Address AddrSpaceManager::resolveConstant(AddrSpace *spc,uintb val,int4 sz,const Address &point,uintb &fullEncoding) const
|
||||
|
||||
{
|
||||
int4 ind = spc->getIndex();
|
||||
if (ind < resolvelist.size()) {
|
||||
AddressResolver *resolve = resolvelist[ind];
|
||||
if (resolve != (AddressResolver *)0)
|
||||
return resolve->resolve(val,sz,point);
|
||||
return resolve->resolve(val,sz,point,fullEncoding);
|
||||
}
|
||||
fullEncoding = val;
|
||||
val = AddrSpace::addressToByte(val,spc->getWordSize());
|
||||
val = spc->wrapOffset(val);
|
||||
return Address(spc,val);
|
||||
|
|
|
@ -147,8 +147,9 @@ public:
|
|||
/// \param val is constant to be resolved to an address
|
||||
/// \param sz is the size of \e val in context.
|
||||
/// \param point is the address at which this constant is being used
|
||||
/// \param fullEncoding is used to hold the full pointer encoding if \b val is a partial encoding
|
||||
/// \return the resolved Address
|
||||
virtual Address resolve(uintb val,int4 sz,const Address &point)=0;
|
||||
virtual Address resolve(uintb val,int4 sz,const Address &point,uintb &fullEncoding)=0;
|
||||
};
|
||||
|
||||
/// \brief A virtual space \e stack space
|
||||
|
@ -249,7 +250,7 @@ public:
|
|||
AddrSpace *getConstantSpace(void) const; ///< Get the constant space
|
||||
Address getConstant(uintb val) const; ///< Get a constant encoded as an Address
|
||||
Address createConstFromSpace(AddrSpace *spc) const; ///< Create a constant address encoding an address space
|
||||
Address resolveConstant(AddrSpace *spc,uintb val,int4 sz,const Address &point) const; ///< Resolve native constant to address
|
||||
Address resolveConstant(AddrSpace *spc,uintb val,int4 sz,const Address &point,uintb &fullEncoding) const;
|
||||
int4 numSpaces(void) const; ///< Get the number of address spaces for this processor
|
||||
AddrSpace *getSpace(int4 i) const; ///< Get an address space via its index
|
||||
AddrSpace *getNextSpaceInOrder(AddrSpace *spc) const; ///< Get the next \e contiguous address space
|
||||
|
|
|
@ -1124,13 +1124,17 @@ Datatype *TypeSpacebase::getSubType(uintb off,uintb *newoff) const
|
|||
|
||||
{
|
||||
Scope *scope = getMap();
|
||||
// uintb unoff = (uintb)(intb)off; // Make sure this is a sign-extension
|
||||
Address addr(spaceid,spaceid->wrapOffset(off));
|
||||
off = AddrSpace::byteToAddress(off, spaceid->getWordSize()); // Convert from byte offset to address unit
|
||||
// It should always be the case that given offset represents a full encoding of the
|
||||
// pointer, so the point of context is unused
|
||||
Address nullPoint;
|
||||
uintb fullEncoding;
|
||||
Address addr = glb->resolveConstant(spaceid, off, spaceid->getAddrSize(), nullPoint, fullEncoding);
|
||||
SymbolEntry *smallest;
|
||||
|
||||
// Assume symbol being referenced is address tied,
|
||||
// so we use empty usepoint
|
||||
smallest = scope->queryContainer(addr,1,Address());
|
||||
smallest = scope->queryContainer(addr,1,nullPoint);
|
||||
|
||||
if (smallest == (SymbolEntry *)0) {
|
||||
*newoff = 0;
|
||||
|
@ -1167,7 +1171,8 @@ int4 TypeSpacebase::compareDependency(const Datatype &op) const
|
|||
Address TypeSpacebase::getAddress(uintb off,int4 sz,const Address &point) const
|
||||
|
||||
{
|
||||
return glb->resolveConstant(spaceid,off,sz,point);
|
||||
uintb fullEncoding;
|
||||
return glb->resolveConstant(spaceid,off,sz,point,fullEncoding);
|
||||
}
|
||||
|
||||
void TypeSpacebase::saveXml(ostream &s) const
|
||||
|
|
|
@ -1378,8 +1378,8 @@ public class SleighLanguage implements Language {
|
|||
SpecXmlUtils.encodeSignedIntegerAttribute(resBuf, "index", element.getUnique());
|
||||
|
||||
int size = element.getSize(); // Size in bits
|
||||
if (size == 20) {
|
||||
// TODO: SegmentedAddressSpace shouldn't really return 20
|
||||
if (element instanceof SegmentedAddressSpace) {
|
||||
// TODO: SegmentedAddressSpace shouldn't really return 21
|
||||
size = 32;
|
||||
}
|
||||
if (size > 64) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue