Merge remote-tracking branch 'origin/GP-3275_ghizard_MDMang_accessible_VxT_nested_parent_info--SQUASHED'

This commit is contained in:
Ryan Kurtz 2023-03-31 11:28:53 -04:00
commit 17a2dcd2ef
2 changed files with 76 additions and 22 deletions

View File

@ -15,6 +15,9 @@
*/
package mdemangler.typeinfo;
import java.util.ArrayList;
import java.util.List;
import mdemangler.*;
import mdemangler.datatype.modifier.MDCVMod;
import mdemangler.naming.MDQualification;
@ -24,23 +27,37 @@ import mdemangler.naming.MDQualification;
* derivatives actually do anything at this time, but they are two very
* different types of tables in C++ and serve as place holders for future
* processing. I created MDVxTable, where the 'x' is 'b' or 'f' of
* MDVbTable or MDVfTable, respectively.
* MDVbTable or MDVfTable, respectively.
*/
public class MDVxTable extends MDTypeInfo {
private MDCVMod cvmod;
private List<MDQualification> nestedQualifications;
private boolean goodNestedTermination;
// String name = "";
public MDVxTable(MDMang dmang) {
super(dmang);
mdtype = new MDType(dmang);
cvmod = new MDCVMod(dmang);
nestedQualifications = new ArrayList<>();
goodNestedTermination = false;
}
public MDCVMod getCVMod() {
return cvmod;
}
/**
* Returns the list of MDQualification that I believe show the nested ownership within
* class parents
* @return the list of qualifications
*/
public List<MDQualification> getNestedQualifications() {
return nestedQualifications;
}
public boolean isConst() {
return cvmod.isConst();
}
@ -65,37 +82,47 @@ public class MDVxTable extends MDTypeInfo {
@Override
protected void parseInternal() throws MDException {
cvmod.parse();
boolean first = true;
StringBuilder modNameBuilder = new StringBuilder();
while ((dmang.peek() != '@') && (dmang.peek() != MDMang.DONE)) {
MDQualification qualification = new MDQualification(dmang);
qualification.parse();
StringBuilder qnameBuilder = new StringBuilder();
qualification.insert(qnameBuilder);
if (first) {
dmang.appendString(modNameBuilder, qnameBuilder.toString());
first = false;
}
else {
dmang.appendString(modNameBuilder, "'s `");
dmang.appendString(modNameBuilder, qnameBuilder.toString());
}
nestedQualifications.add(qualification);
}
// The first @ terminates the qualifier, the second terminates the qualified name
// (which is a list of qualifiers). If there is a third, it likely terminates the
// list of qualified names outside of the MDVxTable.
if (dmang.peek() == '@') {
dmang.increment();
if (!first) {
dmang.insertString(modNameBuilder, "{for `");
dmang.appendString(modNameBuilder, "'}");
}
goodNestedTermination = true;
}
else {
dmang.insertString(modNameBuilder, "{for ??}");
}
nameModifier = modNameBuilder.toString();
nameModifier = generateNameModifier();
}
String generateNameModifier() {
if (!goodNestedTermination) {
return "{for ??}";
}
if (nestedQualifications.isEmpty()) {
return "";
}
boolean first = true;
StringBuilder modNameBuilder = new StringBuilder();
dmang.appendString(modNameBuilder, "{for `");
for (MDQualification qualification : nestedQualifications) {
StringBuilder qnameBuilder = new StringBuilder();
qualification.insert(qnameBuilder);
if (first) {
first = false;
}
else {
dmang.appendString(modNameBuilder, "'s `");
}
dmang.appendString(modNameBuilder, qnameBuilder.toString());
}
dmang.appendString(modNameBuilder, "'}");
return modNameBuilder.toString();
}
}
/******************************************************************************/

View File

@ -15,12 +15,17 @@
*/
package mdemangler;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import generic.test.AbstractGenericTest;
import ghidra.app.util.demangler.DemangledObject;
import mdemangler.naming.MDQualification;
import mdemangler.object.MDObjectCPP;
import mdemangler.typeinfo.MDVxTable;
/**
* This class performs extra demangler testing for special cases that do not fit
@ -53,4 +58,26 @@ public class MDMangExtraTest extends AbstractGenericTest {
demangled = item.toString();
assertEquals(functionNamespaceTruth, demangled);
}
@Test
public void testVxTableNestedQualifications() throws Exception {
// Test string taken from MDMangBaseTest
String mangled = "??_7a@b@@6Bc@d@e@@f@g@h@@i@j@k@@@";
String truth = "const b::a::`vftable'{for `e::d::c's `h::g::f's `k::j::i'}";
MDMangGhidra demangler = new MDMangGhidra();
MDParsableItem item = demangler.demangle(mangled, true);
String demangled = item.toString();
assertEquals(truth, demangled);
MDObjectCPP cppItem = (MDObjectCPP) item;
MDVxTable vxTable = (MDVxTable) cppItem.getTypeInfo();
List<MDQualification> qualifications = vxTable.getNestedQualifications();
assertEquals(3, qualifications.size());
assertEquals("e::d::c", qualifications.get(0).toString());
assertEquals("h::g::f", qualifications.get(1).toString());
assertEquals("k::j::i", qualifications.get(2).toString());
}
}