mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +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);
|
||||
if (offset==-1) return op->getOut()->getTempType(); // Doesn't look like a good pointer add
|
||||
uintb uoffset = AddrSpace::addressToByte(offset,((TypePointer *)rettype)->getWordSize());
|
||||
if (tstruct->getSize() > 0)
|
||||
if (tstruct->getSize() > 0 && !tstruct->isVariableLength())
|
||||
uoffset = uoffset % tstruct->getSize();
|
||||
if (uoffset==0) {
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
else
|
||||
|
@ -4432,7 +4432,7 @@ bool ActionInferTypes::propagateTypeEdge(TypeFactory *typegrp,PcodeOp *op,int4 i
|
|||
}
|
||||
else if (alttype->getMetatype()==TYPE_PTR) {
|
||||
newtype = ((TypePointer *)alttype)->getPtrTo();
|
||||
if (newtype->getSize() != outvn->getTempType()->getSize())
|
||||
if (newtype->getSize() != outvn->getTempType()->getSize() || newtype->isVariableLength())
|
||||
newtype = outvn->getTempType();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -38,7 +38,7 @@ ScopeGhidra::~ScopeGhidra(void)
|
|||
}
|
||||
|
||||
/// 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.
|
||||
/// \param id is the ID associated with the Ghidra namespace
|
||||
/// \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)
|
||||
|
||||
{
|
||||
Datatype *ct = sym->getType();
|
||||
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())
|
||||
tokenColor = EmitXml::global_color;
|
||||
else if (sym->getCategory() == 0)
|
||||
|
|
|
@ -5627,7 +5627,10 @@ AddTreeState::AddTreeState(Funcdata &d,PcodeOp *op,int4 slot)
|
|||
ptrsize = ptr->getSize();
|
||||
ptrmask = calc_mask(ptrsize);
|
||||
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
|
||||
nonmultsum = 0;
|
||||
correct = 0;
|
||||
|
|
|
@ -46,7 +46,7 @@ class AddTreeState {
|
|||
const TypePointer *ct; ///< The pointer data-type
|
||||
const Datatype *baseType; ///< The base data-type being pointed at
|
||||
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 offset; ///< Number of bytes we dig into the base data-type
|
||||
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
|
||||
/// \param tfact is the factory that owns \b this
|
||||
/// \param model is the prototype model
|
||||
/// \param outtype is the return type of the prototype
|
||||
/// \param intypes is the list of input parameters
|
||||
/// \param dotdotdot is true if the prototype takes variable arguments
|
||||
/// \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,
|
||||
bool dotdotdot,Datatype *voidtype)
|
||||
{
|
||||
factory = tfact;
|
||||
flags |= variable_length;
|
||||
if (proto != (FuncProto *)0)
|
||||
delete proto;
|
||||
proto = new FuncProto();
|
||||
|
@ -1123,6 +1126,7 @@ TypeCode::TypeCode(const TypeCode &op) : Datatype(op)
|
|||
|
||||
{
|
||||
proto = (FuncProto *)0;
|
||||
factory = op.factory;
|
||||
if (op.proto != (FuncProto *)0) {
|
||||
proto = new FuncProto();
|
||||
proto->copy(*op.proto);
|
||||
|
@ -1133,6 +1137,7 @@ TypeCode::TypeCode(const string &nm) : Datatype(1,TYPE_CODE,nm)
|
|||
|
||||
{
|
||||
proto = (FuncProto *)0;
|
||||
factory = (TypeFactory *)0;
|
||||
}
|
||||
|
||||
TypeCode::~TypeCode(void)
|
||||
|
@ -1204,6 +1209,14 @@ int4 TypeCode::compareBasic(const TypeCode *op) const
|
|||
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
|
||||
|
||||
{
|
||||
|
@ -1284,6 +1297,8 @@ void TypeCode::restoreXml(const Element *el,TypeFactory &typegrp)
|
|||
iter = list.begin();
|
||||
if (iter == list.end()) return; // No underlying prototype
|
||||
Architecture *glb = typegrp.getArch();
|
||||
factory = &typegrp;
|
||||
flags |= variable_length;
|
||||
proto = new FuncProto();
|
||||
proto->setInternal( glb->defaultfp, typegrp.getTypeVoid() );
|
||||
proto->restoreXml(*iter,glb);
|
||||
|
@ -2107,7 +2122,7 @@ TypeCode *TypeFactory::getTypeCode(ProtoModel *model,Datatype *outtype,
|
|||
bool dotdotdot)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -342,7 +342,8 @@ class TypeCode : public Datatype {
|
|||
protected:
|
||||
friend class TypeFactory;
|
||||
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,
|
||||
bool dotdotdot,Datatype *voidtype); ///< Establish a function pointer
|
||||
virtual void restoreXml(const Element *el,TypeFactory &typegrp);
|
||||
|
@ -354,6 +355,7 @@ public:
|
|||
void setProperties(bool isConstructor,bool isDestructor); ///< Set additional function properties
|
||||
virtual ~TypeCode(void);
|
||||
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 compareDependency(const Datatype &op) const;
|
||||
virtual Datatype *clone(void) const { return new TypeCode(*this); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue