GP-4117 Pass structure/union alignment to decompiler

This commit is contained in:
caheckman 2023-12-06 21:54:27 +00:00
parent 74528b49ec
commit bd43d1b11a
5 changed files with 95 additions and 75 deletions

View file

@ -2793,7 +2793,7 @@ Datatype *CParse::newStruct(const string &ident,vector<TypeDeclarator *> *declis
} }
TypeStruct::assignFieldOffsets(sublist); TypeStruct::assignFieldOffsets(sublist);
if (!glb->types->setFields(sublist,res,-1,0)) { if (!glb->types->setFields(sublist,res,-1,-1,0)) {
setError("Bad structure definition"); setError("Bad structure definition");
glb->types->destroyType(res); glb->types->destroyType(res);
return (Datatype *)0; return (Datatype *)0;
@ -2826,7 +2826,7 @@ Datatype *CParse::newUnion(const string &ident,vector<TypeDeclarator *> *declist
sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb)); sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb));
} }
if (!glb->types->setFields(sublist,res,-1,0)) { if (!glb->types->setFields(sublist,res,-1,-1,0)) {
setError("Bad union definition"); setError("Bad union definition");
glb->types->destroyType(res); glb->types->destroyType(res);
return (Datatype *)0; return (Datatype *)0;

View file

@ -1047,7 +1047,7 @@ Datatype *CParse::newStruct(const string &ident,vector<TypeDeclarator *> *declis
} }
TypeStruct::assignFieldOffsets(sublist); TypeStruct::assignFieldOffsets(sublist);
if (!glb->types->setFields(sublist,res,-1,0)) { if (!glb->types->setFields(sublist,res,-1,-1,0)) {
setError("Bad structure definition"); setError("Bad structure definition");
glb->types->destroyType(res); glb->types->destroyType(res);
return (Datatype *)0; return (Datatype *)0;
@ -1080,7 +1080,7 @@ Datatype *CParse::newUnion(const string &ident,vector<TypeDeclarator *> *declist
sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb)); sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb));
} }
if (!glb->types->setFields(sublist,res,-1,0)) { if (!glb->types->setFields(sublist,res,-1,-1,0)) {
setError("Bad union definition"); setError("Bad union definition");
glb->types->destroyType(res); glb->types->destroyType(res);
return (Datatype *)0; return (Datatype *)0;

View file

@ -423,15 +423,16 @@ void Datatype::encode(Encoder &encoder) const
{ {
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
} }
/// Encode basic data-type properties (name,size,id) as attributes. /// Encode basic data-type properties (name,size,id) as attributes.
/// This routine presumes the initial element is already written to the stream. /// This routine presumes the initial element is already written to the stream.
/// \param meta is the metatype attribute /// \param meta is the metatype attribute to encode
/// \param align is the byte alignment to encode (-1 to not encode alignment)
/// \param encoder is the stream encoder /// \param encoder is the stream encoder
void Datatype::encodeBasic(type_metatype meta,Encoder &encoder) const void Datatype::encodeBasic(type_metatype meta,int4 align,Encoder &encoder) const
{ {
encoder.writeString(ATTRIB_NAME, name); encoder.writeString(ATTRIB_NAME, name);
@ -443,6 +444,8 @@ void Datatype::encodeBasic(type_metatype meta,Encoder &encoder) const
string metastring; string metastring;
metatype2string(meta,metastring); metatype2string(meta,metastring);
encoder.writeString(ATTRIB_METATYPE,metastring); encoder.writeString(ATTRIB_METATYPE,metastring);
if (align > 0)
encoder.writeSignedInteger(ATTRIB_ALIGNMENT, align);
if ((flags & coretype)!=0) if ((flags & coretype)!=0)
encoder.writeBool(ATTRIB_CORE,true); encoder.writeBool(ATTRIB_CORE,true);
if (isVariableLength()) if (isVariableLength())
@ -627,6 +630,9 @@ void Datatype::decodeBasic(Decoder &decoder)
if (decoder.readBool()) if (decoder.readBool())
flags |= variable_length; flags |= variable_length;
} }
else if (attrib == ATTRIB_ALIGNMENT) {
alignment = decoder.readSignedInteger();
}
else if (attrib == ATTRIB_OPAQUESTRING) { else if (attrib == ATTRIB_OPAQUESTRING) {
if (decoder.readBool()) if (decoder.readBool())
flags |= opaque_string; flags |= opaque_string;
@ -798,7 +804,7 @@ void TypeChar::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeBool(ATTRIB_CHAR, true); encoder.writeBool(ATTRIB_CHAR, true);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
} }
@ -845,7 +851,7 @@ void TypeUnicode::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeBool(ATTRIB_UTF, true); encoder.writeBool(ATTRIB_UTF, true);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
} }
@ -945,7 +951,7 @@ void TypePointer::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
if (wordsize != 1) if (wordsize != 1)
encoder.writeUnsignedInteger(ATTRIB_WORDSIZE, wordsize); encoder.writeUnsignedInteger(ATTRIB_WORDSIZE, wordsize);
if (spaceid != (AddrSpace *)0) if (spaceid != (AddrSpace *)0)
@ -1186,7 +1192,7 @@ void TypeArray::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeSignedInteger(ATTRIB_ARRAYSIZE, arraysize); encoder.writeSignedInteger(ATTRIB_ARRAYSIZE, arraysize);
arrayof->encodeRef(encoder); arrayof->encodeRef(encoder);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
@ -1409,7 +1415,7 @@ void TypeEnum::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeString(ATTRIB_ENUM, "true"); encoder.writeString(ATTRIB_ENUM, "true");
map<uintb,string>::const_iterator iter; map<uintb,string>::const_iterator iter;
for(iter=namemap.begin();iter!=namemap.end();++iter) { for(iter=namemap.begin();iter!=namemap.end();++iter) {
@ -1459,36 +1465,47 @@ void TypeEnum::decode(Decoder &decoder,TypeFactory &typegrp)
TypeStruct::TypeStruct(const TypeStruct &op) TypeStruct::TypeStruct(const TypeStruct &op)
: Datatype(op) : Datatype(op)
{ {
setFields(op.field); setFields(op.field,op.size,op.alignment);
size = op.size; // setFields might have changed the size
alignSize = op.alignSize; alignSize = op.alignSize;
} }
/// Copy a list of fields into this structure, establishing its size. /// Copy a list of fields into this structure, establishing its size.
/// Should only be called once when constructing the type /// Should only be called once when constructing the type.
/// Size is calculated from the fields unless a \b fixedSize (>0) is passed in.
/// Alignment is calculated from fields unless a \b fixedAlign (>0) is passed in.
/// \param fd is the list of fields to copy in /// \param fd is the list of fields to copy in
void TypeStruct::setFields(const vector<TypeField> &fd) /// \param fixedSize (if > 0) indicates an overriding size in bytes
/// \param fixedAlign (if > 0) indicates an overriding alignment in bytes
void TypeStruct::setFields(const vector<TypeField> &fd,int4 fixedSize,int4 fixedAlign)
{ {
vector<TypeField>::const_iterator iter; vector<TypeField>::const_iterator iter;
int4 end; int4 end;
// Need to calculate size and alignment // Need to calculate size and alignment
size = 0; int4 calcSize = 0;
alignment = 1; int4 calcAlign = 1;
for(iter=fd.begin();iter!=fd.end();++iter) { for(iter=fd.begin();iter!=fd.end();++iter) {
field.push_back(*iter); field.push_back(*iter);
Datatype *fieldType = (*iter).type; Datatype *fieldType = (*iter).type;
end = (*iter).offset + fieldType->getSize(); end = (*iter).offset + fieldType->getSize();
if (end > size) if (end > calcSize)
size = end; calcSize = end;
int4 curAlign = fieldType->getAlignment(); int4 curAlign = fieldType->getAlignment();
if (curAlign > alignment) if (curAlign > calcAlign)
alignment = curAlign; calcAlign = curAlign;
} }
if (field.size() == 1) { // A single field if (field.size() == 1) { // A single field
if (field[0].type->getSize() == size) // that fills the whole structure if (field[0].type->getSize() == calcSize) // that fills the whole structure
flags |= needs_resolution; // needs special attention flags |= needs_resolution; // needs special attention
} }
if (fixedSize > 0) { // Try to force a size
if (fixedSize < calcSize) // If the forced size is smaller, this is an error
throw LowlevelError("Trying to force too small a size on "+name);
size = fixedSize;
}
else
size = calcSize;
alignment = (fixedAlign < 1) ? calcAlign : fixedAlign;
calcAlignSize(); calcAlignSize();
} }
@ -1715,7 +1732,7 @@ void TypeStruct::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,alignment,encoder);
vector<TypeField>::const_iterator iter; vector<TypeField>::const_iterator iter;
for(iter=field.begin();iter!=field.end();++iter) { for(iter=field.begin();iter!=field.end();++iter) {
(*iter).encode(encoder); (*iter).encode(encoder);
@ -1729,7 +1746,7 @@ void TypeStruct::encode(Encoder &encoder) const
void TypeStruct::decodeFields(Decoder &decoder,TypeFactory &typegrp) void TypeStruct::decodeFields(Decoder &decoder,TypeFactory &typegrp)
{ {
alignment = 1; int4 calcAlign = 1;
int4 maxoffset = 0; int4 maxoffset = 0;
while(decoder.peekElement() != 0) { while(decoder.peekElement() != 0) {
field.emplace_back(decoder,typegrp); field.emplace_back(decoder,typegrp);
@ -1742,8 +1759,8 @@ void TypeStruct::decodeFields(Decoder &decoder,TypeFactory &typegrp)
throw LowlevelError(s.str()); throw LowlevelError(s.str());
} }
int4 curAlign = field.back().type->getAlignment(); int4 curAlign = field.back().type->getAlignment();
if (curAlign > alignment) if (curAlign > calcAlign)
alignment = curAlign; calcAlign = curAlign;
} }
if (size == 0) // We can decode an incomplete structure, indicated by 0 size if (size == 0) // We can decode an incomplete structure, indicated by 0 size
flags |= type_incomplete; flags |= type_incomplete;
@ -1753,6 +1770,8 @@ void TypeStruct::decodeFields(Decoder &decoder,TypeFactory &typegrp)
if (field[0].type->getSize() == size) // that fills the whole structure if (field[0].type->getSize() == size) // that fills the whole structure
flags |= needs_resolution; // needs special resolution flags |= needs_resolution; // needs special resolution
} }
if (alignment < 1)
alignment = calcAlign;
calcAlignSize(); calcAlignSize();
} }
@ -1859,24 +1878,36 @@ void TypeStruct::assignFieldOffsets(vector<TypeField> &list)
/// Copy a list of fields into this union, establishing its size. /// Copy a list of fields into this union, establishing its size.
/// Should only be called once when constructing the type. TypeField \b offset is assumed to be 0. /// Should only be called once when constructing the type. TypeField \b offset is assumed to be 0.
/// Size is calculated from the fields unless a \b fixedSize (>0) is passed in.
/// Alignment is calculated from fields unless a \b fixedAlign (>0) is passed in.
/// \param fd is the list of fields to copy in /// \param fd is the list of fields to copy in
void TypeUnion::setFields(const vector<TypeField> &fd) /// \param fixedSize (if > 0) indicates an overriding size in bytes
/// \param fixedAlign (if > 0) indicates an overriding alignment in bytes
void TypeUnion::setFields(const vector<TypeField> &fd,int4 fixedSize,int4 fixedAlign)
{ {
vector<TypeField>::const_iterator iter; vector<TypeField>::const_iterator iter;
// Need to calculate size and alignment // Need to calculate size and alignment
size = 0; int4 calcSize = 0;
alignment = 1; int4 calcAlign = 1;
for(iter=fd.begin();iter!=fd.end();++iter) { for(iter=fd.begin();iter!=fd.end();++iter) {
field.push_back(*iter); field.push_back(*iter);
Datatype *fieldType = field.back().type; Datatype *fieldType = field.back().type;
int4 end = fieldType->getSize(); int4 end = fieldType->getSize();
if (end > size) if (end > calcSize)
size = end; calcSize = end;
int4 curAlign = fieldType->getAlignment(); int4 curAlign = fieldType->getAlignment();
if (curAlign > alignment) if (curAlign > calcAlign)
alignment = curAlign; calcAlign = curAlign;
} }
if (fixedSize > 0) { // If the caller is trying to force a size
if (fixedSize < calcSize) // If the forced size is smaller, this is an error
throw LowlevelError("Trying to force too small a size on "+name);
size = fixedSize;
}
else
size = calcSize;
alignment = (fixedAlign < 1) ? calcAlign : fixedAlign;
calcAlignSize(); calcAlignSize();
} }
@ -1886,7 +1917,7 @@ void TypeUnion::setFields(const vector<TypeField> &fd)
void TypeUnion::decodeFields(Decoder &decoder,TypeFactory &typegrp) void TypeUnion::decodeFields(Decoder &decoder,TypeFactory &typegrp)
{ {
alignment = 1; int4 calcAlign = 1;
while(decoder.peekElement() != 0) { while(decoder.peekElement() != 0) {
field.emplace_back(decoder,typegrp); field.emplace_back(decoder,typegrp);
if (field.back().offset + field.back().type->getSize() > size) { if (field.back().offset + field.back().type->getSize() > size) {
@ -1895,21 +1926,22 @@ void TypeUnion::decodeFields(Decoder &decoder,TypeFactory &typegrp)
throw LowlevelError(s.str()); throw LowlevelError(s.str());
} }
int4 curAlign = field.back().type->getAlignment(); int4 curAlign = field.back().type->getAlignment();
if (curAlign > alignment) if (curAlign > calcAlign)
alignment = curAlign; calcAlign = curAlign;
} }
if (size == 0) // We can decode an incomplete structure, indicated by 0 size if (size == 0) // We can decode an incomplete structure, indicated by 0 size
flags |= type_incomplete; flags |= type_incomplete;
else else
markComplete(); // Otherwise the union is complete markComplete(); // Otherwise the union is complete
if (alignment < 1)
alignment = calcAlign;
calcAlignSize(); calcAlignSize();
} }
TypeUnion::TypeUnion(const TypeUnion &op) TypeUnion::TypeUnion(const TypeUnion &op)
: Datatype(op) : Datatype(op)
{ {
setFields(op.field); setFields(op.field,op.size,op.alignment);
size = op.size; // setFields might have changed the size
alignSize = op.alignSize; alignSize = op.alignSize;
} }
@ -1985,7 +2017,7 @@ void TypeUnion::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,alignment,encoder);
vector<TypeField>::const_iterator iter; vector<TypeField>::const_iterator iter;
for(iter=field.begin();iter!=field.end();++iter) { for(iter=field.begin();iter!=field.end();++iter) {
(*iter).encode(encoder); (*iter).encode(encoder);
@ -2248,7 +2280,7 @@ void TypePartialUnion::encode(Encoder &encoder) const
{ {
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeSignedInteger(ATTRIB_OFFSET, offset); encoder.writeSignedInteger(ATTRIB_OFFSET, offset);
container->encodeRef(encoder); container->encodeRef(encoder);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
@ -2401,7 +2433,7 @@ void TypePointerRel::encode(Encoder &encoder) const
{ {
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(TYPE_PTRREL,encoder); // Override the metatype for XML encodeBasic(TYPE_PTRREL,-1,encoder); // Override the metatype for XML
if (wordsize != 1) if (wordsize != 1)
encoder.writeUnsignedInteger(ATTRIB_WORDSIZE, wordsize); encoder.writeUnsignedInteger(ATTRIB_WORDSIZE, wordsize);
ptrto->encode(encoder); ptrto->encode(encoder);
@ -2651,7 +2683,7 @@ void TypeCode::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
if (proto != (FuncProto *)0) if (proto != (FuncProto *)0)
proto->encode(encoder); proto->encode(encoder);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
@ -2836,7 +2868,7 @@ void TypeSpacebase::encode(Encoder &encoder) const
return; return;
} }
encoder.openElement(ELEM_TYPE); encoder.openElement(ELEM_TYPE);
encodeBasic(metatype,encoder); encodeBasic(metatype,-1,encoder);
encoder.writeSpace(ATTRIB_SPACE, spaceid); encoder.writeSpace(ATTRIB_SPACE, spaceid);
localframe.encode(encoder); localframe.encode(encoder);
encoder.closeElement(ELEM_TYPE); encoder.closeElement(ELEM_TYPE);
@ -3212,10 +3244,11 @@ void TypeFactory::setDisplayFormat(Datatype *ct,uint4 format)
/// This method should only be used on an incomplete structure. It will mark the structure as complete. /// This method should only be used on an incomplete structure. It will mark the structure as complete.
/// \param fd is the list of fields to set /// \param fd is the list of fields to set
/// \param ot is the TypeStruct object to modify /// \param ot is the TypeStruct object to modify
/// \param fixedsize is 0 or the forced size of the structure /// \param fixedsize is -1 or the forced size of the structure
/// \param fixedalign is -1 or the forced alignment for the structure
/// \param flags are other flags to set on the structure /// \param flags are other flags to set on the structure
/// \return true if modification was successful /// \return true if modification was successful
bool TypeFactory::setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,uint4 flags) bool TypeFactory::setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags)
{ {
if (!ot->isIncomplete()) if (!ot->isIncomplete())
@ -3242,17 +3275,9 @@ bool TypeFactory::setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,
// We could check field overlapping here // We could check field overlapping here
tree.erase(ot); tree.erase(ot);
ot->setFields(fd); ot->setFields(fd,fixedsize,fixedalign);
ot->flags &= ~(uint4)Datatype::type_incomplete; ot->flags &= ~(uint4)Datatype::type_incomplete;
ot->flags |= (flags & (Datatype::opaque_string | Datatype::variable_length | Datatype::type_incomplete)); ot->flags |= (flags & (Datatype::opaque_string | Datatype::variable_length | Datatype::type_incomplete));
if (fixedsize > 0) { // If the caller is trying to force a size
if (fixedsize > ot->size) { // If the forced size is bigger than the size required for fields
ot->size = fixedsize; // Force the bigger size
ot->calcAlignSize();
}
else if (fixedsize < ot->size) // If the forced size is smaller, this is an error
throw LowlevelError("Trying to force too small a size on "+ot->getName());
}
tree.insert(ot); tree.insert(ot);
recalcPointerSubmeta(ot, SUB_PTR); recalcPointerSubmeta(ot, SUB_PTR);
recalcPointerSubmeta(ot, SUB_PTR_STRUCT); recalcPointerSubmeta(ot, SUB_PTR_STRUCT);
@ -3263,10 +3288,11 @@ bool TypeFactory::setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,
/// This method should only be used on an incomplete union. It will mark the union as complete. /// This method should only be used on an incomplete union. It will mark the union as complete.
/// \param fd is the list of fields to set /// \param fd is the list of fields to set
/// \param ot is the TypeUnion object to modify /// \param ot is the TypeUnion object to modify
/// \param fixedsize is 0 or the forced size of the union /// \param fixedsize is -1 or the forced size of the union
/// \param fixedalign is -1 or the forced alignment for the union
/// \param flags are other flags to set on the union /// \param flags are other flags to set on the union
/// \return true if modification was successful /// \return true if modification was successful
bool TypeFactory::setFields(vector<TypeField> &fd,TypeUnion *ot,int4 fixedsize,uint4 flags) bool TypeFactory::setFields(vector<TypeField> &fd,TypeUnion *ot,int4 fixedsize,int4 fixedalign,uint4 flags)
{ {
if (!ot->isIncomplete()) if (!ot->isIncomplete())
@ -3282,17 +3308,9 @@ bool TypeFactory::setFields(vector<TypeField> &fd,TypeUnion *ot,int4 fixedsize,u
} }
tree.erase(ot); tree.erase(ot);
ot->setFields(fd); ot->setFields(fd,fixedsize,fixedalign);
ot->flags &= ~(uint4)Datatype::type_incomplete; ot->flags &= ~(uint4)Datatype::type_incomplete;
ot->flags |= (flags & (Datatype::variable_length | Datatype::type_incomplete)); ot->flags |= (flags & (Datatype::variable_length | Datatype::type_incomplete));
if (fixedsize > 0) { // If the caller is trying to force a size
if (fixedsize > ot->size) { // If the forced size is bigger than the size required for fields
ot->size = fixedsize; // Force the bigger size
ot->calcAlignSize();
}
else if (fixedsize < ot->size) // If the forced size is smaller, this is an error
throw LowlevelError("Trying to force too small a size on "+ot->getName());
}
tree.insert(ot); tree.insert(ot);
return true; return true;
} }
@ -4042,13 +4060,13 @@ Datatype *TypeFactory::decodeTypedef(Decoder &decoder)
TypeStruct *prevStruct = (TypeStruct *)prev; TypeStruct *prevStruct = (TypeStruct *)prev;
TypeStruct *defedStruct = (TypeStruct *)defedType; TypeStruct *defedStruct = (TypeStruct *)defedType;
if (prevStruct->field.size() != defedStruct->field.size()) if (prevStruct->field.size() != defedStruct->field.size())
setFields(defedStruct->field,prevStruct,defedStruct->size,defedStruct->flags); setFields(defedStruct->field,prevStruct,defedStruct->size,defedStruct->alignment,defedStruct->flags);
} }
else { else {
TypeUnion *prevUnion = (TypeUnion *)prev; TypeUnion *prevUnion = (TypeUnion *)prev;
TypeUnion *defedUnion = (TypeUnion *)defedType; TypeUnion *defedUnion = (TypeUnion *)defedType;
if (prevUnion->field.size() != defedUnion->field.size()) if (prevUnion->field.size() != defedUnion->field.size())
setFields(defedUnion->field,prevUnion,defedUnion->size,defedUnion->flags); setFields(defedUnion->field,prevUnion,defedUnion->size,defedUnion->alignment,defedUnion->flags);
} }
return prev; return prev;
} }
@ -4080,7 +4098,7 @@ Datatype* TypeFactory::decodeStruct(Decoder &decoder,bool forcecore)
throw LowlevelError("Redefinition of structure: " + ts.name); throw LowlevelError("Redefinition of structure: " + ts.name);
} }
else { // If structure is a placeholder stub else { // If structure is a placeholder stub
if (!setFields(ts.field,(TypeStruct*)ct,ts.size,ts.flags)) // Define structure now by copying fields if (!setFields(ts.field,(TypeStruct*)ct,ts.size,ts.alignment,ts.flags)) // Define structure now by copying fields
throw LowlevelError("Bad structure definition"); throw LowlevelError("Bad structure definition");
} }
// decoder.closeElement(elemId); // decoder.closeElement(elemId);
@ -4111,7 +4129,7 @@ Datatype* TypeFactory::decodeUnion(Decoder &decoder,bool forcecore)
throw LowlevelError("Redefinition of union: " + tu.name); throw LowlevelError("Redefinition of union: " + tu.name);
} }
else { // If structure is a placeholder stub else { // If structure is a placeholder stub
if (!setFields(tu.field,(TypeUnion*)ct,tu.size,tu.flags)) // Define structure now by copying fields if (!setFields(tu.field,(TypeUnion*)ct,tu.size,tu.alignment,tu.flags)) // Define structure now by copying fields
throw LowlevelError("Bad union definition"); throw LowlevelError("Bad union definition");
} }
// decoder.closeElement(elemId); // decoder.closeElement(elemId);

View file

@ -192,7 +192,7 @@ protected:
int4 alignment; ///< Byte alignment expected for \b this data-type in addressable memory int4 alignment; ///< Byte alignment expected for \b this data-type in addressable memory
int4 alignSize; ///< Size of data-type rounded up to a multiple of \b alignment int4 alignSize; ///< Size of data-type rounded up to a multiple of \b alignment
void decodeBasic(Decoder &decoder); ///< Recover basic data-type properties void decodeBasic(Decoder &decoder); ///< Recover basic data-type properties
void encodeBasic(type_metatype meta,Encoder &encoder) const; ///< Encode basic data-type properties void encodeBasic(type_metatype meta,int4 align,Encoder &encoder) const; ///< Encode basic data-type properties
void encodeTypedef(Encoder &encoder) const; ///< Encode \b this as a \e typedef element to a stream void encodeTypedef(Encoder &encoder) const; ///< Encode \b this as a \e typedef element to a stream
void markComplete(void) { flags &= ~(uint4)type_incomplete; } ///< Mark \b this data-type as completely defined void markComplete(void) { flags &= ~(uint4)type_incomplete; } ///< Mark \b this data-type as completely defined
void setDisplayFormat(uint4 format); ///< Set a specific display format void setDisplayFormat(uint4 format); ///< Set a specific display format
@ -491,7 +491,7 @@ class TypeStruct : public Datatype {
protected: protected:
friend class TypeFactory; friend class TypeFactory;
vector<TypeField> field; ///< The list of fields vector<TypeField> field; ///< The list of fields
void setFields(const vector<TypeField> &fd); ///< Establish fields for \b this void setFields(const vector<TypeField> &fd,int4 fixedSize,int4 fixedAlign); ///< Establish fields for \b this
int4 getFieldIter(int4 off) const; ///< Get index into field list int4 getFieldIter(int4 off) const; ///< Get index into field list
int4 getLowerBoundField(int4 off) const; ///< Get index of last field before or equal to given offset int4 getLowerBoundField(int4 off) const; ///< Get index of last field before or equal to given offset
void decodeFields(Decoder &decoder,TypeFactory &typegrp); ///< Restore fields from a stream void decodeFields(Decoder &decoder,TypeFactory &typegrp); ///< Restore fields from a stream
@ -526,7 +526,7 @@ class TypeUnion : public Datatype {
protected: protected:
friend class TypeFactory; friend class TypeFactory;
vector<TypeField> field; ///< The list of fields vector<TypeField> field; ///< The list of fields
void setFields(const vector<TypeField> &fd); ///< Establish fields for \b this void setFields(const vector<TypeField> &fd,int4 fixedSize,int4 fixedAlign); ///< Establish fields for \b this
void decodeFields(Decoder &decoder,TypeFactory &typegrp); ///< Restore fields from a stream void decodeFields(Decoder &decoder,TypeFactory &typegrp); ///< Restore fields from a stream
public: public:
TypeUnion(const TypeUnion &op); ///< Construct from another TypeUnion TypeUnion(const TypeUnion &op); ///< Construct from another TypeUnion
@ -746,8 +746,8 @@ public:
Datatype *findByName(const string &n); ///< Return type of given name Datatype *findByName(const string &n); ///< Return type of given name
Datatype *setName(Datatype *ct,const string &n); ///< Set the given types name Datatype *setName(Datatype *ct,const string &n); ///< Set the given types name
void setDisplayFormat(Datatype *ct,uint4 format); ///< Set the display format associated with the given data-type void setDisplayFormat(Datatype *ct,uint4 format); ///< Set the display format associated with the given data-type
bool setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,uint4 flags); ///< Set fields on a TypeStruct bool setFields(vector<TypeField> &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags); ///< Set fields on a TypeStruct
bool setFields(vector<TypeField> &fd,TypeUnion *ot,int4 fixedsize,uint4 flags); ///< Set fields on a TypeUnion bool setFields(vector<TypeField> &fd,TypeUnion *ot,int4 fixedsize,int4 fixedalign,uint4 flags); ///< Set fields on a TypeUnion
void setPrototype(const FuncProto *fp,TypeCode *newCode,uint4 flags); ///< Set the prototype on a TypeCode void setPrototype(const FuncProto *fp,TypeCode *newCode,uint4 flags); ///< Set the prototype on a TypeCode
bool setEnumValues(const vector<string> &namelist, bool setEnumValues(const vector<string> &namelist,
const vector<uintb> &vallist, const vector<uintb> &vallist,

View file

@ -478,6 +478,7 @@ public class PcodeDataTypeManager {
} }
encoder.writeString(ATTRIB_METATYPE, "struct"); encoder.writeString(ATTRIB_METATYPE, "struct");
encoder.writeSignedInteger(ATTRIB_SIZE, sz); encoder.writeSignedInteger(ATTRIB_SIZE, sz);
encoder.writeSignedInteger(ATTRIB_ALIGNMENT, type.getAlignment());
DataTypeComponent[] comps = type.getDefinedComponents(); DataTypeComponent[] comps = type.getDefinedComponents();
for (DataTypeComponent comp : comps) { for (DataTypeComponent comp : comps) {
if (comp.isBitFieldComponent() || comp.getLength() == 0) { if (comp.isBitFieldComponent() || comp.getLength() == 0) {
@ -509,6 +510,7 @@ public class PcodeDataTypeManager {
encodeNameIdAttributes(encoder, unionType); encodeNameIdAttributes(encoder, unionType);
encoder.writeString(ATTRIB_METATYPE, "union"); encoder.writeString(ATTRIB_METATYPE, "union");
encoder.writeSignedInteger(ATTRIB_SIZE, unionType.getLength()); encoder.writeSignedInteger(ATTRIB_SIZE, unionType.getLength());
encoder.writeSignedInteger(ATTRIB_ALIGNMENT, unionType.getAlignment());
DataTypeComponent[] comps = unionType.getDefinedComponents(); DataTypeComponent[] comps = unionType.getDefinedComponents();
for (DataTypeComponent comp : comps) { for (DataTypeComponent comp : comps) {
if (comp.getLength() == 0) { if (comp.getLength() == 0) {