mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Variable length types
This commit is contained in:
parent
02e6c66f11
commit
97b04cac7e
7 changed files with 29 additions and 23 deletions
|
@ -4244,7 +4244,7 @@ Datatype *ActionInferTypes::propagateAddIn2Out(TypeFactory *typegrp,PcodeOp *op,
|
||||||
int4 offset = propagateAddPointer(op,inslot);
|
int4 offset = propagateAddPointer(op,inslot);
|
||||||
if (offset==-1) return op->getOut()->getTempType(); // Doesn't look like a good pointer add
|
if (offset==-1) return op->getOut()->getTempType(); // Doesn't look like a good pointer add
|
||||||
uintb uoffset = AddrSpace::addressToByte(offset,((TypePointer *)rettype)->getWordSize());
|
uintb uoffset = AddrSpace::addressToByte(offset,((TypePointer *)rettype)->getWordSize());
|
||||||
if (tstruct->getSize() > 0)
|
if (tstruct->getSize() > 0 && !tstruct->isVariableLength())
|
||||||
uoffset = uoffset % tstruct->getSize();
|
uoffset = uoffset % tstruct->getSize();
|
||||||
if (uoffset==0) {
|
if (uoffset==0) {
|
||||||
if (op->code() == CPUI_PTRSUB) // Go down at least one level
|
if (op->code() == CPUI_PTRSUB) // Go down at least one level
|
||||||
|
@ -4419,7 +4419,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
|
||||||
}
|
}
|
||||||
else if (alttype->getMetatype()==TYPE_PTR) {
|
else if (alttype->getMetatype()==TYPE_PTR) {
|
||||||
newtype = ((TypePointer *)alttype)->getPtrTo();
|
newtype = ((TypePointer *)alttype)->getPtrTo();
|
||||||
if (newtype->getSize() != outvn->getTempType()->getSize()) // Size must be appropriate
|
if (newtype->getSize() != outvn->getTempType()->getSize() || newtype->isVariableLength()) // Size must be appropriate
|
||||||
newtype = outvn->getTempType();
|
newtype = outvn->getTempType();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4432,7 +4432,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
|
||||||
}
|
}
|
||||||
else if (alttype->getMetatype()==TYPE_PTR) {
|
else if (alttype->getMetatype()==TYPE_PTR) {
|
||||||
newtype = ((TypePointer *)alttype)->getPtrTo();
|
newtype = ((TypePointer *)alttype)->getPtrTo();
|
||||||
if (newtype->getSize() != outvn->getTempType()->getSize())
|
if (newtype->getSize() != outvn->getTempType()->getSize() || newtype->isVariableLength())
|
||||||
newtype = outvn->getTempType();
|
newtype = outvn->getTempType();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -38,7 +38,7 @@ ScopeGhidra::~ScopeGhidra(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Ghidra client reports a \e namespace id associated with
|
/// The Ghidra client reports a \e namespace id associated with
|
||||||
/// Symbol. Determine if a matching \e namespac Scope already exists in the cache and build
|
/// Symbol. Determine if a matching \e namespace Scope already exists in the cache and build
|
||||||
/// it if it isn't. This may mean creating a new \e namespace Scope.
|
/// it if it isn't. This may mean creating a new \e namespace Scope.
|
||||||
/// \param id is the ID associated with the Ghidra namespace
|
/// \param id is the ID associated with the Ghidra namespace
|
||||||
/// \return the Scope matching the id.
|
/// \return the Scope matching the id.
|
||||||
|
|
|
@ -1670,21 +1670,7 @@ void PrintC::pushAnnotation(const Varnode *vn,const PcodeOp *op)
|
||||||
void PrintC::pushSymbol(const Symbol *sym,const Varnode *vn,const PcodeOp *op)
|
void PrintC::pushSymbol(const Symbol *sym,const Varnode *vn,const PcodeOp *op)
|
||||||
|
|
||||||
{
|
{
|
||||||
Datatype *ct = sym->getType();
|
|
||||||
EmitXml::syntax_highlight tokenColor;
|
EmitXml::syntax_highlight tokenColor;
|
||||||
if (((sym->getFlags()&Varnode::readonly)!=0)&&(ct->getMetatype()==TYPE_ARRAY)) {
|
|
||||||
Datatype *subct = ((TypeArray *)ct)->getBase();
|
|
||||||
if (subct->isCharPrint()) {
|
|
||||||
SymbolEntry *entry = sym->getFirstWholeMap();
|
|
||||||
if (entry != (SymbolEntry *)0) {
|
|
||||||
ostringstream s;
|
|
||||||
if (printCharacterConstant(s,entry->getAddr(),subct)) {
|
|
||||||
pushAtom(Atom(s.str(),vartoken,EmitXml::const_color,op,vn));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sym->getScope()->isGlobal())
|
if (sym->getScope()->isGlobal())
|
||||||
tokenColor = EmitXml::global_color;
|
tokenColor = EmitXml::global_color;
|
||||||
else if (sym->getCategory() == 0)
|
else if (sym->getCategory() == 0)
|
||||||
|
|
|
@ -5627,7 +5627,10 @@ AddTreeState::AddTreeState(Funcdata &d,PcodeOp *op,int4 slot)
|
||||||
ptrsize = ptr->getSize();
|
ptrsize = ptr->getSize();
|
||||||
ptrmask = calc_mask(ptrsize);
|
ptrmask = calc_mask(ptrsize);
|
||||||
baseType = ct->getPtrTo();
|
baseType = ct->getPtrTo();
|
||||||
size = AddrSpace::byteToAddressInt(baseType->getSize(),ct->getWordSize());
|
if (baseType->isVariableLength())
|
||||||
|
size = 0; // Open-ended size being pointed to, there will be no "multiples" component
|
||||||
|
else
|
||||||
|
size = AddrSpace::byteToAddressInt(baseType->getSize(),ct->getWordSize());
|
||||||
multsum = 0; // Sums start out as zero
|
multsum = 0; // Sums start out as zero
|
||||||
nonmultsum = 0;
|
nonmultsum = 0;
|
||||||
correct = 0;
|
correct = 0;
|
||||||
|
|
|
@ -46,7 +46,7 @@ class AddTreeState {
|
||||||
const TypePointer *ct; ///< The pointer data-type
|
const TypePointer *ct; ///< The pointer data-type
|
||||||
const Datatype *baseType; ///< The base data-type being pointed at
|
const Datatype *baseType; ///< The base data-type being pointed at
|
||||||
int4 ptrsize; ///< Size of the pointer
|
int4 ptrsize; ///< Size of the pointer
|
||||||
int4 size; ///< Size of data-type being pointed to (in address units)
|
int4 size; ///< Size of data-type being pointed to (in address units) or 0 for open ended pointer
|
||||||
uintb ptrmask; ///< Mask for modulo calculations in ptr space
|
uintb ptrmask; ///< Mask for modulo calculations in ptr space
|
||||||
uintb offset; ///< Number of bytes we dig into the base data-type
|
uintb offset; ///< Number of bytes we dig into the base data-type
|
||||||
uintb correct; ///< Number of bytes being double counted
|
uintb correct; ///< Number of bytes being double counted
|
||||||
|
|
|
@ -1092,15 +1092,18 @@ void TypeStruct::restoreXml(const Element *el,TypeFactory &typegrp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on the data-type's function prototype
|
/// Turn on the data-type's function prototype
|
||||||
|
/// \param tfact is the factory that owns \b this
|
||||||
/// \param model is the prototype model
|
/// \param model is the prototype model
|
||||||
/// \param outtype is the return type of the prototype
|
/// \param outtype is the return type of the prototype
|
||||||
/// \param intypes is the list of input parameters
|
/// \param intypes is the list of input parameters
|
||||||
/// \param dotdotdot is true if the prototype takes variable arguments
|
/// \param dotdotdot is true if the prototype takes variable arguments
|
||||||
/// \param voidtype is the reference "void" data-type
|
/// \param voidtype is the reference "void" data-type
|
||||||
void TypeCode::set(ProtoModel *model,
|
void TypeCode::set(TypeFactory *tfact,ProtoModel *model,
|
||||||
Datatype *outtype,const vector<Datatype *> &intypes,
|
Datatype *outtype,const vector<Datatype *> &intypes,
|
||||||
bool dotdotdot,Datatype *voidtype)
|
bool dotdotdot,Datatype *voidtype)
|
||||||
{
|
{
|
||||||
|
factory = tfact;
|
||||||
|
flags |= variable_length;
|
||||||
if (proto != (FuncProto *)0)
|
if (proto != (FuncProto *)0)
|
||||||
delete proto;
|
delete proto;
|
||||||
proto = new FuncProto();
|
proto = new FuncProto();
|
||||||
|
@ -1123,6 +1126,7 @@ TypeCode::TypeCode(const TypeCode &op) : Datatype(op)
|
||||||
|
|
||||||
{
|
{
|
||||||
proto = (FuncProto *)0;
|
proto = (FuncProto *)0;
|
||||||
|
factory = op.factory;
|
||||||
if (op.proto != (FuncProto *)0) {
|
if (op.proto != (FuncProto *)0) {
|
||||||
proto = new FuncProto();
|
proto = new FuncProto();
|
||||||
proto->copy(*op.proto);
|
proto->copy(*op.proto);
|
||||||
|
@ -1133,6 +1137,7 @@ TypeCode::TypeCode(const string &nm) : Datatype(1,TYPE_CODE,nm)
|
||||||
|
|
||||||
{
|
{
|
||||||
proto = (FuncProto *)0;
|
proto = (FuncProto *)0;
|
||||||
|
factory = (TypeFactory *)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeCode::~TypeCode(void)
|
TypeCode::~TypeCode(void)
|
||||||
|
@ -1204,6 +1209,14 @@ int4 TypeCode::compareBasic(const TypeCode *op) const
|
||||||
return 2; // Carry on with comparison of parameters
|
return 2; // Carry on with comparison of parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datatype *TypeCode::getSubType(uintb off,uintb *newoff) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (factory == (TypeFactory *)0) return (Datatype *)0;
|
||||||
|
*newoff = 0;
|
||||||
|
return factory->getBase(1, TYPE_CODE); // Return code byte unattached to function prototype
|
||||||
|
}
|
||||||
|
|
||||||
int4 TypeCode::compare(const Datatype &op,int4 level) const
|
int4 TypeCode::compare(const Datatype &op,int4 level) const
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1284,6 +1297,8 @@ void TypeCode::restoreXml(const Element *el,TypeFactory &typegrp)
|
||||||
iter = list.begin();
|
iter = list.begin();
|
||||||
if (iter == list.end()) return; // No underlying prototype
|
if (iter == list.end()) return; // No underlying prototype
|
||||||
Architecture *glb = typegrp.getArch();
|
Architecture *glb = typegrp.getArch();
|
||||||
|
factory = &typegrp;
|
||||||
|
flags |= variable_length;
|
||||||
proto = new FuncProto();
|
proto = new FuncProto();
|
||||||
proto->setInternal( glb->defaultfp, typegrp.getTypeVoid() );
|
proto->setInternal( glb->defaultfp, typegrp.getTypeVoid() );
|
||||||
proto->restoreXml(*iter,glb);
|
proto->restoreXml(*iter,glb);
|
||||||
|
@ -2107,7 +2122,7 @@ TypeCode *TypeFactory::getTypeCode(ProtoModel *model,Datatype *outtype,
|
||||||
bool dotdotdot)
|
bool dotdotdot)
|
||||||
{
|
{
|
||||||
TypeCode tc(""); // getFuncdata type with no name
|
TypeCode tc(""); // getFuncdata type with no name
|
||||||
tc.set(model,outtype,intypes,dotdotdot,getTypeVoid());
|
tc.set(this,model,outtype,intypes,dotdotdot,getTypeVoid());
|
||||||
return (TypeCode *) findAdd(tc);
|
return (TypeCode *) findAdd(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,8 @@ class TypeCode : public Datatype {
|
||||||
protected:
|
protected:
|
||||||
friend class TypeFactory;
|
friend class TypeFactory;
|
||||||
FuncProto *proto; ///< If non-null, this describes the prototype of the underlying function
|
FuncProto *proto; ///< If non-null, this describes the prototype of the underlying function
|
||||||
void set(ProtoModel *model,
|
TypeFactory *factory; ///< Factory owning \b this
|
||||||
|
void set(TypeFactory *tfact,ProtoModel *model,
|
||||||
Datatype *outtype,const vector<Datatype *> &intypes,
|
Datatype *outtype,const vector<Datatype *> &intypes,
|
||||||
bool dotdotdot,Datatype *voidtype); ///< Establish a function pointer
|
bool dotdotdot,Datatype *voidtype); ///< Establish a function pointer
|
||||||
virtual void restoreXml(const Element *el,TypeFactory &typegrp);
|
virtual void restoreXml(const Element *el,TypeFactory &typegrp);
|
||||||
|
@ -354,6 +355,7 @@ public:
|
||||||
void setProperties(bool isConstructor,bool isDestructor); ///< Set additional function properties
|
void setProperties(bool isConstructor,bool isDestructor); ///< Set additional function properties
|
||||||
virtual ~TypeCode(void);
|
virtual ~TypeCode(void);
|
||||||
virtual void printRaw(ostream &s) const;
|
virtual void printRaw(ostream &s) const;
|
||||||
|
virtual Datatype *getSubType(uintb off,uintb *newoff) const;
|
||||||
virtual int4 compare(const Datatype &op,int4 level) const;
|
virtual int4 compare(const Datatype &op,int4 level) const;
|
||||||
virtual int4 compareDependency(const Datatype &op) const;
|
virtual int4 compareDependency(const Datatype &op) const;
|
||||||
virtual Datatype *clone(void) const { return new TypeCode(*this); }
|
virtual Datatype *clone(void) const { return new TypeCode(*this); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue