mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-12-03 17:41:33 +00:00
GP-1100 fixing pinned symbols
This commit is contained in:
parent
6660f9663b
commit
d694bb7d7b
@ -642,8 +642,8 @@ public class FunctionEditorModel {
|
||||
try {
|
||||
if (autoParamCount < oldAutoCount) {
|
||||
if (oldParams.get(autoParamCount)
|
||||
.getStorage()
|
||||
.getAutoParameterType() != storage.getAutoParameterType()) {
|
||||
.getStorage()
|
||||
.getAutoParameterType() != storage.getAutoParameterType()) {
|
||||
adjustSelectionForRowRemoved(i);
|
||||
}
|
||||
}
|
||||
@ -1047,6 +1047,24 @@ public class FunctionEditorModel {
|
||||
return true;
|
||||
}
|
||||
|
||||
private FunctionSignature getFunctionSignature() {
|
||||
FunctionDefinitionDataType funDt = new FunctionDefinitionDataType(name);
|
||||
funDt.setReturnType(returnInfo.getFormalDataType());
|
||||
List<ParameterDefinition> params = new ArrayList<>();
|
||||
|
||||
for (ParamInfo paramInfo : parameters) {
|
||||
if (paramInfo.isAutoParameter()) {
|
||||
continue;
|
||||
}
|
||||
String paramName = paramInfo.getName();
|
||||
DataType paramDt = paramInfo.getFormalDataType();
|
||||
params.add(new ParameterDefinitionImpl(paramName, paramDt, null));
|
||||
}
|
||||
funDt.setArguments(params.toArray(new ParameterDefinition[params.size()]));
|
||||
funDt.setVarArgs(hasVarArgs);
|
||||
return funDt;
|
||||
}
|
||||
|
||||
Program getProgram() {
|
||||
return program;
|
||||
}
|
||||
@ -1170,7 +1188,7 @@ public class FunctionEditorModel {
|
||||
public void parseSignatureFieldText() throws ParseException, CancelledException {
|
||||
FunctionSignatureParser parser =
|
||||
new FunctionSignatureParser(program.getDataTypeManager(), dataTypeManagerService);
|
||||
FunctionDefinitionDataType f = parser.parse(function.getSignature(), signatureFieldText);
|
||||
FunctionDefinitionDataType f = parser.parse(getFunctionSignature(), signatureFieldText);
|
||||
|
||||
setFunctionData(f);
|
||||
isInParsingMode = false;
|
||||
|
@ -16,7 +16,6 @@
|
||||
package ghidra.app.util.parser;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
@ -98,7 +97,6 @@ public class FunctionSignatureParser {
|
||||
*/
|
||||
public FunctionDefinitionDataType parse(FunctionSignature originalSignature,
|
||||
String signatureText) throws ParseException, CancelledException {
|
||||
|
||||
dtMap.clear();
|
||||
nameMap.clear();
|
||||
if (dtmService != null) {
|
||||
@ -236,18 +234,18 @@ public class FunctionSignatureParser {
|
||||
}
|
||||
|
||||
private String replaceDataTypeIfNeeded(String text, DataType dataType, String replacementName) {
|
||||
String displayName = dataType.getDisplayName();
|
||||
if (canParse(displayName)) {
|
||||
String datatypeName = dataType.getName();
|
||||
if (canParseType(datatypeName)) {
|
||||
return text;
|
||||
}
|
||||
|
||||
dtMap.put(replacementName, dataType);
|
||||
|
||||
return substitute(text, displayName, replacementName);
|
||||
return substitute(text, datatypeName, replacementName);
|
||||
}
|
||||
|
||||
private String replaceNameIfNeeded(String text, String name, String replacementName) {
|
||||
if (canParse(name)) {
|
||||
if (canParseName(name)) {
|
||||
return text;
|
||||
}
|
||||
nameMap.put(replacementName, name);
|
||||
@ -272,36 +270,11 @@ public class FunctionSignatureParser {
|
||||
return dt;
|
||||
}
|
||||
|
||||
// The following regex pattern attempts to isolate the parameter name from
|
||||
// the beginning of a parameter specification. Since the name is optional,
|
||||
// additional steps must be taken in code to ensure that the trailing word of
|
||||
// a multi-word type-specified is not treated as a name (e.g., unsigned long).
|
||||
//
|
||||
// The regex pattern attempts to isolate the following fields:
|
||||
//
|
||||
// <type-specifier> [<array-specifier>|<pointer-specifier>]* [param-name]
|
||||
// group-1 group-3 group-4
|
||||
//
|
||||
// Note: group-2 is an inner group to group-3 is not useful
|
||||
//
|
||||
private static final Pattern parameterNameCapturePattern =
|
||||
Pattern.compile("(.+?)((\\[\\d*\\]|\\*\\d*)\\s*)*([^\\s\\[\\*]+)");
|
||||
|
||||
private DataType resolveDataType(String dataTypeName) throws CancelledException {
|
||||
if (dtMap.containsKey(dataTypeName)) {
|
||||
return dtMap.get(dataTypeName);
|
||||
}
|
||||
|
||||
Matcher m = parameterNameCapturePattern.matcher(dataTypeName);
|
||||
if (m.matches()) {
|
||||
boolean hasPointerOrArraySpec = m.group(3) != null;
|
||||
boolean hasName = (m.group(4) != null) && (m.group(4).length() != 0);
|
||||
if (hasPointerOrArraySpec && hasName) {
|
||||
// name after array/pointer spec - dataTypeName is not a valid datatype
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
DataType dataType = null;
|
||||
try {
|
||||
dataType = dataTypeParser.parse(dataTypeName);
|
||||
@ -330,7 +303,7 @@ public class FunctionSignatureParser {
|
||||
if (nameMap.containsKey(name)) {
|
||||
return nameMap.get(name);
|
||||
}
|
||||
if (!canParse(name)) {
|
||||
if (!canParseName(name)) {
|
||||
throw new ParseException("Can't parse name: " + name);
|
||||
}
|
||||
return name;
|
||||
@ -340,10 +313,14 @@ public class FunctionSignatureParser {
|
||||
return text.replaceFirst(Pattern.quote(searchString), replacementString);
|
||||
}
|
||||
|
||||
private boolean canParse(String text) {
|
||||
private boolean canParseName(String text) {
|
||||
return !StringUtils.containsAny(text, "()*[], ");
|
||||
}
|
||||
|
||||
private boolean canParseType(String text) {
|
||||
return !StringUtils.containsAny(text, "()<>,");
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a simple caching datatype manager service wrapper.<br>
|
||||
* Implementation intended for use with {@link FunctionSignatureParser}
|
||||
|
@ -194,6 +194,75 @@ public class FunctionSignatureParserTest extends AbstractGhidraHeadedIntegration
|
||||
assertEquals("char Bob(longlong a, uint b)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnPointerToNoPointer() throws Exception {
|
||||
FunctionSignature f = fun("char *", "Bob");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "char Bob()");
|
||||
assertEquals("char Bob(void)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnPointerToSizedPointer() throws Exception {
|
||||
FunctionSignature f = fun("char *", "Bob");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "char *32 Bob()");
|
||||
assertEquals("char * Bob(void)", dt.getRepresentation(null, null, 0));
|
||||
assertEquals("char *", dt.getReturnType().getDisplayName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnPointerToPointerPointer() throws Exception {
|
||||
FunctionSignature f = fun("char *", "Bob");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "char * * Bob()");
|
||||
assertEquals("char * * Bob(void)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeReturnTypeToIncludeSizedPointer() throws Exception {
|
||||
FunctionSignature f = fun("char", "Bob");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "char *32 Bob(void)");
|
||||
assertEquals("char * Bob(void)", dt.getRepresentation(null, null, 0));
|
||||
assertEquals("char *32", dt.getReturnType().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseFunctionNameWithSizedPointerReturnType() throws Exception {
|
||||
FunctionSignature f = fun("char *32", "Bob");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "char *32 Joe()");
|
||||
assertEquals("char * Joe(void)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamPointerToSizedPointer() throws Exception {
|
||||
FunctionSignature f = fun("int", "Bob", "char *", "p1");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "int Bob(char *32 p1)");
|
||||
assertEquals("int Bob(char * p1)", dt.getRepresentation(null, null, 0));
|
||||
ParameterDefinition[] arguments = dt.getArguments();
|
||||
assertEquals("char *32", arguments[0].getDataType().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamPointerToPointerPointer() throws Exception {
|
||||
FunctionSignature f = fun("int", "Bob", "char *", "p1");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "int Bob(char * * p1)");
|
||||
assertEquals("int Bob(char * * p1)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeParamTypeToIncludeSizedPointer() throws Exception {
|
||||
FunctionSignature f = fun("int", "Bob", "char", "p1");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "int Bob(char *32 p1)");
|
||||
assertEquals("int Bob(char * p1)", dt.getRepresentation(null, null, 0));
|
||||
ParameterDefinition[] arguments = dt.getArguments();
|
||||
assertEquals("char *32", arguments[0].getDataType().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseParamNameWithSizedPointerDataType() throws Exception {
|
||||
FunctionSignature f = fun("int", "Bob", "char *32", "p1");
|
||||
FunctionDefinitionDataType dt = parser.parse(f, "int Bob(char *32 p2)");
|
||||
assertEquals("int Bob(char * p2)", dt.getRepresentation(null, null, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpacesNotAllowedInTypedFunctionName() {
|
||||
FunctionSignature f = fun("int", "Bob", "int", "a");
|
||||
@ -419,6 +488,15 @@ public class FunctionSignatureParserTest extends AbstractGhidraHeadedIntegration
|
||||
if (name.equals("int")) {
|
||||
return new IntegerDataType();
|
||||
}
|
||||
if (name.equals("char *")) {
|
||||
return new PointerDataType(new CharDataType());
|
||||
}
|
||||
if (name.equals("char *32")) {
|
||||
return new Pointer32DataType(new CharDataType());
|
||||
}
|
||||
if (name.equals("char * *32")) {
|
||||
return new Pointer32DataType(new PointerDataType(new CharDataType()));
|
||||
}
|
||||
return new StructureDataType(name, 2);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user