mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-2830 Parsing pspec symbols
This commit is contained in:
parent
3cf13c2533
commit
8f2450e625
13 changed files with 274 additions and 82 deletions
|
@ -29,6 +29,7 @@ vector<ArchitectureCapability *> ArchitectureCapability::thelist;
|
||||||
const uint4 ArchitectureCapability::majorversion = 5;
|
const uint4 ArchitectureCapability::majorversion = 5;
|
||||||
const uint4 ArchitectureCapability::minorversion = 0;
|
const uint4 ArchitectureCapability::minorversion = 0;
|
||||||
|
|
||||||
|
AttributeId ATTRIB_ADDRESS = AttributeId("address",148);
|
||||||
AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",103);
|
AttributeId ATTRIB_ADJUSTVMA = AttributeId("adjustvma",103);
|
||||||
AttributeId ATTRIB_ENABLE = AttributeId("enable",104);
|
AttributeId ATTRIB_ENABLE = AttributeId("enable",104);
|
||||||
AttributeId ATTRIB_GROUP = AttributeId("group",105);
|
AttributeId ATTRIB_GROUP = AttributeId("group",105);
|
||||||
|
@ -583,15 +584,6 @@ void Architecture::buildAction(DocumentStorage &store)
|
||||||
allacts.resetDefaults();
|
allacts.resetDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This builds the database which holds the status registers setings and other
|
|
||||||
/// information that can affect disassembly depending on context.
|
|
||||||
/// \param store may hold configuration information
|
|
||||||
void Architecture::buildContext(DocumentStorage &store)
|
|
||||||
|
|
||||||
{
|
|
||||||
context = new ContextInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create the database object, which currently doesn't not depend on any configuration
|
/// Create the database object, which currently doesn't not depend on any configuration
|
||||||
/// data. Then create the root (global) scope and attach it to the database.
|
/// data. Then create the root (global) scope and attach it to the database.
|
||||||
/// \param store is the storage for any configuration data
|
/// \param store is the storage for any configuration data
|
||||||
|
@ -605,72 +597,6 @@ Scope *Architecture::buildDatabase(DocumentStorage &store)
|
||||||
return globscope;
|
return globscope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This builds the TypeFactory object specific to this architecture and
|
|
||||||
/// prepopulates it with the \e core types. Core types may be pulled
|
|
||||||
/// from the configuration information, or default core types are used.
|
|
||||||
/// \param store contains possible configuration information
|
|
||||||
void Architecture::buildTypegrp(DocumentStorage &store)
|
|
||||||
|
|
||||||
{
|
|
||||||
const Element *el = store.getTag("coretypes");
|
|
||||||
types = new TypeFactory(this); // Initialize the object
|
|
||||||
if (el != (const Element *)0) {
|
|
||||||
XmlDecode decoder(this,el);
|
|
||||||
types->decodeCoreTypes(decoder);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Put in the core types
|
|
||||||
types->setCoreType("void",1,TYPE_VOID,false);
|
|
||||||
types->setCoreType("bool",1,TYPE_BOOL,false);
|
|
||||||
types->setCoreType("uint1",1,TYPE_UINT,false);
|
|
||||||
types->setCoreType("uint2",2,TYPE_UINT,false);
|
|
||||||
types->setCoreType("uint4",4,TYPE_UINT,false);
|
|
||||||
types->setCoreType("uint8",8,TYPE_UINT,false);
|
|
||||||
types->setCoreType("int1",1,TYPE_INT,false);
|
|
||||||
types->setCoreType("int2",2,TYPE_INT,false);
|
|
||||||
types->setCoreType("int4",4,TYPE_INT,false);
|
|
||||||
types->setCoreType("int8",8,TYPE_INT,false);
|
|
||||||
types->setCoreType("float4",4,TYPE_FLOAT,false);
|
|
||||||
types->setCoreType("float8",8,TYPE_FLOAT,false);
|
|
||||||
types->setCoreType("float10",10,TYPE_FLOAT,false);
|
|
||||||
types->setCoreType("float16",16,TYPE_FLOAT,false);
|
|
||||||
types->setCoreType("xunknown1",1,TYPE_UNKNOWN,false);
|
|
||||||
types->setCoreType("xunknown2",2,TYPE_UNKNOWN,false);
|
|
||||||
types->setCoreType("xunknown4",4,TYPE_UNKNOWN,false);
|
|
||||||
types->setCoreType("xunknown8",8,TYPE_UNKNOWN,false);
|
|
||||||
types->setCoreType("code",1,TYPE_CODE,false);
|
|
||||||
types->setCoreType("char",1,TYPE_INT,true);
|
|
||||||
types->setCoreType("wchar2",2,TYPE_INT,true);
|
|
||||||
types->setCoreType("wchar4",4,TYPE_INT,true);
|
|
||||||
types->cacheCoreTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build the container that holds comments for executable in this Architecture.
|
|
||||||
/// \param store may hold configuration information
|
|
||||||
void Architecture::buildCommentDB(DocumentStorage &store)
|
|
||||||
|
|
||||||
{
|
|
||||||
commentdb = new CommentDatabaseInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build container that holds decoded strings
|
|
||||||
/// \param store may hold configuration information
|
|
||||||
void Architecture::buildStringManager(DocumentStorage &store)
|
|
||||||
|
|
||||||
{
|
|
||||||
stringManager = new StringManagerUnicode(this,2048);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Some processor models (Java byte-code) need a database of constants.
|
|
||||||
/// The database is always built, but may remain empty.
|
|
||||||
/// \param store may hold configuration information
|
|
||||||
void Architecture::buildConstantPool(DocumentStorage &store)
|
|
||||||
|
|
||||||
{
|
|
||||||
cpool = new ConstantPoolInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This registers the OpBehavior objects for all known p-code OpCodes.
|
/// This registers the OpBehavior objects for all known p-code OpCodes.
|
||||||
/// The Translate and TypeFactory object should already be built.
|
/// The Translate and TypeFactory object should already be built.
|
||||||
/// \param store may hold configuration information
|
/// \param store may hold configuration information
|
||||||
|
@ -1257,6 +1183,7 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
|
||||||
}
|
}
|
||||||
else if (subId == ELEM_DEFAULT_SYMBOLS) {
|
else if (subId == ELEM_DEFAULT_SYMBOLS) {
|
||||||
decoder.openElement();
|
decoder.openElement();
|
||||||
|
store.registerTag(decoder.getCurrentXmlElement());
|
||||||
decoder.closeElementSkipping(subId);
|
decoder.closeElementSkipping(subId);
|
||||||
}
|
}
|
||||||
else if (subId == ELEM_DEFAULT_MEMORY_BLOCKS) {
|
else if (subId == ELEM_DEFAULT_MEMORY_BLOCKS) {
|
||||||
|
@ -1449,6 +1376,7 @@ void Architecture::init(DocumentStorage &store)
|
||||||
restoreFromSpec(store);
|
restoreFromSpec(store);
|
||||||
print->initializeFromArchitecture();
|
print->initializeFromArchitecture();
|
||||||
symboltab->adjustCaches(); // In case the specs created additional address spaces
|
symboltab->adjustCaches(); // In case the specs created additional address spaces
|
||||||
|
buildSymbols(store);
|
||||||
postSpecFile(); // Let subclasses do things after translate is ready
|
postSpecFile(); // Let subclasses do things after translate is ready
|
||||||
|
|
||||||
buildInstructions(store); // Must be called after translate is built
|
buildInstructions(store); // Must be called after translate is built
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
|
|
||||||
class Architecture;
|
class Architecture;
|
||||||
|
|
||||||
|
extern AttributeId ATTRIB_ADDRESS; ///< Marshaling attribute "address"
|
||||||
extern AttributeId ATTRIB_ADJUSTVMA; ///< Marshaling attribute "adjustvma"
|
extern AttributeId ATTRIB_ADJUSTVMA; ///< Marshaling attribute "adjustvma"
|
||||||
extern AttributeId ATTRIB_ENABLE; ///< Marshaling attribute "enable"
|
extern AttributeId ATTRIB_ENABLE; ///< Marshaling attribute "enable"
|
||||||
extern AttributeId ATTRIB_GROUP; ///< Marshaling attribute "group"
|
extern AttributeId ATTRIB_GROUP; ///< Marshaling attribute "group"
|
||||||
|
@ -273,13 +274,48 @@ protected:
|
||||||
/// \return the PcodeInjectLibrary object
|
/// \return the PcodeInjectLibrary object
|
||||||
virtual PcodeInjectLibrary *buildPcodeInjectLibrary(void)=0;
|
virtual PcodeInjectLibrary *buildPcodeInjectLibrary(void)=0;
|
||||||
|
|
||||||
virtual void buildTypegrp(DocumentStorage &store); ///< Build the data-type factory/container
|
/// \brief Build the data-type factory/container
|
||||||
virtual void buildCommentDB(DocumentStorage &store); ///< Build the comment database
|
///
|
||||||
virtual void buildStringManager(DocumentStorage &store); ///< Build the string manager
|
/// Build the TypeFactory object specific to \b this Architecture and
|
||||||
virtual void buildConstantPool(DocumentStorage &store); ///< Build the constant pool
|
/// prepopulate it with the \e core types. Core types may be pulled
|
||||||
|
/// from the configuration information, or default core types are used.
|
||||||
|
/// \param store contains possible configuration information
|
||||||
|
virtual void buildTypegrp(DocumentStorage &store)=0;
|
||||||
|
|
||||||
|
/// \brief Build the comment database
|
||||||
|
///
|
||||||
|
/// Build the container that holds comments in \b this Architecture.
|
||||||
|
/// \param store may hold configuration information
|
||||||
|
virtual void buildCommentDB(DocumentStorage &store)=0;
|
||||||
|
|
||||||
|
/// \brief Build the string manager
|
||||||
|
///
|
||||||
|
/// Build container that holds decoded strings for \b this Architecture.
|
||||||
|
/// \param store may hold configuration information
|
||||||
|
virtual void buildStringManager(DocumentStorage &store)=0;
|
||||||
|
|
||||||
|
/// \brief Build the constant pool
|
||||||
|
///
|
||||||
|
/// Some processor models (Java byte-code) need a database of constants.
|
||||||
|
/// The database is always built, but may remain empty.
|
||||||
|
/// \param store may hold configuration information
|
||||||
|
virtual void buildConstantPool(DocumentStorage &store)=0;
|
||||||
|
|
||||||
virtual void buildInstructions(DocumentStorage &store); ///< Register the p-code operations
|
virtual void buildInstructions(DocumentStorage &store); ///< Register the p-code operations
|
||||||
virtual void buildAction(DocumentStorage &store); ///< Build the Action framework
|
virtual void buildAction(DocumentStorage &store); ///< Build the Action framework
|
||||||
virtual void buildContext(DocumentStorage &store); ///< Build the Context database
|
|
||||||
|
/// \brief Build the Context database
|
||||||
|
///
|
||||||
|
/// Build the database which holds status register settings and other
|
||||||
|
/// information that can affect disassembly depending on context.
|
||||||
|
/// \param store may hold configuration information
|
||||||
|
virtual void buildContext(DocumentStorage &store)=0;
|
||||||
|
|
||||||
|
/// \brief Build any symbols from spec files
|
||||||
|
///
|
||||||
|
/// Formal symbols described in a spec file are added to the global scope.
|
||||||
|
/// \param store may hold symbol elements
|
||||||
|
virtual void buildSymbols(DocumentStorage &store)=0;
|
||||||
|
|
||||||
/// \brief Load any relevant specification files
|
/// \brief Load any relevant specification files
|
||||||
///
|
///
|
||||||
|
|
|
@ -3224,6 +3224,32 @@ void Database::setPropertyRange(uint4 flags,const Range &range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The non-zero bits in the \b flags parameter indicate the boolean properties to be cleared.
|
||||||
|
/// No other properties are altered.
|
||||||
|
/// \param flags is the set of properties to clear
|
||||||
|
/// \param range is the memory range to clear
|
||||||
|
void Database::clearPropertyRange(uint4 flags,const Range &range)
|
||||||
|
|
||||||
|
{
|
||||||
|
Address addr1 = range.getFirstAddr();
|
||||||
|
Address addr2 = range.getLastAddrOpen(glb);
|
||||||
|
flagbase.split(addr1);
|
||||||
|
partmap<Address,uint4>::iterator aiter,biter;
|
||||||
|
|
||||||
|
aiter = flagbase.begin(addr1);
|
||||||
|
if (!addr2.isInvalid()) {
|
||||||
|
flagbase.split(addr2);
|
||||||
|
biter = flagbase.begin(addr2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
biter = flagbase.end();
|
||||||
|
flags = ~flags;
|
||||||
|
while(aiter != biter) { // Update bits across whole range
|
||||||
|
(*aiter).second &= flags;
|
||||||
|
++aiter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Encode a single \<db> element to the stream, which contains child elements
|
/// Encode a single \<db> element to the stream, which contains child elements
|
||||||
/// for each Scope (which contain Symbol children in turn).
|
/// for each Scope (which contain Symbol children in turn).
|
||||||
/// \param encoder is the stream encoder
|
/// \param encoder is the stream encoder
|
||||||
|
|
|
@ -925,6 +925,7 @@ public:
|
||||||
Scope *mapScope(Scope *qpoint,const Address &addr,const Address &usepoint);
|
Scope *mapScope(Scope *qpoint,const Address &addr,const Address &usepoint);
|
||||||
uint4 getProperty(const Address &addr) const { return flagbase.getValue(addr); } ///< Get boolean properties at the given address
|
uint4 getProperty(const Address &addr) const { return flagbase.getValue(addr); } ///< Get boolean properties at the given address
|
||||||
void setPropertyRange(uint4 flags,const Range &range); ///< Set boolean properties over a given memory range
|
void setPropertyRange(uint4 flags,const Range &range); ///< Set boolean properties over a given memory range
|
||||||
|
void clearPropertyRange(uint4 flags,const Range &range); ///< Clear boolean properties over a given memory range
|
||||||
void setProperties(const partmap<Address,uint4> &newflags) { flagbase = newflags; } ///< Replace the property map
|
void setProperties(const partmap<Address,uint4> &newflags) { flagbase = newflags; } ///< Replace the property map
|
||||||
const partmap<Address,uint4> &getProperties(void) const { return flagbase; } ///< Get the entire property map
|
const partmap<Address,uint4> &getProperties(void) const { return flagbase; } ///< Get the entire property map
|
||||||
void encode(Encoder &encoder) const; ///< Encode the whole Database to a stream
|
void encode(Encoder &encoder) const; ///< Encode the whole Database to a stream
|
||||||
|
|
|
@ -372,6 +372,55 @@ void ArchitectureGhidra::buildContext(DocumentStorage &store)
|
||||||
context = new ContextGhidra(this);
|
context = new ContextGhidra(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArchitectureGhidra::buildSymbols(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
const Element *symtag = store.getTag(ELEM_DEFAULT_SYMBOLS.getName());
|
||||||
|
if (symtag == (const Element *)0) return;
|
||||||
|
XmlDecode decoder(this,symtag);
|
||||||
|
uint4 el = decoder.openElement(ELEM_DEFAULT_SYMBOLS);
|
||||||
|
while(decoder.peekElement() != 0) {
|
||||||
|
uint4 subel = decoder.openElement(ELEM_SYMBOL);
|
||||||
|
string addrString;
|
||||||
|
string name;
|
||||||
|
int4 size = 0;
|
||||||
|
int4 volatileState = -1;
|
||||||
|
for(;;) {
|
||||||
|
uint4 attribId = decoder.getNextAttributeId();
|
||||||
|
if (attribId == 0) break;
|
||||||
|
if (attribId == ATTRIB_NAME)
|
||||||
|
name = decoder.readString();
|
||||||
|
else if (attribId == ATTRIB_ADDRESS) {
|
||||||
|
addrString = decoder.readString();
|
||||||
|
}
|
||||||
|
else if (attribId == ATTRIB_VOLATILE) {
|
||||||
|
volatileState = decoder.readBool() ? 1 : 0;
|
||||||
|
}
|
||||||
|
else if (attribId == ATTRIB_SIZE)
|
||||||
|
size = decoder.readSignedInteger();
|
||||||
|
}
|
||||||
|
decoder.closeElement(subel);
|
||||||
|
if (name.size() == 0)
|
||||||
|
throw LowlevelError("Missing name attribute in <symbol> element");
|
||||||
|
if (addrString.size() == 0)
|
||||||
|
throw LowlevelError("Missing address attribute in <symbol> element");
|
||||||
|
|
||||||
|
// Currently we only use the volatile attribute on pspec symbols and let Ghidra
|
||||||
|
// feed the global symbol to the decompiler on a per function basic.
|
||||||
|
if (volatileState < 0)
|
||||||
|
continue;
|
||||||
|
Address addr = parseAddressSimple(addrString);
|
||||||
|
if (size == 0)
|
||||||
|
size = addr.getSpace()->getWordSize();
|
||||||
|
Range range(addr.getSpace(),addr.getOffset(),addr.getOffset() + (size-1));
|
||||||
|
if (volatileState == 0)
|
||||||
|
symboltab->clearPropertyRange(Varnode::volatil, range);
|
||||||
|
else
|
||||||
|
symboltab->setPropertyRange(Varnode::volatil, range);
|
||||||
|
}
|
||||||
|
decoder.closeElement(el);
|
||||||
|
}
|
||||||
|
|
||||||
void ArchitectureGhidra::resolveArchitecture(void)
|
void ArchitectureGhidra::resolveArchitecture(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,6 +97,7 @@ class ArchitectureGhidra : public Architecture {
|
||||||
virtual void buildStringManager(DocumentStorage &store);
|
virtual void buildStringManager(DocumentStorage &store);
|
||||||
virtual void buildConstantPool(DocumentStorage &store);
|
virtual void buildConstantPool(DocumentStorage &store);
|
||||||
virtual void buildContext(DocumentStorage &store);
|
virtual void buildContext(DocumentStorage &store);
|
||||||
|
virtual void buildSymbols(DocumentStorage &store);
|
||||||
virtual void buildSpecFile(DocumentStorage &store);
|
virtual void buildSpecFile(DocumentStorage &store);
|
||||||
virtual void modifySpaces(Translate *trans) {} // This is handled directly by GhidraTranslate::initialize
|
virtual void modifySpaces(Translate *trans) {} // This is handled directly by GhidraTranslate::initialize
|
||||||
virtual void postSpecFile(void);
|
virtual void postSpecFile(void);
|
||||||
|
|
|
@ -1036,7 +1036,7 @@ AttributeId ATTRIB_VAL = AttributeId("val",24);
|
||||||
AttributeId ATTRIB_VALUE = AttributeId("value",25);
|
AttributeId ATTRIB_VALUE = AttributeId("value",25);
|
||||||
AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize",26);
|
AttributeId ATTRIB_WORDSIZE = AttributeId("wordsize",26);
|
||||||
|
|
||||||
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",148); // Number serves as next open index
|
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",149); // Number serves as next open index
|
||||||
|
|
||||||
ElementId ELEM_DATA = ElementId("data",1);
|
ElementId ELEM_DATA = ElementId("data",1);
|
||||||
ElementId ELEM_INPUT = ElementId("input",2);
|
ElementId ELEM_INPUT = ElementId("input",2);
|
||||||
|
|
|
@ -323,6 +323,7 @@ public:
|
||||||
document = (Document *)0; rootElement = root; attributeIndex = -1; } ///< Constructor with preparsed root
|
document = (Document *)0; rootElement = root; attributeIndex = -1; } ///< Constructor with preparsed root
|
||||||
XmlDecode(const AddrSpaceManager *spc) : Decoder(spc) {
|
XmlDecode(const AddrSpaceManager *spc) : Decoder(spc) {
|
||||||
document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; } ///< Constructor for use with ingestStream
|
document = (Document *)0; rootElement = (const Element *)0; attributeIndex = -1; } ///< Constructor for use with ingestStream
|
||||||
|
const Element *getCurrentXmlElement(void) const { return elStack.back(); } ///< Get pointer to underlying XML element object
|
||||||
virtual ~XmlDecode(void);
|
virtual ~XmlDecode(void);
|
||||||
virtual void ingestStream(istream &s);
|
virtual void ingestStream(istream &s);
|
||||||
virtual uint4 peekElement(void);
|
virtual uint4 peekElement(void);
|
||||||
|
|
|
@ -194,6 +194,115 @@ PcodeInjectLibrary *SleighArchitecture::buildPcodeInjectLibrary(void)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildTypegrp(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
const Element *el = store.getTag("coretypes");
|
||||||
|
types = new TypeFactory(this); // Initialize the object
|
||||||
|
if (el != (const Element *)0) {
|
||||||
|
XmlDecode decoder(this,el);
|
||||||
|
types->decodeCoreTypes(decoder);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Put in the core types
|
||||||
|
types->setCoreType("void",1,TYPE_VOID,false);
|
||||||
|
types->setCoreType("bool",1,TYPE_BOOL,false);
|
||||||
|
types->setCoreType("uint1",1,TYPE_UINT,false);
|
||||||
|
types->setCoreType("uint2",2,TYPE_UINT,false);
|
||||||
|
types->setCoreType("uint4",4,TYPE_UINT,false);
|
||||||
|
types->setCoreType("uint8",8,TYPE_UINT,false);
|
||||||
|
types->setCoreType("int1",1,TYPE_INT,false);
|
||||||
|
types->setCoreType("int2",2,TYPE_INT,false);
|
||||||
|
types->setCoreType("int4",4,TYPE_INT,false);
|
||||||
|
types->setCoreType("int8",8,TYPE_INT,false);
|
||||||
|
types->setCoreType("float4",4,TYPE_FLOAT,false);
|
||||||
|
types->setCoreType("float8",8,TYPE_FLOAT,false);
|
||||||
|
types->setCoreType("float10",10,TYPE_FLOAT,false);
|
||||||
|
types->setCoreType("float16",16,TYPE_FLOAT,false);
|
||||||
|
types->setCoreType("xunknown1",1,TYPE_UNKNOWN,false);
|
||||||
|
types->setCoreType("xunknown2",2,TYPE_UNKNOWN,false);
|
||||||
|
types->setCoreType("xunknown4",4,TYPE_UNKNOWN,false);
|
||||||
|
types->setCoreType("xunknown8",8,TYPE_UNKNOWN,false);
|
||||||
|
types->setCoreType("code",1,TYPE_CODE,false);
|
||||||
|
types->setCoreType("char",1,TYPE_INT,true);
|
||||||
|
types->setCoreType("wchar2",2,TYPE_INT,true);
|
||||||
|
types->setCoreType("wchar4",4,TYPE_INT,true);
|
||||||
|
types->cacheCoreTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildCommentDB(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
commentdb = new CommentDatabaseInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildStringManager(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
stringManager = new StringManagerUnicode(this,2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildConstantPool(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
cpool = new ConstantPoolInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildContext(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
context = new ContextInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SleighArchitecture::buildSymbols(DocumentStorage &store)
|
||||||
|
|
||||||
|
{
|
||||||
|
const Element *symtag = store.getTag(ELEM_DEFAULT_SYMBOLS.getName());
|
||||||
|
if (symtag == (const Element *)0) return;
|
||||||
|
XmlDecode decoder(this,symtag);
|
||||||
|
uint4 el = decoder.openElement(ELEM_DEFAULT_SYMBOLS);
|
||||||
|
while(decoder.peekElement() != 0) {
|
||||||
|
uint4 subel = decoder.openElement(ELEM_SYMBOL);
|
||||||
|
Address addr;
|
||||||
|
string name;
|
||||||
|
int4 size = 0;
|
||||||
|
int4 volatileState = -1;
|
||||||
|
for(;;) {
|
||||||
|
uint4 attribId = decoder.getNextAttributeId();
|
||||||
|
if (attribId == 0) break;
|
||||||
|
if (attribId == ATTRIB_NAME)
|
||||||
|
name = decoder.readString();
|
||||||
|
else if (attribId == ATTRIB_ADDRESS) {
|
||||||
|
addr = parseAddressSimple(decoder.readString());
|
||||||
|
}
|
||||||
|
else if (attribId == ATTRIB_VOLATILE) {
|
||||||
|
volatileState = decoder.readBool() ? 1 : 0;
|
||||||
|
}
|
||||||
|
else if (attribId == ATTRIB_SIZE)
|
||||||
|
size = decoder.readSignedInteger();
|
||||||
|
}
|
||||||
|
decoder.closeElement(subel);
|
||||||
|
if (name.size() == 0)
|
||||||
|
throw LowlevelError("Missing name attribute in <symbol> element");
|
||||||
|
if (addr.isInvalid())
|
||||||
|
throw LowlevelError("Missing address attribute in <symbol> element");
|
||||||
|
if (size == 0)
|
||||||
|
size = addr.getSpace()->getWordSize();
|
||||||
|
if (volatileState >= 0) {
|
||||||
|
Range range(addr.getSpace(),addr.getOffset(),addr.getOffset() + (size-1));
|
||||||
|
if (volatileState == 0)
|
||||||
|
symboltab->clearPropertyRange(Varnode::volatil, range);
|
||||||
|
else
|
||||||
|
symboltab->setPropertyRange(Varnode::volatil, range);
|
||||||
|
}
|
||||||
|
Datatype *ct = types->getBase(size, TYPE_UNKNOWN);
|
||||||
|
Address usepoint;
|
||||||
|
symboltab->getGlobalScope()->addSymbol(name, ct, addr, usepoint);
|
||||||
|
}
|
||||||
|
decoder.closeElement(el);
|
||||||
|
}
|
||||||
|
|
||||||
void SleighArchitecture::resolveArchitecture(void)
|
void SleighArchitecture::resolveArchitecture(void)
|
||||||
|
|
||||||
{ // Find best architecture
|
{ // Find best architecture
|
||||||
|
|
|
@ -117,6 +117,12 @@ protected:
|
||||||
static void collectSpecFiles(ostream &errs); ///< Gather specification files in normal locations
|
static void collectSpecFiles(ostream &errs); ///< Gather specification files in normal locations
|
||||||
virtual Translate *buildTranslator(DocumentStorage &store);
|
virtual Translate *buildTranslator(DocumentStorage &store);
|
||||||
virtual PcodeInjectLibrary *buildPcodeInjectLibrary(void);
|
virtual PcodeInjectLibrary *buildPcodeInjectLibrary(void);
|
||||||
|
virtual void buildTypegrp(DocumentStorage &store);
|
||||||
|
virtual void buildCommentDB(DocumentStorage &store);
|
||||||
|
virtual void buildStringManager(DocumentStorage &store);
|
||||||
|
virtual void buildConstantPool(DocumentStorage &store);
|
||||||
|
virtual void buildContext(DocumentStorage &store);
|
||||||
|
virtual void buildSymbols(DocumentStorage &store);
|
||||||
virtual void buildSpecFile(DocumentStorage &store);
|
virtual void buildSpecFile(DocumentStorage &store);
|
||||||
virtual void modifySpaces(Translate *trans);
|
virtual void modifySpaces(Translate *trans);
|
||||||
virtual void resolveArchitecture(void);
|
virtual void resolveArchitecture(void);
|
||||||
|
|
|
@ -864,6 +864,37 @@ void AddrSpaceManager::renormalizeJoinAddress(Address &addr,int4 size)
|
||||||
addr = Address(newJoinRecord->unified.space,newJoinRecord->unified.offset);
|
addr = Address(newJoinRecord->unified.space,newJoinRecord->unified.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The string \e must contain a hexadecimal offset. The offset may be optionally prepended with "0x".
|
||||||
|
/// The string may optionally start with the name of the address space to associate with the offset, followed
|
||||||
|
/// by ':' to separate it from the offset. If the name is not present, the default data space is assumed.
|
||||||
|
/// \param val is the string to parse
|
||||||
|
/// \return the parsed address
|
||||||
|
Address AddrSpaceManager::parseAddressSimple(const string &val)
|
||||||
|
|
||||||
|
{
|
||||||
|
string::size_type col = val.find(':');
|
||||||
|
AddrSpace *spc;
|
||||||
|
if (col==string::npos) {
|
||||||
|
spc = getDefaultDataSpace();
|
||||||
|
col = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
string spcName = val.substr(0,col);
|
||||||
|
spc = getSpaceByName(spcName);
|
||||||
|
if (spc == (AddrSpace *)0)
|
||||||
|
throw LowlevelError("Unknown address space: " + spcName);
|
||||||
|
col += 1;
|
||||||
|
}
|
||||||
|
if (col + 2 <= val.size()) {
|
||||||
|
if (val[col] == '0' && val[col+1] == 'x')
|
||||||
|
col += 2;
|
||||||
|
}
|
||||||
|
istringstream s(val.substr(col));
|
||||||
|
uintb off;
|
||||||
|
s >> hex >> off;
|
||||||
|
return Address(spc,AddrSpace::addressToByte(off, spc->getWordSize()));
|
||||||
|
}
|
||||||
|
|
||||||
/// This constructs only a shell for the Translate object. It
|
/// This constructs only a shell for the Translate object. It
|
||||||
/// won't be usable until it is initialized for a specific processor
|
/// won't be usable until it is initialized for a specific processor
|
||||||
/// The main entry point for this is the Translate::initialize method,
|
/// The main entry point for this is the Translate::initialize method,
|
||||||
|
|
|
@ -278,6 +278,9 @@ public:
|
||||||
|
|
||||||
/// \brief Make sure a possibly offset \e join address has a proper JoinRecord
|
/// \brief Make sure a possibly offset \e join address has a proper JoinRecord
|
||||||
void renormalizeJoinAddress(Address &addr,int4 size);
|
void renormalizeJoinAddress(Address &addr,int4 size);
|
||||||
|
|
||||||
|
/// \brief Parse a string with just an \e address \e space name and a hex offset
|
||||||
|
Address parseAddressSimple(const string &val);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief The interface to a translation engine for a processor.
|
/// \brief The interface to a translation engine for a processor.
|
||||||
|
|
|
@ -243,5 +243,6 @@ public record AttributeId(String name, int id) {
|
||||||
// public static final AttributeId ATTRIB_VARIANT = new AttributeId("variant", 143);
|
// public static final AttributeId ATTRIB_VARIANT = new AttributeId("variant", 143);
|
||||||
// public static final AttributeId ATTRIB_VERSION = new AttributeId("version", 144);
|
// public static final AttributeId ATTRIB_VERSION = new AttributeId("version", 144);
|
||||||
|
|
||||||
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 148);
|
// public static final AttributeId ATTRIB_ADDRESS = new AttributeId("address", 148);
|
||||||
|
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 149);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue