mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
Merge remote-tracking branch 'origin/GP-3671_ghizard_simple_MDMang_improvements--SQUASHED'
This commit is contained in:
commit
a6d44ac41a
17 changed files with 245 additions and 350 deletions
|
@ -21,7 +21,6 @@ import java.util.List;
|
|||
|
||||
import mdemangler.MDContext.MDContextType;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.modifier.MDArrayBasicType;
|
||||
import mdemangler.datatype.modifier.MDCVMod;
|
||||
import mdemangler.naming.MDFragmentName;
|
||||
import mdemangler.naming.MDQualification;
|
||||
|
@ -478,10 +477,6 @@ public class MDMang {
|
|||
return fn.parseFragmentName_Md();
|
||||
}
|
||||
|
||||
public void appendArrayNotation(StringBuilder builder, MDArrayBasicType arrayBasicType) {
|
||||
// default empty
|
||||
}
|
||||
|
||||
public boolean allowMDTypeInfoParserDefault() {
|
||||
return false;
|
||||
}
|
||||
|
@ -529,6 +524,3 @@ public class MDMang {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -143,7 +143,8 @@ public class MDMangGhidra extends MDMang {
|
|||
object = processObjectCPP(objectCPP);
|
||||
object.setSpecialPrefix(((MDObjectBracket) item).getPrefix());
|
||||
}
|
||||
//TODO: put other objectReserved derivative types here and return something that Ghidra can use.
|
||||
//TODO: put other objectReserved derivative types here and return something that Ghidra
|
||||
// can use.
|
||||
else {
|
||||
object =
|
||||
new DemangledUnknown(mangledSource, demangledSource, objectReserved.toString());
|
||||
|
@ -740,9 +741,6 @@ public class MDMangGhidra extends MDMang {
|
|||
}
|
||||
return resultDataType;
|
||||
}
|
||||
else if (modifierType instanceof MDStdNullPtrType) {
|
||||
resultDataType.setName(datatype.toString());
|
||||
}
|
||||
else {
|
||||
// not pointer, reference, or array type
|
||||
if ((modifierType.getReferencedType() instanceof MDFunctionType)) {
|
||||
|
@ -819,6 +817,9 @@ public class MDMangGhidra extends MDMang {
|
|||
else if (datatype instanceof MDVarArgsType) {
|
||||
resultDataType.setVarArgs();
|
||||
}
|
||||
else if (datatype instanceof MDStdNullPtrType) {
|
||||
resultDataType.setName(datatype.toString());
|
||||
}
|
||||
else {
|
||||
// MDDataType
|
||||
// TODO MDW64Type needs repeated reference type parsing, just as modifier types need
|
||||
|
@ -852,6 +853,3 @@ public class MDMangGhidra extends MDMang {
|
|||
return dataType.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package mdemangler;
|
||||
|
||||
import mdemangler.datatype.modifier.MDArrayBasicType;
|
||||
import mdemangler.datatype.modifier.MDCVMod;
|
||||
import mdemangler.naming.MDFragmentName;
|
||||
import mdemangler.naming.MDQualification;
|
||||
|
@ -92,11 +91,6 @@ public class MDMangVS2015 extends MDMang {
|
|||
return fn.parseFragmentName_VS2All();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendArrayNotation(StringBuilder builder, MDArrayBasicType arrayBasicType) {
|
||||
arrayBasicType.appendArrayNotation(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowMDTypeInfoParserDefault() {
|
||||
return true;
|
||||
|
@ -118,6 +112,3 @@ public class MDMangVS2015 extends MDMang {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -38,7 +38,7 @@ public class MDDataTypeParser {
|
|||
* @param isHighest - boolean indicating whether something else modifies or names the data
|
||||
* type to be parsed, which impacts when certain overloaded CV modifiers can be applied.
|
||||
* @return - a type derived from MDDataType
|
||||
* @throws MDException
|
||||
* @throws MDException on parsing error
|
||||
*/
|
||||
public static MDDataType parseDataType(MDMang dmang, boolean isHighest) throws MDException {
|
||||
MDDataType dt;
|
||||
|
@ -46,7 +46,7 @@ public class MDDataTypeParser {
|
|||
switch (code) {
|
||||
case '?':
|
||||
dmang.increment();
|
||||
dt = new MDModifierType(dmang);
|
||||
dt = new MDQuestionModifierType(dmang);
|
||||
break;
|
||||
case 'X':
|
||||
// The wiki document says 'X' can be void or coclass, but we have never been able
|
||||
|
@ -72,7 +72,7 @@ public class MDDataTypeParser {
|
|||
* @param isHighest - boolean indicating whether something else modifies or names the data
|
||||
* type to be parsed, which impacts when certain overloaded CV modifiers can be applied.
|
||||
* @return - a type derived from MDDataType
|
||||
* @throws MDException
|
||||
* @throws MDException on parsing error
|
||||
*/
|
||||
public static MDDataType parsePrimaryDataType(MDMang dmang, boolean isHighest)
|
||||
throws MDException {
|
||||
|
@ -84,23 +84,15 @@ public class MDDataTypeParser {
|
|||
dt = parseSpecialExtendedType(dmang, isHighest);
|
||||
break;
|
||||
case 'A':
|
||||
dmang.increment();
|
||||
dt = new MDReferenceType(dmang, isHighest, false, false);
|
||||
break;
|
||||
case 'B':
|
||||
dmang.increment();
|
||||
MDReferenceType rt = new MDReferenceType(dmang);
|
||||
dt = rt;
|
||||
if (isHighest) {
|
||||
if (code == 'B') {
|
||||
rt.clearConst();
|
||||
rt.setVolatile();
|
||||
}
|
||||
else {
|
||||
rt.clearConst();
|
||||
rt.clearVolatile();
|
||||
}
|
||||
}
|
||||
dt = new MDReferenceType(dmang, isHighest, false, true);
|
||||
break;
|
||||
case MDMang.DONE:
|
||||
throw new MDException("Type code not expected: " + code);
|
||||
throw new MDException("PrimaryDataType: no data for type code");
|
||||
default:
|
||||
dt = parseBasicDataType(dmang, isHighest);
|
||||
break;
|
||||
|
@ -116,7 +108,7 @@ public class MDDataTypeParser {
|
|||
* @param isHighest - boolean indicating whether something else modifies or names the data
|
||||
* type to be parsed, which impacts when certain overloaded CV modifiers can be applied.
|
||||
* @return - a type derived from MDDataType
|
||||
* @throws MDException
|
||||
* @throws MDException on parsing error
|
||||
*/
|
||||
public static MDDataType parseSpecialExtendedType(MDMang dmang, boolean isHighest)
|
||||
throws MDException {
|
||||
|
@ -137,13 +129,10 @@ public class MDDataTypeParser {
|
|||
dt = new MDDataReferenceType(dmang);
|
||||
break;
|
||||
case 'Q':
|
||||
dt = new MDDataRightReferenceType(dmang, isHighest, false, false);
|
||||
break;
|
||||
case 'R':
|
||||
MDDataRightReferenceType drrt = new MDDataRightReferenceType(dmang);
|
||||
dt = drrt;
|
||||
if (isHighest && (code == 'R')) {
|
||||
drrt.clearConst();
|
||||
drrt.setVolatile();
|
||||
}
|
||||
dt = new MDDataRightReferenceType(dmang, isHighest, false, true);
|
||||
break;
|
||||
case 'T':
|
||||
dt = new MDStdNullPtrType(dmang);
|
||||
|
@ -151,8 +140,11 @@ public class MDDataTypeParser {
|
|||
case 'Y': // UINFO: QualifiedName only (no type)
|
||||
// TODO: implementation. Try symbol like "?var@@3$$Yabc@@"
|
||||
case 'S': // invalid (UINFO)
|
||||
case 'V': // Empty type parameter pack?
|
||||
case 'Z': // End template parameter pack?
|
||||
case 'F': // Investigate $$F in CVMod processing... does it belong here?
|
||||
default:
|
||||
throw new MDException("TemplateParameterModifierType unrecognized code: " + code);
|
||||
throw new MDException("SpecialDataType: unrecognized code: " + code);
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
@ -163,7 +155,7 @@ public class MDDataTypeParser {
|
|||
* @param isHighest - boolean indicating whether something else modifies or names the data
|
||||
* type to be parsed, which impacts when certain overloaded CV modifiers can be applied.
|
||||
* @return - a type derived from MDDataType
|
||||
* @throws MDException
|
||||
* @throws MDException on parsing error
|
||||
*/
|
||||
public static MDDataType parseBasicDataType(MDMang dmang, boolean isHighest)
|
||||
throws MDException {
|
||||
|
@ -214,32 +206,17 @@ public class MDDataTypeParser {
|
|||
case 'O':
|
||||
dt = new MDLongDoubleDataType(dmang);
|
||||
break;
|
||||
case 'Q':
|
||||
case 'R':
|
||||
case 'S':
|
||||
case 'P':
|
||||
MDPointerType pt = new MDPointerType(dmang);
|
||||
dt = pt;
|
||||
if (isHighest) {
|
||||
switch (code) {
|
||||
case 'P':
|
||||
pt.clearConst();
|
||||
pt.clearVolatile();
|
||||
break;
|
||||
case 'R':
|
||||
pt.clearConst();
|
||||
pt.setVolatile();
|
||||
dt = new MDPointerType(dmang, isHighest, false, false);
|
||||
break;
|
||||
case 'Q':
|
||||
pt.setConst();
|
||||
pt.clearVolatile();
|
||||
dt = new MDPointerType(dmang, isHighest, true, false);
|
||||
break;
|
||||
case 'R':
|
||||
dt = new MDPointerType(dmang, isHighest, false, true);
|
||||
break;
|
||||
case 'S':
|
||||
pt.setConst();
|
||||
pt.setVolatile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
dt = new MDPointerType(dmang, isHighest, true, true);
|
||||
break;
|
||||
case 'T':
|
||||
dt = new MDUnionType(dmang);
|
||||
|
@ -314,6 +291,8 @@ public class MDDataTypeParser {
|
|||
case 'O':
|
||||
// TODO: possibly change this to ExtendedDataType (currently 'O' ArrayType
|
||||
// is a "ModifiedType")--investigate further
|
||||
// 20230731: note that this class uses a CVMod type, which support its
|
||||
// being a MDModifierType.
|
||||
dt = new MDArrayBasicType(dmang);
|
||||
break;
|
||||
case 'P':
|
||||
|
@ -365,9 +344,9 @@ public class MDDataTypeParser {
|
|||
// dt.setTypeName("{MDMANG_UNK_EXTENDEDTYPE:" + tn.emit() + "}"); // 20160728 temp
|
||||
break;
|
||||
case MDMang.DONE:
|
||||
throw new MDException("Type code not expected: " + code);
|
||||
throw new MDException("Extended BasicDataType: no data for type code");
|
||||
default:
|
||||
throw new MDException("Type code not expected: " + code);
|
||||
throw new MDException("Extended BasicDataType: unrecognized code: " + code);
|
||||
}
|
||||
break;
|
||||
case '@':
|
||||
|
@ -380,13 +359,10 @@ public class MDDataTypeParser {
|
|||
dt = dtv;
|
||||
break;
|
||||
case MDMang.DONE:
|
||||
throw new MDException("Type code not expected: " + code);
|
||||
throw new MDException("BasicDataType: no data for type code");
|
||||
default:
|
||||
throw new MDException("Type code not expected: " + code);
|
||||
throw new MDException("BasicDataType: unrecognized code: " + code);
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -15,66 +15,50 @@
|
|||
*/
|
||||
package mdemangler.datatype.extended;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import mdemangler.*;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDDataTypeParser;
|
||||
import mdemangler.datatype.modifier.MDModifierType;
|
||||
|
||||
/**
|
||||
* This class represents an "array referenced" data type within a Microsoft mangled symbol.
|
||||
*/
|
||||
public class MDArrayReferencedType extends MDModifierType {
|
||||
public class MDArrayReferencedType extends MDDataType {
|
||||
|
||||
// public static final String ARR_NOTATION = "[]";
|
||||
private String arrayString = "";
|
||||
// protected MDDataType refDataType;
|
||||
|
||||
private MDDataType refDataType;
|
||||
|
||||
public MDArrayReferencedType(MDMang dmang) {
|
||||
super(dmang, 0);
|
||||
// cvMod.setOtherType();
|
||||
cvMod.clearProperties();
|
||||
cvMod.clearCV();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will possibly become private and also removed
|
||||
* from the base class. It is used to set the arrayString.
|
||||
* @param arrayString -- null not permitted.
|
||||
*/
|
||||
@Override
|
||||
public void setArrayString(String arrayString) {
|
||||
this.arrayString = Objects.requireNonNull(arrayString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArrayString() {
|
||||
return arrayString;
|
||||
}
|
||||
|
||||
public MDDataType getReferencedType() {
|
||||
return refDataType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
if (dmang.peek() == 'Y') {
|
||||
dmang.parseInfoPush(0, "Array Property");
|
||||
dmang.increment();
|
||||
MDEncodedNumber n1 = new MDEncodedNumber(dmang);
|
||||
n1.parse();
|
||||
int num = n1.getValue().intValue();
|
||||
String arrString = "";
|
||||
arrayString = "";
|
||||
while (num-- > 0) {
|
||||
MDEncodedNumber n2 = new MDEncodedNumber(dmang);
|
||||
n2.parse();
|
||||
arrString = arrString + '[' + n2 + ']';
|
||||
arrayString = arrayString + '[' + n2 + ']';
|
||||
}
|
||||
setArrayString(arrString);
|
||||
// refDataType = MDDataTypeParser.parsePrimaryDataType(dmang,
|
||||
// false);
|
||||
// refDataType.setIsReferencedType();
|
||||
// //20170523 refDataType.setIsArray();
|
||||
// dmang.parse(refDataType);
|
||||
refType = MDDataTypeParser.parsePrimaryDataType(dmang, false);
|
||||
// refType.setIsReferencedType();
|
||||
// 20170523 refType.setIsArray();
|
||||
refType.parse();
|
||||
dmang.parseInfoPop();
|
||||
|
||||
refDataType = MDDataTypeParser.parsePrimaryDataType(dmang, false);
|
||||
refDataType.parse();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +69,6 @@ public class MDArrayReferencedType extends MDModifierType {
|
|||
dmang.appendString(builder, ")");
|
||||
}
|
||||
dmang.appendString(builder, getArrayString());
|
||||
// refDataType.insert(builder);
|
||||
refType.insert(builder);
|
||||
refDataType.insert(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,9 @@ import mdemangler.functiontype.MDFunctionType;
|
|||
// TODO: Consider making this an extension of ExtendedDataType (fits with the
|
||||
// other '_X' types.
|
||||
// The array type, however, modifies other types...???
|
||||
// 20230731: note that this class uses a CVMod type, which supports its being a MDModifierType.
|
||||
public class MDArrayBasicType extends MDModifierType {
|
||||
|
||||
public static final String ARR_NOTATION = "[]";
|
||||
|
||||
public MDArrayBasicType(MDMang dmang) {
|
||||
super(dmang);
|
||||
}
|
||||
|
@ -39,10 +38,6 @@ public class MDArrayBasicType extends MDModifierType {
|
|||
super.parseInternal();
|
||||
}
|
||||
|
||||
public void appendArrayNotation(StringBuilder builder) {
|
||||
builder.append(ARR_NOTATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void insertCVMod(StringBuilder builder) {
|
||||
// do nothing.
|
||||
|
@ -51,22 +46,20 @@ public class MDArrayBasicType extends MDModifierType {
|
|||
@Override
|
||||
protected void insertReferredType(StringBuilder builder) {
|
||||
StringBuilder arrayBuilder = new StringBuilder();
|
||||
arrayBuilder.append(ARR_NOTATION);
|
||||
arrayBuilder.append(getArrayString());
|
||||
arrayBuilder.append("[]");
|
||||
MDType dt = this.refType;
|
||||
// TODO: see if we can change from Pointer and Ref to just ModilfierType
|
||||
// on second
|
||||
// component of if.
|
||||
// TODO: confirm and change cast to MDPointerType
|
||||
// while ((dt instanceof MDPointerType) &&
|
||||
// !((MDModifierType) dt).cvMod.isFunctionPointerType()) {
|
||||
// TODO: confirm and change cast to MDPointerType
|
||||
while (((dt instanceof MDPointerType) || (dt instanceof MDArrayReferencedType)) &&
|
||||
!((MDModifierType) dt).cvMod.isFunctionPointerType()) {
|
||||
// MDMANG SPECIALIZATION USED.
|
||||
// dmang.appendArrayNotation(arrayBuilder, this);
|
||||
arrayBuilder.append(((MDModifierType) dt).getArrayString());
|
||||
dt = ((MDModifierType) dt).refType;
|
||||
while (true) {
|
||||
if (dt instanceof MDArrayReferencedType mdArrayRefType) {
|
||||
arrayBuilder.append(mdArrayRefType.getArrayString());
|
||||
dt = mdArrayRefType.getReferencedType();
|
||||
}
|
||||
else if (dt instanceof MDPointerType pointerType &&
|
||||
!pointerType.getCVMod().isFunctionPointerType()) {
|
||||
dt = pointerType.getReferencedType();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((refType instanceof MDFunctionType) && (builder.length() > 0)) {
|
||||
((MDFunctionType) refType).setFromModifier();
|
||||
|
@ -77,61 +70,4 @@ public class MDArrayBasicType extends MDModifierType {
|
|||
dmang.appendString(builder, arrayBuilder.toString());
|
||||
}
|
||||
|
||||
// Parses, but ignores CVEIF, member and based components of all types in
|
||||
// the chain of
|
||||
// nested types.
|
||||
// @Override
|
||||
// public void insert(StringBuilder builder) {
|
||||
// StringBuilder arrayBuilder = new StringBuilder();
|
||||
// arrayBuilder.append(ARR_NOTATION);
|
||||
// arrayBuilder.append(getArrayString());
|
||||
// MDType dt = this.refType;
|
||||
// //TODO: see if we can change from Pointer and Ref to just ModilfierType
|
||||
// on second component of if.
|
||||
//// while ((dt instanceof MDPointerType) &&
|
||||
//// !((MDModifierType) dt).cvMod.isFunctionPointerType()) { //TODO: confirm
|
||||
// and change cast to MDPointerType
|
||||
// while (((dt instanceof MDPointerType) || (dt instanceof
|
||||
// MDArrayReferencedType)) &&
|
||||
// !((MDModifierType) dt).cvMod.isFunctionPointerType()) { //TODO: confirm
|
||||
// and change cast to MDPointerType
|
||||
// //MDMANG SPECIALIZATION USED.
|
||||
// //dmang.appendArrayNotation(arrayBuilder, this);
|
||||
// arrayBuilder.append(((MDModifierType) dt).getArrayString());
|
||||
// dt = ((MDModifierType) dt).refType;
|
||||
// }
|
||||
// if ((refType instanceof MDFunctionType) && (builder.length() > 0)) {
|
||||
// ((MDFunctionType) refType).setFromModifier();
|
||||
// }
|
||||
// dt.insert(builder);
|
||||
// //Following to to clean the Based5 "bug" if seen. See comments in MDBasedAttribute.
|
||||
// dmang.cleanOutput(builder);
|
||||
// dmang.appendString(builder, arrayBuilder.toString());
|
||||
// }
|
||||
|
||||
// //Parses, but ignores CVEIF, member and based components of all types in
|
||||
// the chain of
|
||||
// nested types.
|
||||
// @Override
|
||||
// public void insert(StringBuilder builder) {
|
||||
// //StringBuilder arrayBuilder = new StringBuilder();
|
||||
// builder.append(ARR_NOTATION);
|
||||
// //arrayBuilder.append(getArrayString());
|
||||
// MDType dt = this.refType;
|
||||
// //TODO: see if we can change from Pointer and Ref to just ModilfierType
|
||||
// on second component of if.
|
||||
//// while ((dt instanceof MDPointerType) &&
|
||||
//// !((MDModifierType) dt).cvMod.isFunctionPointerType()) { //TODO: confirm
|
||||
// and change cast to MDPointerType
|
||||
//// builder.append(((MDModifierType) dt).getArrayString());
|
||||
//// dt = ((MDModifierType) dt).refType;
|
||||
//// }
|
||||
// if ((refType instanceof MDFunctionType) && (builder.length() > 0)) {
|
||||
// ((MDFunctionType) refType).setFromModifier();
|
||||
// }
|
||||
// dt.insert(builder);
|
||||
// //Following to to clean the Based5 "bug" if seen.
|
||||
// dmang.cleanOutput(builder); See comments in MDBasedAttribute.
|
||||
// //dmang.appendString(builder, arrayBuilder.toString());
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -25,12 +25,6 @@ import mdemangler.naming.MDQualification;
|
|||
* type within a Microsoft mangled symbol.
|
||||
*/
|
||||
public class MDCVMod extends MDParsableItem {
|
||||
public static final char SPACE = ' ';
|
||||
|
||||
public static final char POINTER_CHAR = '*';
|
||||
public static final char REFERENCE_CHAR = '&';
|
||||
public static final char CARROT_CHAR = '^';
|
||||
public static final char PERCENT_CHAR = '%';
|
||||
// private static final String FUNCTIONPOINTER = "*"; // TODO: eliminate
|
||||
// with
|
||||
// // old code
|
||||
|
@ -39,7 +33,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
// // old code
|
||||
private static final String POINTER = "*";
|
||||
private static final String AMPERSAND = "&";
|
||||
private static final String CARROT = "^";
|
||||
private static final String CARET = "^";
|
||||
private static final String PERCENT = "%";
|
||||
private static final String DOUBLE_AMPERSAND = "&&";
|
||||
|
||||
|
@ -133,7 +127,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
pointer,
|
||||
reference,
|
||||
rightreference,
|
||||
carrot, // TODO: eliminate with old code
|
||||
caret, // TODO: eliminate with old code
|
||||
percent, // TODO: eliminate with old code
|
||||
functionpointer, // TODO: eliminate with old code
|
||||
functionreference, // TODO: eliminate with old code
|
||||
|
@ -160,8 +154,8 @@ public class MDCVMod extends MDParsableItem {
|
|||
modType = CvModifierType.rightreference;
|
||||
}
|
||||
|
||||
// public void setCarrotType() {
|
||||
// modType = cvModifierType.carrot;
|
||||
// public void setCaretType() {
|
||||
// modType = cvModifierType.caret;
|
||||
// }
|
||||
//
|
||||
// public void setPercentType() {
|
||||
|
@ -466,7 +460,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
dmang.increment();
|
||||
setGC();
|
||||
// if (isPointerType()) {
|
||||
// setCarrotType();
|
||||
// setCaretType();
|
||||
// }
|
||||
// else if (isReferenceType()) {
|
||||
// setPercentType();
|
||||
|
@ -476,7 +470,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
dmang.increment();
|
||||
// if ((modType == cvModifierType.pointer) ||
|
||||
// (modType == cvModifierType.functionpointer) ||
|
||||
// (modType == cvModifierType.carrot) ||
|
||||
// (modType == cvModifierType.caret) ||
|
||||
// (modType == cvModifierType.percent) ||
|
||||
// (modType == cvModifierType.reference) ||
|
||||
// (modType == cvModifierType.functionreference)) {
|
||||
|
@ -814,7 +808,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
annotation = PERCENT;
|
||||
}
|
||||
else if (isGC()) {
|
||||
annotation = CARROT;
|
||||
annotation = CARET;
|
||||
}
|
||||
else {
|
||||
annotation = POINTER;
|
||||
|
@ -875,7 +869,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
// annotation = PERCENT;
|
||||
// }
|
||||
// else if (isGC()) {
|
||||
// annotation = CARROT;
|
||||
// annotation = CARET;
|
||||
// }
|
||||
// else {
|
||||
// annotation = POINTER;
|
||||
|
@ -953,7 +947,7 @@ public class MDCVMod extends MDParsableItem {
|
|||
// annotation = PERCENT;
|
||||
// }
|
||||
// else if (isGC()) {
|
||||
// annotation = CARROT;
|
||||
// annotation = CARET;
|
||||
// }
|
||||
// else {
|
||||
// annotation = POINTER;
|
||||
|
|
|
@ -34,12 +34,4 @@ public class MDDataReferenceType extends MDModifierType {
|
|||
super.parseInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
// Override because Array is not allowed.
|
||||
protected void parseArrayProperty() throws MDException {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -19,27 +19,41 @@ import mdemangler.MDException;
|
|||
import mdemangler.MDMang;
|
||||
|
||||
/**
|
||||
* This class represents a "data ref ref" data type within a Microsoft mangled symbol.
|
||||
* This class represents a "data right reference" data type within a Microsoft mangled symbol.
|
||||
* It is one of a number of "extended" data types not originally planned by Microsoft.
|
||||
*/
|
||||
// Added 20170330
|
||||
// TODO: Not sure what this is and Not sure of all the intricacies.
|
||||
// ...but checked that these are all allowed: EIF, CV (ABCD), array property, maanaged
|
||||
// properties
|
||||
// TODO: Seems very closely related to a "reference" type, so might find a way to merge
|
||||
// reference types together.
|
||||
public class MDDataRightReferenceType extends MDModifierType {
|
||||
|
||||
public MDDataRightReferenceType(MDMang dmang) {
|
||||
public MDDataRightReferenceType(MDMang dmang, boolean isHighest, boolean isConst,
|
||||
boolean isVolatile) {
|
||||
super(dmang, 3);
|
||||
if (isHighest) {
|
||||
setConst(isConst);
|
||||
setVolatile(isVolatile);
|
||||
}
|
||||
else {
|
||||
setConst(false);
|
||||
setVolatile(false);
|
||||
}
|
||||
cvMod.setRightReferenceTemplateParameter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
cvMod.setRightReferenceTemplateParameter();
|
||||
super.parseInternal();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
@Override
|
||||
public void insertCVMod(StringBuilder builder) {
|
||||
if (cvMod.isFunction()) {
|
||||
StringBuilder cvBuilder = new StringBuilder();
|
||||
cvMod.insert(cvBuilder);
|
||||
dmang.insertString(builder, cvBuilder.toString());
|
||||
}
|
||||
else {
|
||||
cvMod.insert(builder);
|
||||
}
|
||||
// Following to to clean the Based5 "bug" if seen. See comments in MDBasedAttribute.
|
||||
dmang.cleanOutput(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,19 +27,13 @@ import mdemangler.naming.MDQualification;
|
|||
*/
|
||||
// TODO: Consider looking at getPtrRefDataType()
|
||||
public class MDModifiedTypeParser {
|
||||
public static final char SPACE = ' ';
|
||||
|
||||
public static final char POINTER_CHAR = '*';
|
||||
public static final char REFERENCE_CHAR = '&';
|
||||
public static final char CARROT_CHAR = '^';
|
||||
public static final char PERCENT_CHAR = '%';
|
||||
// private static final String FUNCTIONPOINTER = "*"; //TODO: eliminate with
|
||||
// old code
|
||||
// private static final String FUNCTIONREFERENCE = "&"; //TODO: eliminate
|
||||
// with old code
|
||||
// private static final String POINTER = "*";
|
||||
// private static final String REFERENCE = "&";
|
||||
// private static final String CARROT = "^";
|
||||
// private static final String CARET = "^";
|
||||
// private static final String PERCENT = "%";
|
||||
// private static final String REFREF = "&&";
|
||||
|
||||
|
@ -128,7 +122,7 @@ public class MDModifiedTypeParser {
|
|||
pointer,
|
||||
reference,
|
||||
rightreference,
|
||||
carrot, // TODO: eliminate with old code
|
||||
caret, // TODO: eliminate with old code
|
||||
percent, // TODO: eliminate with old code
|
||||
functionpointer, // TODO: eliminate with old code
|
||||
functionreference, // TODO: eliminate with old code
|
||||
|
@ -154,8 +148,8 @@ public class MDModifiedTypeParser {
|
|||
modType = CvModifierType.rightreference;
|
||||
}
|
||||
|
||||
// public void setCarrotType() {
|
||||
// modType = cvModifierType.carrot;
|
||||
// public void setCaretType() {
|
||||
// modType = cvModifierType.caret;
|
||||
// }
|
||||
//
|
||||
// public void setPercentType() {
|
||||
|
@ -384,7 +378,7 @@ public class MDModifiedTypeParser {
|
|||
dmang.increment();
|
||||
setGC();
|
||||
// if (isPointerType()) {
|
||||
// setCarrotType();
|
||||
// setCaretType();
|
||||
// }
|
||||
// else if (isReferenceType()) {
|
||||
// setPercentType();
|
||||
|
@ -394,7 +388,7 @@ public class MDModifiedTypeParser {
|
|||
dmang.increment();
|
||||
// if ((modType == cvModifierType.pointer) ||
|
||||
// (modType == cvModifierType.functionpointer) ||
|
||||
// (modType == cvModifierType.carrot) ||
|
||||
// (modType == cvModifierType.caret) ||
|
||||
// (modType == cvModifierType.percent) ||
|
||||
// (modType == cvModifierType.reference) ||
|
||||
// (modType == cvModifierType.functionreference)) {
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
package mdemangler.datatype.modifier;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import mdemangler.*;
|
||||
import mdemangler.datatype.*;
|
||||
import mdemangler.datatype.extended.MDArrayReferencedType;
|
||||
|
@ -28,7 +26,7 @@ import mdemangler.functiontype.MDFunctionType;
|
|||
* of the other types.
|
||||
*/
|
||||
// TODO: 20160126: Maybe is should extend MDType which extends MDDT.
|
||||
public class MDModifierType extends MDDataType {
|
||||
public abstract class MDModifierType extends MDDataType {
|
||||
public static final char SPACE = ' ';
|
||||
private static final String CONST = "const";
|
||||
private static final String VOLATILE = "volatile";
|
||||
|
@ -42,10 +40,6 @@ public class MDModifierType extends MDDataType {
|
|||
protected Boolean hasCVMod = true; // 20160329
|
||||
protected MDType refType;
|
||||
|
||||
// Other special types
|
||||
// private boolean isArray;
|
||||
protected String arrayString = "";
|
||||
|
||||
// private String modifierTypeName = "";
|
||||
|
||||
public MDModifierType(MDMang dmang) {
|
||||
|
@ -110,13 +104,8 @@ public class MDModifierType extends MDDataType {
|
|||
// }
|
||||
|
||||
// @Override
|
||||
public void setConst() {
|
||||
isConst = true;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public void clearConst() {
|
||||
isConst = false;
|
||||
public void setConst(boolean isConst) {
|
||||
this.isConst = isConst;
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
@ -125,13 +114,8 @@ public class MDModifierType extends MDDataType {
|
|||
}
|
||||
|
||||
// @Override
|
||||
public void setVolatile() {
|
||||
isVolatile = true;
|
||||
}
|
||||
|
||||
// @Override
|
||||
public void clearVolatile() {
|
||||
isVolatile = false;
|
||||
public void setVolatile(boolean isVolatile) {
|
||||
this.isVolatile = isVolatile;
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
@ -160,7 +144,7 @@ public class MDModifierType extends MDDataType {
|
|||
}
|
||||
|
||||
protected MDDataType parseReferencedType() throws MDException {
|
||||
return MDDataTypeParser.parsePrimaryDataType(dmang, false);
|
||||
return MDDataTypeParser.parseBasicDataType(dmang, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -177,9 +161,9 @@ public class MDModifierType extends MDDataType {
|
|||
refType.parse();
|
||||
// 20160819 if (managedProperty == null ) {
|
||||
// if (cvMod.isPointerType() || cvMod.isReferenceType()) {
|
||||
// //20160819: might need to add more (carrot, percent)
|
||||
// //20160819: might need to add more (caret, percent)
|
||||
// if (cvMod.isFunctionPointerType() || cvMod.isReferenceType()) {
|
||||
// //20160819: might need to add more (carrot, percent)
|
||||
// //20160819: might need to add more (caret, percent)
|
||||
// ((MDFunctionType) refType).setFromModifier();
|
||||
// }
|
||||
// 20160819 if (cvMod.isFunctionPointer()) {
|
||||
|
@ -214,56 +198,12 @@ public class MDModifierType extends MDDataType {
|
|||
// 20170418 dmang.popContext();
|
||||
}
|
||||
|
||||
protected void parseArrayProperty() throws MDException {
|
||||
if (dmang.peek() == 'Y') {
|
||||
dmang.parseInfoPush(0, "Array Property");
|
||||
dmang.increment();
|
||||
MDEncodedNumber n1 = new MDEncodedNumber(dmang);
|
||||
n1.parse();
|
||||
int num = n1.getValue().intValue();
|
||||
String arrString = "";
|
||||
while (num-- > 0) {
|
||||
MDEncodedNumber n2 = new MDEncodedNumber(dmang);
|
||||
n2.parse();
|
||||
arrString = arrString + '[' + n2 + ']';
|
||||
}
|
||||
setArrayString(arrString);
|
||||
dmang.parseInfoPop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will possibly be removed from this class when we
|
||||
* determine how to only use it in MDArrayReference. It is used
|
||||
* to set the arrayString.
|
||||
* @param arrayString -- null not permitted.
|
||||
*/
|
||||
public void setArrayString(String arrayString) {
|
||||
this.arrayString = Objects.requireNonNull(arrayString);
|
||||
}
|
||||
|
||||
public String getArrayString() {
|
||||
return arrayString;
|
||||
}
|
||||
|
||||
protected void insertCVMod(StringBuilder builder) {
|
||||
cvMod.insert(builder);
|
||||
// Following to to clean the Based5 "bug" if seen. See comments in MDBasedAttribute.
|
||||
dmang.cleanOutput(builder); // 20170714
|
||||
}
|
||||
|
||||
public void insertArrayString(StringBuilder builder) {
|
||||
// This is from 'Y' optional prefix
|
||||
// TODO: check if this should also apply to managed properties.
|
||||
if (!arrayString.isEmpty()) {
|
||||
if (!dmang.isEffectivelyEmpty(builder)) {
|
||||
dmang.insertString(builder, "(");
|
||||
dmang.appendString(builder, ")");
|
||||
}
|
||||
dmang.appendString(builder, getArrayString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void insertReferredType(StringBuilder builder) {
|
||||
refType.insert(builder);
|
||||
}
|
||||
|
@ -383,6 +323,3 @@ public class MDModifierType extends MDDataType {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -17,30 +17,30 @@ package mdemangler.datatype.modifier;
|
|||
|
||||
import mdemangler.MDException;
|
||||
import mdemangler.MDMang;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDDataTypeParser;
|
||||
|
||||
/**
|
||||
* This class represents a "pointer" data type within a Microsoft mangled symbol.
|
||||
*/
|
||||
public class MDPointerType extends MDModifierType {
|
||||
|
||||
public MDPointerType(MDMang dmang) {
|
||||
public MDPointerType(MDMang dmang, boolean isHighest, boolean isConst, boolean isVolatile) {
|
||||
super(dmang);
|
||||
if (isHighest) {
|
||||
setConst(isConst);
|
||||
setVolatile(isVolatile);
|
||||
}
|
||||
else {
|
||||
setConst(false);
|
||||
setVolatile(false);
|
||||
}
|
||||
cvMod.setPointerType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
// cvMod.setPointerType();
|
||||
super.parseInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MDDataType parseReferencedType() throws MDException {
|
||||
return MDDataTypeParser.parseBasicDataType(dmang, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertCVMod(StringBuilder builder) {
|
||||
if (cvMod.isFunction()) {
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* ###
|
||||
* 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 mdemangler.datatype.modifier;
|
||||
|
||||
import mdemangler.MDException;
|
||||
import mdemangler.MDMang;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDDataTypeParser;
|
||||
|
||||
/**
|
||||
* This class represents a modifier data type coded with a question mark within a Microsoft mangled
|
||||
* symbol.
|
||||
*/
|
||||
public class MDQuestionModifierType extends MDModifierType {
|
||||
|
||||
public MDQuestionModifierType(MDMang dmang) {
|
||||
super(dmang);
|
||||
cvMod.setQuestionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
super.parseInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MDDataType parseReferencedType() throws MDException {
|
||||
return MDDataTypeParser.parsePrimaryDataType(dmang, false);
|
||||
}
|
||||
}
|
|
@ -17,8 +17,6 @@ package mdemangler.datatype.modifier;
|
|||
|
||||
import mdemangler.MDException;
|
||||
import mdemangler.MDMang;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDDataTypeParser;
|
||||
|
||||
/**
|
||||
* This class represents a "reference" data type within a Microsoft mangled symbol.
|
||||
|
@ -30,22 +28,24 @@ public class MDReferenceType extends MDModifierType {
|
|||
// private static final String modifierTypeName = "&";
|
||||
// private static final String modifierTypeName = "& ";
|
||||
|
||||
public MDReferenceType(MDMang dmang) {
|
||||
public MDReferenceType(MDMang dmang, boolean isHighest, boolean isConst, boolean isVolatile) {
|
||||
super(dmang);
|
||||
if (isHighest) {
|
||||
setConst(isConst);
|
||||
setVolatile(isVolatile);
|
||||
}
|
||||
else {
|
||||
setConst(false);
|
||||
setVolatile(false);
|
||||
}
|
||||
cvMod.setReferenceType(); // TODO: where should this go? remove constructor?
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
// cvMod.setReferenceType();
|
||||
super.parseInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MDDataType parseReferencedType() throws MDException {
|
||||
return MDDataTypeParser.parseBasicDataType(dmang, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertCVMod(StringBuilder builder) {
|
||||
if (cvMod.isFunction()) {
|
||||
|
|
|
@ -15,32 +15,21 @@
|
|||
*/
|
||||
package mdemangler.datatype.modifier;
|
||||
|
||||
import mdemangler.MDException;
|
||||
import mdemangler.MDMang;
|
||||
import mdemangler.datatype.extended.MDExtendedType;
|
||||
|
||||
/**
|
||||
* This class represents a std::nullptr_t type within a Microsoft mangled symbol.
|
||||
* It is one of a number of "extended" data types not originally planned by Microsoft.
|
||||
*/
|
||||
public class MDStdNullPtrType extends MDModifierType {
|
||||
|
||||
private static final String modifierTypeName = "std::nullptr_t";
|
||||
public class MDStdNullPtrType extends MDExtendedType {
|
||||
|
||||
public MDStdNullPtrType(MDMang dmang) {
|
||||
super(dmang, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void parseInternal() throws MDException {
|
||||
cvMod.setOtherType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(StringBuilder builder) {
|
||||
builder.setLength(0);
|
||||
dmang.appendString(builder, modifierTypeName); // TODO: consider moving string here.
|
||||
public String getTypeName() {
|
||||
return "std::nullptr_t";
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -1156,6 +1156,22 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStdNullBackref() throws Exception {
|
||||
mangled = "?fn@@QAAHH$$T0@Z";
|
||||
mdTruth = "public: int __cdecl fn(int,std::nullptr_t,std::nullptr_t)";
|
||||
msTruth = mdTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_OBackref() throws Exception {
|
||||
mangled = "?fn@@QAAHH_OBY01H0@Z";
|
||||
mdTruth = "public: int __cdecl fn(int,int[][2],int[][2])";
|
||||
msTruth = mdTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecial__F() throws Exception {
|
||||
mangled =
|
||||
|
@ -1361,7 +1377,7 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testStdNullptrArgVar() throws Exception {
|
||||
mangled = "?Name@@3$$TA";
|
||||
msTruth = "std::nullptr_t";
|
||||
msTruth = "std::nullptr_t Name";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
@ -7389,7 +7405,7 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testDollarDollar_4() throws Exception {
|
||||
mangled = "?Name@@3$$TA"; //manufactured--interestingly, this is probably not valid: see mstruth. //This is a DataType $$T Modifier
|
||||
msTruth = "std::nullptr_t";
|
||||
msTruth = "std::nullptr_t Name";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
@ -9075,7 +9091,7 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
mangled = "?var@@3$$TA";
|
||||
//mstruth = "?var@@3$$TA";
|
||||
//mdtruth = "";
|
||||
msTruth = "std::nullptr_t";
|
||||
msTruth = "std::nullptr_t var";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
@ -9083,7 +9099,7 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
@Test
|
||||
public void testManagedProperties_DollarDollarT() throws Exception {
|
||||
mangled = "?var@@3$$T";
|
||||
msTruth = "std::nullptr_t";
|
||||
msTruth = "std::nullptr_t var";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
@ -14685,6 +14701,46 @@ public class MDMangBaseTest extends AbstractGenericTest {
|
|||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLRefToFunction() throws Exception {
|
||||
mangled = "?var@@3A6AHH@ZA";
|
||||
msTruth = "int (__cdecl& var)(int)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRRefToFunction() throws Exception {
|
||||
mangled = "?var@@3$$R6AHH@ZA";
|
||||
msTruth = "int (__cdecl&& var)(int)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifierToLRefToFunction() throws Exception {
|
||||
mangled = "?var@@3?DA6AHH@ZA";
|
||||
msTruth = "int (__cdecl&const volatile var)(int)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifierToRRefToFunction() throws Exception {
|
||||
mangled = "?var@@3?D$$R6AHH@ZA";
|
||||
msTruth = "int (__cdecl&&const volatile var)(int)";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedModifiersWithArrayProperties() throws Exception {
|
||||
mangled = "?var@@3PAY01$$RAY01HA";
|
||||
msTruth = "int (&& (* var)[2])[2]";
|
||||
mdTruth = msTruth;
|
||||
demangleAndTest();
|
||||
}
|
||||
|
||||
//TODO: ignore for now.
|
||||
@Ignore
|
||||
public void testFuzzyFit() throws Exception {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue