mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 03:09:36 +08:00
GT-3545 - GNU Demangler - Fix Parsing Issues - Checkpoint 2
Deleted old Generic* demangler classes; all tests passing
This commit is contained in:
@@ -24,7 +24,6 @@ dependencies {
|
||||
compile project(':Graph')
|
||||
compile project(':SoftwareModeling')
|
||||
compile project(':DB')
|
||||
compile project(':Demangler')
|
||||
compile project(':Help')
|
||||
|
||||
compileOnly "junit:junit:4.12"
|
||||
|
||||
-7
@@ -23,7 +23,6 @@ import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.demangler.GenericDemangledAddressTable;
|
||||
|
||||
public class DemangledAddressTable extends DemangledObject {
|
||||
|
||||
@@ -34,12 +33,6 @@ public class DemangledAddressTable extends DemangledObject {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
DemangledAddressTable(GenericDemangledAddressTable generic) {
|
||||
super(generic);
|
||||
|
||||
length = generic.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the address table.
|
||||
* -1 indicates the length is unknown.
|
||||
|
||||
@@ -23,7 +23,6 @@ import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.Enum;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import util.demangler.*;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled data type.
|
||||
@@ -108,51 +107,6 @@ public class DemangledDataType extends DemangledType {
|
||||
super(name);
|
||||
}
|
||||
|
||||
DemangledDataType(GenericDemangledDataType source) {
|
||||
super(source);
|
||||
|
||||
if (source.isArray()) {
|
||||
// TODO GenericDemangledDataType should go away; if so, we don't need to worry
|
||||
// about array dimension impedance
|
||||
arrayDimensions = 1;
|
||||
}
|
||||
|
||||
isClass = source.isClass();
|
||||
isComplex = source.isComplex();
|
||||
isEnum = source.isEnum();
|
||||
isPointer64 = source.isPointer64();
|
||||
isReference = source.isReference();
|
||||
isSigned = source.isSigned();
|
||||
isStruct = source.isStruct();
|
||||
isTemplate = source.isTemplate();
|
||||
isUnaligned = source.isUnaligned();
|
||||
isUnion = source.isUnion();
|
||||
isUnsigned = source.isUnsigned();
|
||||
isVarArgs = source.isVarArgs();
|
||||
// isVolatile = source.isVolatile();
|
||||
pointerLevels = source.getPointerLevels();
|
||||
//enumType = source.getEnumType();
|
||||
isRestrict = source.isRestrict();
|
||||
basedName = source.getBasedName();
|
||||
memberScope = source.getMemberScope();
|
||||
isCoclass = source.isCoclass();
|
||||
isCointerface = source.isCointerface();
|
||||
|
||||
GenericDemangledType otherNamespace = source.getNamespace();
|
||||
if (otherNamespace != null) {
|
||||
namespace = DemangledType.convertToNamespace(source.getNamespace());
|
||||
}
|
||||
|
||||
GenericDemangledTemplate otherTemplate = source.getTemplate();
|
||||
if (otherTemplate != null) {
|
||||
template = new DemangledTemplate(otherTemplate);
|
||||
}
|
||||
|
||||
if (source.isConst()) {
|
||||
setConst();
|
||||
}
|
||||
}
|
||||
|
||||
public DemangledDataType copy() {
|
||||
DemangledDataType copy = new DemangledDataType(getName());
|
||||
copy(this, copy);
|
||||
@@ -172,9 +126,7 @@ public class DemangledDataType extends DemangledType {
|
||||
destination.isUnion = source.isUnion;
|
||||
destination.isUnsigned = source.isUnsigned;
|
||||
destination.isVarArgs = source.isVarArgs;
|
||||
// destination.isVolatile = source.isVolatile;
|
||||
destination.pointerLevels = source.pointerLevels;
|
||||
//destination.enumType = source.enumType;
|
||||
|
||||
destination.isUnaligned = source.isUnaligned();
|
||||
destination.isRestrict = source.isRestrict();
|
||||
|
||||
@@ -31,7 +31,6 @@ import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.demangler.*;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled function.
|
||||
@@ -72,28 +71,6 @@ public class DemangledFunction extends DemangledObject implements ParameterRecei
|
||||
setName(name);
|
||||
}
|
||||
|
||||
DemangledFunction(GenericDemangledFunction other) {
|
||||
super(other);
|
||||
|
||||
GenericDemangledDataType otherReturnType = other.getReturnType();
|
||||
if (otherReturnType != null) {
|
||||
returnType = (DemangledDataType) DemangledObjectFactory.convert(otherReturnType);
|
||||
}
|
||||
callingConvention = other.getCallingConvention();
|
||||
thisPassedOnStack = other.isPassedOnStack();
|
||||
|
||||
GenericDemangledTemplate otherTemplate = other.getTemplate();
|
||||
if (otherTemplate != null) {
|
||||
template = new DemangledTemplate(otherTemplate);
|
||||
}
|
||||
isOverloadedOperator = other.isOverloadedOperator();
|
||||
|
||||
List<GenericDemangledDataType> otherParams = other.getParameters();
|
||||
for (GenericDemangledDataType parameter : otherParams) {
|
||||
parameters.add((DemangledDataType) DemangledObjectFactory.convert(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function return type.
|
||||
* @param returnType the function return type
|
||||
|
||||
-19
@@ -19,8 +19,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.program.model.data.*;
|
||||
import util.demangler.GenericDemangledDataType;
|
||||
import util.demangler.GenericDemangledFunctionPointer;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled function pointer.
|
||||
@@ -56,23 +54,6 @@ public class DemangledFunctionPointer extends DemangledDataType implements Param
|
||||
return ID++;
|
||||
}
|
||||
|
||||
DemangledFunctionPointer(GenericDemangledFunctionPointer generic) {
|
||||
super(generic);
|
||||
|
||||
ID = generic.getID();
|
||||
returnType = (DemangledDataType) DemangledObjectFactory.convert(generic.getReturnType());
|
||||
callingConvention = generic.getCallingConvention();
|
||||
isConstPointer = generic.isConstPointer();
|
||||
|
||||
parentName = generic.getParentName();
|
||||
isTrailingPointer64 = generic.isTrailingPointer64();
|
||||
|
||||
List<GenericDemangledDataType> genericParameters = generic.getParameters();
|
||||
for (GenericDemangledDataType parameter : genericParameters) {
|
||||
parameters.add((DemangledDataType) DemangledObjectFactory.convert(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return type.
|
||||
* @return the return type
|
||||
|
||||
@@ -15,17 +15,10 @@
|
||||
*/
|
||||
package ghidra.app.util.demangler;
|
||||
|
||||
import util.demangler.GenericDemangledMethod;
|
||||
|
||||
// TODO delete this
|
||||
public class DemangledMethod extends DemangledFunction {
|
||||
|
||||
public DemangledMethod(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
DemangledMethod(GenericDemangledMethod generic) {
|
||||
super(generic);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.demangler.GenericDemangledObject;
|
||||
import util.demangler.GenericDemangledType;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled object.
|
||||
@@ -77,33 +75,6 @@ public abstract class DemangledObject implements Demangled {
|
||||
// default
|
||||
}
|
||||
|
||||
DemangledObject(GenericDemangledObject other) {
|
||||
mangled = other.getOriginalMangled();
|
||||
specialPrefix = other.getSpecialPrefix();
|
||||
specialMidfix = other.getSpecialMidfix();
|
||||
specialSuffix = other.getSpecialSuffix();
|
||||
|
||||
GenericDemangledType otherNamespace = other.getNamespace();
|
||||
if (otherNamespace != null) {
|
||||
namespace = DemangledType.convertToNamespace(otherNamespace);
|
||||
}
|
||||
|
||||
visibility = other.getVisibility();
|
||||
storageClass = other.getStorageClass();
|
||||
setName(other.getName());
|
||||
isConst = other.isConst();
|
||||
isVolatile = other.isVolatile();
|
||||
isPointer64 = other.isPointer64();
|
||||
isStatic = other.isStatic();
|
||||
isVirtual = other.isVirtual();
|
||||
isThunk = other.isThunk();
|
||||
|
||||
isUnaligned = other.isUnaligned();
|
||||
isRestrict = other.isRestrict();
|
||||
basedName = other.getBasedName();
|
||||
memberScope = other.getMemberScope();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unmodified demangled name of this object.
|
||||
* This name may contain whitespace and other characters not
|
||||
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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.app.util.demangler;
|
||||
|
||||
import util.demangler.*;
|
||||
|
||||
public class DemangledObjectFactory {
|
||||
|
||||
private DemangledObjectFactory() {
|
||||
// factory
|
||||
}
|
||||
|
||||
public static DemangledObject convert(GenericDemangledObject generic) throws DemangledException {
|
||||
if (generic instanceof GenericDemangledVariable) {
|
||||
return new DemangledVariable((GenericDemangledVariable) generic);
|
||||
}
|
||||
else if (generic instanceof GenericDemangledString) {
|
||||
return new DemangledString((GenericDemangledString) generic);
|
||||
}
|
||||
else if (generic instanceof GenericDemangledMethod) {
|
||||
return new DemangledMethod((GenericDemangledMethod) generic);
|
||||
}
|
||||
else if (generic instanceof GenericDemangledFunction) {
|
||||
return new DemangledFunction((GenericDemangledFunction) generic);
|
||||
}
|
||||
else if (generic instanceof GenericDemangledAddressTable) {
|
||||
return new DemangledAddressTable((GenericDemangledAddressTable) generic);
|
||||
}
|
||||
|
||||
throw new DemangledException("Unknown GenericDemangledObject: " + generic.getClass());
|
||||
}
|
||||
|
||||
public static DemangledType convert(GenericDemangledType generic) {
|
||||
if (generic instanceof GenericDemangledFunctionPointer) {
|
||||
return new DemangledFunctionPointer((GenericDemangledFunctionPointer) generic);
|
||||
}
|
||||
else if (generic instanceof GenericDemangledDataType) {
|
||||
return new DemangledDataType((GenericDemangledDataType) generic);
|
||||
}
|
||||
|
||||
return new DemangledType(generic);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.demangler.GenericDemangledString;
|
||||
|
||||
public class DemangledString extends DemangledObject {
|
||||
private String string;
|
||||
@@ -45,17 +44,6 @@ public class DemangledString extends DemangledObject {
|
||||
this.unicode = unicode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct demangled string from a GenericDemangledString
|
||||
* @param generic generic demangled string
|
||||
*/
|
||||
DemangledString(GenericDemangledString generic) {
|
||||
super(generic);
|
||||
string = generic.getString();
|
||||
length = generic.getLength();
|
||||
unicode = generic.isUnicode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignature(boolean format) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
+2
-16
@@ -1,6 +1,5 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,28 +15,15 @@
|
||||
*/
|
||||
package ghidra.app.util.demangler;
|
||||
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import util.demangler.GenericDemangledDataType;
|
||||
import util.demangler.GenericDemangledTemplate;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class DemangledTemplate implements ParameterReceiver {
|
||||
private List<DemangledDataType> parameters = new ArrayList<DemangledDataType>();
|
||||
|
||||
public DemangledTemplate() {
|
||||
}
|
||||
|
||||
DemangledTemplate(GenericDemangledTemplate template) {
|
||||
List<GenericDemangledDataType> genericParameters = template.getParameters();
|
||||
for (GenericDemangledDataType parameter : genericParameters) {
|
||||
parameters.add((DemangledDataType) DemangledObjectFactory.convert(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParameter(DemangledDataType parameter) {
|
||||
parameters.add(parameter);
|
||||
|
||||
@@ -15,12 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.util.demangler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import util.demangler.GenericDemangledTemplate;
|
||||
import util.demangler.GenericDemangledType;
|
||||
|
||||
// TODO maybe rename this to DemangledNamespace
|
||||
public class DemangledType implements Demangled {
|
||||
@@ -32,61 +27,10 @@ public class DemangledType implements Demangled {
|
||||
private boolean isConst;
|
||||
private boolean isVolatile;
|
||||
|
||||
/**
|
||||
* Takes a {@link DemangledType} with a name that contains namespace elements
|
||||
* (such as Foo::Bar) and breaks it into a hierarchy of types where each type
|
||||
* represents one item in the list of namespace elements.
|
||||
*
|
||||
* @param otherNamespace the type to convert
|
||||
* @return the original type if the name does not represent a namespace; a new type
|
||||
* that contains a child, that contains a child and so on, representing the
|
||||
* split-up of the original namespace string.
|
||||
*/
|
||||
public static Demangled convertToNamespace(GenericDemangledType otherNamespace) {
|
||||
if (otherNamespace == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DemangledType newNamespace = new DemangledType(otherNamespace);
|
||||
String demangledName = newNamespace.getName();
|
||||
|
||||
SymbolPath symbolPath = new SymbolPath(demangledName);
|
||||
if (symbolPath.getParent() == null) {
|
||||
return newNamespace;
|
||||
}
|
||||
|
||||
List<String> names = symbolPath.asList();
|
||||
|
||||
DemangledType lastParent = new DemangledType(names.get(0));
|
||||
for (int i = 1; i < names.size(); i++) {
|
||||
DemangledType child = new DemangledType(names.get(i));
|
||||
child.setNamespace(lastParent);
|
||||
lastParent = child;
|
||||
}
|
||||
|
||||
return lastParent;
|
||||
}
|
||||
|
||||
public DemangledType(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
DemangledType(GenericDemangledType toCopy) {
|
||||
GenericDemangledType otherNamespace = toCopy.getNamespace();
|
||||
|
||||
if (otherNamespace != null) {
|
||||
namespace = convertToNamespace(otherNamespace);
|
||||
}
|
||||
|
||||
setName(toCopy.getName());
|
||||
GenericDemangledTemplate otherTemplate = toCopy.getTemplate();
|
||||
if (otherTemplate != null) {
|
||||
template = new DemangledTemplate(otherTemplate);
|
||||
}
|
||||
isConst = toCopy.isConst();
|
||||
isVolatile = toCopy.isVolatile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unmodified demangled name of this object.
|
||||
* This name may contain whitespace and other characters not
|
||||
|
||||
@@ -29,8 +29,6 @@ import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import util.demangler.GenericDemangledDataType;
|
||||
import util.demangler.GenericDemangledVariable;
|
||||
|
||||
/**
|
||||
* An interface to represent a demangled global variable.
|
||||
@@ -42,15 +40,6 @@ public class DemangledVariable extends DemangledObject {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
DemangledVariable(GenericDemangledVariable other) {
|
||||
super(other);
|
||||
|
||||
GenericDemangledDataType otherDatatype = other.getDataType();
|
||||
if (otherDatatype != null) {
|
||||
datatype = (DemangledDataType) DemangledObjectFactory.convert(otherDatatype);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDatatype(DemangledDataType datatype) {
|
||||
this.datatype = datatype;
|
||||
}
|
||||
|
||||
+6
-7
@@ -21,7 +21,6 @@ import ghidra.app.util.opinion.PeLoader;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import mdemangler.MDException;
|
||||
import mdemangler.MDMangGhidra;
|
||||
import util.demangler.GenericDemangledException;
|
||||
|
||||
/**
|
||||
* A class for demangling debug symbols created using Microsoft Visual Studio.
|
||||
@@ -46,7 +45,7 @@ public class MicrosoftDemangler implements Demangler {
|
||||
DemangledObject demangled = demangleMS(mangled, demangleOnlyKnownPatterns);
|
||||
return demangled;
|
||||
}
|
||||
catch (GenericDemangledException e) {
|
||||
catch (DemangledException e) {
|
||||
throw new DemangledException(true);
|
||||
}
|
||||
}
|
||||
@@ -59,15 +58,15 @@ public class MicrosoftDemangler implements Demangler {
|
||||
DemangledObject demangled = demangleMS(mangled, options.demangleOnlyKnownPatterns());
|
||||
return demangled;
|
||||
}
|
||||
catch (GenericDemangledException e) {
|
||||
catch (DemangledException e) {
|
||||
throw new DemangledException(true);
|
||||
}
|
||||
}
|
||||
|
||||
private DemangledObject demangleMS(String mangled, boolean demangleOnlyKnownPatterns)
|
||||
throws GenericDemangledException {
|
||||
throws DemangledException {
|
||||
if (mangled == null || mangled.length() == 0) {
|
||||
throw new GenericDemangledException(true);
|
||||
throw new DemangledException(true);
|
||||
}
|
||||
|
||||
MDMangGhidra demangler = new MDMangGhidra();
|
||||
@@ -77,8 +76,8 @@ public class MicrosoftDemangler implements Demangler {
|
||||
return object;
|
||||
}
|
||||
catch (MDException e) {
|
||||
GenericDemangledException gde =
|
||||
new GenericDemangledException("Unable to demangle symbol: " + mangled);
|
||||
DemangledException gde =
|
||||
new DemangledException("Unable to demangle symbol: " + mangled);
|
||||
gde.initCause(e);
|
||||
throw gde;
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
eclipse.project.name = 'Framework Demangler'
|
||||
|
||||
dependencies {
|
||||
compile project(':Utility')
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
##VERSION: 2.0
|
||||
Module.manifest||GHIDRA||reviewed||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
@@ -1,249 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
/**
|
||||
* A class for bidirectional iteration over a string.
|
||||
*
|
||||
* Iterators maintain a current character index, whose valid range is from
|
||||
* 0 to string.length()-1.
|
||||
*
|
||||
* The current index can be retrieved by calling getIndex() and set directly
|
||||
* by calling setIndex().
|
||||
*
|
||||
* The methods previous() and next() are used for iteration. They return DONE if
|
||||
* they would move outside the range from 0 to string.length()-1.
|
||||
*/
|
||||
public class CharacterIterator {
|
||||
/**
|
||||
* Constant that is returned when the iterator has reached either the end
|
||||
* or the beginning of the text. The value is '\\uFFFF', the "not a
|
||||
* character" value which should not occur in any valid Unicode string.
|
||||
*/
|
||||
public static final char DONE = '\uFFFF';
|
||||
|
||||
private String string;
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* Constructs a new character iterator using str.
|
||||
* @param str the string to iterate
|
||||
*/
|
||||
public CharacterIterator(String str) {
|
||||
this.string = str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying string.
|
||||
* @return the underlying string
|
||||
*/
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current index.
|
||||
* @return the current index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the iterator.
|
||||
* @return the length of the iterator
|
||||
*/
|
||||
public int getLength() {
|
||||
return string.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position to the specified position in the text.
|
||||
* @param index the position within the text.
|
||||
* @throws IllegalArgumentException if index is not in range from 0 to string.length()-1
|
||||
*/
|
||||
public void setIndex(int index) {
|
||||
if (index < 0 || index > string.length() - 1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are more characters to read
|
||||
* @return true if there are more characters to read
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return index < string.length() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next character without incrementing the current index.
|
||||
* @return the next character without incrementing the current index
|
||||
*/
|
||||
public char peek() {
|
||||
try {
|
||||
return string.charAt(index);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the character current index + lookAhead.
|
||||
* Returns DONE if the computed position is out of range.
|
||||
* @param lookAhead number of characters to look ahead
|
||||
* @return the character at index+lookAhead
|
||||
*/
|
||||
public char peek(int lookAhead) {
|
||||
try {
|
||||
return string.charAt(index + lookAhead);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the current index by one and returns the character
|
||||
* at the new index. If the resulting index is greater or equal
|
||||
* to the end index, the current index is reset to the end index and
|
||||
* a value of DONE is returned.
|
||||
* @return the character at the new position or DONE
|
||||
*/
|
||||
public char next() {
|
||||
try {
|
||||
return string.charAt(++index);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
index = string.length();
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at the current index and then increments the index by one.
|
||||
* If the resulting index is greater or equal
|
||||
* to the end index, the current index is reset to the end index and
|
||||
* a value of DONE is returned.
|
||||
* @return the character at the new position or DONE
|
||||
*/
|
||||
public char getAndIncrement() {
|
||||
try {
|
||||
return string.charAt(index++);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
index = string.length();
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements the current index by one and returns the character
|
||||
* at the new index. If the current index is 0, the index
|
||||
* remains at 0 and a value of DONE is returned.
|
||||
* @return the character at the new position or DONE
|
||||
*/
|
||||
public char previous() {
|
||||
try {
|
||||
return string.charAt(--index);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e) {
|
||||
index = 0;
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next ascii string of the specified length starting
|
||||
* at the current index.
|
||||
* @param len the length of the string to read
|
||||
* @return the next ascii string
|
||||
*/
|
||||
public String nextString(int len) {
|
||||
String s = string.substring(index, index + len);
|
||||
index = index + len;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next integer. The radix must be 10 (decimal).
|
||||
* For example, given "...12fred..". If current index is pointing
|
||||
* to the '1', then this value will return 12.
|
||||
* @return the next base-10 integer.
|
||||
*/
|
||||
public int nextInteger() {
|
||||
int origIndex = index;
|
||||
while (Character.isDigit(peek())) {
|
||||
getAndIncrement();
|
||||
}
|
||||
if (origIndex == index) {
|
||||
return string.charAt(index) - '0';
|
||||
}
|
||||
String s = string.substring(origIndex, index);
|
||||
try {
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
index = origIndex;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for the next occurrence of 'c' starting
|
||||
* at the current index. Returns the character
|
||||
* position in the underlying string or -1 if 'c'
|
||||
* is not found.
|
||||
*/
|
||||
public int find(char c) {
|
||||
for (int i = index; i < string.length(); ++i) {
|
||||
if (string.charAt(i) == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "currnt = " + peek() + "; next = " + peek(1);
|
||||
}
|
||||
|
||||
public String getContext() {
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
|
||||
int amount = 5;
|
||||
int start = index - amount;
|
||||
start = Math.max(start, 0);
|
||||
for (int i = start; i < index; i++) {
|
||||
buffy.append(string.charAt(i));
|
||||
}
|
||||
|
||||
buffy.append('[').append(string.charAt(index)).append(']');
|
||||
|
||||
int end = index + amount + 1;
|
||||
end = Math.min(end, string.length());
|
||||
for (int i = index + 1; i < end; i++) {
|
||||
buffy.append(string.charAt(i));
|
||||
}
|
||||
|
||||
buffy.append(" @ ").append(index);
|
||||
|
||||
return buffy.toString();
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
public class GenericDemangledAddressTable extends GenericDemangledObject {
|
||||
|
||||
private int length;
|
||||
|
||||
public GenericDemangledAddressTable(String name, int length) {
|
||||
this.name = name;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the address table.
|
||||
* -1 indicates the length is unknown.
|
||||
* @return the length of the address table
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignature(boolean format) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if (specialPrefix != null) {
|
||||
buffer.append(specialPrefix);
|
||||
buffer.append(' ');
|
||||
}
|
||||
|
||||
if (namespace != null) {
|
||||
String namespaceStr = namespace.toSignature();
|
||||
buffer.append(namespaceStr);
|
||||
if (!namespaceStr.endsWith(NAMESPACE_SEPARATOR)) {
|
||||
buffer.append(NAMESPACE_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.append(name);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public class GenericDemangledArray extends GenericDemangledDataType {
|
||||
|
||||
private String dataType;
|
||||
|
||||
public GenericDemangledArray(String name) {
|
||||
super(name);
|
||||
setArray();
|
||||
}
|
||||
|
||||
public void setDataType(String dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public String getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyInto(GenericDemangledVariable destination) {
|
||||
super.copyInto(destination);
|
||||
|
||||
if (dataType != null) {
|
||||
GenericDemangledDataType dt = new GenericDemangledDataType(dataType);
|
||||
destination.setDatatype(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: this code is a modified form of what was in the parent class, specifically to
|
||||
* handle arrays. Also, feel free to jigger this around, as long as the tests pass, we are
|
||||
* probably OK. There is probably a lot of code in this method that is not needed.
|
||||
*/
|
||||
@Override
|
||||
public String toSignature() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if (isUnion) {
|
||||
buffer.append(UNION).append(SPACE);
|
||||
}
|
||||
if (isStruct) {
|
||||
buffer.append(STRUCT).append(SPACE);
|
||||
}
|
||||
if (isEnum) {
|
||||
buffer.append(ENUM).append(SPACE);
|
||||
}
|
||||
if (isClass) {
|
||||
buffer.append(CLASS).append(SPACE);
|
||||
}
|
||||
if (isComplex) {
|
||||
buffer.append(COMPLEX).append(SPACE);
|
||||
}
|
||||
if (isVolatile) {
|
||||
buffer.append(VOLATILE).append(SPACE);
|
||||
}
|
||||
if (isSigned) {
|
||||
buffer.append(SIGNED).append(SPACE);
|
||||
}
|
||||
if (isUnsigned) {
|
||||
buffer.append(UNSIGNED).append(SPACE);
|
||||
}
|
||||
|
||||
String space = "";
|
||||
if (dataType != null) {
|
||||
buffer.append(space).append(dataType);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (isConst()) {
|
||||
buffer.append(space).append(CONST);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (getNamespace() != null) {
|
||||
buffer.append(getNamespace().toNamespace());
|
||||
}
|
||||
|
||||
if (getName() != null) {
|
||||
buffer.append(getName());
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (getTemplate() != null) {
|
||||
buffer.append(getTemplate().toTemplate());
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (isUnaligned) {
|
||||
buffer.append(space).append(UNALIGNED);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (isFar) {
|
||||
buffer.append(space).append(FAR);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
if (isRestrict) {
|
||||
buffer.append(space).append(RESTRICT);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
handlePointer(buffer, space);
|
||||
|
||||
if (isReference) {
|
||||
|
||||
// ugly, but MS does this
|
||||
boolean hasPointers = pointerLevels >= 1;
|
||||
if (isConst() && hasPointers) {
|
||||
buffer.append(space).append(CONST);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
buffer.append(space).append(REF_NOTATION);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
handleTrailingPointer(buffer, space);
|
||||
|
||||
if (isArray) {
|
||||
Matcher matcher = ARRAY_SUBSCRIPT_PATTERN.matcher(getName());
|
||||
if (!matcher.find()) {
|
||||
// only put subscript on if the name doesn't have it
|
||||
buffer.append(ARR_NOTATION);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private void handlePointer(StringBuffer buffer, String space) {
|
||||
String myName = getName();
|
||||
if (myName.contains("*")) {
|
||||
return; // don't add pointer notation if it is already in the name
|
||||
}
|
||||
|
||||
boolean hasPointers = pointerLevels >= 1;
|
||||
if (hasPointers) {
|
||||
buffer.append(space + PTR_NOTATION);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTrailingPointer(StringBuffer buffer, String space) {
|
||||
// not sure if we need this here
|
||||
// String myName = getName();
|
||||
// if (myName.contains("*")) {
|
||||
// return; // don't add pointer notation if it is already in the name
|
||||
// }
|
||||
|
||||
if (isPointer64) {
|
||||
buffer.append(space).append(PTR64);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
for (int i = 1; i < pointerLevels; i++) {
|
||||
|
||||
// ugly, but MS does this
|
||||
if (isConst()) {
|
||||
buffer.append(space).append(CONST);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
|
||||
buffer.append(space).append(PTR_NOTATION);
|
||||
space = String.valueOf(SPACE);
|
||||
|
||||
// ugly, but MS does this
|
||||
if (isPointer64) {
|
||||
buffer.append(space).append(PTR64);
|
||||
space = String.valueOf(SPACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 util.demangler;
|
||||
|
||||
public final class GenericDemangledConstants {
|
||||
|
||||
public final static String VISIBILITY_public = "public";
|
||||
public final static String VISIBILITY_protected = "protected";
|
||||
public final static String VISIBILITY_private = "private";
|
||||
public final static String VISIBILITY_static = "static";
|
||||
public final static String VISIBILITY_global = "global";
|
||||
public final static String VISIBILITY_virtual = "virtual";
|
||||
|
||||
public final static String[] VISIBILITY_ARR = { VISIBILITY_public, VISIBILITY_protected,
|
||||
VISIBILITY_private, VISIBILITY_static, VISIBILITY_global, VISIBILITY_virtual, };
|
||||
|
||||
public final static boolean isVisibility(String visibility) {
|
||||
return contains(VISIBILITY_ARR, visibility);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public final static String STORAGE_CLASS_const = "const";
|
||||
public final static String STORAGE_CLASS_volatile = "volatile";
|
||||
public final static String STORAGE_CLASS_far = "far";
|
||||
public final static String STORAGE_CLASS_restrict = "restrict";
|
||||
|
||||
public final static String[] STORAGE_CLASS_ARR = { STORAGE_CLASS_const, STORAGE_CLASS_volatile,
|
||||
STORAGE_CLASS_far, STORAGE_CLASS_restrict, };
|
||||
|
||||
public final static boolean isStorageClass(String storageClass) {
|
||||
return contains(STORAGE_CLASS_ARR, storageClass);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
private final static boolean contains(String[] array, String target) {
|
||||
for (String element : array) {
|
||||
if (element.equals(target)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-579
File diff suppressed because it is too large
Load Diff
-64
@@ -1,64 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 util.demangler;
|
||||
|
||||
/**
|
||||
* A class to handle exceptions that occur demangling.
|
||||
*/
|
||||
public class GenericDemangledException extends Exception {
|
||||
private boolean invalidMangledName;
|
||||
|
||||
/**
|
||||
* Use this constructor to indicate a demangler exception
|
||||
* due to an exception thrown during the demangling process.
|
||||
* @param cause the exception thrown during the demangling process
|
||||
*/
|
||||
public GenericDemangledException(Exception cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this constructor to indicate a demangler exception
|
||||
* due to some general invalid or unsupported mangled string
|
||||
* characteristic. For example, unrecognized datatype.
|
||||
* @param message the invalid or unsupported mangled message
|
||||
*/
|
||||
public GenericDemangledException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this constructor to indicate the demangler failed
|
||||
* because the string to demangle does not appear to represent
|
||||
* a valid mangled name.
|
||||
* @param invalidMangledName true to indicate the string to
|
||||
* demangle does not appear to represent a valid mangled name
|
||||
*/
|
||||
public GenericDemangledException(boolean invalidMangledName) {
|
||||
this.invalidMangledName = invalidMangledName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the string to demangle does not appear to represent
|
||||
* a valid mangled name
|
||||
* @return true if the string to demangle does not appear to represent
|
||||
* a valid mangled name
|
||||
*/
|
||||
public boolean isInvalidMangledName() {
|
||||
return invalidMangledName;
|
||||
}
|
||||
}
|
||||
-241
@@ -1,241 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled function.
|
||||
*/
|
||||
public class GenericDemangledFunction extends GenericDemangledObject implements ParameterReceiver {
|
||||
|
||||
protected GenericDemangledDataType returnType;
|
||||
protected String callingConvention;// __cdecl, __thiscall, etc.
|
||||
protected boolean thisPassedOnStack = true;
|
||||
protected List<GenericDemangledDataType> parameterList =
|
||||
new ArrayList<GenericDemangledDataType>();
|
||||
protected GenericDemangledTemplate template;
|
||||
protected boolean isOverloadedOperator = false;
|
||||
private boolean virtual = false;
|
||||
|
||||
/** Special constructor where it has a templated type before the parameter list */
|
||||
private String templatedConstructorType;
|
||||
|
||||
/**
|
||||
* Constructs a new demangled function.
|
||||
* @param name the name of the function
|
||||
*/
|
||||
public GenericDemangledFunction(String name) throws GenericDemangledException {
|
||||
if (name == null) {
|
||||
throw new GenericDemangledException(
|
||||
"Function name cannot be null; failed to parse mangled name properly");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function return type.
|
||||
* @param returnType the function return type
|
||||
*/
|
||||
public void setReturnType(GenericDemangledDataType returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function calling convention. For example, "__cdecl".
|
||||
* @param callingConvention the function calling convention
|
||||
*/
|
||||
public void setCallingConvention(String callingConvention) {
|
||||
this.callingConvention = callingConvention;
|
||||
}
|
||||
|
||||
/**
|
||||
* 'this' is passed on the stack or false if in a register
|
||||
*
|
||||
*/
|
||||
public void setThisPassedOnStack(boolean thisPassedOnStack) {
|
||||
this.thisPassedOnStack = thisPassedOnStack;
|
||||
}
|
||||
|
||||
public boolean isPassedOnStack() {
|
||||
return thisPassedOnStack;
|
||||
}
|
||||
|
||||
public void setTemplate(GenericDemangledTemplate template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public GenericDemangledTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setVirtual() {
|
||||
this.virtual = true;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return virtual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this demangled function represents
|
||||
* an overloaded operator. For example, "operator+()".
|
||||
* @param isOverloadedOperator true if overloaded operator
|
||||
*/
|
||||
public void setOverloadedOperator(boolean isOverloadedOperator) {
|
||||
this.isOverloadedOperator = isOverloadedOperator;
|
||||
}
|
||||
|
||||
public boolean isOverloadedOperator() {
|
||||
return isOverloadedOperator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.util.demangler.ParameterReceiver
|
||||
*/
|
||||
@Override
|
||||
public void addParameter(GenericDemangledDataType parameter) {
|
||||
parameterList.add(parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.util.demangler.ParameterReceiver
|
||||
*/
|
||||
@Override
|
||||
public List<GenericDemangledDataType> getParameters() {
|
||||
return new ArrayList<GenericDemangledDataType>(parameterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return type or null, if unspecified.
|
||||
* @return the return type or null, if unspecified
|
||||
*/
|
||||
public GenericDemangledDataType getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the calling convention or null, if unspecified.
|
||||
* @return the calling convention or null, if unspecified
|
||||
*/
|
||||
public String getCallingConvention() {
|
||||
return callingConvention;
|
||||
}
|
||||
|
||||
/** Special constructor where it has a templated type before the parameter list */
|
||||
public void setTemplatedConstructorType(String type) {
|
||||
this.templatedConstructorType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignature(boolean format) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if (!(returnType instanceof GenericDemangledFunctionPointer)) {
|
||||
buffer.append(specialPrefix == null ? "" : specialPrefix + " ");
|
||||
buffer.append(visibility == null || "global".equals(visibility) ? "" : visibility + " ");
|
||||
|
||||
if (isStatic()) {
|
||||
buffer.append("static ");
|
||||
}
|
||||
|
||||
if (virtual) {
|
||||
buffer.append("virtual ");
|
||||
}
|
||||
buffer.append(returnType == null ? "" : returnType.toSignature() + " ");
|
||||
}
|
||||
|
||||
buffer.append(callingConvention == null ? "" : callingConvention + " ");
|
||||
if (namespace != null) {
|
||||
buffer.append(namespace.toNamespace());
|
||||
}
|
||||
|
||||
buffer.append(name);
|
||||
if (template != null) {
|
||||
buffer.append(template.toTemplate());
|
||||
}
|
||||
|
||||
if (specialMidfix != null) {
|
||||
buffer.append('[').append(specialMidfix).append(']');
|
||||
}
|
||||
|
||||
// check for special case of 'conversion operator' where we only want to display '()' and
|
||||
// not (void)
|
||||
if (name.endsWith("()")) {
|
||||
if (name.equals("operator")) {
|
||||
buffer.append("()");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (templatedConstructorType != null) {
|
||||
buffer.append('<').append(templatedConstructorType).append('>');
|
||||
}
|
||||
|
||||
Iterator<GenericDemangledDataType> paramIterator = parameterList.iterator();
|
||||
buffer.append('(');
|
||||
String pad = format ? pad(buffer.length()) : "";
|
||||
if (!paramIterator.hasNext()) {
|
||||
buffer.append("void");
|
||||
}
|
||||
|
||||
while (paramIterator.hasNext()) {
|
||||
buffer.append(paramIterator.next().toSignature());
|
||||
if (paramIterator.hasNext()) {
|
||||
buffer.append(',');
|
||||
if (format) {
|
||||
buffer.append('\n');
|
||||
}
|
||||
buffer.append(pad);
|
||||
}
|
||||
}
|
||||
buffer.append(')');
|
||||
buffer.append(storageClass == null ? "" : " " + storageClass);
|
||||
}
|
||||
|
||||
if (returnType instanceof GenericDemangledFunctionPointer) {
|
||||
GenericDemangledFunctionPointer funcPtr = (GenericDemangledFunctionPointer) returnType;
|
||||
String partialSig = funcPtr.toSignature(buffer.toString());
|
||||
buffer = new StringBuffer();
|
||||
buffer.append(specialPrefix == null ? "" : specialPrefix + " ");
|
||||
buffer.append(visibility == null || "global".equals(visibility) ? "" : visibility + " ");
|
||||
if (virtual) {
|
||||
buffer.append("virtual ");
|
||||
}
|
||||
buffer.append(partialSig);
|
||||
}
|
||||
else {
|
||||
if (specialSuffix != null) {
|
||||
buffer.append(specialSuffix);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public String getParameterString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append('(');
|
||||
Iterator<GenericDemangledDataType> dditer = parameterList.iterator();
|
||||
while (dditer.hasNext()) {
|
||||
buffer.append(dditer.next().toSignature());
|
||||
if (dditer.hasNext()) {
|
||||
buffer.append(',');
|
||||
}
|
||||
}
|
||||
buffer.append(')');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
-273
@@ -1,273 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled function pointer.
|
||||
*/
|
||||
public class GenericDemangledFunctionPointer extends GenericDemangledDataType
|
||||
implements ParameterReceiver {
|
||||
|
||||
private static final String DEFAULT_NAME_PREFIX = "FuncDef";
|
||||
private static final String EMPTY_STRING = "";
|
||||
private static final Object NAMESPACE_DELIMITER = "::";
|
||||
private static int ID = 0;
|
||||
private GenericDemangledDataType returnType;
|
||||
protected String callingConvention;// __cdecl, __thiscall, etc.
|
||||
private List<GenericDemangledDataType> parameters = new ArrayList<>();
|
||||
|
||||
private boolean isConstPointer;
|
||||
private String parentName;
|
||||
private boolean isTrailingPointer64;
|
||||
|
||||
/**
|
||||
* Constructs a new demangled function pointer.
|
||||
*/
|
||||
public GenericDemangledFunctionPointer() {
|
||||
super(DEFAULT_NAME_PREFIX + nextID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return type.
|
||||
* @return the return type
|
||||
*/
|
||||
public GenericDemangledDataType getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the return type.
|
||||
* @param returnType the return type
|
||||
*/
|
||||
public void setReturnType(GenericDemangledDataType returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the calling convention or null, if unspecified.
|
||||
* @return the calling convention or null, if unspecified
|
||||
*/
|
||||
public String getCallingConvention() {
|
||||
return callingConvention;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function calling convention. For example, "__cdecl".
|
||||
* @param callingConvention the function calling convention
|
||||
*/
|
||||
public void setCallingConvention(String callingConvention) {
|
||||
this.callingConvention = callingConvention;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a parameters to the end of the parameter list for
|
||||
* this demangled function.
|
||||
* @param parameter the new parameter to add
|
||||
*/
|
||||
@Override
|
||||
public void addParameter(GenericDemangledDataType parameter) {
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the parameters for this demangled functions.
|
||||
* @return a list of the parameters for this demangled functions
|
||||
*/
|
||||
@Override
|
||||
public List<GenericDemangledDataType> getParameters() {
|
||||
return new ArrayList<>(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericDemangledDataType copy() {
|
||||
GenericDemangledFunctionPointer copy = new GenericDemangledFunctionPointer();
|
||||
copyInto(copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyInto(GenericDemangledDataType destination) {
|
||||
super.copyInto(destination);
|
||||
|
||||
GenericDemangledFunctionPointer source = this;
|
||||
|
||||
if (destination instanceof GenericDemangledFunctionPointer) {
|
||||
GenericDemangledFunctionPointer copySource = source;
|
||||
GenericDemangledFunctionPointer copyDestination =
|
||||
(GenericDemangledFunctionPointer) destination;
|
||||
|
||||
if (copySource.returnType != null) {
|
||||
copyDestination.returnType = copySource.returnType.copy();
|
||||
}
|
||||
for (GenericDemangledDataType parameter : copySource.parameters) {
|
||||
copyDestination.parameters.add(parameter.copy());
|
||||
}
|
||||
|
||||
copyDestination.callingConvention = copySource.callingConvention;
|
||||
|
||||
copyDestination.isConstPointer |= copySource.isConstPointer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSignature() {
|
||||
return toSignature(null);
|
||||
}
|
||||
|
||||
public String toSignature(String name) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
if (returnType != null) {
|
||||
buffer.append(returnType.toSignature()).append(SPACE);
|
||||
}
|
||||
|
||||
String s = getConventionPointerNameString(name);
|
||||
if (s.contains(" ") || s.isEmpty()) {
|
||||
// spaces--add parens
|
||||
buffer.append('(').append(s).append(')');
|
||||
}
|
||||
else {// this allows the '__cdecl' in templates to not have parens
|
||||
buffer.append(s);
|
||||
}
|
||||
|
||||
buffer.append('(');
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
buffer.append(parameters.get(i).toSignature());
|
||||
if (i < parameters.size() - 1) {
|
||||
buffer.append(',');
|
||||
}
|
||||
}
|
||||
buffer.append(')');
|
||||
|
||||
if (isConst()) {
|
||||
if (buffer.length() > 2) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
buffer.append(CONST);
|
||||
}
|
||||
|
||||
if (isVolatile()) {
|
||||
if (buffer.length() > 2) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
buffer.append(VOLATILE);
|
||||
}
|
||||
|
||||
if (isTrailingPointer64) {
|
||||
if (buffer.length() > 2) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
buffer.append(PTR64);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private String getConventionPointerNameString(String name) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append(callingConvention == null ? EMPTY_STRING : callingConvention);
|
||||
|
||||
int pointerLevels = getPointerLevels();
|
||||
if (pointerLevels > 0) {
|
||||
if (callingConvention != null) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
|
||||
addParentName(buffer);
|
||||
|
||||
for (int i = 0; i < pointerLevels; ++i) {
|
||||
buffer.append('*');
|
||||
}
|
||||
}
|
||||
|
||||
if (isConstPointer) {
|
||||
buffer.append(CONST);
|
||||
}
|
||||
|
||||
if (isPointer64()) {
|
||||
if (buffer.length() > 2) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
buffer.append(PTR64);
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
if (buffer.length() > 2) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
buffer.append(name);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private void addParentName(StringBuilder buffer) {
|
||||
if (parentName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parentName.startsWith(DEFAULT_NAME_PREFIX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer.length() > 2) {
|
||||
char lastChar = buffer.charAt(buffer.length() - 1);
|
||||
if (SPACE != lastChar) {
|
||||
buffer.append(SPACE);
|
||||
}
|
||||
}
|
||||
buffer.append(parentName).append(NAMESPACE_DELIMITER);
|
||||
}
|
||||
|
||||
public void setConstPointer() {
|
||||
isConstPointer = true;
|
||||
}
|
||||
|
||||
public boolean isConstPointer() {
|
||||
return isConstPointer;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName) {
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public String getParentName() {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public void setTrailingPointer64() {
|
||||
this.isTrailingPointer64 = true;// TODO get real construct name for this method/field
|
||||
}
|
||||
|
||||
public boolean isTrailingPointer64() {
|
||||
return isTrailingPointer64;
|
||||
}
|
||||
|
||||
public void clearPointer64() {
|
||||
this.isPointer64 = false;
|
||||
}
|
||||
|
||||
private synchronized static int nextID() {
|
||||
return ID++;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
public class GenericDemangledMethod extends GenericDemangledFunction {
|
||||
|
||||
public GenericDemangledMethod(String name) throws GenericDemangledException {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
/**
|
||||
* A class to represent a demangled object.
|
||||
*/
|
||||
public abstract class GenericDemangledObject {
|
||||
|
||||
protected static final String NAMESPACE_SEPARATOR = "::";
|
||||
protected static final String AT = "@";
|
||||
|
||||
protected static final String EMPTY_STRING = "";
|
||||
protected static final String SPACE = " ";
|
||||
|
||||
protected String originalMangled;
|
||||
protected String specialPrefix;
|
||||
protected String specialMidfix;
|
||||
protected String specialSuffix;
|
||||
protected GenericDemangledType namespace;
|
||||
protected String visibility;//public, protected, etc.
|
||||
protected String storageClass;//const, volatile, etc
|
||||
protected String name;
|
||||
protected boolean isConst;
|
||||
protected boolean isVolatile;
|
||||
protected boolean isStatic;
|
||||
protected boolean isVirtual;
|
||||
protected boolean isThunk;
|
||||
protected boolean isPointer64;
|
||||
// temp
|
||||
protected boolean isStruct;
|
||||
protected boolean isUnsigned;
|
||||
protected boolean isUnaligned;
|
||||
protected boolean isRestrict;
|
||||
protected String basedName;
|
||||
protected String memberScope;
|
||||
|
||||
private String signature;
|
||||
|
||||
/**
|
||||
* Returns the name of the demangled object.
|
||||
* @return the name of the demangled object
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isConst() {
|
||||
return isConst;
|
||||
}
|
||||
|
||||
public void setConst(boolean isConst) {
|
||||
this.isConst = isConst;
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return isVolatile;
|
||||
}
|
||||
|
||||
public void setVolatile(boolean isVolatile) {
|
||||
this.isVolatile = isVolatile;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isStatic;
|
||||
}
|
||||
|
||||
public void setStatic(boolean isStatic) {
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return isVirtual;
|
||||
}
|
||||
|
||||
public void setVirtual(boolean isVirtual) {
|
||||
this.isVirtual = isVirtual;
|
||||
}
|
||||
|
||||
public boolean isThunk() {
|
||||
return isThunk;
|
||||
}
|
||||
|
||||
public void setThunk(boolean isThunk) {
|
||||
this.isThunk = isThunk;
|
||||
}
|
||||
|
||||
public boolean isPointer64() {
|
||||
return isPointer64;
|
||||
}
|
||||
|
||||
public void setPointer64(boolean isPointer64) {
|
||||
this.isPointer64 = isPointer64;
|
||||
}
|
||||
|
||||
public void setUnsigned() {
|
||||
isUnsigned = true;
|
||||
}
|
||||
|
||||
public void setStruct() {
|
||||
isStruct = true;
|
||||
}
|
||||
|
||||
public void setUnaligned() {
|
||||
isUnaligned = true;
|
||||
}
|
||||
|
||||
public boolean isUnaligned() {
|
||||
return isUnaligned;
|
||||
}
|
||||
|
||||
public void setRestrict() {
|
||||
isRestrict = true;
|
||||
}
|
||||
|
||||
public boolean isRestrict() {
|
||||
return isRestrict;
|
||||
}
|
||||
|
||||
public String getBasedName() {
|
||||
return basedName;
|
||||
}
|
||||
|
||||
public void setBasedName(String basedName) {
|
||||
this.basedName = basedName;
|
||||
}
|
||||
|
||||
public String getMemberScope() {
|
||||
return memberScope;
|
||||
}
|
||||
|
||||
public void setMemberScope(String memberScope) {
|
||||
this.memberScope = memberScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the demangled object
|
||||
* @param name the new name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the original mangled name
|
||||
* @param mangled the original mangled name
|
||||
*/
|
||||
public void setOriginalMangled(String mangled) {
|
||||
this.originalMangled = mangled;
|
||||
}
|
||||
|
||||
public String getOriginalMangled() {
|
||||
return originalMangled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the namespace containing this demangled object.
|
||||
* @return the namespace containing this demangled object
|
||||
*/
|
||||
public GenericDemangledType getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param namespace
|
||||
*/
|
||||
public void setNamespace(GenericDemangledType namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public String getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
public void setVisibilty(String visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
public String getStorageClass() {
|
||||
return storageClass;
|
||||
}
|
||||
|
||||
public void setStorageClass(String storageClass) {
|
||||
this.storageClass = storageClass;
|
||||
}
|
||||
|
||||
public String getSpecialPrefix() {
|
||||
return specialPrefix;
|
||||
}
|
||||
|
||||
public void setSpecialPrefix(String special) {
|
||||
this.specialPrefix = special;
|
||||
}
|
||||
|
||||
public String getSpecialMidfix() {
|
||||
return specialMidfix;
|
||||
}
|
||||
|
||||
public void setSpecialMidfix(String chargeType) {
|
||||
this.specialMidfix = chargeType;
|
||||
}
|
||||
|
||||
public String getSpecialSuffix() {
|
||||
return specialSuffix;
|
||||
}
|
||||
|
||||
public void setSpecialSuffix(String specialSuffix) {
|
||||
this.specialSuffix = specialSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a complete signature for the demangled symbol.
|
||||
* <br>For example:
|
||||
* {@code "unsigned long foo"
|
||||
* "unsigned char * ClassA::getFoo(float, short *)"
|
||||
* "void * getBar(int **, MyStruct &)"}
|
||||
* <br><b>Note: based on the underlying mangling scheme, the
|
||||
* return type may or may not be specified in the signature.</b>
|
||||
* @param format true if signature should be pretty printed
|
||||
* @return a complete signature for the demangled symbol
|
||||
*/
|
||||
public abstract String getSignature(boolean format);
|
||||
|
||||
/**
|
||||
* Sets the signature. Calling this method will
|
||||
* override the auto-generated signature.
|
||||
* @param signature the signature
|
||||
*/
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSignature(false);
|
||||
}
|
||||
|
||||
protected String generatePlateComment() {
|
||||
return (signature == null) ? getSignature(true) : signature;
|
||||
}
|
||||
|
||||
protected String pad(int len) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (int i = 0; i < len; i++) {
|
||||
buffer.append(' ');
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 util.demangler;
|
||||
|
||||
public class GenericDemangledString extends GenericDemangledObject {
|
||||
private String string;
|
||||
private int length;
|
||||
private boolean unicode;
|
||||
|
||||
public GenericDemangledString(String string, int length, boolean unicode) {
|
||||
this.string = string;
|
||||
this.length = length;
|
||||
this.unicode = unicode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignature(boolean format) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if (specialPrefix != null) {
|
||||
buffer.append(specialPrefix + " for ");
|
||||
}
|
||||
buffer.append(string);
|
||||
if (specialSuffix != null) {
|
||||
buffer.append(" " + specialSuffix);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the demangled string.
|
||||
* @return the demangled string
|
||||
*/
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length in bytes of the demangled string.
|
||||
* @return the length in bytes of the demangled string
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the demangled string is unicode.
|
||||
* @return true if the demangled string is unicode
|
||||
*/
|
||||
public boolean isUnicode() {
|
||||
return unicode;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 util.demangler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GenericDemangledTemplate implements ParameterReceiver {
|
||||
private List<GenericDemangledDataType> parameters = new ArrayList<GenericDemangledDataType>();
|
||||
|
||||
public GenericDemangledTemplate() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParameter(GenericDemangledDataType parameter) {
|
||||
parameters.add(parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GenericDemangledDataType> getParameters() {
|
||||
return new ArrayList<GenericDemangledDataType>(parameters);
|
||||
}
|
||||
|
||||
public String toTemplate() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append('<');
|
||||
for (int i = 0; i < parameters.size(); ++i) {
|
||||
buffer.append(parameters.get(i).toSignature());
|
||||
if (i < parameters.size() - 1) {
|
||||
buffer.append(',');
|
||||
}
|
||||
}
|
||||
buffer.append('>');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toTemplate();
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
public class GenericDemangledType {
|
||||
private GenericDemangledType namespace;
|
||||
private String name;
|
||||
private GenericDemangledTemplate template;
|
||||
private boolean isConst;
|
||||
private boolean isVolatile;
|
||||
|
||||
public GenericDemangledType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isConst() {
|
||||
return isConst;
|
||||
}
|
||||
|
||||
public void setConst() {
|
||||
isConst = true;
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return isVolatile;
|
||||
}
|
||||
|
||||
public void setVolatile() {
|
||||
isVolatile = true;
|
||||
}
|
||||
|
||||
public GenericDemangledType getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public void setNamespace(GenericDemangledType namespace) {
|
||||
if (this == namespace) {
|
||||
throw new IllegalArgumentException("Attempt to set this.namespace == this!");
|
||||
}
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public GenericDemangledTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public void setTemplate(GenericDemangledTemplate template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public String toSignature() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if (namespace != null) {
|
||||
buffer.append(namespace.toNamespace());
|
||||
}
|
||||
buffer.append(name);
|
||||
if (template != null) {
|
||||
buffer.append(template.toTemplate());
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public String toNamespace() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if (namespace != null) {
|
||||
buffer.append(namespace.toNamespace());
|
||||
}
|
||||
buffer.append(name);
|
||||
if (template != null) {
|
||||
buffer.append(template.toTemplate());
|
||||
}
|
||||
buffer.append("::");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toSignature();
|
||||
}
|
||||
}
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
/* ###
|
||||
* 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 util.demangler;
|
||||
|
||||
/**
|
||||
* An interface to represent a demangled global variable.
|
||||
*/
|
||||
public class GenericDemangledVariable extends GenericDemangledObject {
|
||||
private GenericDemangledDataType datatype;
|
||||
|
||||
public GenericDemangledVariable(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setDatatype(GenericDemangledDataType datatype) {
|
||||
this.datatype = datatype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data type of this variable.
|
||||
* @return the data type of this variable
|
||||
*/
|
||||
public GenericDemangledDataType getDataType() {
|
||||
return datatype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSignature(boolean format) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append(visibility == null || "global".equals(visibility) ? EMPTY_STRING
|
||||
: visibility + SPACE);
|
||||
|
||||
if (isStatic()) {
|
||||
buffer.append("static ");
|
||||
}
|
||||
|
||||
String spacer = EMPTY_STRING;
|
||||
if (isUnsigned) {
|
||||
buffer.append("unsigned");
|
||||
spacer = SPACE;
|
||||
}
|
||||
|
||||
if (isStruct) {
|
||||
buffer.append("struct");
|
||||
spacer = SPACE;
|
||||
}
|
||||
|
||||
if (specialPrefix != null) {
|
||||
buffer.append(specialPrefix);
|
||||
spacer = SPACE;
|
||||
}
|
||||
|
||||
boolean hasName = (name != null) && !name.isEmpty();
|
||||
if (!(datatype instanceof GenericDemangledFunctionPointer)) {
|
||||
|
||||
if (datatype != null) {
|
||||
buffer.append(spacer);
|
||||
buffer.append(datatype.toSignature());
|
||||
spacer = SPACE;
|
||||
}
|
||||
}
|
||||
|
||||
// e.g., 'const' - this appears after the data type in MS land
|
||||
if (storageClass != null) {
|
||||
buffer.append(spacer).append(storageClass);
|
||||
spacer = SPACE;
|
||||
}
|
||||
|
||||
if (namespace != null) {
|
||||
|
||||
buffer.append(spacer);
|
||||
spacer = EMPTY_STRING;
|
||||
|
||||
buffer.append(namespace.toNamespace());
|
||||
|
||||
if (!hasName) {
|
||||
int end = buffer.length();
|
||||
buffer.delete(end - 2, end); // strip off the last namespace characters
|
||||
}
|
||||
}
|
||||
|
||||
if (hasName) {
|
||||
buffer.append(spacer);
|
||||
spacer = EMPTY_STRING;
|
||||
buffer.append(name);
|
||||
}
|
||||
|
||||
buffer.append(specialMidfix == null ? EMPTY_STRING : specialMidfix + SPACE);
|
||||
buffer.append(specialSuffix == null ? EMPTY_STRING : SPACE + specialSuffix);
|
||||
|
||||
if (datatype instanceof GenericDemangledFunctionPointer) {
|
||||
GenericDemangledFunctionPointer funcPtr = (GenericDemangledFunctionPointer) datatype;
|
||||
return funcPtr.toSignature(buffer.toString());
|
||||
}
|
||||
|
||||
if (isConst()) {
|
||||
buffer.append(" const");
|
||||
}
|
||||
|
||||
return buffer.toString().trim();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 util.demangler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A generic interface to represent
|
||||
* object that support parameters.
|
||||
*/
|
||||
public interface ParameterReceiver {
|
||||
/**
|
||||
* Adds the specified parameter to this object.
|
||||
* @param parameter the parameter to add
|
||||
*/
|
||||
public void addParameter(GenericDemangledDataType parameter);
|
||||
|
||||
/**
|
||||
* Returns the parameters added to this object.
|
||||
* @return the parameters added to this object
|
||||
*/
|
||||
public List<GenericDemangledDataType> getParameters();
|
||||
}
|
||||
Reference in New Issue
Block a user