Merge remote-tracking branch 'origin/GP-3671_ghizard_simple_MDMang_improvements--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-08-02 08:15:21 -04:00
commit a6d44ac41a
17 changed files with 245 additions and 350 deletions

View file

@ -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 {
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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();
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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 {
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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;
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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);
}
}

View file

@ -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());
// }
}

View file

@ -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;

View file

@ -34,12 +34,4 @@ public class MDDataReferenceType extends MDModifierType {
super.parseInternal();
}
@Override
// Override because Array is not allowed.
protected void parseArrayProperty() throws MDException {
return;
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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);
}
}

View file

@ -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)) {

View file

@ -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 {
}
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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()) {

View file

@ -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);
}
}

View file

@ -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()) {

View file

@ -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";
}
}
/******************************************************************************/
/******************************************************************************/

View file

@ -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 {