mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 11:31:43 +00:00
GP-5127 Alignment fix for MultiSlotAssign
This commit is contained in:
parent
d5f4d3b9bc
commit
ab7684a230
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -1252,8 +1252,9 @@ 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_STORAGE = AttributeId("storage",149);
|
AttributeId ATTRIB_STORAGE = AttributeId("storage",149);
|
||||||
|
AttributeId ATTRIB_STACKSPILL = AttributeId("stackspill",150);
|
||||||
|
|
||||||
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",150); // Number serves as next open index
|
AttributeId ATTRIB_UNKNOWN = AttributeId("XMLunknown",151); // 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);
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -736,6 +736,7 @@ extern AttributeId ATTRIB_VAL; ///< Marshaling attribute "val"
|
|||||||
extern AttributeId ATTRIB_VALUE; ///< Marshaling attribute "value"
|
extern AttributeId ATTRIB_VALUE; ///< Marshaling attribute "value"
|
||||||
extern AttributeId ATTRIB_WORDSIZE; ///< Marshaling attribute "wordsize"
|
extern AttributeId ATTRIB_WORDSIZE; ///< Marshaling attribute "wordsize"
|
||||||
extern AttributeId ATTRIB_STORAGE; ///< Marshaling attribute "storage"
|
extern AttributeId ATTRIB_STORAGE; ///< Marshaling attribute "storage"
|
||||||
|
extern AttributeId ATTRIB_STACKSPILL; ///< Marshaling attribute "stackspill"
|
||||||
|
|
||||||
extern ElementId ELEM_DATA; ///< Marshaling element \<data>
|
extern ElementId ELEM_DATA; ///< Marshaling element \<data>
|
||||||
extern ElementId ELEM_INPUT; ///< Marshaling element \<input>
|
extern ElementId ELEM_INPUT; ///< Marshaling element \<input>
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -689,6 +689,7 @@ uint4 MultiSlotAssign::assignAddress(Datatype *dt,const PrototypePieces &proto,i
|
|||||||
vector<int4> tmpStatus = status;
|
vector<int4> tmpStatus = status;
|
||||||
vector<VarnodeData> pieces;
|
vector<VarnodeData> pieces;
|
||||||
int4 sizeLeft = dt->getSize();
|
int4 sizeLeft = dt->getSize();
|
||||||
|
int4 align = dt->getAlignment();
|
||||||
list<ParamEntry>::const_iterator iter = firstIter;
|
list<ParamEntry>::const_iterator iter = firstIter;
|
||||||
list<ParamEntry>::const_iterator endIter = resource->getEntry().end();
|
list<ParamEntry>::const_iterator endIter = resource->getEntry().end();
|
||||||
if (enforceAlignment) {
|
if (enforceAlignment) {
|
||||||
@ -699,7 +700,6 @@ uint4 MultiSlotAssign::assignAddress(Datatype *dt,const PrototypePieces &proto,i
|
|||||||
break; // Reached end of resource list
|
break; // Reached end of resource list
|
||||||
if (entry.getType() == resourceType && entry.getAllGroups().size() == 1) { // Single register
|
if (entry.getType() == resourceType && entry.getAllGroups().size() == 1) { // Single register
|
||||||
if (tmpStatus[entry.getGroup()] == 0) { // Not consumed
|
if (tmpStatus[entry.getGroup()] == 0) { // Not consumed
|
||||||
int4 align = dt->getAlignment();
|
|
||||||
int4 regSize = entry.getSize();
|
int4 regSize = entry.getSize();
|
||||||
if (align <= regSize || (resourcesConsumed % align) == 0)
|
if (align <= regSize || (resourcesConsumed % align) == 0)
|
||||||
break;
|
break;
|
||||||
@ -720,19 +720,20 @@ uint4 MultiSlotAssign::assignAddress(Datatype *dt,const PrototypePieces &proto,i
|
|||||||
if (tmpStatus[entry.getGroup()] != 0)
|
if (tmpStatus[entry.getGroup()] != 0)
|
||||||
continue; // Already consumed
|
continue; // Already consumed
|
||||||
int4 trialSize = entry.getSize();
|
int4 trialSize = entry.getSize();
|
||||||
Address addr = entry.getAddrBySlot(tmpStatus[entry.getGroup()], trialSize,1);
|
Address addr = entry.getAddrBySlot(tmpStatus[entry.getGroup()], trialSize,align);
|
||||||
tmpStatus[entry.getGroup()] = -1; // Consume the register
|
tmpStatus[entry.getGroup()] = -1; // Consume the register
|
||||||
pieces.push_back(VarnodeData());
|
pieces.push_back(VarnodeData());
|
||||||
pieces.back().space = addr.getSpace();
|
pieces.back().space = addr.getSpace();
|
||||||
pieces.back().offset = addr.getOffset();
|
pieces.back().offset = addr.getOffset();
|
||||||
pieces.back().size = trialSize;
|
pieces.back().size = trialSize;
|
||||||
sizeLeft -= trialSize;
|
sizeLeft -= trialSize;
|
||||||
|
align = 1; // Treat remaining partial pieces as having no alignment requirement
|
||||||
}
|
}
|
||||||
if (sizeLeft > 0) { // Have to use stack to get enough bytes
|
if (sizeLeft > 0) { // Have to use stack to get enough bytes
|
||||||
if (!consumeFromStack)
|
if (!consumeFromStack)
|
||||||
return fail;
|
return fail;
|
||||||
int4 grp = stackEntry->getGroup();
|
int4 grp = stackEntry->getGroup();
|
||||||
Address addr = stackEntry->getAddrBySlot(tmpStatus[grp],sizeLeft,1); // Consume all the space we need
|
Address addr = stackEntry->getAddrBySlot(tmpStatus[grp],sizeLeft,align); // Consume all the space we need
|
||||||
if (addr.isInvalid())
|
if (addr.isInvalid())
|
||||||
return fail;
|
return fail;
|
||||||
pieces.push_back(VarnodeData());
|
pieces.push_back(VarnodeData());
|
||||||
@ -841,6 +842,9 @@ void MultiSlotAssign::decode(Decoder &decoder)
|
|||||||
else if (attribId == ATTRIB_ALIGN) {
|
else if (attribId == ATTRIB_ALIGN) {
|
||||||
enforceAlignment = decoder.readBool();
|
enforceAlignment = decoder.readBool();
|
||||||
}
|
}
|
||||||
|
else if (attribId == ATTRIB_STACKSPILL) {
|
||||||
|
consumeFromStack = decoder.readBool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
decoder.closeElement(elemId);
|
decoder.closeElement(elemId);
|
||||||
initializeEntries(); // Need new firstIter
|
initializeEntries(); // Need new firstIter
|
||||||
|
@ -396,6 +396,9 @@
|
|||||||
<optional>
|
<optional>
|
||||||
<attribute name="storage"/>
|
<attribute name="storage"/>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="stackspill"/>
|
||||||
|
</optional>
|
||||||
</element>
|
</element>
|
||||||
<element name="hidden_return">
|
<element name="hidden_return">
|
||||||
<optional>
|
<optional>
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -150,6 +150,7 @@ public class MultiSlotAssign extends AssignAction {
|
|||||||
ArrayList<Varnode> pieces = new ArrayList<>();
|
ArrayList<Varnode> pieces = new ArrayList<>();
|
||||||
ParameterPieces param = new ParameterPieces();
|
ParameterPieces param = new ParameterPieces();
|
||||||
int sizeLeft = dt.getLength();
|
int sizeLeft = dt.getLength();
|
||||||
|
int align = dt.getAlignment();
|
||||||
int iter = firstIter;
|
int iter = firstIter;
|
||||||
int endIter = resource.getNumParamEntry();
|
int endIter = resource.getNumParamEntry();
|
||||||
if (enforceAlignment) {
|
if (enforceAlignment) {
|
||||||
@ -161,7 +162,6 @@ public class MultiSlotAssign extends AssignAction {
|
|||||||
} // Reached end of resource list
|
} // Reached end of resource list
|
||||||
if (entry.getType() == resourceType && entry.getAllGroups().length == 1) { // Single register
|
if (entry.getType() == resourceType && entry.getAllGroups().length == 1) { // Single register
|
||||||
if (tmpStatus[entry.getGroup()] == 0) { // Not consumed
|
if (tmpStatus[entry.getGroup()] == 0) { // Not consumed
|
||||||
int align = dt.getAlignment();
|
|
||||||
int regSize = entry.getSize();
|
int regSize = entry.getSize();
|
||||||
if (align <= regSize || (resourcesConsumed % align) == 0) {
|
if (align <= regSize || (resourcesConsumed % align) == 0) {
|
||||||
break;
|
break;
|
||||||
@ -186,11 +186,12 @@ public class MultiSlotAssign extends AssignAction {
|
|||||||
continue;
|
continue;
|
||||||
} // Already consumed
|
} // Already consumed
|
||||||
int trialSize = entry.getSize();
|
int trialSize = entry.getSize();
|
||||||
entry.getAddrBySlot(tmpStatus[entry.getGroup()], trialSize, 1, param);
|
entry.getAddrBySlot(tmpStatus[entry.getGroup()], trialSize, align, param);
|
||||||
tmpStatus[entry.getGroup()] = -1; // Consume the register
|
tmpStatus[entry.getGroup()] = -1; // Consume the register
|
||||||
Varnode vn = new Varnode(param.address, trialSize);
|
Varnode vn = new Varnode(param.address, trialSize);
|
||||||
pieces.add(vn);
|
pieces.add(vn);
|
||||||
sizeLeft -= trialSize;
|
sizeLeft -= trialSize;
|
||||||
|
align = 1; // Treat remaining partial pieces as having no alignment requirement
|
||||||
}
|
}
|
||||||
boolean onePieceJoin = false;
|
boolean onePieceJoin = false;
|
||||||
if (sizeLeft > 0) { // Have to use stack to get enough bytes
|
if (sizeLeft > 0) { // Have to use stack to get enough bytes
|
||||||
@ -198,7 +199,7 @@ public class MultiSlotAssign extends AssignAction {
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
int grp = stackEntry.getGroup();
|
int grp = stackEntry.getGroup();
|
||||||
tmpStatus[grp] = stackEntry.getAddrBySlot(tmpStatus[grp], sizeLeft, 1, param); // Consume all the space we need
|
tmpStatus[grp] = stackEntry.getAddrBySlot(tmpStatus[grp], sizeLeft, align, param); // Consume all the space we need
|
||||||
if (param.address == null) {
|
if (param.address == null) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
@ -276,6 +277,9 @@ public class MultiSlotAssign extends AssignAction {
|
|||||||
else if (name.equals(ATTRIB_ALIGN.name())) {
|
else if (name.equals(ATTRIB_ALIGN.name())) {
|
||||||
enforceAlignment = SpecXmlUtils.decodeBoolean(attrib.getValue());
|
enforceAlignment = SpecXmlUtils.decodeBoolean(attrib.getValue());
|
||||||
}
|
}
|
||||||
|
else if (name.equals(ATTRIB_STACKSPILL.name())) {
|
||||||
|
consumeFromStack = SpecXmlUtils.decodeBoolean(attrib.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parser.end(elem);
|
parser.end(elem);
|
||||||
try {
|
try {
|
||||||
|
@ -242,6 +242,7 @@ public record AttributeId(String name, int id) {
|
|||||||
|
|
||||||
// public static final AttributeId ATTRIB_ADDRESS = new AttributeId("address", 148);
|
// public static final AttributeId ATTRIB_ADDRESS = new AttributeId("address", 148);
|
||||||
public static final AttributeId ATTRIB_STORAGE = new AttributeId("storage", 149);
|
public static final AttributeId ATTRIB_STORAGE = new AttributeId("storage", 149);
|
||||||
|
public static final AttributeId ATTRIB_STACKSPILL = new AttributeId("stackspill", 150);
|
||||||
|
|
||||||
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 150);
|
public static final AttributeId ATTRIB_UNKNOWN = new AttributeId("XMLunknown", 151);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user