Decompiler support for offset/relative pointers

This commit is contained in:
caheckman 2021-10-05 16:46:19 -04:00
parent 513c9beb9d
commit cce187a4c5
18 changed files with 746 additions and 174 deletions

View file

@ -127,6 +127,7 @@ void IfaceDecompCapability::registerCommands(IfaceStatus *status)
status->registerCom(new IfcCallOtherFixup(),"fixup","callother");
status->registerCom(new IfcVolatile(),"volatile");
status->registerCom(new IfcReadonly(),"readonly");
status->registerCom(new IfcPointerSetting(),"pointer","setting");
status->registerCom(new IfcPreferSplit(),"prefersplit");
status->registerCom(new IfcStructureBlocks(),"structure","blocks");
status->registerCom(new IfcAnalyzeRange(), "analyze","range");
@ -2889,6 +2890,48 @@ void IfcReadonly::execute(istream &s)
*status->optr << "Successfully marked range as readonly" << endl;
}
/// \class IfcPointerSetting
/// \brief Create a pointer with additional settings: `pointer setting <name> <basetype> offset <val>`
///
/// The new data-type is named and must be pointer. It must have a setting
/// - \b offset which creates a shifted pointer
void IfcPointerSetting::execute(istream &s)
{
if (dcp->conf == (Architecture *)0)
throw IfaceExecutionError("No load image present");
string typeName;
string baseType;
string setting;
s >> ws;
if (s.eof())
throw IfaceParseError("Missing name");
s >> typeName >> ws;
if (s.eof())
throw IfaceParseError("Missing base-type");
s >> baseType >> ws;
if (s.eof())
throw IfaceParseError("Missing setting");
s >> setting >> ws;
if (setting == "offset") {
int4 off = -1;
s.unsetf(ios::dec | ios::hex | ios::oct); // Let user specify base
s >> off;
if (off <= 0)
throw IfaceParseError("Missing offset");
Datatype *bt = dcp->conf->types->findByName(baseType);
if (bt == (Datatype *)0 || bt->getMetatype() != TYPE_STRUCT)
throw IfaceParseError("Base-type must be a structure");
Datatype *ptrto = TypePointerRel::getPtrTo(bt, off, *dcp->conf->types);
AddrSpace *spc = dcp->conf->getDefaultDataSpace();
dcp->conf->types->getTypePointerRel(spc->getAddrSize(), bt, ptrto, spc->getWordSize(), off,typeName);
}
else
throw IfaceParseError("Unknown pointer setting: "+setting);
*status->optr << "Successfully created pointer: " << typeName << endl;
}
/// \class IfcPreferSplit
/// \brief Mark a storage location to be split: `prefersplit <address+size> <splitsize>`
///