GP-2291 Support for unions through partial containers

This commit is contained in:
caheckman 2022-08-24 11:46:46 -04:00
parent d3efd60d54
commit cb9c12894e
21 changed files with 678 additions and 182 deletions

View file

@ -57,6 +57,7 @@ void IfaceDecompCapability::registerCommands(IfaceStatus *status)
status->registerCom(new IfcMapexternalref(),"map","externalref");
status->registerCom(new IfcMaplabel(),"map","label");
status->registerCom(new IfcMapconvert(),"map","convert");
status->registerCom(new IfcMapunionfacet(), "map", "unionfacet");
status->registerCom(new IfcPrintdisasm(),"disassemble");
status->registerCom(new IfcDecompile(),"decompile");
status->registerCom(new IfcDump(),"dump");
@ -711,6 +712,39 @@ void IfcMapconvert::execute(istream &s)
dcp->fd->getScopeLocal()->addEquateSymbol("", format, value, addr, hash);
}
/// \class IfcMapunionfacet
/// \brief Create a union field forcing directive: `map facet <union> <fieldnum> <address> <hash>`
///
/// Creates a \e facet directive that associates a given field of a \e union data-type with
/// a varnode in the context of a specific p-code op accessing it. The varnode and p-code op
/// are specified by dynamic hash.
void IfcMapunionfacet::execute(istream &s)
{
Datatype *ct;
string unionName;
int4 fieldNum;
int4 size;
uint8 hash;
if (dcp->fd == (Funcdata *)0)
throw IfaceExecutionError("No function loaded");
s >> ws >> unionName;
ct = dcp->conf->types->findByName(unionName);
if (ct == (Datatype *)0 || ct->getMetatype() != TYPE_UNION)
throw IfaceParseError("Bad union data-type: " + unionName);
s >> ws >> dec >> fieldNum;
if (fieldNum < -1 || fieldNum >= ct->numDepend())
throw IfaceParseError("Bad field index");
Address addr = parse_machaddr(s,size,*dcp->conf->types); // Read pc address of hash
s >> hex >> hash; // Parse the hash value
ostringstream s2;
s2 << "unionfacet" << dec << (fieldNum + 1) << '_' << hex << addr.getOffset();
Symbol *sym = dcp->fd->getScopeLocal()->addUnionFacetSymbol(s2.str(), ct, fieldNum, addr, hash);
dcp->fd->getScopeLocal()->setAttribute(sym, Varnode::typelock | Varnode::namelock);
}
/// \class IfcPrintdisasm
/// \brief Print disassembly of a memory range: `disassemble [<address1> <address2>]`
///