diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.cc index 65bac75e6e..998ea56c98 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.cc @@ -2793,8 +2793,11 @@ Datatype *CParse::newStruct(const string &ident,vector *declis } TypeStruct::assignFieldOffsets(sublist); - if (!glb->types->setFields(sublist,res,-1,-1,0)) { - setError("Bad structure definition"); + try { + glb->types->setFields(sublist,res,-1,-1,0); + } + catch (LowlevelError &err) { + setError(err.explain); glb->types->destroyType(res); return (Datatype *)0; } @@ -2826,8 +2829,11 @@ Datatype *CParse::newUnion(const string &ident,vector *declist sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb)); } - if (!glb->types->setFields(sublist,res,-1,-1,0)) { - setError("Bad union definition"); + try { + glb->types->setFields(sublist,res,-1,-1,0); + } + catch (LowlevelError &err) { + setError(err.explain); glb->types->destroyType(res); return (Datatype *)0; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y index d5068d5458..c95526decb 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/grammar.y @@ -1047,8 +1047,11 @@ Datatype *CParse::newStruct(const string &ident,vector *declis } TypeStruct::assignFieldOffsets(sublist); - if (!glb->types->setFields(sublist,res,-1,-1,0)) { - setError("Bad structure definition"); + try { + glb->types->setFields(sublist,res,-1,-1,0); + } + catch (LowlevelError &err) { + setError(err.explain); glb->types->destroyType(res); return (Datatype *)0; } @@ -1080,8 +1083,11 @@ Datatype *CParse::newUnion(const string &ident,vector *declist sublist.emplace_back(i,0,decl->getIdentifier(),decl->buildType(glb)); } - if (!glb->types->setFields(sublist,res,-1,-1,0)) { - setError("Bad union definition"); + try { + glb->types->setFields(sublist,res,-1,-1,0); + } + catch (LowlevelError &err) { + setError(err.explain); glb->types->destroyType(res); return (Datatype *)0; } diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc index 4d5707e1bb..1665508087 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.cc @@ -3247,8 +3247,7 @@ void TypeFactory::setDisplayFormat(Datatype *ct,uint4 format) /// \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 -/// \return true if modification was successful -bool TypeFactory::setFields(vector &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags) +void TypeFactory::setFields(vector &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags) { if (!ot->isIncomplete()) @@ -3260,8 +3259,10 @@ bool TypeFactory::setFields(vector &fd,TypeStruct *ot,int4 fixedsize, for(iter=fd.begin();iter!=fd.end();++iter) { Datatype *ct = (*iter).type; // Do some sanity checks on the field - if (ct->getMetatype() == TYPE_VOID) return false; - if ((*iter).name.size() == 0) return false; + if (ct == (Datatype *)0 || ct->getMetatype() == TYPE_VOID) + throw LowlevelError("Bad field data-type for structure: "+ot->getName()); + else if ((*iter).name.size() == 0) + throw LowlevelError("Bad field name for structure: "+ot->getName()); if ((*iter).offset != -1) { int4 end = (*iter).offset + ct->getSize(); @@ -3281,18 +3282,16 @@ bool TypeFactory::setFields(vector &fd,TypeStruct *ot,int4 fixedsize, tree.insert(ot); recalcPointerSubmeta(ot, SUB_PTR); recalcPointerSubmeta(ot, SUB_PTR_STRUCT); - return true; } -/// If \b fixedsize is greater than 0, force the final structure to have that size. +/// If \b fixedsize is greater than 0, force the final union to have that size. /// 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 ot is the TypeUnion object to modify /// \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 -/// \return true if modification was successful -bool TypeFactory::setFields(vector &fd,TypeUnion *ot,int4 fixedsize,int4 fixedalign,uint4 flags) +void TypeFactory::setFields(vector &fd,TypeUnion *ot,int4 fixedsize,int4 fixedalign,uint4 flags) { if (!ot->isIncomplete()) @@ -3302,9 +3301,12 @@ bool TypeFactory::setFields(vector &fd,TypeUnion *ot,int4 fixedsize,i for(iter=fd.begin();iter!=fd.end();++iter) { Datatype *ct = (*iter).type; // Do some sanity checks on the field - if (ct->getMetatype() == TYPE_VOID) return false; - if ((*iter).offset != 0) return false; - if ((*iter).name.size() == 0) return false; + if (ct == (Datatype *)0 || ct->getMetatype() == TYPE_VOID) + throw LowlevelError("Bad field data-type for union: "+ot->getName()); + else if ((*iter).offset != 0) + throw LowlevelError("Non-zero field offset for union: "+ot->getName()); + else if ((*iter).name.size() == 0) + throw LowlevelError("Bad field name for union: "+ot->getName()); } tree.erase(ot); @@ -3312,7 +3314,6 @@ bool TypeFactory::setFields(vector &fd,TypeUnion *ot,int4 fixedsize,i ot->flags &= ~(uint4)Datatype::type_incomplete; ot->flags |= (flags & (Datatype::variable_length | Datatype::type_incomplete)); tree.insert(ot); - return true; } /// The given prototype is copied into the given code data-type @@ -4098,8 +4099,7 @@ Datatype* TypeFactory::decodeStruct(Decoder &decoder,bool forcecore) throw LowlevelError("Redefinition of structure: " + ts.name); } else { // If structure is a placeholder stub - if (!setFields(ts.field,(TypeStruct*)ct,ts.size,ts.alignment,ts.flags)) // Define structure now by copying fields - throw LowlevelError("Bad structure definition"); + setFields(ts.field,(TypeStruct*)ct,ts.size,ts.alignment,ts.flags); // Define structure now by copying fields } // decoder.closeElement(elemId); return ct; @@ -4129,8 +4129,7 @@ Datatype* TypeFactory::decodeUnion(Decoder &decoder,bool forcecore) throw LowlevelError("Redefinition of union: " + tu.name); } else { // If structure is a placeholder stub - if (!setFields(tu.field,(TypeUnion*)ct,tu.size,tu.alignment,tu.flags)) // Define structure now by copying fields - throw LowlevelError("Bad union definition"); + setFields(tu.field,(TypeUnion*)ct,tu.size,tu.alignment,tu.flags); // Define structure now by copying fields } // decoder.closeElement(elemId); return ct; diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh index ea6b9c416f..76710b3e41 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/type.hh @@ -746,8 +746,8 @@ public: Datatype *findByName(const string &n); ///< Return type of given 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 - bool setFields(vector &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags); ///< Set fields on a TypeStruct - bool setFields(vector &fd,TypeUnion *ot,int4 fixedsize,int4 fixedalign,uint4 flags); ///< Set fields on a TypeUnion + void setFields(vector &fd,TypeStruct *ot,int4 fixedsize,int4 fixedalign,uint4 flags); ///< Set fields on a TypeStruct + void setFields(vector &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 bool setEnumValues(const vector &namelist, const vector &vallist,