mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-29 22:46:44 +08:00
GP-6776 additional fixes
This commit is contained in:
+2
-1
@@ -327,7 +327,8 @@ public class SymPcodeExecutor extends PcodeExecutor<Sym> {
|
|||||||
for (int i = 0; i < arguments.length; i++) {
|
for (int i = 0; i < arguments.length; i++) {
|
||||||
types[i + 1] = arguments[0].getDataType();
|
types[i + 1] = arguments[0].getDataType();
|
||||||
}
|
}
|
||||||
VariableStorage[] vsLocs = convention.getStorageLocations(program, types, false);
|
VariableStorage[] vsLocs =
|
||||||
|
convention.getStorageLocations(program, types, false, sig.hasVarArgs());
|
||||||
Address min = null;
|
Address min = null;
|
||||||
Address max = null; // Exclusive
|
Address max = null; // Exclusive
|
||||||
for (VariableStorage vs : vsLocs) {
|
for (VariableStorage vs : vsLocs) {
|
||||||
|
|||||||
+6
-4
@@ -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.
|
||||||
@@ -189,10 +189,11 @@ class FunctionData extends FunctionDataView {
|
|||||||
|
|
||||||
void setVarArgs(boolean enable) {
|
void setVarArgs(boolean enable) {
|
||||||
this.hasVarArgs = enable;
|
this.hasVarArgs = enable;
|
||||||
|
updateParameterAndReturnStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update dynamic storage and auto-params when custom storage is disasbled.
|
* Update dynamic storage and auto-params when custom storage is disabled.
|
||||||
* Returns immediately if custom storage is enabled.
|
* Returns immediately if custom storage is enabled.
|
||||||
*/
|
*/
|
||||||
void updateParameterAndReturnStorage() {
|
void updateParameterAndReturnStorage() {
|
||||||
@@ -218,7 +219,8 @@ class FunctionData extends FunctionDataView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VariableStorage[] paramStorage =
|
VariableStorage[] paramStorage =
|
||||||
effectiveCallingConvention.getStorageLocations(getProgram(), dataTypes, true, hasVarArgs);
|
effectiveCallingConvention.getStorageLocations(getProgram(), dataTypes, true,
|
||||||
|
hasVarArgs);
|
||||||
|
|
||||||
returnInfo.setStorage(paramStorage[0]);
|
returnInfo.setStorage(paramStorage[0]);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||||
@@ -429,7 +429,8 @@ public class StringParameterPropagator extends GhidraScript {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
VariableStorage storage =
|
VariableStorage storage =
|
||||||
convention.getArgLocation(paramIndex, func.getParameters(), dt, currentProgram);
|
convention.getArgLocation(paramIndex, func.getParameters(), dt, currentProgram,
|
||||||
|
false);
|
||||||
if (storage.isUnassignedStorage()) {
|
if (storage.isUnassignedStorage()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -498,7 +499,7 @@ public class StringParameterPropagator extends GhidraScript {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
VariableStorage storage = convention.getArgLocation(i - 1, f.getParameters(),
|
VariableStorage storage = convention.getArgLocation(i - 1, f.getParameters(),
|
||||||
DataType.DEFAULT, currentProgram);
|
DataType.DEFAULT, currentProgram, false);
|
||||||
if (storage.isUnassignedStorage()) {
|
if (storage.isUnassignedStorage()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -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.
|
||||||
@@ -234,7 +234,7 @@ public class FillOutStructureHelper {
|
|||||||
typeList[i] = inputs[i].getHigh().getDataType();
|
typeList[i] = inputs[i].getHigh().getDataType();
|
||||||
}
|
}
|
||||||
VariableStorage[] storageLocations =
|
VariableStorage[] storageLocations =
|
||||||
model.getStorageLocations(currentProgram, typeList, false);
|
model.getStorageLocations(currentProgram, typeList, false, function.hasVarArgs());
|
||||||
return storageLocations[slot].getMinAddress();
|
return storageLocations[slot].getMinAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ public class UseropEmuSyscallDefinition<T> implements EmuSyscallDefinition<T> {
|
|||||||
for (int i = 0; i < locs.length; i++) {
|
for (int i = 0; i < locs.length; i++) {
|
||||||
locs[i] = dtMachineWord;
|
locs[i] = dtMachineWord;
|
||||||
}
|
}
|
||||||
VariableStorage[] vss = convention.getStorageLocations(program, locs, false);
|
VariableStorage[] vss = convention.getStorageLocations(program, locs, false, false);
|
||||||
|
|
||||||
outVar = getSingleVnStorage(vss[0]);
|
outVar = getSingleVnStorage(vss[0]);
|
||||||
inVars = Arrays.asList(new Varnode[inputCount]);
|
inVars = Arrays.asList(new Varnode[inputCount]);
|
||||||
|
|||||||
+8
-4
@@ -615,12 +615,14 @@ public class FunctionManagerDB implements FunctionManager {
|
|||||||
* @param returnDataType
|
* @param returnDataType
|
||||||
* @param currentParams
|
* @param currentParams
|
||||||
* @param paramOffset offset within currentParams for first parameter
|
* @param paramOffset offset within currentParams for first parameter
|
||||||
|
* @param hasVarArgs if true, any storage rules specific to varargs function will be applied
|
||||||
* @return return variable storage if dynamic storage does not match current custom storage -
|
* @return return variable storage if dynamic storage does not match current custom storage -
|
||||||
* this is done so that this storage can be assigned if currently <UNASSIGNED>. If dynamic
|
* this is done so that this storage can be assigned if currently <UNASSIGNED>. If dynamic
|
||||||
* storage matches null will be returned.
|
* storage matches null will be returned.
|
||||||
*/
|
*/
|
||||||
private VariableStorage checkDynamicStorageConversion(DataType returnDataType,
|
private VariableStorage checkDynamicStorageConversion(DataType returnDataType,
|
||||||
Parameter[] currentParams, int paramOffset, PrototypeModel callingConvention) {
|
Parameter[] currentParams, int paramOffset, PrototypeModel callingConvention,
|
||||||
|
boolean hasVarArgs) {
|
||||||
DataType types[] = new DataType[currentParams.length - paramOffset + 1];
|
DataType types[] = new DataType[currentParams.length - paramOffset + 1];
|
||||||
types[0] = returnDataType;
|
types[0] = returnDataType;
|
||||||
int index = 1;
|
int index = 1;
|
||||||
@@ -629,7 +631,7 @@ public class FunctionManagerDB implements FunctionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VariableStorage[] paramStorage =
|
VariableStorage[] paramStorage =
|
||||||
callingConvention.getStorageLocations(program, types, true);
|
callingConvention.getStorageLocations(program, types, true, hasVarArgs);
|
||||||
// TODO: Only handles a single auto-param insertion (could be more auto-params)
|
// TODO: Only handles a single auto-param insertion (could be more auto-params)
|
||||||
index = (paramStorage.length == types.length) ? 1 : 2; // May have inserted extra parameter
|
index = (paramStorage.length == types.length) ? 1 : 2; // May have inserted extra parameter
|
||||||
if ((paramStorage.length - 1) != types.length) {
|
if ((paramStorage.length - 1) != types.length) {
|
||||||
@@ -681,7 +683,8 @@ public class FunctionManagerDB implements FunctionManager {
|
|||||||
if (CompilerSpec.CALLING_CONVENTION_thiscall.equals(func.getCallingConventionName())) {
|
if (CompilerSpec.CALLING_CONVENTION_thiscall.equals(func.getCallingConventionName())) {
|
||||||
if (params.length != 0 && isLikelyThisParam(params[0])) {
|
if (params.length != 0 && isLikelyThisParam(params[0])) {
|
||||||
returnStorage =
|
returnStorage =
|
||||||
checkDynamicStorageConversion(returnDataType, params, 1, callingConvention);
|
checkDynamicStorageConversion(returnDataType, params, 1, callingConvention,
|
||||||
|
func.hasVarArgs());
|
||||||
if (returnStorage == null) {
|
if (returnStorage == null) {
|
||||||
useDynamic = true;
|
useDynamic = true;
|
||||||
func.removeVariable(params[0]);
|
func.removeVariable(params[0]);
|
||||||
@@ -690,7 +693,8 @@ public class FunctionManagerDB implements FunctionManager {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
returnStorage =
|
returnStorage =
|
||||||
checkDynamicStorageConversion(returnDataType, params, 0, callingConvention);
|
checkDynamicStorageConversion(returnDataType, params, 0, callingConvention,
|
||||||
|
func.hasVarArgs());
|
||||||
useDynamic = (returnStorage == null);
|
useDynamic = (returnStorage == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -141,7 +141,8 @@ class FunctionVariables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VariableStorage[] variableStorage =
|
VariableStorage[] variableStorage =
|
||||||
callingConvention.getStorageLocations(function.getProgram(), dataTypes, true);
|
callingConvention.getStorageLocations(function.getProgram(), dataTypes, true,
|
||||||
|
function.hasVarArgs());
|
||||||
returnParam.setDynamicStorage(variableStorage[0]);
|
returnParam.setDynamicStorage(variableStorage[0]);
|
||||||
|
|
||||||
int autoIndex = 0;
|
int autoIndex = 0;
|
||||||
|
|||||||
+66
-22
@@ -285,7 +285,7 @@ public class PrototypeModel {
|
|||||||
*/
|
*/
|
||||||
public VariableStorage getNextArgLocation(Parameter[] params, DataType dataType,
|
public VariableStorage getNextArgLocation(Parameter[] params, DataType dataType,
|
||||||
Program program) {
|
Program program) {
|
||||||
return getArgLocation(params != null ? params.length : 0, params, dataType, program);
|
return getArgLocation(params != null ? params.length : 0, params, dataType, program, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -315,9 +315,46 @@ public class PrototypeModel {
|
|||||||
* @param program is the Program
|
* @param program is the Program
|
||||||
* @return parameter location or {@link VariableStorage#UNASSIGNED_STORAGE} if
|
* @return parameter location or {@link VariableStorage#UNASSIGNED_STORAGE} if
|
||||||
* unable to determine suitable location
|
* unable to determine suitable location
|
||||||
|
* @deprecated Use {@link #getArgLocation(int, Parameter[], DataType, Program, boolean)}
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public VariableStorage getArgLocation(int argIndex, Parameter[] params, DataType dataType,
|
public VariableStorage getArgLocation(int argIndex, Parameter[] params, DataType dataType,
|
||||||
Program program) {
|
Program program) {
|
||||||
|
return getArgLocation(argIndex, params, dataType, program, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the preferred parameter location for a specified index,
|
||||||
|
* which will be added/inserted within the set of existing function params.
|
||||||
|
* If existing parameters use custom storage, this method should not be used.
|
||||||
|
* <br>
|
||||||
|
* Note: storage will not be assigned to the {@link DataType#DEFAULT default undefined} datatype,
|
||||||
|
* zero-length datatype, or any subsequent parameter following such a parameter.
|
||||||
|
* <br>
|
||||||
|
* Warning: The use of this method with a null {@code params} argument, or incorrect
|
||||||
|
* datatypes, is highly discouraged since it will produce inaccurate results.
|
||||||
|
* It is recommended that a complete function signature be used in
|
||||||
|
* conjunction with the {@link #getStorageLocations(Program, DataType[], boolean)}
|
||||||
|
* method. Parameter storage allocation may be affected by the return datatype
|
||||||
|
* specified (e.g., hidden return storage parameter).
|
||||||
|
*
|
||||||
|
* @param argIndex is the index (0: return storage, 1..n: parameter storage)
|
||||||
|
* @param params existing set parameters to which the parameter specified by
|
||||||
|
* argIndex will be added/inserted be appended. Element-0 corresponds to the return
|
||||||
|
* datatype. Parameter elements prior to the argIndex are required for an accurate
|
||||||
|
* storage determination to be made. Any preceeding parameters not specified will be assumed
|
||||||
|
* as a 1-byte integer type which could cause an erroneous storage result to be returned.
|
||||||
|
* A null params list will cause all preceeding params to be assumed in a similar fashion.
|
||||||
|
* @param dataType dataType associated with next parameter location or null
|
||||||
|
* for a default undefined type.
|
||||||
|
* @param program is the Program
|
||||||
|
* @param hasVarArgs if true, any assignment rules specific to varargs functions will be applied.
|
||||||
|
* @return parameter location or {@link VariableStorage#UNASSIGNED_STORAGE} if
|
||||||
|
* unable to determine suitable location
|
||||||
|
*/
|
||||||
|
public VariableStorage getArgLocation(int argIndex, Parameter[] params, DataType dataType,
|
||||||
|
Program program, boolean hasVarArgs) {
|
||||||
|
|
||||||
if (dataType != null) {
|
if (dataType != null) {
|
||||||
dataType = dataType.clone(program.getDataTypeManager());
|
dataType = dataType.clone(program.getDataTypeManager());
|
||||||
@@ -338,7 +375,7 @@ public class PrototypeModel {
|
|||||||
}
|
}
|
||||||
arr[argIndex + 1] = dataType;
|
arr[argIndex + 1] = dataType;
|
||||||
|
|
||||||
VariableStorage res[] = getStorageLocations(program, arr, false);
|
VariableStorage res[] = getStorageLocations(program, arr, false, hasVarArgs);
|
||||||
return res[res.length - 1];
|
return res[res.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,12 +415,13 @@ public class PrototypeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the variable storage for a given array of return/parameter datatypes. The first array element
|
* Compute the variable storage for a given array of return/parameter datatypes.
|
||||||
* is the return datatype, which is followed by any input parameter datatypes in order.
|
* The first array element is the return datatype, which is followed by any input parameter
|
||||||
* If addAutoParams is true, pointer datatypes will automatically be inserted for "this" or "hidden return"
|
* datatypes in order. If addAutoParams is true, pointer datatypes will automatically be
|
||||||
* input parameters, if needed. In this case, the dataTypes array should not include explicit entries for
|
* inserted for "this" or "hidden return"input parameters, if needed. In this case, the
|
||||||
* these parameters. If addAutoParams is false, the dataTypes array is assumed to already contain explicit
|
* dataTypes array should not include explicit entries for these parameters. If addAutoParams
|
||||||
* entries for any of these parameters.
|
* is false, the dataTypes array is assumed to already contain explicit entries for any of
|
||||||
|
* these parameters.
|
||||||
* <br>
|
* <br>
|
||||||
* Note: storage will not be assigned to the {@link DataType#DEFAULT default undefined} datatype
|
* Note: storage will not be assigned to the {@link DataType#DEFAULT default undefined} datatype
|
||||||
* or zero-length datatypes or any subsequent parameter following such a parameter.
|
* or zero-length datatypes or any subsequent parameter following such a parameter.
|
||||||
@@ -395,30 +433,36 @@ public class PrototypeModel {
|
|||||||
* @return dynamic storage locations orders by ordinal where first element corresponds to
|
* @return dynamic storage locations orders by ordinal where first element corresponds to
|
||||||
* return storage. The returned array may also include additional auto-parameter storage
|
* return storage. The returned array may also include additional auto-parameter storage
|
||||||
* locations.
|
* locations.
|
||||||
|
* @deprecated Use {@link #getStorageLocations(Program,DataType[],boolean,boolean)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public VariableStorage[] getStorageLocations(Program program, DataType[] dataTypes,
|
public VariableStorage[] getStorageLocations(Program program, DataType[] dataTypes,
|
||||||
boolean addAutoParams) {
|
boolean addAutoParams) {
|
||||||
return getStorageLocations(program, dataTypes, addAutoParams, false);
|
return getStorageLocations(program, dataTypes, addAutoParams, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate input and output storage locations given a function prototype,
|
* Compute the variable storage for a given array of return/parameter datatypes.
|
||||||
* with optional variable-argument support.
|
* The first array element is the return datatype, which is followed by any input parameter
|
||||||
* <p>
|
* datatypes in order. If addAutoParams is true, pointer datatypes will automatically be
|
||||||
* This overload additionally sets {@link PrototypePieces#firstVarArgSlot} when
|
* inserted for "this" or "hidden return"input parameters, if needed. In this case, the
|
||||||
* {@code isVarArgs} is true, enabling {@code VarargsFilter}-based calling-convention
|
* dataTypes array should not include explicit entries for these parameters. If addAutoParams
|
||||||
* rules (e.g. {@code <varargs/>} in a .cspec) to be applied correctly.
|
* is false, the dataTypes array is assumed to already contain explicit entries for any of
|
||||||
*
|
* these parameters.
|
||||||
|
* <br>
|
||||||
|
* Note: storage will not be assigned to the {@link DataType#DEFAULT default undefined} datatype
|
||||||
|
* or zero-length datatypes or any subsequent parameter following such a parameter.
|
||||||
|
*
|
||||||
* @param program is the Program
|
* @param program is the Program
|
||||||
* @param dataTypes return/parameter datatypes (first element is always the return datatype,
|
* @param dataTypes return/parameter datatypes (first element is always the return datatype,
|
||||||
* i.e., minimum array length is 1)
|
* i.e., minimum array length is 1)
|
||||||
* @param addAutoParams true if auto-parameter storage locations can be generated
|
* @param addAutoParams true if auto-parameter storage locations can be generated
|
||||||
* @param isVarArgs true if the function takes variable arguments; when true, all
|
* @param isVarArgs If true, the last input parameter will be treated as the last fixed argument
|
||||||
* data-types supplied in {@code dataTypes} are treated as non-optional and the first
|
* of a varargs function (via {@link PrototypePieces#firstVarArgSlot}).
|
||||||
* vararg slot is set to immediately follow the last supplied parameter
|
* @return dynamic storage locations orders by ordinal where first element corresponds to
|
||||||
* @return dynamic storage locations ordered by ordinal where first element corresponds to
|
* return storage. The returned array may also include additional auto-parameter storage
|
||||||
* return storage. The returned array may also include additional auto-parameter storage
|
* locations.
|
||||||
* locations.
|
*
|
||||||
*/
|
*/
|
||||||
public VariableStorage[] getStorageLocations(Program program, DataType[] dataTypes,
|
public VariableStorage[] getStorageLocations(Program program, DataType[] dataTypes,
|
||||||
boolean addAutoParams, boolean isVarArgs) {
|
boolean addAutoParams, boolean isVarArgs) {
|
||||||
|
|||||||
+4
-3
@@ -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.
|
||||||
@@ -752,7 +752,8 @@ public class VariableUtilities {
|
|||||||
arr[0] = DataType.VOID;
|
arr[0] = DataType.VOID;
|
||||||
arr[1] = dt;
|
arr[1] = dt;
|
||||||
VariableStorage thisStorage =
|
VariableStorage thisStorage =
|
||||||
convention.getStorageLocations(function.getProgram(), arr, true)[1];
|
convention.getStorageLocations(function.getProgram(), arr, true,
|
||||||
|
function.hasVarArgs())[1];
|
||||||
try {
|
try {
|
||||||
return new ParameterImpl("this", 0, dt, thisStorage, false, function.getProgram(),
|
return new ParameterImpl("this", 0, dt, thisStorage, false, function.getProgram(),
|
||||||
SourceType.ANALYSIS);
|
SourceType.ANALYSIS);
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
<datatype name="struct" minsize="1"/>
|
<datatype name="struct" minsize="1"/>
|
||||||
<convert_to_ptr/>
|
<convert_to_ptr/>
|
||||||
</rule>
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="union" minsize="1"/>
|
||||||
|
<convert_to_ptr/>
|
||||||
|
</rule>
|
||||||
<rule>
|
<rule>
|
||||||
<datatype name="any" maxsize="4"/>
|
<datatype name="any" maxsize="4"/>
|
||||||
<join stackspill="true"/>
|
<join stackspill="true"/>
|
||||||
@@ -78,6 +82,10 @@
|
|||||||
<datatype name="struct"/>
|
<datatype name="struct"/>
|
||||||
<hidden_return/>
|
<hidden_return/>
|
||||||
</rule>
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<datatype name="union"/>
|
||||||
|
<hidden_return/>
|
||||||
|
</rule>
|
||||||
<rule>
|
<rule>
|
||||||
<datatype name="any" maxsize="8"/>
|
<datatype name="any" maxsize="8"/>
|
||||||
<join/>
|
<join/>
|
||||||
|
|||||||
-31
@@ -25,37 +25,6 @@ public class MSP430_CSpecTest extends CSpecPrototypeTest {
|
|||||||
|
|
||||||
private static final String[] EXPECTED_PROTOTYPE_ERRORS = {
|
private static final String[] EXPECTED_PROTOTYPE_ERRORS = {
|
||||||
"paramsVariadic_I_I_C_C_S_S_I_I_L_L_50",
|
"paramsVariadic_I_I_C_C_S_S_I_I_L_L_50",
|
||||||
"paramsUnion_56",
|
|
||||||
"paramsUnion_57",
|
|
||||||
"paramsUnion_58",
|
|
||||||
"paramsUnion_59",
|
|
||||||
"paramsUnion_60",
|
|
||||||
"paramsUnion_61",
|
|
||||||
"paramsUnion_62",
|
|
||||||
"paramsUnion_63",
|
|
||||||
"paramsUnion_64",
|
|
||||||
"paramsUnion_65",
|
|
||||||
"paramsUnion_66",
|
|
||||||
"paramsUnion_67",
|
|
||||||
"paramsUnion_68",
|
|
||||||
"paramsUnion_69",
|
|
||||||
"paramsUnion_70",
|
|
||||||
"paramsUnion_71",
|
|
||||||
"paramsUnion_72",
|
|
||||||
"paramsUnion_73",
|
|
||||||
"paramsUnion_74",
|
|
||||||
"paramsUnion_75",
|
|
||||||
"paramsUnion_76",
|
|
||||||
"returnUnion_82",
|
|
||||||
"returnUnion_83",
|
|
||||||
"returnUnion_89",
|
|
||||||
"returnUnion_90",
|
|
||||||
"returnUnion_96",
|
|
||||||
"returnUnion_102",
|
|
||||||
"returnUnion_104",
|
|
||||||
"returnUnion_112",
|
|
||||||
"returnUnion_121",
|
|
||||||
"returnUnion_130",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public MSP430_CSpecTest() throws Exception {
|
public MSP430_CSpecTest() throws Exception {
|
||||||
|
|||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/* ###
|
||||||
|
* 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 static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import generic.test.AbstractGenericTest;
|
||||||
|
import ghidra.app.plugin.processors.sleigh.SleighLanguageProvider;
|
||||||
|
import ghidra.program.database.ProgramBuilder;
|
||||||
|
import ghidra.program.model.data.*;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.model.listing.VariableStorage;
|
||||||
|
|
||||||
|
public class VarargsStorageTest extends AbstractGenericTest {
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_MSP430_stdcall() throws Exception {
|
||||||
|
|
||||||
|
Language language = SleighLanguageProvider.getSleighLanguageProvider()
|
||||||
|
.getLanguage(new LanguageID("TI_MSP430:LE:16:default"));
|
||||||
|
ProgramBuilder builder = new ProgramBuilder("test", language);
|
||||||
|
|
||||||
|
program = builder.getProgram();
|
||||||
|
PrototypeModel model = program.getCompilerSpec().getCallingConvention("__stdcall");
|
||||||
|
DataType intType = new UnsignedIntegerDataType(program.getDataTypeManager());
|
||||||
|
DataType voidType = new VoidDataType(program.getDataTypeManager());
|
||||||
|
assertNotNull(model);
|
||||||
|
DataType[] inputs = new DataType[4];
|
||||||
|
inputs[0] = voidType;
|
||||||
|
inputs[1] = intType;
|
||||||
|
inputs[2] = intType;
|
||||||
|
inputs[3] = intType;
|
||||||
|
VariableStorage[] storage = model.getStorageLocations(program, inputs, false, false);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertEquals("R12", storage[1].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertEquals("R13", storage[2].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertEquals("R14", storage[3].getFirstVarnode().toString(language));
|
||||||
|
|
||||||
|
// TI_MSP430 __stdcall passes the last fixed argument of a variadic function
|
||||||
|
// on the stack, so storage[3] should be a stack location instead of R14
|
||||||
|
storage = model.getStorageLocations(program, inputs, false, true);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertEquals("R12", storage[1].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertEquals("R13", storage[2].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertTrue(storage[3].isStackStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_avr8__stdcall() throws Exception {
|
||||||
|
|
||||||
|
Language language = SleighLanguageProvider.getSleighLanguageProvider()
|
||||||
|
.getLanguage(new LanguageID("avr8:LE:16:default"));
|
||||||
|
ProgramBuilder builder = new ProgramBuilder("test", language);
|
||||||
|
|
||||||
|
program = builder.getProgram();
|
||||||
|
PrototypeModel model = program.getCompilerSpec().getCallingConvention("__stdcall");
|
||||||
|
DataType intType = new UnsignedIntegerDataType(program.getDataTypeManager());
|
||||||
|
DataType voidType = new VoidDataType(program.getDataTypeManager());
|
||||||
|
assertNotNull(model);
|
||||||
|
DataType[] inputs = new DataType[4];
|
||||||
|
inputs[0] = voidType;
|
||||||
|
inputs[1] = intType;
|
||||||
|
inputs[2] = intType;
|
||||||
|
inputs[3] = intType;
|
||||||
|
VariableStorage[] storage = model.getStorageLocations(program, inputs, false, false);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertEquals("R25R24", storage[1].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertEquals("R23R22", storage[2].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertEquals("R21R20", storage[3].getFirstVarnode().toString(language));
|
||||||
|
|
||||||
|
// avr8 __stdcall passes all parameters of a variadic function on the stack
|
||||||
|
storage = model.getStorageLocations(program, inputs, false, true);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertTrue(storage[1].isStackStorage());
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertTrue(storage[2].isStackStorage());
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertTrue(storage[3].isStackStorage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_x64__stdcall() throws Exception {
|
||||||
|
|
||||||
|
Language language = SleighLanguageProvider.getSleighLanguageProvider()
|
||||||
|
.getLanguage(new LanguageID("x86:LE:64:default"));
|
||||||
|
ProgramBuilder builder = new ProgramBuilder("test", "x86:LE:64:default", "gcc", null);
|
||||||
|
|
||||||
|
program = builder.getProgram();
|
||||||
|
PrototypeModel model = program.getCompilerSpec().getCallingConvention("__stdcall");
|
||||||
|
DataType longType = new UnsignedLongDataType(program.getDataTypeManager());
|
||||||
|
DataType voidType = new VoidDataType(program.getDataTypeManager());
|
||||||
|
assertNotNull(model);
|
||||||
|
DataType[] inputs = new DataType[4];
|
||||||
|
inputs[0] = voidType;
|
||||||
|
inputs[1] = longType;
|
||||||
|
inputs[2] = longType;
|
||||||
|
inputs[3] = longType;
|
||||||
|
VariableStorage[] storage = model.getStorageLocations(program, inputs, false, false);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertEquals("RDI", storage[1].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertEquals("RSI", storage[2].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertEquals("RDX", storage[3].getFirstVarnode().toString(language));
|
||||||
|
|
||||||
|
// x64 gcc __stdcall does not assign parameters differently for variadic functions
|
||||||
|
storage = model.getStorageLocations(program, inputs, false, true);
|
||||||
|
assertEquals(1, storage[1].getVarnodeCount());
|
||||||
|
assertEquals("RDI", storage[1].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[2].getVarnodeCount());
|
||||||
|
assertEquals("RSI", storage[2].getFirstVarnode().toString(language));
|
||||||
|
assertEquals(1, storage[3].getVarnodeCount());
|
||||||
|
assertEquals("RDX", storage[3].getFirstVarnode().toString(language));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user