From e1cc67a3d2f048f3bf5d74f9235f45cf31550d81 Mon Sep 17 00:00:00 2001 From: caheckman <48068198+caheckman@users.noreply.github.com> Date: Wed, 14 Aug 2024 21:09:15 +0000 Subject: [PATCH] GP-4849 Volatile attribute in tag. --- .../src/decompile/cpp/architecture.cc | 48 ++++++++++++++----- .../src/decompile/cpp/architecture.hh | 6 +-- .../Decompiler/src/decompile/cpp/transform.cc | 34 +++---------- .../Decompiler/src/decompile/cpp/transform.hh | 6 +-- .../data/languages/processor_spec.rxg | 5 ++ .../processors/sleigh/SleighLanguage.java | 35 +++++++------- .../PowerPC/data/languages/ppc_32.pspec | 8 ++-- .../data/languages/ppc_32_mpc8270.pspec | 8 ++-- .../PowerPC/data/languages/ppc_64.pspec | 8 ++-- 9 files changed, 85 insertions(+), 73 deletions(-) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc index 4cccca2ca5..841e9ec22d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.cc @@ -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 \ 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 \ 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 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(); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh index 73dc41296b..ebd0e84343 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/architecture.hh @@ -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 diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.cc index 64fc4ff9ae..888785af9c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.cc @@ -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) diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh index 08462ed07c..58bdecb44c 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/transform.hh @@ -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 \ 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 diff --git a/Ghidra/Framework/SoftwareModeling/data/languages/processor_spec.rxg b/Ghidra/Framework/SoftwareModeling/data/languages/processor_spec.rxg index b3e4f25b8b..12b9e86a1e 100644 --- a/Ghidra/Framework/SoftwareModeling/data/languages/processor_spec.rxg +++ b/Ghidra/Framework/SoftwareModeling/data/languages/processor_spec.rxg @@ -114,6 +114,11 @@ + + + + + diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java index c577072f3c..330b0a80ef 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/SleighLanguage.java @@ -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 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) { diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_32.pspec b/Ghidra/Processors/PowerPC/data/languages/ppc_32.pspec index 8c9194eb1a..260c1622b1 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_32.pspec +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_32.pspec @@ -304,8 +304,8 @@ - - + + @@ -321,8 +321,8 @@ - - + + diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_32_mpc8270.pspec b/Ghidra/Processors/PowerPC/data/languages/ppc_32_mpc8270.pspec index 95fdbf330c..409b563b24 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_32_mpc8270.pspec +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_32_mpc8270.pspec @@ -302,8 +302,8 @@ don't know about the DCRs though - - + + @@ -319,8 +319,8 @@ don't know about the DCRs though - - + + diff --git a/Ghidra/Processors/PowerPC/data/languages/ppc_64.pspec b/Ghidra/Processors/PowerPC/data/languages/ppc_64.pspec index 028581a0f2..d61b9f0b2c 100644 --- a/Ghidra/Processors/PowerPC/data/languages/ppc_64.pspec +++ b/Ghidra/Processors/PowerPC/data/languages/ppc_64.pspec @@ -301,8 +301,8 @@ - - + + @@ -318,8 +318,8 @@ - - + +