mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-02 00:51:54 +00:00
Merge remote-tracking branch 'origin/GT-3309_CodeDatatype' into patch
This commit is contained in:
commit
0b6b7faebd
@ -398,34 +398,44 @@ void Symbol::restoreXml(const Element *el)
|
|||||||
restoreXmlBody(list.begin());
|
restoreXmlBody(list.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionSymbol::buildType(int4 size)
|
/// Get the number of bytes consumed by a SymbolEntry representing \b this Symbol.
|
||||||
|
/// By default, this is the number of bytes consumed by the Symbol's data-type.
|
||||||
|
/// This gives the amount of leeway a search has when the address queried does not match
|
||||||
|
/// the exact address of the Symbol. With functions, the bytes consumed by a SymbolEntry
|
||||||
|
/// may not match the data-type size.
|
||||||
|
/// \return the number of bytes in a default SymbolEntry
|
||||||
|
int4 Symbol::getBytesConsumed(void) const
|
||||||
|
|
||||||
|
{
|
||||||
|
return type->getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FunctionSymbol::buildType(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
TypeFactory *types = scope->getArch()->types;
|
TypeFactory *types = scope->getArch()->types;
|
||||||
type = types->getTypeCode();
|
type = types->getTypeCode();
|
||||||
// Entries for functions have small size starting at the entry address
|
|
||||||
// of the function in order to deal with non-contiguous functions
|
|
||||||
// The size used to always be 1, but now we need sizes (slightly) larger than 1
|
|
||||||
// to accomodate pointer constants that encode extra information in the lower bit(s)
|
|
||||||
// of an otherwise aligned pointer. If the encoding is not aprior detected, it is interpreted
|
|
||||||
// initially as a straight address that comes up 1 (or more) bytes off of the start of the function
|
|
||||||
// In order to detect this, we need to lay down a slightly larger size than 1
|
|
||||||
if (size > 1)
|
|
||||||
type = types->getTypeArray(size,type);
|
|
||||||
|
|
||||||
flags |= Varnode::namelock | Varnode::typelock;
|
flags |= Varnode::namelock | Varnode::typelock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a function \e shell, made up of just the name of the function and
|
/// Build a function \e shell, made up of just the name of the function and
|
||||||
/// a placeholder data-type, without the underlying Funcdata object.
|
/// a placeholder data-type, without the underlying Funcdata object.
|
||||||
|
/// A SymbolEntry for a function has a small size starting at the entry address,
|
||||||
|
/// in order to deal with non-contiguous functions.
|
||||||
|
/// We need a size (slightly) larger than 1 to accommodate pointer constants that encode
|
||||||
|
/// extra information in the lower bit(s) of an otherwise aligned pointer.
|
||||||
|
/// If the encoding is not initially detected, it is interpreted
|
||||||
|
/// as a straight address that comes up 1 (or more) bytes off of the start of the function
|
||||||
|
/// In order to detect this, we need to lay down a slightly larger size than 1
|
||||||
/// \param sc is the Scope that will contain the new Symbol
|
/// \param sc is the Scope that will contain the new Symbol
|
||||||
/// \param nm is the name of the new Symbol
|
/// \param nm is the name of the new Symbol
|
||||||
/// \param size is the number of bytes the Symbol should consume
|
/// \param size is the number of bytes a SymbolEntry should consume
|
||||||
FunctionSymbol::FunctionSymbol(Scope *sc,const string &nm,int4 size)
|
FunctionSymbol::FunctionSymbol(Scope *sc,const string &nm,int4 size)
|
||||||
: Symbol(sc)
|
: Symbol(sc)
|
||||||
{
|
{
|
||||||
fd = (Funcdata *)0;
|
fd = (Funcdata *)0;
|
||||||
buildType(size);
|
consumeSize = size;
|
||||||
|
buildType();
|
||||||
name = nm;
|
name = nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +443,8 @@ FunctionSymbol::FunctionSymbol(Scope *sc,int4 size)
|
|||||||
: Symbol(sc)
|
: Symbol(sc)
|
||||||
{
|
{
|
||||||
fd = (Funcdata *)0;
|
fd = (Funcdata *)0;
|
||||||
buildType(size);
|
consumeSize = size;
|
||||||
|
buildType();
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionSymbol::~FunctionSymbol(void) {
|
FunctionSymbol::~FunctionSymbol(void) {
|
||||||
@ -469,9 +480,9 @@ void FunctionSymbol::restoreXml(const Element *el)
|
|||||||
fd = new Funcdata("",scope,Address());
|
fd = new Funcdata("",scope,Address());
|
||||||
fd->restoreXml(el);
|
fd->restoreXml(el);
|
||||||
name = fd->getName();
|
name = fd->getName();
|
||||||
if (type->getSize() < fd->getSize()) {
|
if (consumeSize < fd->getSize()) {
|
||||||
if ((fd->getSize()>1)&&(fd->getSize() <= 8))
|
if ((fd->getSize()>1)&&(fd->getSize() <= 8))
|
||||||
buildType(fd->getSize());
|
consumeSize = fd->getSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // functionshell
|
else { // functionshell
|
||||||
@ -934,8 +945,9 @@ SymbolEntry *Scope::addMap(const SymbolEntry &entry)
|
|||||||
entry.symbol->flags |= Varnode::persist;
|
entry.symbol->flags |= Varnode::persist;
|
||||||
|
|
||||||
SymbolEntry *res;
|
SymbolEntry *res;
|
||||||
|
int4 consumeSize = entry.symbol->getBytesConsumed();
|
||||||
if (entry.addr.isInvalid())
|
if (entry.addr.isInvalid())
|
||||||
res = addDynamicMapInternal(entry.symbol,Varnode::mapped,entry.hash,0,entry.symbol->getType()->getSize(),entry.uselimit);
|
res = addDynamicMapInternal(entry.symbol,Varnode::mapped,entry.hash,0,consumeSize,entry.uselimit);
|
||||||
else {
|
else {
|
||||||
if (entry.uselimit.empty()) {
|
if (entry.uselimit.empty()) {
|
||||||
entry.symbol->flags |= Varnode::addrtied;
|
entry.symbol->flags |= Varnode::addrtied;
|
||||||
@ -943,7 +955,7 @@ SymbolEntry *Scope::addMap(const SymbolEntry &entry)
|
|||||||
// can only happen if use is not limited
|
// can only happen if use is not limited
|
||||||
entry.symbol->flags |= glb->symboltab->getProperty(entry.addr);
|
entry.symbol->flags |= glb->symboltab->getProperty(entry.addr);
|
||||||
}
|
}
|
||||||
res = addMapInternal(entry.symbol,Varnode::mapped,entry.addr,0,entry.symbol->getType()->getSize(),entry.uselimit);
|
res = addMapInternal(entry.symbol,Varnode::mapped,entry.addr,0,consumeSize,entry.uselimit);
|
||||||
if (entry.addr.isJoin()) {
|
if (entry.addr.isJoin()) {
|
||||||
// The address is a join, we add extra SymbolEntry maps for each of the pieces
|
// The address is a join, we add extra SymbolEntry maps for each of the pieces
|
||||||
JoinRecord *rec = glb->findJoin(entry.addr.getOffset());
|
JoinRecord *rec = glb->findJoin(entry.addr.getOffset());
|
||||||
|
@ -208,6 +208,7 @@ public:
|
|||||||
void restoreXmlBody(List::const_iterator iter); ///< Restore details of the Symbol from XML
|
void restoreXmlBody(List::const_iterator iter); ///< Restore details of the Symbol from XML
|
||||||
virtual void saveXml(ostream &s) const; ///< Save \b this Symbol to an XML stream
|
virtual void saveXml(ostream &s) const; ///< Save \b this Symbol to an XML stream
|
||||||
virtual void restoreXml(const Element *el); ///< Restore \b this Symbol from an XML stream
|
virtual void restoreXml(const Element *el); ///< Restore \b this Symbol from an XML stream
|
||||||
|
virtual int4 getBytesConsumed(void) const; ///< Get number of bytes consumed within the address->symbol map
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Force a specific display format for constant symbols
|
/// Force a specific display format for constant symbols
|
||||||
@ -235,14 +236,16 @@ inline bool SymbolEntry::isAddrTied(void) const {
|
|||||||
/// Symbol is thus associated with all the meta-data about the function.
|
/// Symbol is thus associated with all the meta-data about the function.
|
||||||
class FunctionSymbol : public Symbol {
|
class FunctionSymbol : public Symbol {
|
||||||
Funcdata *fd; ///< The underlying meta-data object for the function
|
Funcdata *fd; ///< The underlying meta-data object for the function
|
||||||
|
int4 consumeSize; ///< Minimum number of bytes to consume with the start address
|
||||||
virtual ~FunctionSymbol(void);
|
virtual ~FunctionSymbol(void);
|
||||||
void buildType(int4 size); ///< Build the data-type associated with \b this Symbol
|
void buildType(void); ///< Build the data-type associated with \b this Symbol
|
||||||
public:
|
public:
|
||||||
FunctionSymbol(Scope *sc,const string &nm,int4 size); ///< Construct given the name
|
FunctionSymbol(Scope *sc,const string &nm,int4 size); ///< Construct given the name
|
||||||
FunctionSymbol(Scope *sc,int4 size); ///< Constructor for use with restoreXml
|
FunctionSymbol(Scope *sc,int4 size); ///< Constructor for use with restoreXml
|
||||||
Funcdata *getFunction(void); ///< Get the underlying Funcdata object
|
Funcdata *getFunction(void); ///< Get the underlying Funcdata object
|
||||||
virtual void saveXml(ostream &s) const;
|
virtual void saveXml(ostream &s) const;
|
||||||
virtual void restoreXml(const Element *el);
|
virtual void restoreXml(const Element *el);
|
||||||
|
virtual int4 getBytesConsumed(void) const { return consumeSize; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief A Symbol that holds \b equate information for a constant
|
/// \brief A Symbol that holds \b equate information for a constant
|
||||||
|
@ -1893,6 +1893,24 @@ Datatype *TypeFactory::downChain(Datatype *ptrtype,uintb &off)
|
|||||||
return getTypePointer(ptype->size,pt,ptype->getWordSize());
|
return getTypePointer(ptype->size,pt,ptype->getWordSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The data-type propagation system can push around data-types that are \e partial or are
|
||||||
|
/// otherwise unrepresentable in the source language. This method substitutes those data-types
|
||||||
|
/// with a concrete data-type that is representable, or returns the same data-type if is already concrete.
|
||||||
|
/// Its important that the returned data-type have the same size as the original data-type regardless.
|
||||||
|
/// \param ct is the given data-type
|
||||||
|
/// \return the concrete data-type
|
||||||
|
Datatype *TypeFactory::concretize(Datatype *ct)
|
||||||
|
|
||||||
|
{
|
||||||
|
type_metatype metatype = ct->getMetatype();
|
||||||
|
if (metatype == TYPE_CODE) {
|
||||||
|
if (ct->getSize() != 1)
|
||||||
|
throw LowlevelError("Primitive code data-type that is not size 1");
|
||||||
|
ct = getBase(1, TYPE_UNKNOWN);
|
||||||
|
}
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
/// Restore a Datatype object from an XML tag description: either \<type>, \<typeref>, or \<void>
|
/// Restore a Datatype object from an XML tag description: either \<type>, \<typeref>, or \<void>
|
||||||
/// \param el is the XML element describing the data-type
|
/// \param el is the XML element describing the data-type
|
||||||
/// \return the restored Datatype object
|
/// \return the restored Datatype object
|
||||||
|
@ -435,6 +435,7 @@ public:
|
|||||||
bool dotdotdot); ///< Create a "function" datatype
|
bool dotdotdot); ///< Create a "function" datatype
|
||||||
void destroyType(Datatype *ct); ///< Remove a data-type from \b this
|
void destroyType(Datatype *ct); ///< Remove a data-type from \b this
|
||||||
Datatype *downChain(Datatype *ptrtype,uintb &off); ///< Find a sub-type matching a pointer and offset
|
Datatype *downChain(Datatype *ptrtype,uintb &off); ///< Find a sub-type matching a pointer and offset
|
||||||
|
Datatype *concretize(Datatype *ct); ///< Convert given data-type to concrete form
|
||||||
void dependentOrder(vector<Datatype *> &deporder) const; ///< Place all data-types in dependency order
|
void dependentOrder(vector<Datatype *> &deporder) const; ///< Place all data-types in dependency order
|
||||||
void saveXml(ostream &s) const; ///< Save \b this container to stream
|
void saveXml(ostream &s) const; ///< Save \b this container to stream
|
||||||
void saveXmlCoreTypes(ostream &s) const; ///< Save core types to stream
|
void saveXmlCoreTypes(ostream &s) const; ///< Save core types to stream
|
||||||
|
@ -513,7 +513,7 @@ void ScopeLocal::createEntry(const RangeHint &a)
|
|||||||
{
|
{
|
||||||
Address addr(space,a.start);
|
Address addr(space,a.start);
|
||||||
Address usepoint;
|
Address usepoint;
|
||||||
Datatype *ct = a.type;
|
Datatype *ct = glb->types->concretize(a.type);
|
||||||
int4 num = a.size/ct->getSize();
|
int4 num = a.size/ct->getSize();
|
||||||
if (num>1)
|
if (num>1)
|
||||||
ct = glb->types->getTypeArray(num,ct);
|
ct = glb->types->getTypeArray(num,ct);
|
||||||
|
Loading…
Reference in New Issue
Block a user