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

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -924,23 +924,47 @@ void Architecture::decodeIncidentalCopy(Decoder &decoder)
decoder.closeElement(elemId);
}
/// Look for \<register> elements that have a \e vector_lane_size attribute.
/// Record these so that the decompiler can split large registers into appropriate lane size pieces.
/// Read \<register> elements to collect specific properties associated with the register storage.
/// \param decoder is the stream decoder
void Architecture::decodeLaneSizes(Decoder &decoder)
void Architecture::decodeRegisterData(Decoder &decoder)
{
vector<uint4> maskList;
LanedRegister lanedRegister; // Only allocate once
uint4 elemId = decoder.openElement(ELEM_REGISTER_DATA);
while(decoder.peekElement() != 0) {
if (lanedRegister.decode(decoder)) {
int4 sizeIndex = lanedRegister.getWholeSize();
while (maskList.size() <= sizeIndex)
maskList.push_back(0);
maskList[sizeIndex] |= lanedRegister.getSizeBitMask();
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();
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);
lanerecords.clear();
@ -1172,7 +1196,7 @@ void Architecture::parseProcessorConfig(DocumentStorage &store)
else if (subId == ELEM_SEGMENTOP)
userops.decodeSegmentOp(decoder,this);
else if (subId == ELEM_REGISTER_DATA) {
decodeLaneSizes(decoder);
decodeRegisterData(decoder);
}
else if (subId == ELEM_DATA_SPACE) {
uint4 elemId = decoder.openElement();

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -368,7 +368,7 @@ protected:
void decodeVolatile(Decoder &decoder); ///< Apply volatile region configuration
void decodeReturnAddress(Decoder &decoder); ///< Apply return address 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 decodeDeadcodeDelay(Decoder &decoder); ///< Apply dead-code delay configuration
void decodeInferPtrBounds(Decoder &decoder); ///< Apply pointer inference bounds

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -294,32 +294,13 @@ void LanedRegister::LanedIterator::normalize(void)
size = -1; // Indicate ending iterator
}
/// Parse any vector lane sizes.
/// \param decoder is the stream decoder
/// \return \b true if the XML description provides lane sizes
bool LanedRegister::decode(Decoder &decoder)
/// Collect specific lane sizes in this object.
/// \param registerSize is the size of the laned register in bytes
/// \param laneSizes is a comma separated list of sizes
void LanedRegister::parseSizes(int4 registerSize,string laneSizes)
{
uint4 elemId = decoder.openElement(ELEM_REGISTER);
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;
wholeSize = registerSize;
sizeBitMask = 0;
string::size_type pos = 0;
while(pos != string::npos) {
@ -343,7 +324,6 @@ bool LanedRegister::decode(Decoder &decoder)
throw LowlevelError("Bad lane size: " + value);
addLaneSize(sz);
}
return true;
}
TransformManager::~TransformManager(void)

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -115,7 +115,7 @@ private:
public:
LanedRegister(void) { wholeSize = 0; sizeBitMask = 0; } ///< Constructor for use with decode
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
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

View File

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

View File

@ -20,8 +20,8 @@ import static ghidra.pcode.utils.SlaFormat.*;
import java.io.*;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -82,7 +82,7 @@ public class SleighLanguage implements Language {
*/
private String segmentedspace = "";
private String segmentType = "";
private AddressSet volatileAddresses;
private AddressSet volatileAddresses = new AddressSet();
private AddressSet volatileSymbolAddresses;
private AddressSet nonVolatileSymbolAddresses;
private ContextCache contextcache = null;
@ -155,9 +155,6 @@ public class SleighLanguage implements Language {
}
private void buildVolatileSymbolAddresses() {
if (volatileAddresses == null) {
volatileAddresses = new AddressSet();
}
if (volatileSymbolAddresses != null) {
volatileAddresses.add(volatileSymbolAddresses);
}
@ -378,10 +375,10 @@ public class SleighLanguage implements Language {
// get existing proto and use it
// if doesn't exist in map, cache info and store new proto
res = instructProtoMap.computeIfAbsent(hashcode, h -> {
newProto.cacheInfo(buf, context, true);
return newProto;
newProto.cacheInfo(buf, context, true);
return newProto;
});
if (inDelaySlot && res.hasDelaySlots()) {
throw new NestedDelaySlotException();
}
@ -680,9 +677,6 @@ public class SleighLanguage implements Language {
throw new SleighException("no support for volatile registers yet");
}
Pair<Address, Address> range = parseRange(next);
if (volatileAddresses == null) {
volatileAddresses = new AddressSet();
}
volatileAddresses.addRange(range.first, range.second);
// skip the end tag
parser.end(next);
@ -709,6 +703,7 @@ public class SleighLanguage implements Language {
String registerAlias = reg.getAttribute("alias");
String groupName = reg.getAttribute("group");
boolean isHidden = SpecXmlUtils.decodeBoolean(reg.getAttribute("hidden"));
boolean isVolatile = SpecXmlUtils.decodeBoolean(reg.getAttribute("volatile"));
if (registerRename != null) {
if (!registerBuilder.renameRegister(registerName, registerRename)) {
throw new SleighException(
@ -732,6 +727,11 @@ public class SleighLanguage implements Language {
if (isHidden) {
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");
if (sizes != null) {
String[] lanes = sizes.split(",");
@ -753,7 +753,7 @@ public class SleighLanguage implements Language {
else if (elName.equals("default_symbols")) {
XmlElement subel = parser.start();
Address previousAddr = null;
int previousSize = 1;
int previousSize = 1;
while (parser.peek().getName().equals("symbol")) {
XmlElement symbol = parser.start();
String labelName = symbol.getAttribute("name");
@ -765,9 +765,11 @@ public class SleighLanguage implements Language {
Address startAddress = null;
if (addressString.equalsIgnoreCase("next")) {
if (previousAddr == null) {
Msg.error(this, "use of addr=\"next\" tag with no previous address for " +
labelName + " : " + description.getSpecFile());
} else {
Msg.error(this,
"use of addr=\"next\" tag with no previous address for " +
labelName + " : " + description.getSpecFile());
}
else {
startAddress = previousAddr.add(previousSize);
}
}
@ -784,7 +786,8 @@ public class SleighLanguage implements Language {
else {
AddressLabelInfo info;
try {
info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment, false,
info = new AddressLabelInfo(startAddress, rangeSize, labelName, comment,
false,
isEntry, type, isVolatile);
}
catch (AddressOverflowException e) {

View File

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

View File

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