diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataType.java index 84f723170b..0dd6bac35a 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataType.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. @@ -227,6 +227,14 @@ public class MDDataType extends MDType { } // super.insert(builder); } + + /** + * Insert this type as though it is an template or function argument + * @param the builder to which the insertion is made + */ + public void insertAsArg(StringBuilder builder) { + insert(builder); + } } /******************************************************************************/ diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/complex/MDComplexType.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/complex/MDComplexType.java index 9e6b7641e9..b88de1cbcf 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/complex/MDComplexType.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/complex/MDComplexType.java @@ -65,12 +65,16 @@ public class MDComplexType extends MDDataType { super.insert(builder); } - public void insertWithoutComplexTag(StringBuilder builder) { + @Override + public void insertAsArg(StringBuilder builder) { // TODO: look at what needs to be done to get rid of this? if ((builder.length() != 0) && (builder.charAt(0) != ' ')) { dmang.insertString(builder, " "); } qualifiedName.insert(builder); + if (dmang.getOutputOptions().applyUdtArgumentTypeTag()) { + super.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 23031bde9a..9298776795 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 @@ -44,7 +44,7 @@ public class MDArrayBasicType extends MDModifierType { } @Override - protected void insertReferredType(StringBuilder builder) { + protected void insertReferredType(StringBuilder builder, boolean isArg) { StringBuilder arrayBuilder = new StringBuilder(); arrayBuilder.append("[]"); MDType dt = this.refType; 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 5d0d1d3b54..51ed2e4872 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 @@ -204,12 +204,27 @@ public abstract class MDModifierType extends MDDataType { dmang.cleanOutput(builder); // 20170714 } - protected void insertReferredType(StringBuilder builder) { - refType.insert(builder); + protected void insertReferredType(StringBuilder builder, boolean asArg) { + // LATER: Investigate weather we can change refType definition from MDType to MDDataType + if (refType instanceof MDDataType mdt && asArg) { + mdt.insertAsArg(builder); + } + else { + refType.insert(builder); + } } @Override public void insert(StringBuilder builder) { + insertInternal(builder, false); + } + + @Override + public void insertAsArg(StringBuilder builder) { + insertInternal(builder, true); + } + + private void insertInternal(StringBuilder builder, boolean asArg) { // Added 20170412 to try have available to get MSFT affect on this // "invalid" condition. // if (cvMod.isBasedPtrBased()) { @@ -274,12 +289,12 @@ public abstract class MDModifierType extends MDDataType { // builder.insertString(" "); //20160701 if (refType instanceof MDArrayReferencedType) { // 20170714 refType.insert(builder); - insertReferredType(builder);// 20170714 + insertReferredType(builder, asArg);// 20170714 } else if (cvMod.isPinPointer()) { StringBuilder refBuilder = new StringBuilder(); // 20170714 refType.insert(refBuilder); - insertReferredType(refBuilder);// 20170714 + insertReferredType(refBuilder, asArg);// 20170714 dmang.appendString(refBuilder, " "); if (!(cvMod.isQuestionType() || (cvMod.isPointerType() && (refType instanceof MDVoidDataType)))) { @@ -296,7 +311,7 @@ public abstract class MDModifierType extends MDDataType { else if (cvMod.isCLIArray()) { StringBuilder refBuilder = new StringBuilder(); // 20170714 refType.insert(refBuilder); - insertReferredType(refBuilder);// 20170714 + insertReferredType(refBuilder, asArg);// 20170714 if (!(refType instanceof MDVoidDataType)) { cvMod.insertManagedPropertiesPrefix(refBuilder); // cvMod.insertManagedProperties(refBuilder); @@ -319,7 +334,7 @@ public abstract class MDModifierType extends MDDataType { // } // //Could be function (function pointer or function) or data. // 20170714 refType.insert(builder); - insertReferredType(builder);// 20170714 + insertReferredType(builder, asArg);// 20170714 } } } diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/functiontype/MDArgumentsList.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/functiontype/MDArgumentsList.java index 6bae505175..5d2859c945 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/functiontype/MDArgumentsList.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/functiontype/MDArgumentsList.java @@ -119,13 +119,7 @@ public class MDArgumentsList extends MDParsableItem { } firstArgDone = true; StringBuilder argBuilder = new StringBuilder(); - if (arg instanceof MDComplexType ct && - !dmang.getOutputOptions().applyUdtArgumentTypeTag()) { - ct.insertWithoutComplexTag(argBuilder); - } - else { - arg.insert(argBuilder); - } + arg.insertAsArg(argBuilder); dmang.appendString(builder, argBuilder.toString().trim()); // doing toString() allows the Based5 "bug" to be cleaned per parameter. // possible: dmang.appendString(builder, arg.toString().trim()); 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 d535457554..09ef697e81 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/template/MDTemplateArgumentsList.java @@ -202,19 +202,13 @@ public class MDTemplateArgumentsList extends MDParsableItem { if (args.size() > 0) { // boolean firstArgDone = false; Iterator delimIter = commaDelimiter.iterator(); - for (MDType arg : args) { + for (MDDataType arg : args) { if (delimIter.next()) { dmang.appendString(builder, ","); } // firstArgDone = true; StringBuilder argBuilder = new StringBuilder(); - if (arg instanceof MDComplexType ct && - !dmang.getOutputOptions().applyUdtArgumentTypeTag()) { - ct.insertWithoutComplexTag(argBuilder); - } - else { - arg.insert(argBuilder); - } + arg.insertAsArg(argBuilder); dmang.appendString(builder, argBuilder.toString()); } } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/DemangledFunctionTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/DemangledFunctionTest.java index cdca51a6f6..a565e079eb 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/DemangledFunctionTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/DemangledFunctionTest.java @@ -299,6 +299,56 @@ public class DemangledFunctionTest extends AbstractGhidraHeadlessIntegrationTest assertTrue(demangled instanceof DemangledFunction); assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY)); + String className = + "F,bool,C::B_const&>_>"; + String functionName = className + "_>"; + + Function function = assertFunction(functionName, addr); + assertNoBookmarkAt(addr); + + Symbol[] symbols = symbolTable.getSymbols(addr); + assertEquals(2, symbols.length); + assertEquals(functionName, symbols[0].getName()); + assertEquals(mangled, symbols[1].getName()); + + // Check for the Class 'this' pointer + Parameter[] parameters = function.getParameters(); + assertEquals(2, parameters.length); + Parameter p1 = parameters[0]; + assertEquals("this", p1.getName()); + assertEquals(className + " *", p1.getDataType().toString()); + + Namespace ns = symbols[0].getParentNamespace(); + assertEquals(className, ns.getName(false)); + ns = ns.getParentNamespace(); + assertEquals("E", ns.getName(false)); + } + + @Test + public void testFunctionThisPointerWithTags() throws Exception { + + // + // Test a function within a class that has a 'this' pointer + // + + String mangled = + "??$?0V?$A@_NABW4B@C@@@D@E@@@?$F@V?$G@U?$H@Q6A_NABW4B@C@@@Z$0A@@D@E@@_NABW4B@C@@@D@E@@@E@@QAE@ABV?$F@V?$A@_NABW4B@C@@@D@E@@@1@@Z"; + Address addr = addr("0x0101"); + + SymbolTable symbolTable = program.getSymbolTable(); + symbolTable.createLabel(addr, mangled, SourceType.IMPORTED); + + MicrosoftDemangler demangler = new MicrosoftDemangler(); + MangledContext mangledContext = + demangler.createMangledContext(mangled, + MicrosoftDemanglerOptions.DEFAULT_UNDERLYING_OUTPUT, program, addr); + DemanglerOptions options = mangledContext.getOptions(); + // TODO: need direct way to change "for function" vs. just address and program; which might mean MicrosoftDemanglerContext + //mangledContext.setIsFunction(true); + DemangledObject demangled = demangler.demangle(mangledContext); + assertTrue(demangled instanceof DemangledFunction); + assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY)); + String className = "F,bool,enum_C::B_const&>_>"; String functionName = className + "_>";