mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-4849 Volatile attribute in <register> tag.
This commit is contained in:
parent
be305db930
commit
e1cc67a3d2
9 changed files with 85 additions and 73 deletions
|
@ -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);
|
||||||
int4 sizeIndex = lanedRegister.getWholeSize();
|
bool isVolatile = false;
|
||||||
while (maskList.size() <= sizeIndex)
|
string laneSizes;
|
||||||
maskList.push_back(0);
|
for(;;) {
|
||||||
maskList[sizeIndex] |= lanedRegister.getSizeBitMask();
|
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();
|
||||||
|
while (maskList.size() <= sizeIndex)
|
||||||
|
maskList.push_back(0);
|
||||||
|
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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -378,8 +375,8 @@ public class SleighLanguage implements Language {
|
||||||
// get existing proto and use it
|
// get existing proto and use it
|
||||||
// if doesn't exist in map, cache info and store new proto
|
// if doesn't exist in map, cache info and store new proto
|
||||||
res = instructProtoMap.computeIfAbsent(hashcode, h -> {
|
res = instructProtoMap.computeIfAbsent(hashcode, h -> {
|
||||||
newProto.cacheInfo(buf, context, true);
|
newProto.cacheInfo(buf, context, true);
|
||||||
return newProto;
|
return newProto;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inDelaySlot && res.hasDelaySlots()) {
|
if (inDelaySlot && res.hasDelaySlots()) {
|
||||||
|
@ -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(",");
|
||||||
|
@ -753,7 +753,7 @@ public class SleighLanguage implements Language {
|
||||||
else if (elName.equals("default_symbols")) {
|
else if (elName.equals("default_symbols")) {
|
||||||
XmlElement subel = parser.start();
|
XmlElement subel = parser.start();
|
||||||
Address previousAddr = null;
|
Address previousAddr = null;
|
||||||
int previousSize = 1;
|
int previousSize = 1;
|
||||||
while (parser.peek().getName().equals("symbol")) {
|
while (parser.peek().getName().equals("symbol")) {
|
||||||
XmlElement symbol = parser.start();
|
XmlElement symbol = parser.start();
|
||||||
String labelName = symbol.getAttribute("name");
|
String labelName = symbol.getAttribute("name");
|
||||||
|
@ -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,
|
||||||
labelName + " : " + description.getSpecFile());
|
"use of addr=\"next\" tag with no previous address for " +
|
||||||
} else {
|
labelName + " : " + description.getSpecFile());
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue