mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Breaking out ParamListRegisterOut
This commit is contained in:
parent
f235e46adc
commit
a00de6cbac
7 changed files with 224 additions and 146 deletions
|
@ -38,12 +38,11 @@ public interface ParamList {
|
|||
* Given a list of datatypes, calculate the storage locations used for passing those datatypes
|
||||
* @param prog is the active progra
|
||||
* @param proto is the list of datatypes
|
||||
* @param isinput is true if this parameter list is being processed for input arguments, false for output
|
||||
* @param res is the vector for holding the VariableStorage corresponding to datatypes
|
||||
* @param addAutoParams if true add/process auto-parameters
|
||||
*/
|
||||
public void assignMap(Program prog, DataType[] proto, boolean isinput,
|
||||
ArrayList<VariableStorage> res, boolean addAutoParams);
|
||||
public void assignMap(Program prog, DataType[] proto, ArrayList<VariableStorage> res,
|
||||
boolean addAutoParams);
|
||||
|
||||
public void saveXml(StringBuilder buffer, boolean isInput);
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.program.model.lang;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
|
||||
/**
|
||||
* A list of resources describing possible storage locations for a function's return value,
|
||||
* and a strategy for selecting a storage location based on data-types in a function signature.
|
||||
*
|
||||
* The assignment strategy for this class is to take the first storage location in the list
|
||||
* that fits for the given function signature's return data-type.
|
||||
*/
|
||||
public class ParamListRegisterOut extends ParamListStandard {
|
||||
|
||||
@Override
|
||||
public void assignMap(Program prog, DataType[] proto, ArrayList<VariableStorage> res,
|
||||
boolean addAutoParams) {
|
||||
int[] status = new int[numgroup];
|
||||
for (int i = 0; i < numgroup; ++i) {
|
||||
status[i] = 0;
|
||||
}
|
||||
VariableStorage store = assignAddress(prog, proto[0], status, false, false);
|
||||
res.add(store);
|
||||
}
|
||||
|
||||
}
|
|
@ -143,37 +143,30 @@ public class ParamListStandard implements ParamList {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void assignMap(Program prog, DataType[] proto, boolean isinput,
|
||||
ArrayList<VariableStorage> res, boolean addAutoParams) {
|
||||
public void assignMap(Program prog, DataType[] proto, ArrayList<VariableStorage> res,
|
||||
boolean addAutoParams) {
|
||||
int[] status = new int[numgroup];
|
||||
for (int i = 0; i < numgroup; ++i) {
|
||||
status[i] = 0;
|
||||
}
|
||||
|
||||
if (isinput) {
|
||||
if (addAutoParams && res.size() == 2) { // Check for hidden parameters defined by the output list
|
||||
DataTypeManager dtm = prog.getDataTypeManager();
|
||||
Pointer pointer = dtm.getPointer(proto[0]);
|
||||
VariableStorage store = assignAddress(prog, pointer, status, true, false);
|
||||
res.set(1, store);
|
||||
}
|
||||
for (int i = 1; i < proto.length; ++i) {
|
||||
VariableStorage store;
|
||||
if ((pointermax != 0) && (proto[i] != null) &&
|
||||
(proto[i].getLength() > pointermax)) { // DataType is too big
|
||||
// Assume datatype is stored elsewhere and only the pointer is passed
|
||||
DataTypeManager dtm = prog.getDataTypeManager();
|
||||
Pointer pointer = dtm.getPointer(proto[i]);
|
||||
store = assignAddress(prog, pointer, status, false, true);
|
||||
}
|
||||
else {
|
||||
store = assignAddress(prog, proto[i], status, false, false);
|
||||
}
|
||||
res.add(store);
|
||||
}
|
||||
if (addAutoParams && res.size() == 2) { // Check for hidden parameters defined by the output list
|
||||
DataTypeManager dtm = prog.getDataTypeManager();
|
||||
Pointer pointer = dtm.getPointer(proto[0]);
|
||||
VariableStorage store = assignAddress(prog, pointer, status, true, false);
|
||||
res.set(1, store);
|
||||
}
|
||||
else {
|
||||
VariableStorage store = assignAddress(prog, proto[0], status, false, false);
|
||||
for (int i = 1; i < proto.length; ++i) {
|
||||
VariableStorage store;
|
||||
if ((pointermax != 0) && (proto[i] != null) && (proto[i].getLength() > pointermax)) { // DataType is too big
|
||||
// Assume datatype is stored elsewhere and only the pointer is passed
|
||||
DataTypeManager dtm = prog.getDataTypeManager();
|
||||
Pointer pointer = dtm.getPointer(proto[i]);
|
||||
store = assignAddress(prog, pointer, status, false, true);
|
||||
}
|
||||
else {
|
||||
store = assignAddress(prog, proto[i], status, false, false);
|
||||
}
|
||||
res.add(store);
|
||||
}
|
||||
}
|
||||
|
@ -279,11 +272,12 @@ public class ParamListStandard implements ParamList {
|
|||
throw new XmlParseException(
|
||||
"<pentry> in the join space not allowed in <group> tag");
|
||||
}
|
||||
if (count > 1) {
|
||||
ParamEntry.orderWithinGroup(pe.get(pe.size() - 2), lastEntry);
|
||||
if (count > 2) {
|
||||
ParamEntry.orderWithinGroup(pe.get(pe.size() - 3), lastEntry);
|
||||
}
|
||||
}
|
||||
// Check that all entries in the group are distinguishable
|
||||
for (int i = 1; i < count; ++i) {
|
||||
ParamEntry curEntry = pe.get(pe.size() - 1 - i);
|
||||
for (int j = 0; j < i; ++i) {
|
||||
ParamEntry.orderWithinGroup(pe.get(pe.size() - 1 - j), curEntry);
|
||||
}
|
||||
}
|
||||
parser.end(el);
|
||||
|
|
|
@ -24,11 +24,23 @@ import ghidra.util.exception.InvalidInputException;
|
|||
import ghidra.xml.XmlParseException;
|
||||
import ghidra.xml.XmlPullParser;
|
||||
|
||||
public class ParamListStandardOut extends ParamListStandard {
|
||||
/**
|
||||
* A list of resources describing possible storage locations for a function's return value,
|
||||
* and a strategy for selecting a storage location based on data-types in a function signature.
|
||||
*
|
||||
* Similar to the parent class, when assigning storage, the first entry that matches the data-type
|
||||
* is chosen. But if this instance fails to find a match (because the return value data-type is too
|
||||
* big) the data-type is converted to a pointer and storage is assigned based on that pointer.
|
||||
* Additionally, if configured, this instance will signal that a hidden input parameter is required
|
||||
* to fully model where the large return value is stored.
|
||||
*
|
||||
* The resource list is checked to ensure entries are distinguishable.
|
||||
*/
|
||||
public class ParamListStandardOut extends ParamListRegisterOut {
|
||||
|
||||
@Override
|
||||
public void assignMap(Program prog, DataType[] proto, boolean isinput,
|
||||
ArrayList<VariableStorage> res, boolean addAutoParams) {
|
||||
public void assignMap(Program prog, DataType[] proto, ArrayList<VariableStorage> res,
|
||||
boolean addAutoParams) {
|
||||
|
||||
int[] status = new int[numgroup];
|
||||
for (int i = 0; i < numgroup; ++i) {
|
||||
|
@ -64,11 +76,10 @@ public class ParamListStandardOut extends ParamListStandard {
|
|||
public void restoreXml(XmlPullParser parser, CompilerSpec cspec) throws XmlParseException {
|
||||
super.restoreXml(parser, cspec);
|
||||
|
||||
// ParamEntry tags in the output list are considered a group
|
||||
// ParamEntry tags in the output list are considered a group. Check that entries are distinguishable.
|
||||
for (int i = 1; i < entry.length; ++i) {
|
||||
ParamEntry.orderWithinGroup(entry[i - 1], entry[i]);
|
||||
if (i > 1) {
|
||||
ParamEntry.orderWithinGroup(entry[i - 2], entry[i]);
|
||||
for (int j = 0; j < i; ++j) {
|
||||
ParamEntry.orderWithinGroup(entry[j], entry[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ public class PrototypeModel {
|
|||
DataType[] arr = new DataType[1];
|
||||
arr[0] = clone;
|
||||
ArrayList<VariableStorage> res = new ArrayList<>();
|
||||
outputParams.assignMap(program, arr, false, res, false);
|
||||
outputParams.assignMap(program, arr, res, false);
|
||||
if (res.size() > 0) {
|
||||
return res.get(0);
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ public class PrototypeModel {
|
|||
}
|
||||
|
||||
DataType arr[] = new DataType[argIndex + 2];
|
||||
arr[0] = DataType.VOID; // Assume the return type is void
|
||||
arr[0] = VoidDataType.dataType; // Assume the return type is void
|
||||
for (int i = 0; i < argIndex; ++i) {
|
||||
if (params != null && i < params.length) {
|
||||
arr[i + 1] = params[i].getDataType(); // Copy in current types if we have them
|
||||
|
@ -291,8 +291,8 @@ public class PrototypeModel {
|
|||
}
|
||||
|
||||
ArrayList<VariableStorage> res = new ArrayList<>();
|
||||
outputParams.assignMap(program, dataTypes, false, res, addAutoParams);
|
||||
inputParams.assignMap(program, dataTypes, true, res, addAutoParams);
|
||||
outputParams.assignMap(program, dataTypes, res, addAutoParams);
|
||||
inputParams.assignMap(program, dataTypes, res, addAutoParams);
|
||||
VariableStorage[] finalres = new VariableStorage[res.size()];
|
||||
res.toArray(finalres);
|
||||
|
||||
|
@ -351,7 +351,7 @@ public class PrototypeModel {
|
|||
}
|
||||
else if (strategy.equals("register")) {
|
||||
inputParams = new ParamListStandard();
|
||||
outputParams = new ParamListStandard();
|
||||
outputParams = new ParamListRegisterOut();
|
||||
inputListType = InputListType.REGISTER;
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue