diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMang.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMang.java index 51bc11287e..38a7bcdae0 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMang.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMang.java @@ -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 { } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java index a6784da73d..829c1390c3 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java @@ -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(); } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangVS2015.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangVS2015.java index c061f08b65..ac4c53182a 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangVS2015.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangVS2015.java @@ -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 { } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataTypeParser.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataTypeParser.java index 66cb0a1109..1349bcbe38 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataTypeParser.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataTypeParser.java @@ -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(); - break; - case 'Q': - pt.setConst(); - pt.clearVolatile(); - break; - case 'S': - pt.setConst(); - pt.setVolatile(); - break; - } - } + dt = new MDPointerType(dmang, isHighest, false, false); + break; + case 'Q': + dt = new MDPointerType(dmang, isHighest, true, false); + break; + case 'R': + dt = new MDPointerType(dmang, isHighest, false, true); + break; + case 'S': + 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; } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/extended/MDArrayReferencedType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/extended/MDArrayReferencedType.java index 17e5620e8b..54952ade0c 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/extended/MDArrayReferencedType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/extended/MDArrayReferencedType.java @@ -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); } } diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDArrayBasicType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDArrayBasicType.java index 7f7784df22..5aa8350813 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDArrayBasicType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDArrayBasicType.java @@ -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()); - // } } diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDCVMod.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDCVMod.java index 705363074f..5b36be3f25 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDCVMod.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDCVMod.java @@ -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; diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataReferenceType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataReferenceType.java index 8e29735c7c..dae57d4792 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataReferenceType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataReferenceType.java @@ -34,12 +34,4 @@ public class MDDataReferenceType extends MDModifierType { super.parseInternal(); } - @Override - // Override because Array is not allowed. - protected void parseArrayProperty() throws MDException { - return; - } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataRightReferenceType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataRightReferenceType.java index 0bde39e1d6..c5249032dd 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataRightReferenceType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDDataRightReferenceType.java @@ -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); + } +} diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifiedTypeParser.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifiedTypeParser.java index c7cd2fea61..6b4f905af4 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifiedTypeParser.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifiedTypeParser.java @@ -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)) { diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifierType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifierType.java index 33da85f73e..e9702f14b5 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifierType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDModifierType.java @@ -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 { } } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDPointerType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDPointerType.java index 2e92ad7196..5d8001cf09 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDPointerType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDPointerType.java @@ -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()) { diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDQuestionModifierType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDQuestionModifierType.java new file mode 100644 index 0000000000..5bba64b58c --- /dev/null +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDQuestionModifierType.java @@ -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); + } +} diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDReferenceType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDReferenceType.java index ad4d44f6af..2cac310d7a 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDReferenceType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDReferenceType.java @@ -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()) { diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDStdNullPtrType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDStdNullPtrType.java index 114e69e838..d283ea4aa9 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDStdNullPtrType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/modifier/MDStdNullPtrType.java @@ -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"; } } - -/******************************************************************************/ -/******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java index e3d19224f9..0b30ec957d 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java @@ -4,9 +4,9 @@ * 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. diff --git a/Ghidra/Features/MicrosoftDmang/src/test/java/mdemangler/MDMangBaseTest.java b/Ghidra/Features/MicrosoftDmang/src/test/java/mdemangler/MDMangBaseTest.java index d5cbf0c447..de963a96c2 100644 --- a/Ghidra/Features/MicrosoftDmang/src/test/java/mdemangler/MDMangBaseTest.java +++ b/Ghidra/Features/MicrosoftDmang/src/test/java/mdemangler/MDMangBaseTest.java @@ -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 {