GP-4849 Volatile attribute in <register> tag.

This commit is contained in:
caheckman 2024-08-14 21:09:15 +00:00
parent be305db930
commit e1cc67a3d2
9 changed files with 85 additions and 73 deletions

View file

@ -924,23 +924,47 @@ void Architecture::decodeIncidentalCopy(Decoder &decoder)
decoder.closeElement(elemId); decoder.closeElement(elemId);
} }
/// Look for \<register> elements that have a \e vector_lane_size attribute. /// Read \<register> elements to collect specific properties associated with the register storage.
/// Record these so that the decompiler can split large registers into appropriate lane size pieces.
/// \param decoder is the stream decoder /// \param decoder is the stream decoder
void Architecture::decodeLaneSizes(Decoder &decoder) void Architecture::decodeRegisterData(Decoder &decoder)
{ {
vector<uint4> maskList; vector<uint4> maskList;
LanedRegister lanedRegister; // Only allocate once
uint4 elemId = decoder.openElement(ELEM_REGISTER_DATA); uint4 elemId = decoder.openElement(ELEM_REGISTER_DATA);
while(decoder.peekElement() != 0) { while(decoder.peekElement() != 0) {
if (lanedRegister.decode(decoder)) { uint4 subId = decoder.openElement(ELEM_REGISTER);
bool isVolatile = false;
string laneSizes;
for(;;) {
uint4 attribId = decoder.getNextAttributeId();
if (attribId == 0) break;
if (attribId == ATTRIB_VECTOR_LANE_SIZES) {
laneSizes = decoder.readString();
}
else if (attribId == ATTRIB_VOLATILE) {
isVolatile = decoder.readBool();
}
}
if (!laneSizes.empty() || isVolatile) {
decoder.rewindAttributes();
VarnodeData storage;
storage.space = (AddrSpace *)0;
storage.decodeFromAttributes(decoder);
if (!laneSizes.empty()) {
LanedRegister lanedRegister;
lanedRegister.parseSizes(storage.size,laneSizes);
int4 sizeIndex = lanedRegister.getWholeSize(); int4 sizeIndex = lanedRegister.getWholeSize();
while (maskList.size() <= sizeIndex) while (maskList.size() <= sizeIndex)
maskList.push_back(0); maskList.push_back(0);
maskList[sizeIndex] |= lanedRegister.getSizeBitMask(); maskList[sizeIndex] |= lanedRegister.getSizeBitMask();
} }
if (isVolatile) {
Range range( storage.space, storage.offset, storage.offset+storage.size-1);
symboltab->setPropertyRange(Varnode::volatil,range);
}
}
decoder.closeElement(subId);
} }
decoder.closeElement(elemId); decoder.closeElement(elemId);
lanerecords.clear(); lanerecords.clear();
@ -1172,7 +1196,7 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
else if (subId == ELEM_SEGMENTOP) else if (subId == ELEM_SEGMENTOP)
userops.decodeSegmentOp(decoder,this); userops.decodeSegmentOp(decoder,this);
else if (subId == ELEM_REGISTER_DATA) { else if (subId == ELEM_REGISTER_DATA) {
decodeLaneSizes(decoder); decodeRegisterData(decoder);
} }
else if (subId == ELEM_DATA_SPACE) { else if (subId == ELEM_DATA_SPACE) {
uint4 elemId = decoder.openElement(); uint4 elemId = decoder.openElement();

View file

@ -368,7 +368,7 @@ protected:
void decodeVolatile(Decoder &decoder); ///< Apply volatile region configuration void decodeVolatile(Decoder &decoder); ///< Apply volatile region configuration
void decodeReturnAddress(Decoder &decoder); ///< Apply return address configuration void decodeReturnAddress(Decoder &decoder); ///< Apply return address configuration
void decodeIncidentalCopy(Decoder &decoder); ///< Apply incidental copy configuration void decodeIncidentalCopy(Decoder &decoder); ///< Apply incidental copy configuration
void decodeLaneSizes(Decoder &decoder); ///< Apply lane size configuration void decodeRegisterData(Decoder &decoder); ///< Read specific register properties
void decodeStackPointer(Decoder &decoder); ///< Apply stack pointer configuration void decodeStackPointer(Decoder &decoder); ///< Apply stack pointer configuration
void decodeDeadcodeDelay(Decoder &decoder); ///< Apply dead-code delay configuration void decodeDeadcodeDelay(Decoder &decoder); ///< Apply dead-code delay configuration
void decodeInferPtrBounds(Decoder &decoder); ///< Apply pointer inference bounds void decodeInferPtrBounds(Decoder &decoder); ///< Apply pointer inference bounds

View file

@ -294,32 +294,13 @@ void LanedRegister::LanedIterator::normalize(void)
size = -1; // Indicate ending iterator size = -1; // Indicate ending iterator
} }
/// Parse any vector lane sizes. /// Collect specific lane sizes in this object.
/// \param decoder is the stream decoder /// \param registerSize is the size of the laned register in bytes
/// \return \b true if the XML description provides lane sizes /// \param laneSizes is a comma separated list of sizes
bool LanedRegister::decode(Decoder &decoder) void LanedRegister::parseSizes(int4 registerSize,string laneSizes)
{ {
uint4 elemId = decoder.openElement(ELEM_REGISTER); wholeSize = registerSize;
string laneSizes;
for(;;) {
uint4 attribId = decoder.getNextAttributeId();
if (attribId == 0) break;
if (attribId == ATTRIB_VECTOR_LANE_SIZES) {
laneSizes = decoder.readString();
break;
}
}
if (laneSizes.empty()) {
decoder.closeElement(elemId);
return false;
}
decoder.rewindAttributes();
VarnodeData storage;
storage.space = (AddrSpace *)0;
storage.decodeFromAttributes(decoder);
decoder.closeElement(elemId);
wholeSize = storage.size;
sizeBitMask = 0; sizeBitMask = 0;
string::size_type pos = 0; string::size_type pos = 0;
while(pos != string::npos) { while(pos != string::npos) {
@ -343,7 +324,6 @@ bool LanedRegister::decode(Decoder &decoder)
throw LowlevelError("Bad lane size: " + value); throw LowlevelError("Bad lane size: " + value);
addLaneSize(sz); addLaneSize(sz);
} }
return true;
} }
TransformManager::~TransformManager(void) TransformManager::~TransformManager(void)

View file

@ -115,7 +115,7 @@ private:
public: public:
LanedRegister(void) { wholeSize = 0; sizeBitMask = 0; } ///< Constructor for use with decode LanedRegister(void) { wholeSize = 0; sizeBitMask = 0; } ///< Constructor for use with decode
LanedRegister(int4 sz,uint4 mask) { wholeSize = sz; sizeBitMask = mask; } ///< Constructor LanedRegister(int4 sz,uint4 mask) { wholeSize = sz; sizeBitMask = mask; } ///< Constructor
bool decode(Decoder &decoder); ///< Parse \<register> elements for lane sizes void parseSizes(int4 registerSize,string laneSizes); ///< Parse a \e vector_lane_sizes attribute
int4 getWholeSize(void) const { return wholeSize; } ///< Get the size in bytes of the whole laned register int4 getWholeSize(void) const { return wholeSize; } ///< Get the size in bytes of the whole laned register
uint4 getSizeBitMask(void) const { return sizeBitMask; } ///< Get the bit mask of possible lane sizes uint4 getSizeBitMask(void) const { return sizeBitMask; } ///< Get the bit mask of possible lane sizes
void addLaneSize(int4 size) { sizeBitMask |= ((uint4)1 << size); } ///< Add a new \e size to the allowed list void addLaneSize(int4 size) { sizeBitMask |= ((uint4)1 << size); } ///< Add a new \e size to the allowed list

View file

@ -114,6 +114,11 @@
<ref name="boolean_type"/> <ref name="boolean_type"/>
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="volatile">
<ref name="boolean_type"/>
</attribute>
</optional>
<optional> <optional>
<attribute name="vector_lane_sizes"/> <attribute name="vector_lane_sizes"/>
</optional> </optional>

View file

@ -20,8 +20,8 @@ import static ghidra.pcode.utils.SlaFormat.*;
import java.io.*; import java.io.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -82,7 +82,7 @@ public class SleighLanguage implements Language {
*/ */
private String segmentedspace = ""; private String segmentedspace = "";
private String segmentType = ""; private String segmentType = "";
private AddressSet volatileAddresses; private AddressSet volatileAddresses = new AddressSet();
private AddressSet volatileSymbolAddresses; private AddressSet volatileSymbolAddresses;
private AddressSet nonVolatileSymbolAddresses; private AddressSet nonVolatileSymbolAddresses;
private ContextCache contextcache = null; private ContextCache contextcache = null;
@ -155,9 +155,6 @@ public class SleighLanguage implements Language {
} }
private void buildVolatileSymbolAddresses() { private void buildVolatileSymbolAddresses() {
if (volatileAddresses == null) {
volatileAddresses = new AddressSet();
}
if (volatileSymbolAddresses != null) { if (volatileSymbolAddresses != null) {
volatileAddresses.add(volatileSymbolAddresses); volatileAddresses.add(volatileSymbolAddresses);
} }
@ -680,9 +677,6 @@ public class SleighLanguage implements Language {
throw new SleighException("no support for volatile registers yet"); throw new SleighException("no support for volatile registers yet");
} }
Pair<Address, Address> range = parseRange(next); Pair<Address, Address> range = parseRange(next);
if (volatileAddresses == null) {
volatileAddresses = new AddressSet();
}
volatileAddresses.addRange(range.first, range.second); volatileAddresses.addRange(range.first, range.second);
// skip the end tag // skip the end tag
parser.end(next); parser.end(next);
@ -709,6 +703,7 @@ public class SleighLanguage implements Language {
String registerAlias = reg.getAttribute("alias"); String registerAlias = reg.getAttribute("alias");
String groupName = reg.getAttribute("group"); String groupName = reg.getAttribute("group");
boolean isHidden = SpecXmlUtils.decodeBoolean(reg.getAttribute("hidden")); boolean isHidden = SpecXmlUtils.decodeBoolean(reg.getAttribute("hidden"));
boolean isVolatile = SpecXmlUtils.decodeBoolean(reg.getAttribute("volatile"));
if (registerRename != null) { if (registerRename != null) {
if (!registerBuilder.renameRegister(registerName, registerRename)) { if (!registerBuilder.renameRegister(registerName, registerRename)) {
throw new SleighException( throw new SleighException(
@ -732,6 +727,11 @@ public class SleighLanguage implements Language {
if (isHidden) { if (isHidden) {
registerBuilder.setFlag(registerName, Register.TYPE_HIDDEN); registerBuilder.setFlag(registerName, Register.TYPE_HIDDEN);
} }
if (isVolatile) {
Address first = register.getAddress();
Address second = first.add(register.getNumBytes() - 1);
volatileAddresses.addRange(first, second);
}
String sizes = reg.getAttribute("vector_lane_sizes"); String sizes = reg.getAttribute("vector_lane_sizes");
if (sizes != null) { if (sizes != null) {
String[] lanes = sizes.split(","); String[] lanes = sizes.split(",");
@ -765,9 +765,11 @@ public class SleighLanguage implements Language {
Address startAddress = null; Address startAddress = null;
if (addressString.equalsIgnoreCase("next")) { if (addressString.equalsIgnoreCase("next")) {
if (previousAddr == null) { if (previousAddr == null) {
Msg.error(this, "use of addr=\"next\" tag with no previous address for " + Msg.error(this,
"use of addr=\"next\" tag with no previous address for " +
labelName + " : " + description.getSpecFile()); labelName + " : " + description.getSpecFile());
} else { }
else {
startAddress = previousAddr.add(previousSize); startAddress = previousAddr.add(previousSize);
} }
} }
@ -784,7 +786,8 @@ public class SleighLanguage implements Language {
else { else {
AddressLabelInfo info; AddressLabelInfo info;
try { try {
info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment, false, info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment,
false,
isEntry, type, isVolatile); isEntry, type, isVolatile);
} }
catch (AddressOverflowException e) { catch (AddressOverflowException e) {

View file

@ -304,8 +304,8 @@
<register name="spr109" group="SPR_UNNAMED"/> <register name="spr109" group="SPR_UNNAMED"/>
<register name="spr10a" group="SPR_UNNAMED"/> <register name="spr10a" group="SPR_UNNAMED"/>
<register name="spr10b" group="SPR_UNNAMED"/> <register name="spr10b" group="SPR_UNNAMED"/>
<register name="TBLr" group="SPR"/> <register name="TBLr" group="SPR" volatile="true"/>
<register name="TBUr" group="SPR"/> <register name="TBUr" group="SPR" volatile="true"/>
<register name="spr10e" group="SPR_UNNAMED"/> <register name="spr10e" group="SPR_UNNAMED"/>
<register name="spr10f" group="SPR_UNNAMED"/> <register name="spr10f" group="SPR_UNNAMED"/>
@ -321,8 +321,8 @@
<register name="spr119" group="SPR_UNNAMED"/> <register name="spr119" group="SPR_UNNAMED"/>
<register name="spr11a" rename="EAR" group="SPR"/> <register name="spr11a" rename="EAR" group="SPR"/>
<register name="spr11b" group="SPR_UNNAMED"/> <register name="spr11b" group="SPR_UNNAMED"/>
<register name="TBLw" group="SPR"/> <register name="TBLw" group="SPR" volatile="true"/>
<register name="TBUw" group="SPR"/> <register name="TBUw" group="SPR" volatile="true"/>
<register name="spr11e" group="SPR_UNNAMED"/> <register name="spr11e" group="SPR_UNNAMED"/>
<register name="spr11f" rename="PVR" group="SPR"/> <register name="spr11f" rename="PVR" group="SPR"/>

View file

@ -302,8 +302,8 @@ don't know about the DCRs though
<register name="spr109" group="SPR_UNNAMED"/> <register name="spr109" group="SPR_UNNAMED"/>
<register name="spr10a" group="SPR_UNNAMED"/> <register name="spr10a" group="SPR_UNNAMED"/>
<register name="spr10b" group="SPR_UNNAMED"/> <register name="spr10b" group="SPR_UNNAMED"/>
<register name="TBLr" group="SPR"/> <register name="TBLr" group="SPR" volatile="true"/>
<register name="TBUr" group="SPR"/> <register name="TBUr" group="SPR" voaltile="true"/>
<register name="spr10e" group="SPR_UNNAMED"/> <register name="spr10e" group="SPR_UNNAMED"/>
<register name="spr10f" group="SPR_UNNAMED"/> <register name="spr10f" group="SPR_UNNAMED"/>
@ -319,8 +319,8 @@ don't know about the DCRs though
<register name="spr119" group="SPR_UNNAMED"/> <register name="spr119" group="SPR_UNNAMED"/>
<register name="spr11a" rename="EAR" group="SPR"/> <register name="spr11a" rename="EAR" group="SPR"/>
<register name="spr11b" group="SPR_UNNAMED"/> <register name="spr11b" group="SPR_UNNAMED"/>
<register name="TBLw" group="SPR"/> <register name="TBLw" group="SPR" volatile="true"/>
<register name="TBUw" group="SPR"/> <register name="TBUw" group="SPR" volatile="true"/>
<register name="spr11e" rename="SVR" group="SPR"/> <register name="spr11e" rename="SVR" group="SPR"/>
<register name="spr11f" rename="PVR" group="SPR"/> <register name="spr11f" rename="PVR" group="SPR"/>

View file

@ -301,8 +301,8 @@
<register name="spr109" group="SPR_UNNAMED"/> <register name="spr109" group="SPR_UNNAMED"/>
<register name="spr10a" group="SPR_UNNAMED"/> <register name="spr10a" group="SPR_UNNAMED"/>
<register name="spr10b" group="SPR_UNNAMED"/> <register name="spr10b" group="SPR_UNNAMED"/>
<register name="TBLr" group="SPR"/> <register name="TBLr" group="SPR" volatile="true"/>
<register name="TBUr" group="SPR"/> <register name="TBUr" group="SPR" volatile="true"/>
<register name="spr10e" group="SPR_UNNAMED"/> <register name="spr10e" group="SPR_UNNAMED"/>
<register name="spr10f" group="SPR_UNNAMED"/> <register name="spr10f" group="SPR_UNNAMED"/>
@ -318,8 +318,8 @@
<register name="spr119" group="SPR_UNNAMED"/> <register name="spr119" group="SPR_UNNAMED"/>
<register name="spr11a" rename="EAR" group="SPR"/> <register name="spr11a" rename="EAR" group="SPR"/>
<register name="spr11b" group="SPR_UNNAMED"/> <register name="spr11b" group="SPR_UNNAMED"/>
<register name="TBLw" group="SPR"/> <register name="TBLw" group="SPR" volatile="true"/>
<register name="TBUw" group="SPR"/> <register name="TBUw" group="SPR" volatile="true"/>
<register name="spr11e" group="SPR_UNNAMED"/> <register name="spr11e" group="SPR_UNNAMED"/>
<register name="spr11f" rename="PVR" group="SPR"/> <register name="spr11f" rename="PVR" group="SPR"/>