mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 14:20:11 +08:00
GP-6526 - MicrosoftDemangler - fix logic and tests for argument tags
This commit is contained in:
@@ -227,6 +227,14 @@ public class MDDataType extends MDType {
|
|||||||
}
|
}
|
||||||
// super.insert(builder);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|||||||
+5
-1
@@ -65,12 +65,16 @@ public class MDComplexType extends MDDataType {
|
|||||||
super.insert(builder);
|
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?
|
// TODO: look at what needs to be done to get rid of this?
|
||||||
if ((builder.length() != 0) && (builder.charAt(0) != ' ')) {
|
if ((builder.length() != 0) && (builder.charAt(0) != ' ')) {
|
||||||
dmang.insertString(builder, " ");
|
dmang.insertString(builder, " ");
|
||||||
}
|
}
|
||||||
qualifiedName.insert(builder);
|
qualifiedName.insert(builder);
|
||||||
|
if (dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
||||||
|
super.insert(builder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ public class MDArrayBasicType extends MDModifierType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void insertReferredType(StringBuilder builder) {
|
protected void insertReferredType(StringBuilder builder, boolean isArg) {
|
||||||
StringBuilder arrayBuilder = new StringBuilder();
|
StringBuilder arrayBuilder = new StringBuilder();
|
||||||
arrayBuilder.append("[]");
|
arrayBuilder.append("[]");
|
||||||
MDType dt = this.refType;
|
MDType dt = this.refType;
|
||||||
|
|||||||
+21
-6
@@ -204,12 +204,27 @@ public abstract class MDModifierType extends MDDataType {
|
|||||||
dmang.cleanOutput(builder); // 20170714
|
dmang.cleanOutput(builder); // 20170714
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void insertReferredType(StringBuilder builder) {
|
protected void insertReferredType(StringBuilder builder, boolean asArg) {
|
||||||
refType.insert(builder);
|
// 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
|
@Override
|
||||||
public void insert(StringBuilder builder) {
|
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
|
// Added 20170412 to try have available to get MSFT affect on this
|
||||||
// "invalid" condition.
|
// "invalid" condition.
|
||||||
// if (cvMod.isBasedPtrBased()) {
|
// if (cvMod.isBasedPtrBased()) {
|
||||||
@@ -274,12 +289,12 @@ public abstract class MDModifierType extends MDDataType {
|
|||||||
// builder.insertString(" "); //20160701
|
// builder.insertString(" "); //20160701
|
||||||
if (refType instanceof MDArrayReferencedType) {
|
if (refType instanceof MDArrayReferencedType) {
|
||||||
// 20170714 refType.insert(builder);
|
// 20170714 refType.insert(builder);
|
||||||
insertReferredType(builder);// 20170714
|
insertReferredType(builder, asArg);// 20170714
|
||||||
}
|
}
|
||||||
else if (cvMod.isPinPointer()) {
|
else if (cvMod.isPinPointer()) {
|
||||||
StringBuilder refBuilder = new StringBuilder();
|
StringBuilder refBuilder = new StringBuilder();
|
||||||
// 20170714 refType.insert(refBuilder);
|
// 20170714 refType.insert(refBuilder);
|
||||||
insertReferredType(refBuilder);// 20170714
|
insertReferredType(refBuilder, asArg);// 20170714
|
||||||
dmang.appendString(refBuilder, " ");
|
dmang.appendString(refBuilder, " ");
|
||||||
if (!(cvMod.isQuestionType() ||
|
if (!(cvMod.isQuestionType() ||
|
||||||
(cvMod.isPointerType() && (refType instanceof MDVoidDataType)))) {
|
(cvMod.isPointerType() && (refType instanceof MDVoidDataType)))) {
|
||||||
@@ -296,7 +311,7 @@ public abstract class MDModifierType extends MDDataType {
|
|||||||
else if (cvMod.isCLIArray()) {
|
else if (cvMod.isCLIArray()) {
|
||||||
StringBuilder refBuilder = new StringBuilder();
|
StringBuilder refBuilder = new StringBuilder();
|
||||||
// 20170714 refType.insert(refBuilder);
|
// 20170714 refType.insert(refBuilder);
|
||||||
insertReferredType(refBuilder);// 20170714
|
insertReferredType(refBuilder, asArg);// 20170714
|
||||||
if (!(refType instanceof MDVoidDataType)) {
|
if (!(refType instanceof MDVoidDataType)) {
|
||||||
cvMod.insertManagedPropertiesPrefix(refBuilder);
|
cvMod.insertManagedPropertiesPrefix(refBuilder);
|
||||||
// cvMod.insertManagedProperties(refBuilder);
|
// cvMod.insertManagedProperties(refBuilder);
|
||||||
@@ -319,7 +334,7 @@ public abstract class MDModifierType extends MDDataType {
|
|||||||
// }
|
// }
|
||||||
// //Could be function (function pointer or function) or data.
|
// //Could be function (function pointer or function) or data.
|
||||||
// 20170714 refType.insert(builder);
|
// 20170714 refType.insert(builder);
|
||||||
insertReferredType(builder);// 20170714
|
insertReferredType(builder, asArg);// 20170714
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -119,13 +119,7 @@ public class MDArgumentsList extends MDParsableItem {
|
|||||||
}
|
}
|
||||||
firstArgDone = true;
|
firstArgDone = true;
|
||||||
StringBuilder argBuilder = new StringBuilder();
|
StringBuilder argBuilder = new StringBuilder();
|
||||||
if (arg instanceof MDComplexType ct &&
|
arg.insertAsArg(argBuilder);
|
||||||
!dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
|
||||||
ct.insertWithoutComplexTag(argBuilder);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
arg.insert(argBuilder);
|
|
||||||
}
|
|
||||||
dmang.appendString(builder, argBuilder.toString().trim());
|
dmang.appendString(builder, argBuilder.toString().trim());
|
||||||
// doing toString() allows the Based5 "bug" to be cleaned per parameter.
|
// doing toString() allows the Based5 "bug" to be cleaned per parameter.
|
||||||
// possible: dmang.appendString(builder, arg.toString().trim());
|
// possible: dmang.appendString(builder, arg.toString().trim());
|
||||||
|
|||||||
+2
-8
@@ -202,19 +202,13 @@ public class MDTemplateArgumentsList extends MDParsableItem {
|
|||||||
if (args.size() > 0) {
|
if (args.size() > 0) {
|
||||||
// boolean firstArgDone = false;
|
// boolean firstArgDone = false;
|
||||||
Iterator<Boolean> delimIter = commaDelimiter.iterator();
|
Iterator<Boolean> delimIter = commaDelimiter.iterator();
|
||||||
for (MDType arg : args) {
|
for (MDDataType arg : args) {
|
||||||
if (delimIter.next()) {
|
if (delimIter.next()) {
|
||||||
dmang.appendString(builder, ",");
|
dmang.appendString(builder, ",");
|
||||||
}
|
}
|
||||||
// firstArgDone = true;
|
// firstArgDone = true;
|
||||||
StringBuilder argBuilder = new StringBuilder();
|
StringBuilder argBuilder = new StringBuilder();
|
||||||
if (arg instanceof MDComplexType ct &&
|
arg.insertAsArg(argBuilder);
|
||||||
!dmang.getOutputOptions().applyUdtArgumentTypeTag()) {
|
|
||||||
ct.insertWithoutComplexTag(argBuilder);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
arg.insert(argBuilder);
|
|
||||||
}
|
|
||||||
dmang.appendString(builder, argBuilder.toString());
|
dmang.appendString(builder, argBuilder.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+50
@@ -299,6 +299,56 @@ public class DemangledFunctionTest extends AbstractGhidraHeadlessIntegrationTest
|
|||||||
assertTrue(demangled instanceof DemangledFunction);
|
assertTrue(demangled instanceof DemangledFunction);
|
||||||
assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY));
|
assertTrue(demangled.applyTo(program, addr, options, TaskMonitor.DUMMY));
|
||||||
|
|
||||||
|
String className =
|
||||||
|
"F<E::D::G<E::D::H<bool_(__cdecl*const)(C::B_const&),0>,bool,C::B_const&>_>";
|
||||||
|
String functionName = className + "<E::D::A<bool,C::B_const&>_>";
|
||||||
|
|
||||||
|
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 =
|
String className =
|
||||||
"F<class_E::D::G<struct_E::D::H<bool_(__cdecl*const)(enum_C::B_const&),0>,bool,enum_C::B_const&>_>";
|
"F<class_E::D::G<struct_E::D::H<bool_(__cdecl*const)(enum_C::B_const&),0>,bool,enum_C::B_const&>_>";
|
||||||
String functionName = className + "<class_E::D::A<bool,enum_C::B_const&>_>";
|
String functionName = className + "<class_E::D::A<bool,enum_C::B_const&>_>";
|
||||||
|
|||||||
Reference in New Issue
Block a user